Discussions
29 routes. Chemins relatifs à https://api.nexus-engine.eu/api/v1.
GET
/projects/:id/messages
Le fil de discussion d’équipe d’un projet.
Requêtelimit (≤ 200, défaut 100), query (recherche dans le texte), avant (identifiant d’un message : la page plus ancienne que lui)
RéponseMessageDto[]
POST
/projects/:id/messages
Poste un message dans le fil d’un projet. Citer quelqu’un (mentions) l’AFFECTE à ce projet. Écrit comme la personne l’écrirait : un accueil tient en « @Prénom Nom Voici le projet nexus://projet/<id> », son identifiant dans mentions.
Corpscontent, replyToId, citations (session, task, file, diff), mentions (identifiants de membres), attachments (liste de {name, mimeType, dataBase64})
RéponseMessageDto
NoteL’affectation suit la règle des tâches, quel que soit le rôle du cité : ajout seulement, jamais un retrait ; un affecté déjà en place n’est pas touché et un hérité de dossier reste hérité ; soi-même excepté (on ne s’appelle pas). Une citation qui ne désigne pas un membre ACTIF de cette entreprise est écartée SANS BRUIT — 200, l’identifiant ne figure pas dans les mentions rendues —, jamais un 400 qui apprendrait ce que l’identifiant désigne. Ce qui a été posé va au journal (« affectation posée par une citation »), sans recopier le texte du message.
POST
/projects/:id/messages/lus
Dit que la personne a LU le fil d’un projet jusqu’à un message (l’application Message le fait) : ses citations et réponses de ce projet jusque-là passent lues, et la pastille « Messages » s’éteint sur ses écrans.
Corpsjusqua (date ISO du dernier message lu)
Réponse{ marquees }
NoteRien n’est « traité » : lire n’est pas répondre. Une citation arrivée après « jusqua » reste non lue.
GET
/messages/:id
Un message par son seul identifiant, quelle que soit sa table — ce que le lien de partage « nexus://message/<id> » désigne. Cherche dans la discussion d’un projet puis dans le fil d’une demande, chacune sous sa garde, et rend un seul « introuvable » : ni l’existence, ni le rangement ne transparaissent. Sans les pièces jointes, seulement leurs noms.
PATCH
/messages/:id
Modifie mon message. Les mentions sont recalculées depuis le texte.
Corpscontent
RéponseMessageDto
NoteContrairement à l’envoi, une citation ajoutée ici n’affecte PERSONNE et ne notifie personne : ces mentions-là ne viennent pas de l’appelant mais sont re-déduites du texte, par correspondance de noms sur l’annuaire de l’entreprise.
DELETE
/messages/:id
Supprime mon message.
POST
/messages/:id/reactions
Pose ou retire une réaction (👍, ❤️, ✅).
Corpsemoji
RéponseMessageDto
GET
/messages/:id/attachments/:attachmentId
Le contenu d’une pièce jointe de message, en base64.
Réponse{ name, mimeType, size, dataBase64 }
GET
/projects/:id/stream
Flux temps réel d’un projet (SSE) : messages, tâches, sessions, présence.
Réponsetext/event-stream, événements SseEvent
POST
/projects/:id/documents
Partage un document dans un projet : il monte au serveur, et le lien désigne cette copie. Le même contenu sous le même nom rend la ligne existante.
Corpsname, mimeType, dataBase64 (20 Mo décodés au plus)
RéponseDocumentPartageDto { id, projectId, name, mimeType, size, createdAt, uploadedByName, existait }
NoteUne copie datée, pas un fichier vivant : un contenu modifié fait une ligne neuve.
GET
/documents/:id
La fiche d’un document partagé — nom, taille, qui — sans son contenu. Lisible par qui a accès à son projet.
RéponseOmit<DocumentPartageDto, existait>
GET
/documents/:id/contenu
Le contenu d’un document partagé, en base64, sous la même règle d’accès que sa fiche.
RéponseDocumentPartageContenuDto
GET
/projects/:id/fichiers-ia
Les fichiers écrits par les agents du projet, toutes discussions confondues (archivées comprises, supprimées exclues) : une projection des relevés de chaque discussion, avec les marques (archivé, parti à la corbeille) et les documents partagés du même nom.
RéponseFichiersIaDto { fichiers: FichierIaDto[], aveugle, limites }
NoteSous mode aveugle, la liste est vide par construction et `aveugle` le dit. Les 500 discussions les plus récentes seulement.
PUT
/projects/:id/fichiers-ia/marque
session de l’application seulement
Pose ou retire une marque sur un fichier écrit par un agent : archivé (sort de la liste, reste sur le disque) ou parti à la corbeille du poste.
CorpsrelPath, archived?, deleted? (au moins un des deux)
RéponseMarqueFichierIaDto { relPath, archivedAt, archivedByName, deletedAt }
NoteLe geste d’une personne : la corbeille est celle du poste qui porte le fichier.
GET
/projects/:id/partages-fichiers
Les liens de partage à un tiers des fichiers IA du projet, les plus récents d’abord : état, expiration, consultations. Jamais le jeton.
RéponsePartageFichierDto[]
POST
/projects/:id/partages-fichiers
session de l’application seulement
Crée un lien web qui montre un fichier IA à un tiers, sans compte, pendant sept jours (`https://nexus-engine.eu/f#<jeton>`).
CorpsrelPath, name, dataBase64 (10 Mo au plus)
RéponsePartageFichierCreeDto { partage, lien }
NoteLe contenu MONTE sur le serveur : c’est une copie, figée, effacée à l’échéance. Refusé sous mode aveugle, pour un fichier qui n’est pas un document, et pour un nom de fichier de secrets. Le lien n’est rendu qu’ici, une fois ; un lien vivant portant déjà ce contenu est réemployé et `lien` est alors vide.
DELETE
/partages-fichiers/:id
Révoque un lien de partage de fichier : la page du tiers le dit aussitôt.
GET
/projects/:id/memoire
Ce que Nexus a retenu de ce projet : code indexé, sessions closes, décisions des discussions, notes. Pagination par curseur, ou recherche (`q`) par le même moteur que celui des agents.
Requêtekind, q, cursor, limit
RéponseMemoireObjetDto { items, suivant, projets }
NoteSous l’AFFECTATION, pas `requireAdmin` : l’écran d’administration voit toute l’entreprise et y supprime, celui-ci lit un projet. Un projet en mode aveugle rend ses lignes avec `retenu: AVEUGLE` et un extrait nul.
GET
/memoire/fragment/:id
Le contenu entier d’un fragment de mémoire, si son projet est à votre portée.
RéponseMemoireFragmentDetailDto
NoteUne route pour les trois fiches, gardée par `accesProjet` sur le projet DU fragment. Une note transversale (sans projet) n’est pas lisible ici : « introuvable », le même mot que pour une autre entreprise.
GET
/serveurs-application
Mes serveurs de discussion d’application (Message) : ceux des applications que je publie, ceux des applications que j’ai achetées (ou installées si elles sont gratuites), et ceux où un salon m’est ouvert. Chacun avec les SEULS salons que je lis.
Réponse{ serveurs: ServeurApplicationDto[] }
NotePersonne n’est AJOUTÉ à un serveur : l’appartenance se calcule à chaque requête des installations et des achats (remboursé ou désinstallé = sorti). Une application publiée avant ce chantier reçoit son serveur à la première lecture de son propriétaire.
GET
/serveurs-application/:id
Un serveur d’application : nom et icône de l’application, son propriétaire, s’il est fermé (application retirée, révoquée ou supprimée : il se lit encore, plus rien ne s’y écrit) et les salons que je lis. Le propriétaire reçoit aussi le NOMBRE de membres et les personnes nommées de chaque salon.
Réponse{ serveur: ServeurApplicationDto }
NoteUn serveur où l’on ne peut rien lire rend 404, comme un identifiant inexistant ou d’un autre espace.
GET
/serveurs-application/:id/personnes
Pour le propriétaire : les personnes qu’il peut NOMMER dans un salon « choisis » — les membres de son espace, et les membres du serveur qui se sont montrés en y écrivant — et le nombre de membres du serveur.
Réponse{ personnes: PersonneDuServeurDto[], membres: number }
NoteLes autres membres restent un nombre : avoir installé une application ne vaut pas se présenter à son éditeur. 403 `PROPRIETAIRE` pour un membre qui n’est pas le propriétaire.
POST
/serveurs-application/:id/salons
Le propriétaire crée un salon, avec sa portée : TOUS (les membres du serveur), CHOISIS (des personnes nommées), RESTREINT (lui seul) ou ESPACE (les membres de son espace de travail).
Corps{ nom, portee?: TOUS|CHOISIS|RESTREINT|ESPACE (défaut TOUS), choisis?: memberId[] }
Réponse{ serveur: ServeurApplicationDto, salonId, ecartes: string[] }
NoteUn nom proposé qui n’est pas nommable est ÉCARTÉ et rendu dans `ecartes`, jamais ajouté. Une clé d’API ne crée rien (403). 409 `FERME` sur un serveur fermé. Journal `serveur-application.salon-cree`.
PATCH
/serveurs-application/:id/salons/:salonId
Le propriétaire renomme un salon, le déplace, change sa PORTÉE après coup, ou remplace la liste de ses personnes choisies.
Corps{ nom?, portee?, choisis?: memberId[] (remplace la liste), position? }
Réponse{ serveur: ServeurApplicationDto, ecartes: string[] }
NoteQuitter « choisis » vide la liste. Journal `serveur-application.salon-modifie` (la portée et le NOMBRE de choisis, jamais leurs noms).
DELETE
/serveurs-application/:id/salons/:salonId
Le propriétaire supprime un salon, et ses messages avec lui.
Réponse{ serveur: ServeurApplicationDto }
NoteLe geste d’une personne : une clé d’API ou un agent reçoivent 403 `GESTE_D_UNE_PERSONNE`. Journal `serveur-application.salon-supprime`.
GET
/serveurs-application/:id/salons/:salonId/messages
Les messages d’un salon que je lis, par pages de 100, du plus ancien au plus récent ; `avant` pour la page précédente.
Requêteavant (identifiant d’un message)
Réponse{ messages: MessageSalonApplicationDto[], plusAnciens: boolean }
NoteL’auteur est nommé par son nom d’affichage — jamais son adresse ni son espace de travail.
POST
/serveurs-application/:id/salons/:salonId/messages
Écrire dans un salon que je lis, en mon nom.
Corps{ texte } (8 000 signes au plus)
Réponse{ message: MessageSalonApplicationDto }
NoteUne clé d’API n’écrit pas (403). 409 `FERME` quand l’application n’est plus publiée.
PATCH
/serveurs-application/:id/salons/:salonId/messages/:messageId
Modifier un de mes messages.
Corps{ texte }
Réponse{ message: MessageSalonApplicationDto }
DELETE
/serveurs-application/:id/salons/:salonId/messages/:messageId
Supprimer un de mes messages — ou, pour le propriétaire, n’importe quel message de son serveur.