Skip to content

Mariano/cs 437#2992

Open
Marfuen wants to merge 42 commits into
mainfrom
mariano/cs-437
Open

Mariano/cs 437#2992
Marfuen wants to merge 42 commits into
mainfrom
mariano/cs-437

Conversation

@Marfuen
Copy link
Copy Markdown
Contributor

@Marfuen Marfuen commented Jun 2, 2026

What does this PR do?

  • Fixes #XXXX (GitHub issue number)
  • Fixes COMP-XXXX (Linear issue number - should be visible at the bottom of the GitHub issue description)

Visual Demo (For contributors especially)

A visual demonstration is strongly recommended, for both the original and new change (video / image - any one).

Video Demo (if applicable):

  • Show screen recordings of the issue or feature.
  • Demonstrate how to reproduce the issue, the behavior before and after the change.

Image Demo (if applicable):

  • Add side-by-side screenshots of the original and updated change.
  • Highlight any significant change(s).

Mandatory Tasks (DO NOT REMOVE)

  • I have self-reviewed the code (A decent size PR without self-review might be rejected).
  • I have updated the developer docs in /docs if this PR makes changes that would require a documentation change. If N/A, write N/A here and check the checkbox.
  • I confirm automated tests are in place that prove my fix is effective or that my feature works.

How should this be tested?

  • Are there environment variables that should be set?
  • What are the minimal test data to have?
  • What is expected (happy path) to have (input and output)?
  • Any other important info that could help to test that PR

Checklist

  • I haven't read the contributing guide
  • My code doesn't follow the style guidelines of this project
  • I haven't commented my code, particularly in hard-to-understand areas
  • I haven't checked if my changes generate no new warnings

Summary by cubic

Adds the ISO 27001 ISMS area with six auto-derived, editable, versioned documents (4.1, 4.2a, 4.2b/c, 4.3, 5.1, 6.2) plus DOCX/PDF export, approvals, drift detection, and a short setup wizard. Delivers CS-437 by letting customers generate auditor-ready foundational documents from existing platform data.

  • New Features

    • “ISO 27001 (ISMS)” tab on Documents (shown when ISO 27001 is active and is-isms-enabled is on) with cards for Context (4.1), Interested Parties (4.2a), Requirements & Treatment (4.2b/c), Scope (4.3), Leadership (5.1), Objectives (6.2); full detail pages with registers or narrative forms.
    • Deterministic generation from org data with drift alerts; manual edits preserved; one-click regenerate; branded DOCX/PDF exports via docx and jspdf-autotable.
    • Submit/approve/decline workflow with version snapshots; document↔control links at org level; Framework Editor “ISMS Documents” mapping each doc to a clause requirement and control templates; ensure-setup is template-driven and idempotent.
    • Generic register endpoints for issues/parties/requirements/objectives; a ~12‑question wizard stores an ISMS profile and can generate all six documents; routes/pages are gated for private testing.
  • Bug Fixes

    • Approvals: approve/decline require needs_review and the assigned approver; any content edit (registers, narrative, control links) reverts approved docs to draft; control-link edits only downgrade approval when links actually change; approval runs with snapshot capture in one transaction.
    • Drift/determinism: detects wizard/vendor-category/department/member changes and Interested Parties edits via a stable fingerprint; deterministic selections; regulator dedupe; blank objectives ignored; Scope/Leadership include wizard answers.
    • Data integrity and UX: requirement party IDs validated to the same document; objectives owner validated; ensure-setup derives org from session; Zod-validated bodies documented via @ApiBody; narrative save is atomic and preserves user content unless empty; single isLatest version enforced; register creates serialize position allocation with a per-document advisory lock; stable forms and export uses apiClient.

Written for commit e92d083. Summary will update on new commits.

Review in cubic

Marfuen and others added 26 commits May 29, 2026 13:26
Placement (framework-grouped Documents page, ISO 27001 (ISMS) tab),
IsmsDocument substrate following the SOA pattern, clause-requirement
linkage, per-document data models, PDF reuse + net-new DOCX export,
feature-flagged all-or-nothing release, and slice-first build sequence.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
IsmsDocument + IsmsDocumentVersion (versioned narrative, source snapshot for
drift, pdf/docx urls, sign-off) and IsmsContextIssue (clause 4.1 register),
mirroring the SOADocument pattern. Links the global FrameworkEditorFramework +
org + ISO clause requirement. Back-relations on Organization,
FrameworkEditorFramework, FrameworkEditorRequirement, and Member.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
NestJS isms module (@controller path:'isms' v1) mirroring SOA: ensure-setup,
get document, deterministic Context-of-Organization (4.1) generation from
platform data, context-issue CRUD with derived->manual override, sign-off
(submit/approve/decline), drift detection vs approved snapshot, and branded
PDF + net-new DOCX export (docx@9.7.1). All endpoints gated
@RequirePermission('audit', ...) to match SOA. 63 Jest tests. openapi regen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ion (4.1) (CS-437)

Add framework-grouped Documents tabs with a flag-gated, ISO-27001-conditional
"ISO 27001 (ISMS)" tab (IsmsOverview: 6 foundational-doc cards + the moved SOA
card). Full Context of the Organization (4.1) detail page: useIsmsDocument hook,
generate-from-platform-data, editable internal/external issues register with
derived->manual override, drift banner, submit/approve/decline sign-off, and
PDF/DOCX export. Mutations gated on audit:update; readers can view + export.
isIsmsEnabled defaults off (PostHog) until the full pack ships. Vitest tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Permissions: switch ISMS endpoints from `audit` to the `evidence` resource
  (reads incl. ensure-setup -> evidence:read; mutations -> evidence:update).
  `evidence` matches the Documents route gate and is the correct semantic fit:
  owner/admin author + sign off, auditor read-only (review + export), others
  excluded. Frontend mutation gating moved to evidence:update.
- Drop the isIsmsEnabled runtime flag. The ISO 27001 (ISMS) tab is now purely
  framework-conditional (visible when ISO 27001 is active); the unmerged branch
  is the release gate. SOA card now lives solely in the ISMS tab.
- Spec updated to match (permissions + merge-gated release).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… Objectives (CS-437)

Add IsmsInterestedParty (4.2a), IsmsInterestedPartyRequirement (4.2b/c, linked
to a party), and IsmsObjective (6.2) register tables + IsmsObjectiveStatus enum,
all reusing the shared IsmsContextSource derived/manual flag. Scope (4.3) and
Leadership (5.1) are singletons stored in IsmsDocumentVersion.narrative.
Additive migration only.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…tch (CS-437)

Refactor generate/drift/export to dispatch by IsmsDocumentType to per-document
handler modules (documents/registry.ts). Add deterministic derivation, register
CRUD, and branded PDF/DOCX export for: Interested Parties (4.2a), Requirements &
Treatment (4.2b/c, linked to parties), Objectives (6.2), plus singleton narrative
docs Scope (4.3) and Leadership (5.1) stored zod-validated in version.narrative.
Single platform-data source; per-type drift snapshots; manual rows preserved on
regenerate. All endpoints @RequirePermission('evidence', ...). 138 Jest tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…CS-437)

Generalize useIsmsDocument (generic createRow/updateRow/deleteRow + saveNarrative)
and the [type] route dispatch, enable all six overview cards, and add functional
detail pages on the proven Context pattern:
- Interested Parties Register (4.2a), Requirements & ISMS Treatment (4.2b/c),
  Information Security Objectives Plan (6.2) - editable registers
- ISMS Scope Statement (4.3, certificate sentence first-class) and Leadership
  Commitment (5.1, clause 5.1 a-h) - narrative forms via saveNarrative
Each reuses DriftBanner + IsmsApprovalSection, gates mutations on evidence:update,
and offers PDF/DOCX export. Vitest tests per document (admin vs read-only).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
One profile per org+framework holding the ~12 un-derivable wizard answers as a
Zod-validated JSON blob that feeds document generation. Additive migration.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
API: IsmsProfile get-or-init/save/complete + generate-all, a shared Zod
WizardAnswers schema, computed defaults for pre-population (capabilities from
Types of Services, certificate sentence, default objectives/outcomes, cloud
split), and threading wizard answers through derivation (insurance/regulators/
contractors/EU-rep -> Interested Parties & Requirements; certificate sentence +
cloud split + capabilities -> Scope; deputy SPO -> Leadership; confirmed
objectives -> 6.2).

Frontend: 6-step wizard (12 questions, confirm-or-edit, pre-filled from defaults)
with partial saves per step and complete -> generate-all on finish; "Run setup
wizard" entry point on the ISMS overview. RHF+Zod, design-system only.

189 API jest tests; wizard Vitest tests; all ISMS checks green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…S-438)

Adds the evidence:update-gated wizard launch button to IsmsOverview
(missed by the prior wizard commit's add path).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add FrameworkEditorIsmsDocumentTemplate (one per doc type, with default clause)
and FrameworkEditorIsmsDocumentRequirementLink (framework-scoped template->clause
mapping, editable in the Framework Editor), plus IsmsDocument.templateId
provenance. Additive migration.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…, Paul A)

Seed the 6 ISMS doc templates; add a framework-editor CRUD/mapping API
(framework-editor/isms-document-template: list, update, link/unlink a clause
requirement per framework, PlatformAdminGuard); rework ensure-setup to be
template-driven (requirement = framework-scoped link ?? clause-match ?? seeded
defs fallback) with IsmsDocument.templateId provenance; and a Framework Editor
"ISMS Documents" tab/page to author the template->requirement mappings.

238 api jest tests; framework-editor + api typecheck clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
FrameworkEditorControlIsmsDocumentLink (template: control template <-> ISMS doc
template, framework-scoped) and IsmsDocumentControlLink (org: document <-> control),
mirroring how policies/document-types link to controls. Back-relations on
FrameworkEditorFramework/ControlTemplate/IsmsDocumentTemplate, Control, IsmsDocument.
Additive migration.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Template level (Framework Editor): link/unlink control templates to ISMS doc
templates + a "Controls" mapping cell on the ISMS Documents page.
Org level: POST/DELETE /v1/isms/documents/:id/controls (like policies),
getDocument returns controlLinks, ensure-setup auto-derives a doc's org control
links from its template's control mapping. A "Linked controls" section
(IsmsControlMappings) on all 6 document detail pages, mirroring PolicyControlMappings.

257 api jest tests; api/framework-editor/app typecheck clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…-grade (CS-437)

Establish a shared ISMS presentation kit (IsmsStatusBadge, IsmsDocumentCard,
IsmsPageHeader, IsmsSummaryRow, IsmsEmptyState, IsmsRegisterShell, IsmsSourceBadge,
IsmsRowActions) and restyle the whole area with it: overview (summary stats +
Section/Grid of document cards + SOA section + Empty state), the 6 detail pages
(consistent header + Section composition), register tables (DS Table + Empty
states), drift (Alert), control mappings, approval, and the wizard (Progress +
Field steps). One status language, no hand-rolled badges. Strictly design-system
components only. Tests + typecheck green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Wizard: Select shows the human label via items prop (#8) + controlled-from-first-
render value, no console warning (#9); Finish validation jumps to the first
invalid step (#6); form re-seeds when the profile loads post-mount (#7).
Shared: source badge reads "Manual" not "Edited" (#1); approval section is
status-aware — approved/declined/pending states instead of a bare submit (#2);
compact empty state (#4); delete confirmation dialog on register rows (#5).
Detail pages: content-first ordering across all 6 (#3).
API: certificate-sentence whitespace normalized (#11); cloud-split/capabilities
feed scope correctly (#10). Plus QA findings doc + openapi regen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…rview (CS-437)

Replace the dense always-on-textarea tables (Context internal/external issues,
Interested Parties, Requirements, Objectives) with calm read-first cards: source
chip + provenance leading, the primary field prominent, secondary fields as
muted labelled values, count-badged sections, compact empty states, and an
explicit Edit affordance (Save/Cancel) with the delete-confirm preserved. New
shared kit: IsmsRegisterCard, IsmsCardActions, IsmsAddCard. Design-system only;
register component props/behaviour unchanged. 42 ISMS tests pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Read mode is now a compact two-line row — issue prominent, effect muted beneath,
source chip + provenance on the right, hover-reveal actions, tighter padding —
instead of an airy card with a labelled effect field. Roomy labelled form kept
for editing. Tighter row spacing. Cuts ~half the vertical space per item for
long lists. DS-only; behaviour unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace the loud uppercase AUTO-DERIVED pill + raw "framework:GDPR" key with a
quiet muted line + small icon and a humanized source ("GDPR framework", "Vendor
register", "Workforce", "Setup wizard"). Manual rows keep a small badge so human
overrides still stand out. Shared component, so all four registers benefit.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Drop the misleading auto/ML icon and the disconnected right-floating label;
render the humanized source as a plain pill beneath each entry's description
(GDPR framework / Vendor register / Workforce / Manual). Reads like a tag on the
entry rather than floating metadata.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
framework:GDPR -> "GDPR" (not "GDPR framework"); the name alone is clearer.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The submit-for-approval / approved banner now renders directly under the header,
above drift/content/linked-controls, so the sign-off state and action are the
first thing you see on a document rather than buried at the bottom. Applied
identically across all six detail pages.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…(CS-437)

The auto-derive provenance pill (WORKFORCE / GDPR / HIPAA) just restated the
party name sitting next to it. Removed it; the category badge (CUSTOMER /
SUPPLIER / REGULATOR) stays since that's real classification, not a restatement.
Made IsmsRegisterCard.header optional so edit mode renders without it (actions
stay right-aligned via ml-auto).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…nt (CS-439)

Redesign the ISO 27001 Context of the Organization PDF/DOCX export to match the
hand-authored reference document, and capture the data it needs.

- db: add `category` to IsmsContextIssue (4.1 grouping) + migration
- derivation: assign each derived issue an ISO 4.1 category; export the
  external/internal category taxonomies
- export: pull org overview (onboarding Q&A), mission (company description) and
  intended outcomes (wizard answers / defaults) at export time; build rich
  metadata (document code, clause, classification, owner, next review, issue date)
- builder: buildContextSections now emits the full 7-section structure — purpose,
  organization overview, mission + intended outcomes, categorised external and
  internal issue tables (Category / Issue / Effect), linkage, review
- renderers: rebuild PDF (jspdf + jspdf-autotable) and DOCX with a cover block,
  metadata table, numbered sections, real bordered tables, bullet lists and a
  footer with classification + page numbers; split PDF into its own module
- ui: add an ISO 4.1 category picker to the issue add form + edit row, show the
  category as a pill in read mode
- tests: API builder/derivation/service + app picker coverage

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…s (CS-437)

Wrap the ISO 27001 (ISMS) tab in the `is-isms-enabled` PostHog flag so it can be
privately tested per-org (matching the is-*-enabled convention). The tab now
shows only when ISO 27001 is active AND the flag is on; local development falls
through so it stays visible without PostHog configured.

Move the Statement of Applicability card out of the ISMS tab and back to the top
of the general Documents list (gated on ISO 27001 presence), while we privately
test the ISMS area.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@linear
Copy link
Copy Markdown

linear Bot commented Jun 2, 2026

CS-437

@vercel
Copy link
Copy Markdown

vercel Bot commented Jun 2, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
comp-framework-editor Ready Ready Preview, Comment Jun 3, 2026 9:19pm
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
app Skipped Skipped Jun 3, 2026 9:19pm
portal Skipped Skipped Jun 3, 2026 9:19pm

Request Review

@Marfuen
Copy link
Copy Markdown
Contributor Author

Marfuen commented Jun 2, 2026

@cubic-dev-ai ultrareview this

@Marfuen
Copy link
Copy Markdown
Contributor Author

Marfuen commented Jun 2, 2026

@cubic-dev-ai review this

@cubic-dev-ai
Copy link
Copy Markdown
Contributor

cubic-dev-ai Bot commented Jun 2, 2026

@cubic-dev-ai review this

@Marfuen I have started the AI code review. It will take a few minutes to complete.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cubic analysis

10 issues found across 203 files

Confidence score: 2/5

  • There is a concrete user-impacting regression risk in apps/app/src/app/(app)/[orgId]/documents/isms/components/ContextOfOrganizationClient.tsx: handleUpdateIssue swallows API errors, so IssueRow can exit edit mode and lose unsaved edits when save fails.
  • Several high-confidence behavior issues (7/10) increase merge risk, including stale local state in apps/framework-editor/app/(pages)/isms-documents/useIsmsDocumentRows.ts after template re-fetches and hardcoded admin-only access in apps/api/src/framework-editor/isms-document-template/isms-document-template.controller.ts that can block RBAC-based delegation.
  • Data-intent consistency is also at risk in apps/api/src/isms/documents/objectives.ts and apps/api/src/isms/documents/org-profile.ts, where explicitly saved empty values can be overwritten by regenerated defaults.
  • Pay close attention to apps/app/src/app/(app)/[orgId]/documents/isms/components/ContextOfOrganizationClient.tsx, apps/framework-editor/app/(pages)/isms-documents/useIsmsDocumentRows.ts, apps/api/src/framework-editor/isms-document-template/isms-document-template.controller.ts, apps/api/src/isms/documents/objectives.ts, and apps/api/src/isms/documents/org-profile.ts - these carry the highest chance of user-visible regressions and authorization/data-intent mismatches.

Linked issue analysis

Linked issue: CS-437: [Feature] A. Foundational documents

Status Acceptance criteria Notes
Add an ISMS area in Documents (ISO 27001 / ISMS tab) and an ISMS overview with document cards Front-end tab wiring and overview components added; DocumentsPageTabs updated and IsmsOverview plus many UI cards/components added.
Provide the six foundational document types (4.1 Context, 4.2a Interested Parties, 4.2b/c Requirements, 4.3 Scope, 5.1 Leadership Commitment, 6.2 Objectives) Schema, type definitions and handler modules for each document type are present; ISMS_TYPE_DEFINITIONS and IsmsDocumentType defined; per-document derivation modules added.
Deterministic generation from platform data (collectPlatformData + per-document derivations) and generate-all flow Platform-data collection, generate/runDerivation and replace-derived-rows logic implemented; generate-all DTO and service paths exist.
Customer-editable registers where manual overrides are preserved (derived → manual on edit) and regenerate preserves manual edits Services flip derived rows to 'manual' on edit and replaceDerivedRows preserves manual rows; register services and controllers added for CRUD.
Versioning, submit/approve/decline workflow and approval invalidation when content changes IsmsDocument and IsmsDocumentVersion model work is supported by services and DTOs; approval invalidation helper and narrative save that resets approvals implemented; submit/approval DTO and UI present.
Export to DOCX and PDF (branded, cover metadata, structured sections) Both docx and PDF renderers implemented, export generator dispatch, DTO and client export helper present; deps added to package.json.
Short setup wizard (~12 questions) that persists profile answers and can generate all documents in a single session Full wizard client + server-side profile schema, services and generate-all plumbing implemented, including defaults and merge logic.
Drift detection and one-click regenerate UI (flagging when underlying platform data changed) Snapshot diffing and snapshot upsert implemented; drift API/hooks and UI components exist (useIsmsDrift, DriftBanner, snapshot logic).
Consolidated register CRUD endpoints (create / update / delete) routed by register segment A generic register-registry routes requests to per-register services; controller exists exposing create/update/delete for registers.
⚠️ Definition-of-done: Pressmaster and Kidan packs reproducible and match/exceed hand-authored quality Renderers and metadata exist to create DOCX/PDF outputs and a QA file was added, but there is no example output or explicit automated regression comparing generated packs to existing hand-authored artifacts in the diff to verify parity/quality.
⚠️ Definition-of-done: Pressmaster/Kidan Stage-1 findings (4.1,4.2,4.3,6.2) closable using platform output alone Generation targets the specified clauses and derivation logic maps platform data to clause content, but auditor acceptance is outcome-level and there are no audit-run artifacts or acceptance tests proving those engagements' findings are closable solely with generated docs.

Tip: instead of fixing issues one by one fix them all with cubic
Partial review: This PR has more than 100 files, so cubic reviewed the highest-priority files first.
For a deeper review of large PRs, comment @cubic-dev-ai ultrareview. Learn more.

Re-trigger cubic

Comment thread apps/app/src/app/(app)/[orgId]/documents/isms/wizard/WizardObjectivesEditor.tsx Outdated
Comment thread apps/api/src/isms/wizard/isms-profile.controller.ts
Comment thread apps/app/src/app/(app)/[orgId]/documents/isms/wizard/page.tsx Outdated
Comment thread apps/app/src/app/(app)/[orgId]/documents/isms/wizard/page.tsx
Comment thread apps/api/src/isms/documents/objectives.ts Outdated
Comment thread apps/api/src/isms/documents/org-profile.ts
- clients: every create/update/delete handler re-throws after toast so a failed
  save keeps the row/form open with the user's input (regression from the shell
  refactor)
- route gating: new server layout gates the whole /documents/isms/* segment on
  the is-isms-enabled flag (+ ISO 27001 active), so wizard/detail pages aren't
  reachable by direct URL during private testing
- wizard: stable row keys in WizardObjectivesEditor (was array index); breadcrumb
  href matches its link
- single-source the objective zod schema (ObjectivesForm imported the shared one)
- framework-editor: useIsmsDocumentRows re-syncs local state when templates prop changes
- @ApiBody on the isms-profile @Req endpoint
- respect an explicitly-emptied wizard objectives / intended-outcomes array
  instead of reseeding defaults (only fall back when never set)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel vercel Bot temporarily deployed to Preview – portal June 2, 2026 20:02 Inactive
@Marfuen
Copy link
Copy Markdown
Contributor Author

Marfuen commented Jun 2, 2026

@cubic-dev-ai review this

@cubic-dev-ai
Copy link
Copy Markdown
Contributor

cubic-dev-ai Bot commented Jun 2, 2026

@cubic-dev-ai review this

@Marfuen I have started the AI code review. It will take a few minutes to complete.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cubic analysis

11 issues found across 207 files

Confidence score: 3/5

  • There is concrete regression risk in persistence logic: packages/db/prisma/migrations/20260529172752_add_isms_foundational_documents/migration.sql allows multiple isLatest=true rows, which can make “latest version” reads nondeterministic.
  • apps/api/src/isms/isms-narrative.service.ts and apps/api/src/isms/isms-context-issue.service.ts perform key reads/calculations outside transactions, creating race windows under concurrency (wrong-version narrative writes, unique-constraint crashes, and duplicate ordering positions).
  • Workflow integrity is also at risk: apps/api/src/isms/isms-document-control.service.ts can modify approved documents without triggering approval invalidation, and several frontend schema/linking issues increase validation and data-consistency drift risk.
  • Pay close attention to packages/db/prisma/migrations/20260529172752_add_isms_foundational_documents/migration.sql, apps/api/src/isms/isms-narrative.service.ts, apps/api/src/isms/isms-context-issue.service.ts, apps/api/src/isms/isms-document-control.service.ts - they carry the highest likelihood of user-visible data integrity and process-state regressions.

Linked issue analysis

Linked issue: CS-437: [Feature] A. Foundational documents

Status Acceptance criteria Notes
Add new ISO 27001 (ISMS) Documents area and navigation tab (feature-flagged / framework-gated) Frontend adds ISMS overview/route, DocumentsPageTabs was updated to surface an ISMS tab and layout enforces feature-flag + framework gating.
Implement the six foundational document types server-side (types, DB schema, migrations, templates) Prisma schema, multiple migrations and template seed entries add the IsmsDocument types and related tables.
Deterministic generation of document content from platform data (collect + per-document derivations) There is a centralized data collector and per-document derivation modules with unit tests; runDerivation wires them into generation logic.
Documents are editable and manual overrides are preserved (editing flips source to manual) Register services explicitly flip derived rows to 'manual' on edit; narrative save and register CRUD exist; UI provides inline edit forms.
Versioning and approval workflow (submit / approve / decline) with approval invalidation on edits Document version snapshot upsert, approval DTOs and narrative/version services exist; invalidateApprovalIfNeeded used when edits occur.
DOCX and PDF export (branded) implemented Export generator + separate DOCX and PDF renderers exist, with metadata handling including primary colour; docx/jspdf deps added.
Setup wizard to collect non-derivable inputs and ability to generate all six documents Wizard schema, controller/service, client components, generate-all DTO and generate flow are implemented and tested; defaults and merging logic present.
Frontend: overview, per-document detail pages and register UIs (add/update/delete) Many client components implement overview cards, per-document shells, register tables, add/edit rows, control mapping, and tests are included.
Drift detection and one-click regenerate flow (snapshot, diff, UI banner) Snapshot capture, diff logic and UI drift banner plus useIsmsDrift hook and regenerate flows are implemented.
Control ↔ ISMS document mapping (link/unlink controls) Backend control-link service and frontend control-mapping UI and APIs are implemented.
⚠️ Exports & generation in a single session (wizard → generate → export all six documents) All pieces exist (wizard, generateAll, export endpoints and client hooks), showing an end-to-end path. However, end-to-end integration tests or an explicit e2e flow demonstrating export-of-all-six-in-single-session are not present in the diff to fully validate this behavior in CI.
Pressmaster and Kidan packs are reproducible and platform output alone closes Stage-1 findings The issue's DoD requires reproducing specific vendor packs and closing real audit findings; the PR implements the generation pipeline and export tooling, but I see no explicit seeded content, acceptance tests, or sample outputs demonstrating Pressmaster/Kidan comparability or any audit-closing validation artifacts in this diff.

Tip: instead of fixing issues one by one fix them all with cubic
Partial review: This PR has more than 100 files, so cubic reviewed the highest-priority files first.
For a deeper review of large PRs, comment @cubic-dev-ai ultrareview. Learn more.

Re-trigger cubic

Comment thread apps/app/src/app/(app)/[orgId]/documents/isms/components/issue-schema.ts Outdated
Comment thread apps/api/src/isms/isms-narrative.service.ts Outdated
Comment thread apps/api/src/isms/isms-context-issue.service.ts Outdated
Comment thread apps/app/src/app/(app)/[orgId]/documents/isms/components/ScopeClient.tsx Outdated
Comment thread apps/app/src/app/(app)/[orgId]/documents/isms/components/RequirementsForm.tsx Outdated
Comment thread apps/app/src/app/(app)/[orgId]/documents/isms/components/AddIssueForm.tsx Outdated
Comment thread apps/api/src/isms/isms-document-control.service.ts Outdated
# Conflicts:
#	apps/app/src/app/(app)/[orgId]/documents/components/SOAOverviewCard.tsx
…(CS-437)

- atomic read+write: narrative latest-version read and register nextPosition now
  run inside their transactions (no stale-version write / position TOCTOU)
- control-link add/remove invalidate approval (revert approved doc to draft),
  consistent with register/narrative edits
- DB: partial unique index enforces at most one isLatest=true version per document
- shared zod schemas trim before min(1) (whitespace-only no longer passes); the
  last three forms (interested-parties, requirements, add-issue) import the shared
  schema instead of duplicating it
- wizard page derives org from the [orgId] route param, not session active org
- ScopeClient keys the narrative form on the stable version id (no remount on save)
- framework-editor link handlers guard against double-linking

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 issues found across 23 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Fix all with cubic | Re-trigger cubic

Comment thread apps/api/src/isms/isms-interested-party.service.ts
Comment thread apps/api/src/isms/isms-document-control.service.ts Outdated
Comment thread apps/api/src/isms/isms-context-issue.service.ts
Comment thread apps/api/src/isms/isms-objective.service.ts
…approval (CS-437)

- register creates take a per-document Postgres advisory xact lock before
  allocating position, so concurrent creates can't read the same max(position)
  and persist duplicate ordering keys (a moved-read-into-tx alone doesn't
  serialize under READ COMMITTED). Shared lockDocumentForPositions helper.
- control-link add/remove now invalidate approval only when a row actually
  changes (createMany/deleteMany count > 0), so an idempotent re-link / no-op
  unlink no longer downgrades an approved document.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant