Feature #85
closedSecOps ticket type + Feature/Bug/SecOps ticketing tabs — extends #24/#70
0%
conversation:secops-tracker-tabs
Description
**Lié à :** #24/#70 · **Surface :** Client-Dashboard fullstack (`api/` + `src/`)
Les tickets de sécurité (hook scan→ticket) doivent être d'un **type distinct (tracker `SecOps`, id 4)** et le ticketing doit offrir des onglets **Feature / Bug / SecOps**.
**Backend (`api/`)** :
- `infrastructure/config.py` : `redmine_secops_tracker_id` défaut **4** (env `REDMINE_SECOPS_TRACKER_ID`).
- `infrastructure/redmine/scan_adapter.py` : `create_ticket` crée le ticket avec **tracker_id = SecOps (4)** (passer `tracker_id` à `RedmineClient.create_issue` ; l'ajouter au client si besoin).
- `domain/redmine/value_objects.py` : `RedmineIssue` porte le `tracker` (id + name) si pas déjà ; le board le lit.
- `domain/tasks/value_objects.py` + `application/task_board.py` : ajouter `category: "secops" | "bug" | "feature"` à `TaskSummary`/`TaskDetail` — `secops` si tracker==SecOps(4), sinon dérivé de la classification existante (#26 : `issue_type`/classification dans la description → `bug`|`feature`, défaut `feature`).
- `presentation/api/tasks.py` : exposer `category` sur `TaskSummaryOut` (+ detail). Pas de nouvel appel upstream.
**Frontend (`src/`)** :
- Une nav d'onglets **Feature / Bug / SecOps** au-dessus du board de ticketing (`app/projects/[id]/ticketing/page.tsx`), filtrant les colonnes par `task.category`. SecOps = uniquement les tickets de sécurité. Réutiliser les composants/tokens existants (pas de nouvelle couleur). i18n `en.ts`.
## Critères d'acceptation
- Les tickets créés par le hook scan→ticket sont de tracker **SecOps** (4).
- `TaskSummaryOut.category` = secops/bug/feature exposé (multi-tenant, pas d'appel upstream).
- Onglets Feature/Bug/SecOps filtrent le board ; SecOps n'affiche que les tickets de sécurité.
- FR/EN ; gates verts backend (pytest/ruff/mypy) + frontend (vitest/tsc/eslint/build). TDD.
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/85-secops-tabs
- pr_url set to https://github.com/omdev-tech/PipeLiner-Client/pull/36
PR ouverte vers `dev` : https://github.com/omdev-tech/PipeLiner-Client/pull/36
Branche : `feat/85-secops-tabs` (basée sur `origin/master` à jour).
Implémentation (fullstack, TDD) :
**Backend (`api/`)**
- `config` : `redmine_secops_tracker_id` (défaut **4**, env `REDMINE_SECOPS_TRACKER_ID`).
- `RedmineClient.create_issue` accepte désormais `tracker_id` (le défaut reste le tracker Feature) ; le parseur mappe `tracker: {id, name}` sur `RedmineIssue`.
- `scan_adapter.create_ticket` crée les tickets de sécurité sur le **tracker SecOps (4)**.
- `TaskSummary`/`TaskDetail` portent `category` (`secops | bug | feature`) : `secops` si tracker == SecOps, sinon `bug`/`feature` dérivé de la classification IA (#26) dans la description (défaut `feature`). Aucun appel upstream supplémentaire. Exposé sur `TaskSummaryOut`/`TaskDetailOut`.
**Frontend (`src/`)**
- Nav d'onglets **Feature / Bug / SecOps** au-dessus du board de ticketing, filtrant les lignes par `task.category` (SecOps = uniquement `category==="secops"`). Onglet sélectionné persisté dans l'URL (`?tab=`) comme les filtres existants. Réutilise les composants/tokens existants ; clés i18n ajoutées dans `en.ts` uniquement.
**Gates (verts des deux côtés)**
- Backend : `pytest -q` ×2 sur pgvector éphémère (474 passés), `ruff check .`, `mypy src`.
- Frontend : `vitest run` (506 passés), `tsc --noEmit`, `eslint .`, `npm run build` (le log `ENVIRONMENT_FALLBACK` sur `/admin` est le pré-existant non bloquant documenté).
Statut : In development → QA.
RA Updated by Redmine Admin about 2 months ago
- Status changed from QA to Shipped
Verified live in production: the Feature / Bug / SecOps ticketing tabs and the SecOps tracker are deployed and visible on pipeliner.omdev.tech (PR #36, merged to master and deployed). Closing QA → Shipped. Follow-up count bug tracked separately in #86/#161.