Commit Graph

426 Commits

Author SHA1 Message Date
kitos 2afb886cd9 feat(assign): let leads manually assign operators + sync Jira; send platform as Jira label
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
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.
2026-07-10 08:44:14 +02:00
kitos 119db6f91d fix(jira): wrap select-field values in {value: ...} for Jira REST API
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
Jira Cloud's REST API rejects a bare string for select-type custom
fields with 'Specify a valid id or name for <field>' — confirmed live
against the real Jira instance. This silently broke Severity, Data
Sensitivity, Attack success, Attack detected, and Attack contained on
every ticket create/update, masked until now by the non-fatal
exception handling around each call.
2026-07-09 17:08:53 +02:00
kitos d726e3adfe fix(jira): correct Data Sensitivity field ID and replicate Jira's real classification scheme
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
The auto-create-ticket call was sending customfield_11233 (a field that
doesn't exist in the project) instead of the real Data Sensitivity field
customfield_11814, which made Jira reject the WHOLE issue and silently
block ticket creation for every new test.

Also replaces Aegis's invented 4-tier data_classification scheme
(public_release/general_use/confidential/restricted) with the 6 values
Jira's Data Sensitivity field actually uses (public/general_use/
internal_use_only/trusted_people/customer_content/pii), since that is
the classification the organization actually applies. Includes a data
migration remapping existing rows and a defensive retry if Jira ever
rejects an unscreened custom field again.
2026-07-09 16:33:41 +02:00
kitos 512b682cc5 fix(jira): correct user_find_by_user_string kwarg breaking account-id auto-detection
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
atlassian-python-api takes limit, not maxResults. The TypeError was
silently swallowed at DEBUG level, so every non-admin user's Jira
account-id lookup failed even with a valid email and working admin
Jira connection.
2026-07-09 15:26:36 +02:00
kitos 8031682e9c feat(matrix): unify Techniques and Coverage Matrix into one page
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
Techniques (/techniques) and Coverage Matrix (/matrix) showed the same
underlying data (Technique.status_global) with completely different
visual styles — discrete Tailwind status colors + ID+name cells on
Techniques, vs. a continuous score-gradient hex color + ID-only cells
(name via tooltip) on the heatmap. Coverage Matrix also has 3 layers
(Threat Actor, Detection Rules, Campaign) with no Techniques equivalent,
so Techniques was the strict subset — merged into Coverage Matrix rather
than the other way around.

- HeatmapCell now uses the same discrete status-color palette as the old
  TechniqueCell (cellColors.ts), shows the technique name inline, and
  keeps zoom/virtualization/hover-tooltip untouched.
- HeatmapLegend restyled to match (swatch + label + description per
  tier, review_required as an overlay badge) instead of the old
  hex-gradient bar.
- MatrixPage gains a Matrix/List view toggle and a status filter
  (coverage/threat-actor layers only) — both ported from the old
  Techniques page — so nothing it offered is lost.
- /techniques now redirects to /matrix; removed TechniquesPage,
  AttackMatrix, TechniqueCell (fully superseded). /techniques/:mitreId
  (detail) and /techniques/review-queue are untouched.

Known pre-existing limitation carried over, not introduced or fixed
here: the heatmap only places a multi-tactic technique under its first
tactic column (_format_tactic takes tactic_str.split(",")[0]), while the
old Techniques matrix placed it under every tactic it belongs to.
2026-07-09 14:19:38 +02:00
kitos 0de9f4a6c0 feat(heatmap): expose technique name + real status on every layer
The Coverage Matrix heatmap only ever showed the bare MITRE ID on each
cell (name only via hover tooltip), and colored cells from a continuous
score -> hex gradient with no discrete status concept — unlike the
Techniques page, which showed ID+name inline with a fixed 5-color status
palette. Unifying the two pages' visual style requires both pieces of
data to exist server-side.

- Adds "name" to all 4 layer builders (coverage/threat-actor/detection-
  rules/campaign) — harmless extra field for Navigator exports, lets the
  frontend show it inline.
- Adds "status" (the real TechniqueStatus value) to the coverage and
  threat-actor layers specifically — the only two backed by an actual
  TechniqueStatus concept; detection-rules/campaign scores don't
  correspond to one and don't get this field.
2026-07-09 14:12:58 +02:00
kitos 4e31359fca feat(frontend): add technique/platform/outcome/date filters to Validated Tests
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
The "200" badge on the Validated Tests page was a hardcoded query limit,
not the real total — silently hiding results beyond the 200th once there
were more validated tests than that. Now shows the true total via the new
/tests/count endpoint, and warns when the fetched page doesn't cover all
matches.

Adds filter controls beyond the existing name/technique text search:
technique (MITRE ID or name), platform, attack outcome, detection
outcome, and a validated-date range — all pushed down to the server via
the new GET /tests filters instead of only ever searching the current
page client-side.
2026-07-09 12:45:54 +02:00
kitos 226869d308 feat(tests): richer server-side filters + true total count for GET /tests
GET /tests caps limit at 200, so any page relying on len(results) for a
"total" count (e.g. Validated Tests) silently under-reports once there
are more matches than the page size — the 200 shown was a page cap, not
the real total.

- Adds GET /tests/count, sharing its query-building with list_tests()
  via a new _build_test_query() so the two can't drift apart.
- Adds technique_search (free-text on MITRE ID or name), attack_success,
  detection_result, and validated_from/validated_to filters, so callers
  aren't limited to state/technique_id/platform/creator.
2026-07-09 12:45:05 +02:00
kitos adae7e617e fix(jira): report which admin config field is actually missing
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
POST /system/jira-test bundled 4 independent checks (enabled, url,
admin_email, admin_api_token) behind has_admin_jira_configured() but
always blamed "Admin Email and Admin API Token" regardless of which one
failed. Found via live QA: URL/email/token were all correctly saved, but
the "Enable Jira Integration" toggle was never switched on — the error
message pointed at the wrong fields, making it look like the already-set
credentials were missing.
2026-07-09 12:02:04 +02:00
kitos 4ddd7f9ec3 feat(jira): sync the full Purple Team workflow status to Jira
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
Previously only red_executing (-> "In Progress") ever changed the Jira
issue's status; every other Aegis transition (red_review, blue_evaluating,
blue_review, in_review, validated, rejected, disputed) only posted a
comment, leaving the Jira board stuck on whatever status it started with.

Expands push_test_event() to a full TestState -> Jira-status table
covering the whole lifecycle (To-Do -> In Progress -> RT Test Review ->
Queued Blue Team -> In Progress -> Blue Team Test Review -> Validation ->
Done/Rejected/Dispute), matching the Purple Team Jira workflow. Adds two
new lifecycle hooks that the generic dispatch can't handle correctly:

- push_bt_work_started(): blue_evaluating covers both "queued, unclaimed"
  and "actively being worked" — needs an explicit push when the blue tech
  clicks Start Evaluation, or it never leaves "Queued Blue Team".
- disputed state push: a conflicting lead vote previously produced zero
  Jira signal at all.

Also fills two real gaps: reopen_red_review and reopen_blue_review never
synced anything to Jira before. Their target status differs on purpose —
reopen_red_review pushes "In Progress" (Aegis resumes the same operator
immediately, no re-claim), while reopen_blue_review pushes "Queued Blue
Team" (Aegis clears blue_work_started_at, forcing a fresh "Start
Evaluation" click) — verified against the actual field-reset behavior in
test_entity.py rather than assumed symmetry between the two teams.
2026-07-08 13:39:15 +02:00
kitos ccc99439d5 docs: add Jira/Tempo service account requirements and use cases
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
Requirements + use-case document to support requesting a dedicated
Jira/Tempo service account for the Purple Team project, to replace the
personal-employee-account credentials currently configured as Aegis's
Jira integration identity. Grounded in the actual implemented
integration (ticket lifecycle sync, Tempo worklog attribution, account
auto-discovery) rather than the aspirational design.
2026-07-08 11:30:33 +02:00
kitos df49d336f7 fix(security): stop leaking live Jira/Tempo admin tokens in config export
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
_REDACTED_KEYS listed jira.api_token/jira.password/tempo.api_token, but
routers/system.py actually writes admin credentials under
jira.admin_api_token and tempo.admin_token. The mismatch meant every
config export bundle included the live Jira and Tempo admin API tokens
in plaintext instead of redacting them. Found while researching the
Jira/Tempo integration for a service-account request; added a
regression test.
2026-07-08 11:08:09 +02:00
kitos 0b6a664651 test(admin): cover config export/import bundle (Block 4)
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
The "Export Configuration" admin feature (GET/POST /admin/export-config,
/admin/import-config) was already fully implemented — admin-gated,
redacts secrets, scoped to genuine config (settings/webhooks/SSO/scoring/
custom templates/users) rather than bulk data — but had zero test
coverage for an admin-sensitive data-migration endpoint.

Adds coverage for: admin-only gating on both endpoints, secret redaction
(SMTP password, SSO private key), custom-template-only scoping, safe user
import (forced password reset, no secret restoration from "[REDACTED]"
placeholders), and round-trip import idempotency. All pass against the
existing implementation — no bugs found.
2026-07-08 10:15:11 +02:00
kitos 8cf8001de5 feat(frontend): My Reviews queue, duplicate-test badge, tactic order, legend + tooltip fixes
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
- TestsPage gains a "My Reviews" toggle for red_lead/blue_lead, separate
  from "My Tasks" — filters by reviewer_id at the red_review/blue_review
  gate instead of the unrelated in_review validation stage
- Test Catalog cards now warn when a technique already has existing
  tests, using the backend's new existing_test_count
- ExecutiveDashboardPage drops its duplicate client-side tactic-order
  sort now that the backend returns canonical order; time-range filter
  now notes which sections it actually scopes
- HeatmapLegend adds the missing review_required swatch (as an overlay
  indicator, matching how it's actually rendered on cells) and hover
  tooltips reusing StatusBadge's copy instead of being unexplained
  static color chips
- Fix a real React key bug in ControlsTable: rows were grouped in a
  keyless shorthand fragment, which can misreconcile when the table is
  filtered/sorted; switched to a keyed Fragment
- Minor: CompliancePage summary-card grid no longer strands a lone card
  on tablet widths
2026-07-08 08:46:24 +02:00
kitos 1c8fa436ab feat(backend): enforce campaign scheduling, add reviewer queue filter, tactic order, duplicate-test counts
- start_execution now blocks a test from starting before its campaign's
  start_date, closing a gap where the field was persisted but never
  enforced
- GET /tests gains a reviewer_id "my reviews" filter for the red_review/
  blue_review lead-gate stage, distinct from pending_validation_side
  (which only ever covered the later in_review stage and ignored
  assignment entirely)
- get_coverage_by_tactic now returns all 14 MITRE tactics in canonical
  kill-chain order instead of an alphabetical, partial list — the
  regular Dashboard and Executive Dashboard both consume this endpoint
  and previously disagreed on order/completeness
- test-template listing now includes existing_test_count per technique
  so the catalog can warn before creating a likely-duplicate test
2026-07-08 08:46:09 +02:00
kitos 21c6febd22 fix(frontend): render markdown descriptions properly, fix tooltip/banner wording
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
- Wrap 8 previously-raw description fields in MarkdownText so imported
  markdown (links, bold, lists, MITRE citations) renders instead of
  showing literal syntax: campaign cards, D3FEND countermeasure
  descriptions, compliance framework/control descriptions, detection
  rule descriptions, threat-actor and technique reference descriptions,
  and the RT-import preview description
- Fix the "Validated" status tooltip claiming a "≥2 tests" threshold
  when the real rule is ≥1 validated test with full detection; reworded
  the adjacent "Partial" tooltip for the same clarity
- Generalize the technique review_required banner text away from
  "MITRE ATT&CK sync" — review can also be triggered by Atomic/Caldera/
  Elastic/Sigma/LOLBAS imports, intel scans, and stale-detection checks
2026-07-07 16:30:27 +02:00
kitos c234fd64c2 feat(d3fend): flag review_required on new ATT&CK-D3FEND mappings
Mirrors the existing Atomic/Caldera/Elastic/Sigma/LOLBAS import pattern —
D3FEND mapping import was the one source silently skipping the
review_required flag, so leads never got prompted to review techniques
that only gained new D3FEND coverage.
2026-07-07 16:20:01 +02:00
kitos b6da0e22c2 feat(jira): push Attack Contained field (customfield_11885) on BT submit
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
Maps Test.containment_result (contained/partially_contained/not_contained)
to Yes/Partial/No, mirroring the existing Attack Success/Attack Detected
field push in push_bt_submitted. Field ID was the last missing piece
blocking this from Block 4.
2026-07-07 15:46:17 +02:00
kitos 1ddbd6989f fix(frontend): hide viewer-only risk-compute UI, proactively renew session
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
- Executive Dashboard no longer auto-triggers POST /risk/compute or shows
  the Refresh scores button for roles the backend rejects (viewer), which
  was causing a 403 on load
- AuthContext now proactively renews the session cookie every 20 minutes
  while the app is open, so an actively-used session doesn't rely solely
  on the reactive on-401 refresh racing against its own token's expiry
2026-07-07 13:42:54 +02:00
kitos bd26b09827 fix(backend): resolve refresh-token expiry deadlock, missing Jira on normal campaign approval, discarded threat-actor campaign start_date
- /auth/refresh now allows a short grace window past expiry and checks
  the blacklist, so an active session's silent refresh no longer fails
  the instant its own token expires
- normal manager /approve flow now creates Jira tickets for the campaign
  and its already-linked tests, matching the admin-only /activate path
- GenerateFromActorPayload now accepts start_date and threads it through
  to the new campaign instead of silently discarding it
2026-07-07 13:42:26 +02:00
kitos fefe70baed Merge branch 'main' of https://git.undiamagico.es/kitos/Aegis into claude/adoring-vaughan-273f91
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
2026-07-07 11:30:09 +02:00
kitos 1519ccc95c feat(tests): update data classification UI to org's 4-tier scheme 2026-07-07 11:16:45 +02:00
kitos a66fefa30b feat(classification): org data classification scheme, tactic-based initial default, operator edit rights 2026-07-07 11:16:35 +02:00
kitos b6b674d620 fix(deps): regenerate lock with babel/core 7.29.7 and esbuild 0.28.1 (overrides applied)
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
2026-07-07 11:01:28 +02:00
kitos 42b05379f7 fix(deps): revert babel/core lock to 7.29.0 (npm ci fails with manual sub-dep mismatch)
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
2026-07-07 10:47:23 +02:00
kitos d6fbc2ffe8 fix(deps): bump starlette>=1.3.1, pydantic-settings>=2.14.2; override babel/core>=7.29.6, esbuild>=0.28.1
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
2026-07-07 10:30:15 +02:00
kitos 949e5d42c4 fix(migration): cast CASE expression to enum type in b058 UPDATE statement
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
2026-07-06 17:01:25 +02:00
kitos c0a88fc489 feat(tests): attack_success 3-value UI, data classification badge, reorder containment options
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
2026-07-06 16:19:50 +02:00
kitos 022c1c756a feat(jira): pause/hold status mapping, RT/BT dates, TTP, attack_success 3-value field, hours 2026-07-06 16:19:39 +02:00
kitos 19c4866103 feat(tests): dispute resolution UI — manager escalation + red/blue queue selector
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
2026-07-06 12:40:21 +02:00
kitos f53e124c50 fix(tests): fix veto bug preventing disputed state, add manager notification and dispute-resolution routing 2026-07-06 12:40:05 +02:00
kitos 388c9773ab docs(tests): implementation plan for red/blue review workflow
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
2026-07-06 12:08:18 +02:00
kitos d5e3df00f9 feat(tests): review panels, blind visibility UX, red_review/blue_review badges 2026-07-06 12:02:14 +02:00
kitos 82033b5037 feat(tests): types and API client for red/blue review workflow 2026-07-06 12:02:07 +02:00
kitos 8a028bf0ed feat(tests): blind red/blue visibility until both reviews are approved 2026-07-06 11:42:35 +02:00
kitos b527eeac7d feat(tests): review-red/review-blue router endpoints 2026-07-06 11:42:34 +02:00
kitos e3cd75bb56 feat(tests): retarget submit-red/submit-blue through review gates, add review decisions 2026-07-06 10:56:41 +02:00
kitos 22be620665 feat(tests): load-balanced reviewer selection and Jira reviewer sync 2026-07-06 10:56:40 +02:00
kitos c41876b62f feat(tests): migration for red_review/blue_review states and review columns 2026-07-06 10:40:39 +02:00
kitos 2d98ed5ec6 feat(tests): add review assignment columns to Test model 2026-07-06 10:39:54 +02:00
kitos 58d1da93ce feat(tests): add red_review/blue_review states to test state machine 2026-07-06 10:38:15 +02:00
kitos af65681179 fix(campaigns): hide direct remove-test button on active campaigns
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
Direct test removal is now gated to draft-only at the service layer
(active campaigns must go through a modification request that a
manager approves). The trash-icon button on the tests table still
showed for active campaigns and would always fail with a 400 —
restrict it to draft, matching the backend gate.
2026-07-04 12:02:11 +02:00
kitos 164ef25393 fix(campaigns): complete ACTION_LABELS map and timeline cache invalidation
Adds the 4 backend-logged campaign actions missing from ACTION_LABELS
(delete_campaign, generate_campaign, schedule_campaign,
recurring_campaign_run), and wires campaign-timeline invalidation into
the remaining audit-logging mutations on the page (complete, schedule,
approve/reject modification request) so the timeline panel updates
live instead of only on next reload, consistent with submit/approve/
reject campaign.
2026-07-04 12:02:11 +02:00
kitos 83b4d2578a feat(campaigns): audit timeline UI and manager role in role pickers 2026-07-04 12:02:10 +02:00
kitos aeaf1cf243 fix(campaigns): reset modification-request modal state on close, not just on success
Previously action/testId/justification only reset inside the success
handler, so cancelling and reopening the modal left stale form values.
Mirrors the reset-on-close pattern already used by AddTestToCampaignModal.
2026-07-04 12:02:10 +02:00
kitos 952b6f27d7 feat(campaigns): modification request UI on campaign detail page 2026-07-04 12:02:10 +02:00
kitos b106780102 fix(campaigns): drop dead force param from activateCampaign API client
The backend endpoint no longer accepts a force query param (a draft
campaign can never have a future start_date to force past). No frontend
code currently calls this function, but keep it matching the real
backend contract in case a future admin UI wires it up.
2026-07-04 12:02:10 +02:00
kitos 6b6375ddad feat(campaigns): submit/approve/reject UI on campaign detail page 2026-07-04 12:02:10 +02:00
kitos f19d10e19c feat(campaigns): remove lead-set start dates, add pending-approval filter 2026-07-04 12:02:10 +02:00
kitos 858dd3e9e7 docs(campaigns): explain why CampaignModificationRequest.test_id can be null 2026-07-04 12:02:10 +02:00