Admin administers the site — it no longer has any override on
validate-red/blue, review-red/blue, resolve-dispute, request-discussion,
reopen, hold, resume, assign-operators, or classification-update.
Introduces require_any_role_strict(), a role dependency without the
global admin bypass, so these specific endpoints truly exclude admin
instead of only removing it from the (redundant) role tuple.
Managers gain the ability to assign red_tech/blue_tech operators
(POST /tests/{id}/assign, GET /users/operators) alongside leads, since
that's coordination, not resolving a ticket.
Also enlarges and repositions the operator-assignment controls next
to the Start Execution button, and fixes a literal '\u2014' rendering
as text instead of an em dash in the test detail technique line.
Adds GET /users/operators (leads+admin) and wires a lead-only assign
control into the test detail header, calling the existing but
previously unreachable POST /tests/{id}/assign endpoint. Manual
assignment now also pushes the Jira ticket assignee immediately
instead of waiting for the operator to start execution.
Also adds test.platform as a kebab-case label on Jira ticket creation.
Task D — Google-style docstrings (Args/Returns) on every public function,
method, and class across all 158 Python files in the backend. Zero ruff D
violations (pydocstyle Google convention).
Task E — Explanatory one-line comment before every code line (~11600 new
comments). ruff check passes clean after isort re-sort.
Each user can now store their own personal Tempo API token in their
profile settings. Time is logged using each user's own credentials.
Backend:
- Migration b044: adds tempo_api_token column to users table
- User model: adds tempo_api_token column
- UserPreferencesUpdate: adds tempo_api_token field (write-only)
- UserOut: adds tempo_api_token (excluded) + tempo_token_set bool;
@model_validator derives both jira_token_set and tempo_token_set
- users router: handles tempo_api_token same as jira_api_token
(empty string clears it, never returned in responses)
- tempo_service: refactored to per-user token; has_tempo_configured(),
get_user_tempo_client(user) use user.tempo_api_token; global
TEMPO_ENABLED still acts as kill-switch
- system router: /system/tempo-test now uses current user's personal
token (any role); removed global TEMPO_API_TOKEN dependency
Frontend:
- settings.ts: UserPreferencesUpdate.tempo_api_token, UserMeOut.tempo_token_set
- SettingsPage ProfileSection: Tempo Integration section with password
field, show/hide toggle, configured badge, and Test Tempo button —
mirrors the Jira token UX exactly
- JiraConfigSection: removed stale global Tempo test block
Users can now set a separate Atlassian email for Jira authentication
in Settings → Profile → Jira Integration. Falls back to the Aegis
account email when not set, so existing setups are unaffected.
- Migration b043: adds jira_email column to users table
- User model/schema: expose jira_email read/write
- jira_service: _effective_jira_email() uses jira_email ?? email
- Frontend: replaces read-only email display with editable input
- Add jira_api_token field to User model + migration b042
- Per-user Jira client: user's corporate email + personal Atlassian token
- Admin-configurable Jira URL/project via system_configs (GET/PATCH /system/jira-config + POST /system/jira-test)
- Auto-create Jira ticket when a test is created (non-fatal)
- Push lifecycle comments on every state transition: draft→red_executing→blue_evaluating→in_review→validated/rejected→draft
- Rich ticket descriptions with technique, MITRE ID, priority from severity, labels
- UserOut.jira_token_set (bool) instead of exposing raw token
- PATCH /users/me/preferences now accepts jira_api_token
- Phase 6.1: WebhookConfig model, CRUD router (/api/v1/webhooks, admin-only),
dispatch_webhook() with HMAC signing; integrated into test validation,
campaign completion, and MITRE sync job
- Phase 7.1: SMTP email service with send_test_validated_email,
send_campaign_completed_email, send_new_mitre_techniques_email;
notify_role_with_email() added to notification_service
- Phase 7.2: notification_preferences and jira_account_id on User model;
PATCH /users/me/preferences endpoint; Alembic migrations b031phase6 and b032phase7