129 lines
6.0 KiB
Markdown
129 lines
6.0 KiB
Markdown
# Format JSON du spooler tickets (projects/<id>/data/issues/)
|
||
|
||
Les mails et réponses sont stockés dans **projects/<id>/data/issues/** (sous ia_dev, par projet). Filtrage par **expéditeurs autorisés** (conf.json → `tickets.authorized_emails`), sans s’appuyer sur le statut « non lu ». Le traitement se base uniquement sur le **statut des issues** ; aucun enregistrement n’est supprimé.
|
||
|
||
## Emplacement et nommage des fichiers
|
||
|
||
- **Racine** : `ia_dev/projects/<id>/data/issues/` (id = slug projet, ex. contenu de `ai_project_id` ou `.ia_project` à la racine du dépôt)
|
||
- **Messages entrants** : `<date>_<from_sanitized>_<uid>.<status>` (le `_<uid>` assure l’unicité par message IMAP)
|
||
- `date` : `YYYY-MM-DDTHHmmss` (ex. `2026-03-14T094530`)
|
||
- `from_sanitized` : adresse expéditeur rendue sûre pour le système de fichiers (ex. `user_example.com` pour `user@example.com` : `@` → `_`, caractères interdits remplacés ou supprimés)
|
||
- `uid` : UID IMAP (évite les doublons pour un même expéditeur à la même seconde)
|
||
- `status` : `pending` | `inprogress` | `done`
|
||
- **Réponses envoyées** : `<date>_<from_sanitized>.response` (même base de nom que le message entrant associé, extension `.response`)
|
||
- **Pièces jointes (pj)** : pour un message entrant de base `<base>` (ex. `2026-03-14T094530_laurence_lecoffre.io_42`), les pièces jointes sont dans le répertoire **`<base>.d/`** (ex. `2026-03-14T094530_laurence_lecoffre.io_42.d/`). Nommage des fichiers : `<index>_<nom_fichier_sanitifé>` (ex. `0_document.pdf`, `1_capture.png`). Le JSON du message contient le tableau `attachments` avec pour chaque entrée le chemin relatif à `data/issues/`, le type MIME et la taille pour que l’agent qui traite les tickets puisse les utiliser.
|
||
|
||
Exemples :
|
||
- `2026-03-14T094530_laurence_lecoffre.io.pending` — message entrant en attente
|
||
- `2026-03-14T094530_laurence_lecoffre.io.inprogress` — en cours de traitement
|
||
- `2026-03-14T094530_laurence_lecoffre.io.done` — traité
|
||
- `2026-03-14T101200_laurence_lecoffre.io.response` — réponse envoyée
|
||
|
||
## Schéma JSON — message entrant (incoming)
|
||
|
||
Fichiers `.pending`, `.inprogress`, `.done`.
|
||
|
||
```json
|
||
{
|
||
"version": 1,
|
||
"type": "incoming",
|
||
"message_id": "<original.Message-ID@host>",
|
||
"from": "laurence@lecoffre.io",
|
||
"to": ["ai.support.lecoffreio@4nkweb.com"],
|
||
"subject": "Demande d'information",
|
||
"date": "Fri, 14 Mar 2026 09:45:30 +0100",
|
||
"body": "Texte brut du corps du mail.",
|
||
"references": ["<id1@host>", "<id2@host>"],
|
||
"in_reply_to": "<id2@host>",
|
||
"uid": "42",
|
||
"created_at": "2026-03-14T09:45:35Z",
|
||
"issue_number": null,
|
||
"status": "pending",
|
||
"attachments": [
|
||
{
|
||
"filename": "document.pdf",
|
||
"path": "2026-03-14T094530_laurence_lecoffre.io_42.d/0_document.pdf",
|
||
"content_type": "application/pdf",
|
||
"size": 12345
|
||
},
|
||
{
|
||
"filename": "capture.png",
|
||
"path": "2026-03-14T094530_laurence_lecoffre.io_42.d/1_capture.png",
|
||
"content_type": "image/png",
|
||
"size": 6789
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
| Champ | Type | Description |
|
||
|-------|------|-------------|
|
||
| `version` | number | Version du schéma (1) |
|
||
| `type` | string | `"incoming"` |
|
||
| `message_id` | string | En-tête Message-ID du mail |
|
||
| `from` | string | Adresse de l’expéditeur |
|
||
| `to` | string[] | Adresses destinataires |
|
||
| `subject` | string | Sujet |
|
||
| `date` | string | Date d’envoi (RFC2822 ou ISO8601) |
|
||
| `body` | string | Corps du message (texte brut) |
|
||
| `references` | string[] | En-tête References (liste de Message-IDs) |
|
||
| `in_reply_to` | string \| null | En-tête In-Reply-To |
|
||
| `uid` | string | UID IMAP (pour référence, pas pour marquer lu) |
|
||
| `created_at` | string | Date d’écriture dans le spool (ISO8601) |
|
||
| `issue_number` | number \| null | Numéro d’issue Gitea si une issue a été créée |
|
||
| `status` | string | `pending` \| `inprogress` \| `done` |
|
||
| `attachments` | array | Pièces jointes : tableau d’objets (voir ci-dessous). `path` est relatif à `data/issues/` ; les fichiers sont dans `<base>.d/`. L’agent qui traite les tickets peut les lire depuis `projects/<id>/data/issues/<path>`. |
|
||
|
||
**Objet pièce jointe** : `filename` (nom d’origine), `path` (chemin relatif sous `projects/<id>/data/issues/`), `content_type` (MIME), `size` (octets).
|
||
|
||
## Schéma JSON — réponse envoyée (response)
|
||
|
||
Fichiers `.response`.
|
||
|
||
```json
|
||
{
|
||
"version": 1,
|
||
"type": "response",
|
||
"in_reply_to_message_id": "<original.Message-ID@host>",
|
||
"to": "laurence@lecoffre.io",
|
||
"subject": "Re: Demande d'information",
|
||
"body": "Texte de la réponse envoyée par l'agent.",
|
||
"sent_at": "2026-03-14T10:12:00Z",
|
||
"created_at": "2026-03-14T10:12:00Z"
|
||
}
|
||
```
|
||
|
||
| Champ | Type | Description |
|
||
|-------|------|-------------|
|
||
| `version` | number | Version du schéma (1) |
|
||
| `type` | string | `"response"` |
|
||
| `in_reply_to_message_id` | string | Message-ID du mail auquel on répond |
|
||
| `to` | string | Destinataire de la réponse |
|
||
| `subject` | string | Sujet de la réponse (ex. Re: …) |
|
||
| `body` | string | Corps de la réponse envoyée |
|
||
| `sent_at` | string | Date d’envoi (ISO8601) |
|
||
| `created_at` | string | Date de création du fichier (ISO8601) |
|
||
|
||
## Configuration projet (conf.json)
|
||
|
||
- **ticketing_url** et la config ticketing sont sous la clé **`tickets`** (et non plus sous `git`).
|
||
- **`tickets`** contient :
|
||
- `ticketing_url` : URL des issues Gitea
|
||
- `authorized_emails` :
|
||
- **`to`** : récupérer **uniquement** les mails **envoyés à** cette adresse (destinataire).
|
||
- **`from`** : récupérer **uniquement** les mails **envoyés par** ces adresses (expéditeurs autorisés).
|
||
|
||
Exemple :
|
||
|
||
```json
|
||
"tickets": {
|
||
"ticketing_url": "https://git.4nkweb.com/4nk/lecoffre_ng/issues",
|
||
"authorized_emails": {
|
||
"to": "ai.support.lecoffreio@4nkweb.com",
|
||
"from": ["ai.support.lecoffreio@4nkweb.com", "laurence@lecoffre.io"]
|
||
}
|
||
}
|
||
```
|
||
|
||
La récupération ne prend que les messages **envoyés à** `authorized_emails.to` **et** **expédités par** une des adresses de `authorized_emails.from`. Aucun marquage « lu / non lu » ; aucun enregistrement du spool n’est supprimé.
|