feat: link AI incidents to model/use case and owner via FK (issue #4583) - #4667
Merged
MuhammadKhalilzadeh merged 21 commits intoSep 11, 2026
Merged
MuhammadKhalilzadeh merged 21 commits into
MuhammadKhalilzadeh merged 21 commits into
Conversation
…, tenant reference checks
…reference validation
Contributor
✅ Coverage Gate PassedAll coverage thresholds are met. |
… (issue #4583) - zero out the global MuiPaper marginTop/borderRadius on the drawer paper, matching every other drawer in the app (DrawerFrame, Annex/ISO drawers) - add minWidth: 0 to the affected model/owner row so a long selected model name truncates with ellipsis instead of growing the select and squeezing the adjacent owner dropdown
…l keeps them (issue #4583) Raw list/detail queries resolve model_inventory_name / project_title / assignee_name via LEFT JOIN aliases, but the fields were plain 'declare'd class properties — not sequelize attributes — so mapToModel dropped them and the API returned null. Table cells showed '-' and the AFFECTED MODEL / OWNER filter dropdowns were empty. Declaring them as DataType.VIRTUAL columns makes sequelize carry the aliased values into dataValues. Adds a regression spec pinning the aliases as model attributes with a field mapping, and a build-from-raw-row assertion.
…(issue #4583) Prepend the app-standard '(none)' option to the affected-model and owner dropdowns. Selecting it stores '', which handleSaveIncident normalises to null, so saving unlinks the FK via the existing PATCH null support.
MuhammadKhalilzadeh
deleted the
mo-393-sept-10-link-AI-incidents-to-model-use-case
branch
September 11, 2026 11:22
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Describe your changes
AI incidents referenced the affected system and responsible people as free text (
ai_project,model_system_version,reporter,approved_by) with no relational integrity — making it impossible to reliably answer "show all incidents for this model/use case" or "which incidents is this person accountable for".This PR closes the issue by converting those typed-string references into real foreign keys:
Backend
20260910060000-add-fks-to-ai-incident-managements.js: adds nullablemodel_inventory_id → model_inventories(id),project_id → projects(id),assignee_id → users(id)(allON DELETE SET NULL— incidents are EU AI Act Art. 73 compliance records, so deleting a model/user must not erase incident history;SET NULLfollows themodel_risks.ownerprecedent in the same base migration), plus 3 org-scoped indexes. Additive only → runs cleanly on fresh DB and as an upgrade; no forced backfill.POST/PATCH /api/ai-incident-managementsaccept the three optional FKs (explicitnullunlinks);GET /api/ai-incident-managementssupports?model_inventory_id=&project_id=&assignee_id=filters; responses include the FK ids plus joined display names (model_inventory_name,project_title,assignee_name) viaLEFT JOINs.validateIncidentReferences) that blocks cross-org linkage (IDOR) that a bare FK constraint cannot catch.Frontend
/modelInventory) and Owner assignee dropdown (users by id); the use-case select now recordsproject_idalongside the legacyai_projecttitle.Tests
createNewIncident/updateIncident/toSafeJSON/toJSON) and FK validation specs — backend jest 23/23 green; frontend vitest 9/9 green;tsc/tsc -bclean both sides.ai_incident_managements,createTestIncidentfactory, andincidents.isolation.test.ts(list scoping, org-scoped filters, cross-tenant denial, cross-tenant FK reference rejection, org stamping on create). Registry requirement noted in the checklist below.Full delivery record:
docs/plans/MULTI_AGENT_PLAN_issue-4583.md.Write your issue number after "Fixes "
Fixes #4583
How to test
1. Backend build & unit tests
2. Migration (fresh + upgrade)
3. Tenant isolation (requires test DB)
cd Servers npm run test:integration -- --testPathPattern=incidents.isolation4. API smoke (any HTTP client, bearer token of an Admin/Editor)
5. Verifying through the UI
Screenshots / demo
UI screenshots not attached — no running dev environment with seeded data available in the authoring environment; all backend behavior is covered by unit + integration tests, and the UI steps above were verified against the component test suite (
IncidentManagement.test.tsx, 4 tests green).Please ensure all items are checked off before requesting a review:
backend,frontend,enhancement)npm run generate:swagger). (no routes changed — only query params on an existing GET;npm run check:api-drift→ no drift, 791/791 operations)authenticateJWTand the generated spec declaresbearerAuthsecurity. (routes unchanged — all remain behindauthenticateJWT)npm run check:api-driftand committed the regeneratedswagger.yamlandendpoints.ts. (no drift detected; no regen needed)ai_incidentsregistry entry,createTestIncidentfactory,incidents.isolation.test.ts, and cleanup coverage)