Feature #51
closedFeature #26: Implémenter la classification automatique et l'estimation de complexité des tickets par l'assistant AI
Frontend — affichage classification, complexité & tag bf-disagree sur la page et la liste
0%
conversation:21#26
Description
**Parent :** #26 · **Taille :** M · **Dépendances :** #49 (contrat backend) · **Surface :** frontend (`src/`, Next.js 16, Atomic Design, next-intl)
## Objectif
Après création, afficher la **classification**, la **note de complexité** (+ explication) et le tag **`bf-disagree`** sur la page du ticket (`TaskDetailPane`) et dans la **liste** des tickets.
- `TaskDetailPane` affiche classification + note + explication.
- Le tag `bf-disagree` (orange `#FF9800` + tooltip) apparaît sur la page détaillée **et** dans la liste.
- Réutilise le composant tag créé pour la prévisualisation (#50) — pas de duplication.
## Acceptance criteria
- [ ] `TaskDetailPane` affiche classification + note + explication.
- [ ] Tag `bf-disagree` (#FF9800 + tooltip) visible sur la page détaillée du ticket.
- [ ] Tag `bf-disagree` visible dans la liste des tickets.
- [ ] Le composant tag est partagé avec la prévisualisation (pas de réimplémentation).
- [ ] FR/EN (clés dans `en.ts` uniquement) + isolation multi-tenant.
- [ ] Gate vert : `npx vitest run`, `npx tsc --noEmit`, `npx eslint .`, `npm run build`. TDD.
Files
RA Updated by Redmine Admin about 2 months ago
- Status changed from Submitted to Spec
- spec_ref updated (diff)
RA Updated by Redmine Admin about 2 months ago
- Status changed from Spec to In development
RA Updated by Redmine Admin about 2 months ago
- Status changed from In development to QA
- branch set to feat/51-classification-display
- pr_url set to https://github.com/omdev-tech/PipeLiner-Client/pull/29
PR ouverte vers `dev` : https://github.com/omdev-tech/PipeLiner-Client/pull/29
Implémentation (branchée sur `origin/dev` car dépend de #50 — atom `BfDisagreeTag` + champs read-model, encore sur `dev`) :
- **Page du ticket (`TaskDetailPane`)** : carte read-only « Classification & complexité » (classification, note `/10` + explication) + tag `bf-disagree` (#FF9800 + tooltip) en cas de désaccord.
- **Liste (`TaskRow`)** : même atom `BfDisagreeTag` affiché en ligne sur les tickets concernés.
- Le composant tag est **réutilisé** (#50), pas réimplémenté.
- Parser `src/features/tasks/ticketMeta.ts` : lit le bloc de métadonnées que le flux de création (#49) ajoute à la description Redmine, et le retire du corps markdown affiché (affichage unique, read-only).
- i18n : clés ajoutées dans `en.ts` uniquement (`fr.ts` re-exporte).
Petit ajout backend inséparable (la liste ne renvoie pas les descriptions) : booléen `bf_disagree` dérivé du marqueur sur `TaskSummary`/`TaskSummaryOut` — aucun nouvel appel upstream. À noter pour le suivi : c'est la seule portion non strictement frontend.
Gate vert : `vitest` (458), `tsc`, `eslint`, `build` ; backend touché : pytest unit-green + ruff + mypy OK. TDD.
→ Passage en QA.
RA Updated by Redmine Admin about 2 months ago
- File qa-51-rapport.txt qa-51-rapport.txt added
RA Updated by Redmine Admin about 2 months ago
- File qa-51-vitest.txt qa-51-vitest.txt added
RA Updated by Redmine Admin about 2 months ago
**QA — PASS** (tous les criteres OK). Le ticket reste en **QA** (promotion preprod = autre agent).
**Smoke test — portes de qualite (branche `feat/51-classification-display` @ 19cd23e)**
- `npx vitest run` : **458 passed** / 86 fichiers — suites ciblees ticketMeta(12) + BfDisagreeTag(5) + TaskRow(3) + TaskDetailPane(13) = 33 OK
- `npx tsc --noEmit` : exit 0 — OK
- `npx eslint .` : exit 0 — OK
- `npm run build` : exit 0 (log `/admin` `ENVIRONMENT_FALLBACK` pre-existant, non bloquant) — OK
- Backend (`api/.venv`, `PYTHONPATH=src`) : `test_task_board_use_cases.py` **13 passed**, dont `test_list_project_tasks_flags_bf_disagree_from_description`. (Integration FastAPI `test_tasks_api.py` = besoin Postgres, hors smoke ; derivation couverte par le use-case unitaire.)
**Criteres d'acceptation**
- [OK] `TaskDetailPane` affiche classification + note + explication — carte triage read-only "Classification & complexity" (`TaskDetailPane.tsx:256-257`, `parseTicketMeta`/`stripTicketMetaBlock`).
- [OK] Tag `bf-disagree` (#FF9800 + tooltip) sur la page detaillee — `import @/components/atoms/BfDisagreeTag` (`TaskDetailPane.tsx:8`).
- [OK] Tag `bf-disagree` dans la liste — `TaskRow.tsx:6` import + `:123` `<BfDisagreeTag>` inline sur les rangees flaggees. Enabler backend minimal car les rangees ne lisent pas les descriptions : `has_bf_disagree(description)` -> `TaskSummary.bf_disagree` -> `TaskSummaryOut.bf_disagree` (aucun nouvel appel upstream).
- [OK] Composant tag **partage** avec la previsualisation (#50), pas de reimplementation — meme atome importe par `TicketDraftPanel.tsx:6`, `TaskRow`, `TaskDetailPane` ; couleur `#FF9800` definie UNIQUEMENT dans l'atome (`atoms/BfDisagreeTag.tsx:45`).
- [OK] FR/EN : cles ajoutees dans `en.ts` uniquement (`tasks.triage.*` + `bfDisagreeTooltip`, en.ts:435-459), `fr.ts` re-exporte `en` (`typeof en`). Isolation multi-tenant inchangee (proxy `owned_project`).
- [OK] `parseTicketMeta`/`stripTicketMetaBlock` parsent + masquent le bloc meta — exportes `ticketMeta.ts:116/:132`, 12 tests parser verts.
- [OK] Gate vert + TDD.
**Smoke live UI** : prod `https://pipeliner.omdev.tech` atteignable (200) mais derriere authentification (page "Sign in"). Pas d'identifiants utilisables sans secret -> fallback sur les tests de rendu (Testing Library) comme preuve visuelle, conformement au plan. Aucun secret manipule ni inclus dans les preuves.
**Preuves jointes** : `qa-51-rapport.txt`, `qa-51-vitest.txt`.