diff --git a/db/migrations/20180307213043_fixes_and_messages.js b/db/migrations/20180307213043_fixes_and_messages.js
new file mode 100644
index 0000000000000000000000000000000000000000..7c46a723b9ad3ae6efb4f501eb215e97dd1b0488
--- /dev/null
+++ b/db/migrations/20180307213043_fixes_and_messages.js
@@ -0,0 +1,44 @@
+
+exports.up = async function(knex, Promise) {
+    await knex.schema.renameTable("posts", "messages");
+    await knex.schema.table('messages', function(table){
+        table.renameColumn('description', 'content');
+    });
+    await knex.schema.createTable('announcements', function (table){
+        table.inherits('messages');
+    });
+    await knex.schema.createTable('events', function (table){
+        table.inherits('messages');
+        table.string('location');
+        table.dateTime('start_time');
+        table.dateTime('end_time');
+        table.boolean('is_announcement');
+    });
+    await knex.schema.createTable('group_message_relationships', function(table){
+        table.integer('message').notNullable();
+        table.string('group').notNullable();
+        table.enum('status', ['join', 'host', 'publish']).notNullable();
+    });
+    await knex.schema.createTable('user_participation', function(table){
+        table.integer('event').notNullable();
+        table.string('user_uid').notNullable();
+        table.enum('user_db', ['ldap']).notNullable().defaultTo('ldap');
+    });
+    return;
+};
+
+exports.down = async function(knex, Promise) {
+    await knex.schema.dropTable('group_message_relationships');
+    await knex.schema.dropTable('user_participation');
+    let event_posts = await knex.select().from('events');
+    let announcment_posts = await knex.select().from('announcements');
+    await knex.schema.dropTable('events');
+    await knex.schema.dropTable('announcements');
+    await knex.schema.renameTable('messages', 'posts');
+    await knex.schema.table('posts', function(table){
+        table.renameColumn('content', 'description');
+    });
+    await knex('messages').insert(event_posts);
+    await knex('messages').insert(announcment_posts);
+    return;
+};
diff --git a/src/graphql/connectors/connectors.js b/src/graphql/connectors/connectors.js
index ed0e679d7a4458831f1e52b673017ffd2a040d0b..9981605456b1e984d51bed623c261609ed8639ec 100644
--- a/src/graphql/connectors/connectors.js
+++ b/src/graphql/connectors/connectors.js
@@ -11,45 +11,45 @@ import { exportAllDeclaration } from 'babel-types';
 export { renseignerSurUtilisateur, repliquerTOLdesIds, listerMembres };
 
 /*
-Le tag @rights et la gestion des authorisations
-
-Le système GraphQL est pensé comme l'interface par laquelle les utilisateurs 
-intéragissent avec sigma, les graphismes en moins.
-Pour cette raison, et pour des questions de sécurité, il faut partir du principe que
-l'utilisateir peut rédiger n'importe quelle requête, et que c'est au niveau des resolvers
-que la sécurité ce déroule. C'est dans cette optique que j'utilise le tag @rights
-
-Commençons par un rappel sur le fonctionnement des droits. 
-Chaque utilisateur a un certain niveau de droit sur chaque groupe. Ce niveau de droit indique
-ce qu'il a le droit de savoir et de faire. Chaque niveau est inclu dans les niveaus supérieur.
-Les différends niveaux sont :
-none - aucun droit
-viewer : l'utilisateur a visibilité sur le groupe. Il sait que le groupe existe, et a accès à un certain nombre d'infos.
-member : l'utilisateur est membre du groupe
-speaker : l'utilisateur peut parler au nom du groupe. Il a le droit de publier des annonces et d'organiser des évènements
-admin : l'utilisateur a tous les droits sur le groupe
-
-Certaines fonctions de connectors effectuent des vérifications d'authorisations avant 
-de renvoyer une réponse, d'autres non. Pour être sur qu'on ne renvoie jamais de réponse
-sans avoir au préalable éffectué les bonnes vérifications, chaque fonction possède dans sa
-description un attribut droit, qui décrit les droits que fournit cette fonction.
-
-La valeur de @rights peut être :
-super - la fonction n'effectue aucune vérification, et renvoie le resultat demandé
-admin( groupUID ) - la fonction ne fait que ce qu'un admin du groupe indiqué aurait le droit de faire
-speaker( groupUID ), member( groupUID ), veiwer( groupUID ) - même chose
-user - la fonction ne fait que ce que l'utiliateur a le droit de faire (vérifications via l'argument user)
-
-La procédure a suivre est la suivante : quand une fonction possède un certain niveau de droit, 
-elle ne peut appeler une fonction possédant un niveau de droit plus large que si 
-1 ) on a au préalable vérifié que l'utilisateur possédait effectivement ces droits. 
-ou
-2 ) on s'est assuré que l'opération effectuée par cet appel particulier de la fonction était dans les droits
-de l'utilisateur
-
-Les resolvers de base de mutation et query ont des droits user.
-
-Les fonctions qui ne modifient pas la BDD et ne renvoient pas de données sur la BDD n'ont pas de rights.
+    Le tag @rights et la gestion des authorisations
+
+    Le système GraphQL est pensé comme l'interface par laquelle les utilisateurs 
+    intéragissent avec sigma, les graphismes en moins.
+    Pour cette raison, et pour des questions de sécurité, il faut partir du principe que
+    l'utilisateir peut rédiger n'importe quelle requête, et que c'est au niveau des resolvers
+    que la sécurité ce déroule. C'est dans cette optique que j'utilise le tag @rights
+
+    Commençons par un rappel sur le fonctionnement des droits. 
+    Chaque utilisateur a un certain niveau de droit sur chaque groupe. Ce niveau de droit indique
+    ce qu'il a le droit de savoir et de faire. Chaque niveau est inclu dans les niveaus supérieur.
+    Les différends niveaux sont :
+    none - aucun droit
+    viewer : l'utilisateur a visibilité sur le groupe. Il sait que le groupe existe, et a accès à un certain nombre d'infos.
+    member : l'utilisateur est membre du groupe
+    speaker : l'utilisateur peut parler au nom du groupe. Il a le droit de publier des annonces et d'organiser des évènements
+    admin : l'utilisateur a tous les droits sur le groupe
+
+    Certaines fonctions de connectors effectuent des vérifications d'authorisations avant 
+    de renvoyer une réponse, d'autres non. Pour être sur qu'on ne renvoie jamais de réponse
+    sans avoir au préalable éffectué les bonnes vérifications, chaque fonction possède dans sa
+    description un attribut droit, qui décrit les droits que fournit cette fonction.
+
+    La valeur de @rights peut être :
+    super - la fonction n'effectue aucune vérification, et renvoie le resultat demandé
+    admin( groupUID ) - la fonction ne fait que ce qu'un admin du groupe indiqué aurait le droit de faire
+    speaker( groupUID ), member( groupUID ), veiwer( groupUID ) - même chose
+    user - la fonction ne fait que ce que l'utiliateur a le droit de faire (vérifications via l'argument user)
+
+    La procédure a suivre est la suivante : quand une fonction possède un certain niveau de droit, 
+    elle ne peut appeler une fonction possédant un niveau de droit plus large que si 
+    1 ) on a au préalable vérifié que l'utilisateur possédait effectivement ces droits. 
+    ou
+    2 ) on s'est assuré que l'opération effectuée par cet appel particulier de la fonction était dans les droits
+    de l'utilisateur
+
+    Les resolvers de base de mutation et query ont des droits user.
+
+    Les fonctions qui ne modifient pas la BDD et ne renvoient pas de données sur la BDD n'ont pas de rights.
 */
 
 
@@ -420,15 +420,78 @@ export const getUser = (user, userUID) => {
     return result;
 };
 
+export async function getVisibleAnnouncementsCallback(user){
+    return query_builder => {
+        return query_builder;
+    };
+};
+
+export async function getVisibleEventsCallback(user){
+    return query_builder => {
+        return query_builder;
+    };
+};
+
 /**
- * @function Renvoie un événement en fonction de son identifiant.
+ * @summary Renvoie un message en fonction de son identifiant.
  * @param {*} user - Utilisateur effectuant la requête.
  * @param {*} eventID - Identifiant unique de l'événement.
+ * @rights super
  */
-export const getEvent = (user, eventID) => {
-    return quickPromise(null);
+export async function getMessage(user, messageID){
+    let announcement = await knex.select().from('announcements').where('id', messageID);
+    if(announcement){
+        let res = announcement[0];
+        res.type = "Announcement"
+        return res;
+    }
+    let event = await knex.select().from('events').where('id', messageID);
+    if(event){
+        let res = event[0];
+        res.type = "Event"
+        return res;
+    }
+    return undefined;
 };
 
+/**
+ * @summary Renvoie un message en fonction de son identifiant.
+ * @param {*} user - Utilisateur effectuant la requête.
+ * @param {*} eventID - Identifiant unique de l'événement.
+ * @rights super
+ */
+export async function getMessageIfVisible(user, messageID){
+    let announcement = await knex
+        .with('visible_announcements', await getVisibleAnnouncementsCallback(user))
+        .select().from('visible_announcements').where('id', messageID);
+    if(announcement){
+        let res = announcement[0];
+        res.type = "Announcement"
+        return res;
+    }
+    let event = await knex
+        .with('visible_events', await getVisibleEventsCallback(user))
+        .select().from('visible_events').where('id', messageID);
+    if(event){
+        let res = event[0];
+        res.type = "Event"
+        return res;
+    }
+    return undefined;
+};
+
+
+export async function getMessageHostsCallback(user, messageID){
+    return function(query_builder){
+        return query_builder.select('group').from('group_message_relationships')
+            .where('message', messageID);
+    }
+}
+
+export async function getMessageHosts(user, messageID){
+
+}
+
 /**
  * @summary Renvoie simplement un groupe en fonction de son identifiant.
  * @param {Object} user - Utilisateur effectuant la requête.
@@ -539,6 +602,55 @@ export async function getMetaGroupMemberUsers(user, metaGroupUID){
     }
 };
 
+function recursive_callback_intersecter(callbackList){
+    let cb = callbackList.pop();
+    if(callbackList){
+        let intersecter = recursive_callback_intersecter(callbackList);
+        return function(query_builder){
+            return knex.with('callback_set', cb)
+                        .with('intersection', intersection)
+                        .select('intersection.uid').from('intersection')
+                        .innerJoin('callback_set', function(){
+                            this.on('callback_set.uid', '=', 'intersection.uid');
+                        });
+        }
+    }else{
+        return cb;
+    }
+}
+
+export async function getSimpleGroupsFromCallbacks (user, cbList){
+    
+    let intersection = await recursive_callback_intersecter(cbList);
+    return knex.with('intersection', intersection).select().from("simple_groups")
+        .innerJoin('intersection', function (){
+        this.on('intersection.uid', '=', 'simple_groups.uid');
+    });
+}
+
+export async function getMetaGroupsFromCallbacks (user, cbList){
+    
+    let intersection = await recursive_callback_intersecter(cbList);
+    return knex.with('intersection', intersection).select().from("meta_groups")
+        .innerJoin('intersection', function (){
+        this.on('intersection.uid', '=', 'meta_groups.uid');
+    });
+}
+
+/**
+ * @summary Renvoie tous les groupes dans l'intersection définie par les callbacks
+ * @desc Cette fonction effectue une requête knex. Elle gère l'arête de parenté.
+ * @arg {Object} user - Représente l'utilisateur qui a effectué la requête. 
+ * @arg {String} wantedType - Type de groupe voulu : `"simple"`, `"meta"` ou `"all"`. 
+ * @return {Promise} Retour de requête knex. Liste de tous les groupes que l'utilisateur a le droit de voire.
+ * @rights user
+ */
+export async function getGroupsFromCallbacks(user, cbList){
+    let all_simple_groups = await getSimpleGroupsFromCallbacks(user, cbList);
+    let all_meta_groups = await getMetaGroupsFromCallbacks(user, cbList);
+    return all_simple_groups.concat(all_meta_groups);
+}
+
 
 /*
  * réflexion sur une façon possible de gérer les utilisateurs sans en demander trop à LDAP
diff --git a/src/graphql/resolvers.js b/src/graphql/resolvers.js
index 0ba5f15f2b999610a919638547628c8453d9ae42..5539fc0896185343ef3fb4058e33f4540b0dca47 100644
--- a/src/graphql/resolvers.js
+++ b/src/graphql/resolvers.js
@@ -261,6 +261,35 @@ export const resolvers = {
         }
     },
 
+    Message: {
+
+        __resolveType: function(obj){
+            return obj.type;
+        }
+
+    },
+
+    Announcement: {
+        forEvent : function(obj, args, context){
+            // le champ is_announcement n'existe que sur les Events
+            // une ligne de la bdd events peut résoudre comme évènement ou comme annonce
+            if(obj.is_announcement) 
+                return obj;
+            else
+                return null;
+        }
+    },
+
+    Event: {
+        asAnnouncement : function(obj, args, context){
+            // le champ is_announcement indique si il existe une annonce qui va avec l'évènement
+            // une ligne de la bdd events peut résoudre comme évènement ou comme annonce
+            if(obj.is_announcement) 
+                return obj;
+            else
+                return null;
+        }
+    },
 
     // @rights viewer(obj.uid)
     Group: {
diff --git a/src/graphql/typeDefs/actions.js b/src/graphql/typeDefs/actions.js
index 53a982caeb0e23860aa0b4ba87f297f85cc7356c..6e0fad9e9fa94bb479455bdfe017373067f5ea4a 100644
--- a/src/graphql/typeDefs/actions.js
+++ b/src/graphql/typeDefs/actions.js
@@ -87,7 +87,7 @@ const subQueries = `
         allMessages: [Message]
         allEvents: [Event]
         allPosts: [Post]
-        post(id: ID): Post
+        message(id: ID): Message
         allAnnouncements: [Announcement]
     }
 
diff --git a/src/graphql/typeDefs/objects.js b/src/graphql/typeDefs/objects.js
index 454dabc24c384d6330983356271208051557a7f7..5c580f7f582c5efc163f0d6d17233482a4d58ea2 100644
--- a/src/graphql/typeDefs/objects.js
+++ b/src/graphql/typeDefs/objects.js
@@ -84,6 +84,7 @@ const Message = `
         id: ID!
         # Titre du message
         title: String!
+        content: String
         createdAt: String!
         updatedAt: String!
         # Auteur(s) du message
@@ -99,7 +100,7 @@ const Post = `
         createdAt: String!
         updatedAt: String!
         authors: [Group]
-        description: String!
+        content: String!
     }
 `;
 
@@ -111,8 +112,10 @@ const Announcement = `
         createdAt: String!
         updatedAt: String!
         authors: [Group]
-        description: String!
+        content: String!
+        importance: Int
         views: Int
+        forEvent : Event
     }
 `;
 
@@ -134,6 +137,7 @@ const Event = `
         participatingGroups: [Group]
         participatingUsers: [User]
         description: String
+        asAnnouncement : Announcment
     }
 `;