Project

General

Profile

Actions

Feature #85

closed
RA

SecOps ticket type + Feature/Bug/SecOps ticketing tabs — extends #24/#70

Feature #85: SecOps ticket type + Feature/Bug/SecOps ticketing tabs — extends #24/#70

Added by Redmine Admin about 2 months ago. Updated about 2 months ago.

Status:
Shipped
Priority:
Normal
Assignee:
-
Start date:
06/12/2026
Due date:
% Done:

0%

Estimated time:
spec_ref:

conversation:secops-tracker-tabs

build_status:
build_number:
ci_run_url:
scan_status:
scan_report_url:
deploy_status:
preprod_url:
deployed_at:
branch:
feat/85-secops-tabs
pr_url:
https://github.com/omdev-tech/PipeLiner-Client/pull/36
security_key:
severity:
paused:

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 Actions #1

  • Status changed from Submitted to Spec
  • spec_ref updated (diff)

RA Updated by Redmine Admin about 2 months ago Actions #2

  • Status changed from Spec to In development

RA Updated by Redmine Admin about 2 months ago Actions #3

  • 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 Actions #4

  • 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.

Actions

Also available in: PDF Atom