Aller au contenu

Transferts

58 routes. Chemins relatifs à https://api.nexus-engine.eu/api/v1.

POST /transferts/:id/lectures session de l’application seulement

Les adresses signées d’un LOT de fichiers (1 à 100), pour une personne du transfert : c’est ce que l’application de bureau demande pour reconstruire l’envoi sur le disque.

Corpsfichiers: string[]
RéponseAutorisationsDto { lectures: LectureAutoriseeDto[], refus: { fichier, code, raison? }[] }
NoteUne PERSONNE en session, ou une DÉLÉGATION `nxt_…` qui porte RECEVOIR (lot 11 : le moteur du poste ou la commande `nexus-transfert` écrit les octets, le modèle ne voit jamais l’adresse) ; un agent par l’API ou une clé d’API reçoit 403. Un fichier non diffusable est refusé nommément, le lot n’échoue jamais en bloc. Un « téléchargement commencé » par fichier, pas deux pour le même membre dans les 10 minutes (une reprise). Plafond partagé avec la lecture d’un fichier seul : 600 par minute.
POST /transferts

Crée un transfert de fichiers (métadonnées seules) avec le premier lot de son manifeste, et réserve son quota. Projet facultatif : sans projet, seuls son auteur et les administrateurs le voient.

Corpstitre, message, projectId, genre (ENVOI, DEMANDE), expireDansJours (1 à 30, défaut 7), entrees (≤ 1 000 : { chemin, genre FICHIER | DOSSIER, taille, mime, sha256 }), complet (défaut vrai), v (1), origine? ({ sorte: STUDIO, creationId, version, sha256 } — lot 16)
RéponseTransfertDto (201 ; 200 quand la création est rejouée)
NoteEn-tête facultatif Idempotency-Key (8 à 128 caractères) : même clé et même corps rendent le même transfert, une autre requête sous la même clé est refusée 422 IDEMPOTENCE. Un lot porteur d’un seul chemin refusé est refusé en entier (400 CHEMIN_REFUSE, liste `chemins`). Quota plein : 507 QUOTA. Lot 16 : `origine` dit que le transfert est la COPIE d’une version du Studio ; elle est VÉRIFIÉE (création du projet `projectId`, version et empreinte — sinon 404 INTROUVABLE, comme un inexistant), écrite au fait CREATION et au journal, et refusée pour un envoi CONFIDENTIEL ou sans projet (409 ETAT, raison ORIGINE). La création ne bouge pas : l’expiration ou la suppression du transfert ne la touche pas.
POST /transferts/:id/manifeste

Ajoute un lot d’entrées (≤ 1 000) au manifeste d’un transfert ; `complet` le ferme.

Corpsentrees, complet (défaut faux), v (1)
Réponse{ transfert: TransfertDto, ajoutees }
NoteUn lot rejoué après une coupure n’écrit rien (`ajoutees: 0`). Un manifeste complet refuse toute entrée nouvelle (409 ETAT).
GET /transferts

Les transferts visibles, du plus récent au plus ancien.

Requêtelimite (1 à 100, défaut 50), curseur, projectId, creation, version (lot 16)
RéponsePageDto<TransfertDto> ({ elements, suivant })
NoteProjet en mode aveugle : un agent ou une clé reçoit les mesures seules (titre et message à null, mesuresSeules vrai). Lot 16 : `creation` (et `version`) ne rend que les transferts nés de cette création du Studio — « déjà partagée ? », pour proposer de partager l’existant plutôt que d’envoyer une copie de plus.
GET /transferts/stockage

L’état du stockage objet de Transfert : configuré ou non. Jamais un repli — sans stockage, les envois sont refusés (503 STOCKAGE_INDISPONIBLE, raison NON_CONFIGURE).

RéponseEtatStockageTransfertDto ({ configure, fournisseur?, hote?, region?, bucket?, chiffrement?, manque?, invalides?, stockageEntreprise? })
NoteLes détails (hôte, région, bucket, noms des variables manquantes) ne sont rendus qu’à un administrateur ; aucune clé ni aucun secret, jamais. Lot 15 : avec un bucket PROPRE actif, `stockageEntreprise` le nomme et `configure` dit s’il est utilisable — non utilisable, les envois sont refusés (503 `STOCKAGE_INDISPONIBLE`, raison `STOCKAGE_ENTREPRISE`), jamais envoyés chez Nexus en douce.
GET /transferts/stockages Owner et Admin

Lot 15 — les stockages PROPRES de l’entreprise (ses buckets S3) : fournisseur et région du catalogue, bucket, préfixe de clé, état (`A_VERIFIER`, `CONFORME`, `NON_CONFORME`, `EN_RETRAIT`, `RETIRE`, `REVOQUE`), dernier rapport de vérification et ce qui manque, transferts qui y vivent ; et où vont les nouveaux transferts.

RéponseStockagesEntrepriseDto { stockages: StockageEntrepriseDto[], essaiLocal, nouveauxTransferts }
NoteAdministrateurs seulement (403 REFUSE sinon). Aucune clé ni aucun secret : un préfixe de quatre caractères. `no-store`.
POST /transferts/stockages Owner et Admin session de l’application seulement

Connecte un bucket de l’entreprise : un fournisseur et une région du CATALOGUE (jamais une adresse libre), le bucket, sa clé, et une clé d’analyse en lecture seule facultative. Nexus le vérifie pour de vrai (privé, écriture, lecture signée, par plage, en pièce jointe, CORS, cycle de vie, droits de la clé d’analyse) et range le rapport. Rien n’est activé.

CorpsConnecterStockageInput { libelle, fournisseur, region, bucket, cle: { accessKeyId, secretAccessKey }, cleAnalyse?, chiffrementServeur?, port? }
RéponseStockageEntrepriseDto (201)
NoteUn administrateur, en session (`ROUTES_SESSION_SEULE`). Fournisseur ou région hors catalogue : 409 `ETAT` raison `FOURNISSEUR` ; le stockage local d’essai n’est proposé que si le serveur porte `NEXUS_TRANSFERT_STOCKAGE_LOCAL=1`. Les clés sont chiffrées et ne ressortent jamais. Journal `transfert.stockage-connecte`, sans secret.
POST /transferts/stockages/:id/verifier Owner et Admin session de l’application seulement

Revérifie le bucket pour de vrai et range le nouveau rapport (CONFORME ou NON_CONFORME).

RéponseStockageEntrepriseDto
NoteUn administrateur, en session. Clés effacées (retiré, révoqué) : 409 `ETAT` raison `STOCKAGE_RETIRE`. Le tour d’entretien revérifie aussi le stockage actif toutes les 24 h. Une autre entreprise : 404, comme un inexistant.
POST /transferts/stockages/:id/preparer Owner et Admin session de l’application seulement

Pose la règle CORS (les origines de la page de Nexus) et le cycle de vie (envois abandonnés, filet de purge) sur le bucket, puis le vérifie.

Réponse{ stockage: StockageEntrepriseDto, preparation: { cors, cycleDeVie } }
NoteUn administrateur, en session. Sans `NEXUS_TRANSFERT_S3_ORIGINES` au serveur : 409 `ETAT` raison `ORIGINES`. Journal `transfert.stockage-prepare`.
POST /transferts/stockages/:id/activer Owner et Admin session de l’application seulement

Les NOUVEAUX transferts de l’entreprise iront dans ce bucket. Un transfert garde à vie le stockage où il est né : rien ne bouge.

RéponseStockageEntrepriseDto
NoteUn administrateur, en session. Seul un stockage CONFORME s’active (409 `ETAT` raison `NON_CONFORME` sinon) ; un seul actif à la fois. Journal `transfert.stockage-active`.
POST /transferts/stockages/desactiver Owner et Admin session de l’application seulement

Revient au stockage de Nexus pour les nouveaux transferts. Aucun transfert ne bouge.

RéponseStockagesEntrepriseDto
NoteUn administrateur, en session. Journal `transfert.stockage-nexus`.
POST /transferts/stockages/:id/cles Owner et Admin session de l’application seulement

Change les clés (rotation) : les nouvelles sont VÉRIFIÉES sur le bucket avant d’être posées ; si elles échouent, les anciennes restent et le rapport dit pourquoi. Les transferts en cours continuent.

Corps{ cle: { accessKeyId, secretAccessKey }, cleAnalyse?: { … } | null }
Réponse{ applique: boolean, stockage: StockageEntrepriseDto, rapport: RapportStockageDto }
NoteUn administrateur, en session. `cleAnalyse: null` retire la clé d’analyse, absente la garde. Journal `transfert.stockage-cles` (avec `applique`), sans secret.
POST /transferts/stockages/:id/retirer Owner et Admin session de l’application seulement

Retire un stockage : plus aucun nouveau transfert ; ceux qui y vivent restent lisibles jusqu’à leur purge, puis le tour efface ses clés (`EN_RETRAIT` → `RETIRE`). Sans transfert vivant, c’est immédiat.

RéponseStockageEntrepriseDto
NoteUn administrateur, en session. Journal `transfert.stockage-retire`.
POST /transferts/stockages/:id/revoquer Owner et Admin session de l’application seulement

Révoque un stockage (une clé fuitée) : ses clés s’effacent sur-le-champ. Ses transferts ne se lisent plus depuis Nexus (503 `STOCKAGE_INDISPONIBLE` raison `RETIRE`) ; leurs objets restent chez le fournisseur, que le cycle de vie du bucket finit d’effacer.

RéponseStockageEntrepriseDto
NoteUn administrateur, en session. Irréversible : il faut reconnecter le bucket avec de nouvelles clés. Journal `transfert.stockage-revoque`.
GET /transferts/analyses/etat

L’état de l’analyse antivirale : les workers (état, moteur, âge des signatures, dernier battement), la file de l’entreprise (en attente, en cours, en échec, l’attente la plus ancienne) et les mesures des dernières 24 h (analyses, octets relus, temps de moteur, verdicts).

RéponseEtatAnalyseDto ({ workers, file, dernieres24h, limites })
NoteAdministrateurs seulement (403 sinon). Ni l’hôte ni le processus d’un worker, aucun nom de fichier, aucun prix : les mesures qui font le coût, écrites par les workers.
GET /transferts/:id

Le détail d’un transfert, sans aucune URL.

RéponseTransfertDto
NoteUn transfert d’une autre entreprise ou d’un projet non affecté est un 404, comme un identifiant inexistant.
GET /transferts/:id/fichiers

Les entrées du manifeste, par pages (un transfert peut en porter 100 000).

Requêtelimite (1 à 1 000, défaut 500), curseur
RéponsePageDto<TransfertFichierDto>
POST /transferts/:id/fichiers/:fileId/envoi

Ouvre (ou reprend) l’envoi d’un fichier du manifeste chez le stockage objet. Rend la géométrie : taille, taille de partie, nombre de parties.

Corps{} (aucun paramètre : le serveur décide de la taille des parties)
Réponse{ taille, taillePartie, nombreParties, vide?, finalise? }
NoteRejouée, elle REPREND l’envoi vivant au lieu d’en créer un second ; un envoi perdu par le stockage est remplacé. Fichier vide : `vide`, rien à envoyer, le serveur écrit l’objet. Fichier déjà finalisé : `finalise`. Stockage non configuré : 503 STOCKAGE_INDISPONIBLE (raison NON_CONFIGURE, non réessayable). Aucun octet ne passe par cette route.
POST /transferts/:id/fichiers/:fileId/parties

Signe un lot de parties (≤ 100) : une URL par partie, valable pour CET envoi et la taille EXACTE de la partie.

Corps{ numeros: number[] } (1 à 100 numéros, 1 à 10 000)
Réponse{ parties: [{ numero, url, entetes, expireA }] }
NoteLes URL sont des SECRETS de courte durée (15 min), rendues en `Cache-Control: no-store` : le client y envoie la partie par PUT, directement au stockage. Refusée à un agent (403 REFUSE) — une URL signée n’entre jamais dans le contexte d’un modèle ; l’envoi d’un agent passe par le poste. Un numéro au-delà du fichier : 409 ETAT, raison PARTIE_HORS_FICHIER, `parties`.
GET /transferts/:id/fichiers/:fileId/parties

Les parties que le STOCKAGE a déjà reçues pour l’envoi en cours (numéro, taille). C’est lui qui fait foi à la reprise, jamais le client.

Réponse{ parties: [{ numero, taille }] }
NoteRien d’ouvert : liste vide. Envoi perdu par le stockage : 409 ETAT, raison ENVOI_INCONNU — le client rouvre (`…/envoi`).
POST /transferts/:id/fichiers/:fileId/finaliser

Assemble l’objet à partir des parties que le stockage LISTE, puis le RELIT : le fichier n’est finalisé qu’après relecture de sa taille. Le dernier fichier d’un manifeste complet fait passer le transfert en vérification (jamais directement « prêt »).

Corps{ sha256? } (l’empreinte calculée par le client : une déclaration, comparée au manifeste, vérifiée plus tard par un worker)
Réponse{ deja, statutTransfert }
NoteParties absentes ou de mauvaise taille : 409 ETAT, raison PARTIES_MANQUANTES, `parties` (le client ne renvoie qu’elles). Taille relue ou empreinte en désaccord : 409 INCOHERENT, le fichier passe en échec. Rejouée sur un fichier finalisé : 200, `deja: true`. Deux finalisations concurrentes n’en comptent qu’une.
POST /transferts/:id/petits

Lot 17 — ouvre et signe un LOT de dépôts DIRECTS pour des petits fichiers (≤ 4 Mio, ≤ 100 par appel) : une URL de PUT par fichier, sa taille signée. Un appel pour cent fichiers, au lieu de deux par fichier. Chaque fichier est jugé seul ; un refus le renvoie au chemin multipart.

Corps{ fichiers: string[] } (1 à 100 identifiants de fichiers de CE transfert)
RéponsePetitsOuvertsDto { depots: [{ fileId, url, entetes, expireA }], refus: [{ fileId, raison: INTROUVABLE | FINALISE | TAILLE | MULTIPART | ETAT }] }
NoteLes URL sont des secrets de courte durée (15 min) : refusées à un agent (403 REFUSE), comme les parties ; une délégation `ENVOYER` les obtient pour le poste. Un fichier d’un autre transfert est INTROUVABLE. Stockage sans dépôt direct : 409 ETAT raison PETITS_INDISPONIBLES (le client garde le chemin multipart). `no-store`.
POST /transferts/:id/petits/finaliser

Lot 17 — finalise un LOT de dépôts directs : chaque objet est RELU au stockage (HEAD) et comparé au manifeste, comme un fichier unique. Le dernier fichier d’un manifeste complet fait passer le transfert en vérification.

Corps{ fichiers: [{ id, sha256 }] } (1 à 100 ; l’empreinte calculée par le client, relue par le worker d’analyse)
RéponsePetitsFinalisesDto { resultats: [{ fileId, issue: FINALISE | DEJA | ABSENT | INCOHERENT | REFUSE, detail? }], statutTransfert }
NoteABSENT : le PUT n’est pas arrivé, le client le renvoie. INCOHERENT : taille ou empreinte en désaccord, le fichier passe en échec. Rejouée : DEJA. Le lot n’échoue jamais en bloc pour un fichier.
GET /transferts/direct/reglages

Lot 18 — le direct entre postes : le niveau ouvert par le serveur (déclaré, effectif), la coupure par l’entreprise, le consentement pour les tiers.

RéponseReglagesDirectDto { niveau, effectif, coupe, tiers, stunConfigure, relaisConfigure }
PATCH /transferts/direct/reglages session de l’application seulement

Lot 18 — un administrateur COUPE le direct pour son entreprise, ou CONSENT à servir les tiers en direct (leur navigateur voit des adresses réseau du poste).

Corps{ coupe?, tiers? }
RéponseReglagesDirectDto
NoteAdministrateur, en session seulement ; journalisé.
POST /transferts/:id/fichiers/:fileId/direct session de l’application seulement

Lot 18 — un membre, sur son poste, demande le DIRECT pour un fichier qu’il voit (réception sur le poste).

RéponseOuvertureDirectDto { direct: SessionDirectDto | null, raison }
NoteDepuis un POSTE seulement (jamais une clé, un agent, une délégation : `SANS_POSTE`). Le poste émetteur est prévenu par son flux personnel. `direct: null` dit pourquoi ; le stockage sert alors.
POST /transferts/direct/:sid/signal session de l’application seulement

Lot 18 — un message de la négociation, d’un poste (émetteur ou destinataire) vers l’autre bout de SA session.

Corps{ sorte, sdp?, candidat?, raison? }
Réponse{ livre }
NoteSeuls les deux bouts d’une session l’atteignent (membre ET appareil) ; sinon 404.
POST /transferts/direct/:sid/issue session de l’application seulement

Lot 18 — le poste destinataire déclare l’issue (voie, octets, durées, type de candidat) ; la session se ferme.

Corps{ issue, octetsDirect, octetsStockage, dureeDirectMs, dureeStockageMs, candidat, raison? }
Réponse{ ok }
POST /transferts/:id/fichiers/:fileId/abandonner

Annule l’envoi en cours d’un fichier : les parties reçues sont abandonnées chez le stockage, le fichier redevient ATTENDU.

Réponse{ abandonne }
NoteRejouable (`abandonne: false` quand rien n’était ouvert). Un fichier finalisé ne s’annule pas : 409 FINALISE. Possible sur un transfert supprimé (nettoyage).
POST /transferts/:id/fichiers/:fileId/telecharger session de l’application seulement

Une URL signée de 5 minutes pour lire UN fichier d’un transfert qu’on voit — le téléchargement d’une personne de l’entreprise.

Réponse{ fichier, url, expireA, nom, taille, sha256 }
NoteNi un agent par l’API (une URL signée n’entre jamais dans le contexte d’un modèle) ni une clé d’API ; une délégation qui porte RECEVOIR, oui (lot 11). Un fichier pas encore finalisé, en analyse, non analysé ou infecté ne se lit pas — pas même par l’entreprise. `no-store`.
POST /transferts/:id/fichiers/:fileId/apercu session de l’application seulement

L’APERÇU d’un fichier d’un transfert qu’on voit (lot 19) — le même que celui du tiers : demandé, suivi, puis ses adresses signées.

RéponseApercuDto
NoteNi un agent (le contenu d’un fichier reçu n’entre jamais dans le contexte d’un modèle) ni une clé d’API ; une délégation, oui. Seulement un transfert PRÊT et un fichier diffusable. Rien n’est compté. `no-store`.
POST /transferts/:id/partages session de l’application seulement

Crée un lien externe : ouvert (`LIEN`) ou réservé à des adresses confirmées par code (`VERIFIE`). L’adresse `…/t#<jeton>` n’est rendue QU’ICI ; la base n’en garde que l’empreinte.

Corps{ mode, destinataires?, expireDansJours?, maxTelechargements?, envoyerLeLien? } ; en-tête `Idempotency-Key` facultatif
Réponse201 PartageCreeDto { partage, url, envoi? } (200 pour une répétition) ; pour une délégation : PartageRemisDto { partage, url: null, envoi }
NoteUn geste de PERSONNE (`ROUTES_SESSION_SEULE`) : ni clé, ni agent par l’API. Exception (lot 11) : une DÉLÉGATION `nxt_…` qui porte PARTAGER crée un lien `VERIFIE` seulement, que Nexus envoie lui-même par courriel aux adresses — la réponse ne rend JAMAIS l’adresse du lien (`url: null`). `envoyerLeLien` (vérifié seulement) fait envoyer le lien par Nexus à une personne aussi ; `envoi` compte les courriels acceptés par le relais. Mode aveugle : 403 `MODE_AVEUGLE`. Une DEMANDE de fichiers reçoit un lien de DÉPÔT (lot 10), tant que sa collecte est ouverte (sinon 410 `FERME`) et sans plafond de téléchargements. L’échéance du lien ne dépasse jamais celle du transfert. Même clé et même corps dans les 24 h : le MÊME lien ; corps différent : 422 `IDEMPOTENCE`. `no-store`.
POST /transferts/demandes session de l’application seulement

Demande des fichiers à des tiers sans compte (lot 10) : crée la DEMANDE (un transfert de genre `DEMANDE`, avec ses règles) ET son premier lien de dépôt, d’un seul geste. Le lien n’est rendu QU’ICI.

Corps{ titre, instructions?, projectId?, expireDansJours?, regles?: { typesAcceptes, fichierOctetsMax, fichiersMax, octetsMax }, mode: LIEN | VERIFIE, destinataires?, envoyerLeLien? } ; en-tête `Idempotency-Key` facultatif
Réponse201 DemandeCreeeDto { transfert, partage, url, envoi? } ; pour une délégation : DemandeRemiseDto (`url: null`)
NoteUn geste de PERSONNE (`ROUTES_SESSION_SEULE`) : ni clé, ni agent par l’API. Une DÉLÉGATION qui porte DEMANDER crée une demande `VERIFIE` seulement, et Nexus envoie le lien de dépôt aux adresses (lot 11). Mode aveugle : 403 `MODE_AVEUGLE`. Les règles sont bornées (10 000 fichiers, 1 To) ; l’espace de l’entreprise reste le plafond final. `no-store`.
POST /transferts/:id/fermer session de l’application seulement

Ferme la collecte d’une demande : plus aucun dépôt, par aucun lien ; les fichiers pas encore arrivés en entier sont RETIRÉS (place rendue, envoi coupé) ; la demande passe en analyse puis se publie.

RéponseFermetureDemandeDto { transfert, retires }
NoteUn geste de PERSONNE (`ROUTES_SESSION_SEULE`). Rejouée : sans effet (`retires: 0`). Un envoi : 409 `ETAT` raison `PAS_UNE_DEMANDE`. Les liens ne sont pas révoqués : un déposant relit encore son reçu.
GET /transferts/:id/deposants

Les déposants d’une demande : référence, nom DÉCLARÉ (jamais vérifié), adresse VÉRIFIÉE (code d’un lien vérifié) — deux identités qui ne se confondent pas —, dossier, fichiers annoncés et reçus, dernier geste.

RéponseDeposantDto[]
NoteJamais la clé d’un navigateur (seule son empreinte est en base). Projet en mode aveugle : un agent ou une clé ne reçoit ni nom ni adresse.
DELETE /transferts/:id/fichiers/:fileId session de l’application seulement

Retire un fichier DÉPOSÉ d’une demande ouverte (ou échue) : effacé du stockage, sa place rendue, son analyse annulée.

Réponse204
NoteUn geste de PERSONNE (`ROUTES_SESSION_SEULE`). Un envoi : 409 `ETAT` raison `PAS_UNE_DEMANDE` ; une collecte fermée : 410 `FERME`.
GET /transferts/:id/partages

Les liens d’un transfert (200 plus récents) avec leur statut CALCULÉ (actif, expiré, révoqué, épuisé), le même que la page du tiers.

RéponsePartageDto[]
NoteAucun jeton, aucune adresse de lien. Les destinataires d’un partage vérifié sont rendus, sauf à un agent ou une clé sur un projet en mode aveugle.
POST /transferts/:id/partages/:sid/revoquer

Révoque un lien : la page et toute nouvelle autorisation le refusent aussitôt. Ne supprime AUCUN fichier.

RéponsePartageDto
NoteRejouable (la première date reste). Une URL déjà signée vit encore au plus 5 minutes, et un téléchargement COMMENCÉ va à son terme : un fichier déjà reçu ne se rappelle pas. Ouvert aux agents et aux clés : fermer est sans risque. Possible sur un transfert supprimé.
GET /transferts/:id/evenements

Le journal d’un transfert (200 derniers faits) ; lisible après la suppression par son auteur et les administrateurs, pour constater la purge.

Réponseliste de { id, genre, acteur, acteurNom, fichierId, partageId, detail, at }
GET /transferts/:id/suivi

Le SUIVI d’un transfert (lot 20) : ses destinataires et le niveau de PREUVE atteint par chacun (page ouverte, téléchargement commencé, réception confirmée — jamais une lecture), l’historique REGROUPÉ (un dossier de mille fichiers fait une ligne), les notifications émises et l’état de leur courriel.

RéponseSuiviTransfertDto { transfert, suivi, destinataires[], historique[], avis[], tronque, limites[] }
NoteLu dans le journal, comme les webhooks : l’écran, le MCP (`transfer_read`) et un script disent la même chose. Un destinataire est une adresse confirmée par code, ou un lien ouvert tout entier (jamais un appareil).
PATCH /transferts/:id/suivi

Règle QUAND prévenir l’auteur qu’un transfert a été récupéré (lot 20) : par destinataire (défaut), à la première récupération, ou jamais.

Corps{ suivi: CHAQUE | PREMIER | AUCUN }
Réponse{ suivi }
NoteL’auteur ou un administrateur ; sinon 403. Les CANAUX (cloche, courriel) suivent les préférences de chacun (Paramètres › Notifications). Journalisé `transfert.suivi`.
GET /transferts/evenements

LE FLUX DE RATTRAPAGE (lot 20) : les faits des transferts qu’on voit, après un curseur, dans l’ordre — ce qu’un script ou un poste relit à sa reconnexion.

Corpsrequête : apres? (curseur opaque), limite? (1–500)
RéponseFluxEvenementsDto { evenements: [{ id, transfert, genre, acteur, acteurNom, fichierId, partageId, detail, at }], curseur, suite }
NoteLes droits sont ceux du MOMENT : un membre retiré d’un projet n’en lit plus rien ; une délégation, sa seule portée. Les faits des 30 dernières secondes attendent l’appel suivant (une transaction longue n’est jamais sautée). Garder le `curseur` et le repasser : rien n’est perdu, rien n’est rendu deux fois.
DELETE /transferts/:id session de l’application seulement

Supprime un transfert (logiquement) et pose sa purge physique.

Réponse204
NoteSon auteur ou un administrateur, en session : ni clé ni agent. Rejouée, la suppression ne réécrit rien.
POST /transferts/delegations session de l’application seulement

Tire une DÉLÉGATION : un jeton `nxt_…` pour un script ou un agent hors de Nexus, qui agit sous VOTRE identité, dans UN projet (ou vos transferts sans projet), ou un seul transfert, pour des actions et une durée choisies. Le jeton n’est rendu QU’ICI.

Corps{ libelle, projectId (null : sans projet), transferId?, actions: (LIRE | ENVOYER | RECEVOIR | PARTAGER | DEMANDER)[], dureeHeures (1 à 720, défaut 24), octetsMax?, transfertsMax?, pourAgent?: { moteur, modele?, discussion? } }
Réponse201 DelegationCreeeDto { delegation, jeton }
NoteUn geste de PERSONNE (`ROUTES_SESSION_SEULE`) : ni clé, ni agent, ni délégation. La portée est jugée avec VOS droits (un projet que vous ne voyez pas : 404). `pourAgent` : ce que le poste tire pour un agent de Nexus — deux heures, 50 Go et 50 transferts au plus, libellé « Agent · <moteur> ». 50 délégations vivantes par membre. Le jeton s’emploie en `Authorization: Bearer nxt_…` et n’ouvre QUE les routes de Transfert de ses actions.
GET /transferts/delegations

Vos délégations (un administrateur : celles de l’entreprise), vivantes, échues ou révoquées : préfixe, portée, actions, consommation, dernier emploi.

RéponseDelegationDto[]
NoteJamais un jeton (seule son empreinte est en base).
POST /transferts/delegations/:id/revoquer

Révoque une délégation : son jeton est refusé aussitôt (401). Rejouable.

RéponseDelegationDto
NoteSon auteur ou un administrateur. Couper se fait de partout, vite : ouvert aux clés et aux agents. Un transfert déjà créé par elle reste.
GET /transferts/delegation

La délégation qui appelle : ses actions, sa portée, son échéance, ce qu’il lui reste — c’est la première question de la commande `nexus-transfert`.

RéponseDelegationDto
NoteAppelée avec un jeton `nxt_…` seulement.
POST /transferts/delegation/revoquer

La délégation qui appelle se révoque elle-même : un script qui a fini rend son jeton.

RéponseDelegationDto
NoteAppelée avec un jeton `nxt_…` seulement. Le poste l’emploie à la fermeture d’une discussion d’agent.
POST /transferts/webhooks Owner et Admin session de l’application seulement

Pose une ADRESSE PRÉVENUE : Nexus y envoie, signés (HMAC-SHA-256), les faits des transferts de l’entreprise — identifiants et mesures, jamais un nom de fichier. Le secret de signature n’est rendu QU’ICI.

Corps{ libelle, url (https, publique), genres?: EvenementTransfertGenre[] (vide : tous), projectId? }
Réponse201 WebhookTransfertCreeDto { webhook, secret }
NoteUn administrateur, en session. L’adresse est jugée à la pose ET à chaque envoi : https seulement, sans identifiants, et AUCUNE de ses adresses résolues dans un réseau privé, local ou réservé (IPv4 et IPv6, formes mappées comprises) ; la connexion se fait à l’adresse jugée, et une redirection n’est jamais suivie. Dix adresses par entreprise. Livraison au moins une fois, sortie d’une boîte d’envoi écrite dans la transaction du fait : en-têtes `nexus-webhook-id` (le même à chaque essai), `-timestamp`, `-signature` (`v1=<hex>` de `id.timestamp.corps`), `-event`. Huit essais sur un peu plus d’une journée ; 410 suspend aussitôt, vingt abandons d’affilée aussi.
GET /transferts/webhooks Owner et Admin

Les adresses prévenues de l’entreprise : indice d’adresse (jamais l’adresse entière), faits écoutés, état, dernière livraison.

RéponseWebhookTransfertDto[]
PATCH /transferts/webhooks/:id Owner et Admin session de l’application seulement

Désactive ou réactive une adresse prévenue (une adresse suspendue se réactive ainsi).

Corps{ actif: boolean }
RéponseWebhookTransfertDto
DELETE /transferts/webhooks/:id Owner et Admin

Retire une adresse prévenue et ses livraisons en attente. Les faits restent au journal des transferts.

Réponse204
POST /transferts/webhooks/:id/essai Owner et Admin

Envoie à l’adresse une livraison d’ESSAI, signée comme les autres (genre `ESSAI`), et rend sa réponse.

Réponse{ code, erreur, livre }
GET /transferts/webhooks/:id/livraisons Owner et Admin

Les livraisons d’une adresse (les plus récentes, conservées 30 jours) : statut, essais, dernier code, prochain essai.

RéponseLivraisonWebhookDto[]
POST /transferts/webhooks/:id/livraisons/:lid/rejouer Owner et Admin

Remet une livraison en attente, avec le MÊME identifiant : le consommateur la reconnaît s’il l’avait déjà traitée.

RéponseLivraisonWebhookDto
GET /transferts/exploitation Owner et Admin

Le tableau d’exploitation de Transfert : quota (plafond, réservé, palier), stocké et dérivés, flux sur 24 h et 30 jours (envoyé MESURÉ, sortie ESTIMÉE), qui réserve l’espace, travaux et workers, compteurs du processus, coût mensuel ESTIMÉ sur la grille du fournisseur datée, dernier rapprochement, réglages.

RéponseExploitationTransfertDto
NoteAdministrateurs seulement (403 REFUSE sinon). Une estimation porte le mot et ses hypothèses : ce n’est pas une facture. Les compteurs du processus repartent de zéro à chaque redémarrage (`processus.depuis`). Aucun nom de fichier, aucun secret.
POST /transferts/exploitation/rapprochement Owner et Admin session de l’application seulement

Relit le stockage de l’entreprise et le compare à ce que la base dit finalisé : objets relus, attendus, orphelins (un objet sans ligne), manquants (une ligne sans objet).

Corps{}
RéponseRapprochementDto { at, objets, octets, attenduObjets, attenduOctets, orphelins, manquants, tronque }
NoteUn administrateur, en session : des appels au fournisseur. 200 pages de 1 000 objets au plus ; au-delà, `tronque` et les nombres sont des minimums. Journal `transfert.rapprochement`.
POST /transferts/exploitation/purges/relancer Owner et Admin session de l’application seulement

Remet en attente les purges en ÉCHEC de l’entreprise (essais remis à zéro) ; le tour d’entretien les reprend dans la minute.

Réponse{ relancees: number }
NoteUn administrateur, en session. Journal `transfert.purges-relancees`. À faire APRÈS avoir corrigé la cause (runbook de Transfert § 4).