ia_dev/gitea-issues/TICKETS_SPOOL_FORMAT.md

129 lines
6.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 sappuyer sur le statut « non lu ». Le traitement se base uniquement sur le **statut des issues** ; aucun enregistrement nest 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 lunicité 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 lagent 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 lexpéditeur |
| `to` | string[] | Adresses destinataires |
| `subject` | string | Sujet |
| `date` | string | Date denvoi (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 dissue Gitea si une issue a été créée |
| `status` | string | `pending` \| `inprogress` \| `done` |
| `attachments` | array | Pièces jointes : tableau dobjets (voir ci-dessous). `path` est relatif à `data/issues/` ; les fichiers sont dans `<base>.d/`. Lagent qui traite les tickets peut les lire depuis `projects/<id>/data/issues/<path>`. |
**Objet pièce jointe** : `filename` (nom dorigine), `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 denvoi (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 nest supprimé.