SOA as document: replace export with publish workflow#1022
Merged
SachaProbo merged 1 commit intomainfrom Apr 16, 2026
Merged
Conversation
a7b699b to
396a25a
Compare
Contributor
There was a problem hiding this comment.
6 issues found across 48 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="e2e/console/statement_of_applicability_test.go">
<violation number="1" location="e2e/console/statement_of_applicability_test.go:487">
P2: Authorization negative tests should assert FORBIDDEN explicitly, not just any error.</violation>
</file>
<file name="apps/console/src/pages/organizations/statements-of-applicability/dialogs/PublishStatementOfApplicabilityDialog.tsx">
<violation number="1" location="apps/console/src/pages/organizations/statements-of-applicability/dialogs/PublishStatementOfApplicabilityDialog.tsx:108">
P2: Only close/reset the dialog after a confirmed successful publish result; otherwise show an error to avoid silent failure UX.</violation>
</file>
<file name="apps/console/src/pages/organizations/statements-of-applicability/dialogs/CreateStatementOfApplicabilityDialog.tsx">
<violation number="1" location="apps/console/src/pages/organizations/statements-of-applicability/dialogs/CreateStatementOfApplicabilityDialog.tsx:100">
P2: Handle GraphQL errors in `onCompleted` before showing success. Right now the dialog can report success for failed mutation completions.</violation>
</file>
<file name="pkg/coredata/control_obligation.go">
<violation number="1" location="pkg/coredata/control_obligation.go:163">
P1: Prefixing `scope.SQLFragment()` with `o.` breaks `NoScope` (`TRUE` becomes `o.TRUE`) and causes runtime SQL errors.</violation>
</file>
<file name="pkg/coredata/document.go">
<violation number="1" location="pkg/coredata/document.go:38">
P1: Adding `ContentSource` to `Document` without updating all `Document` SELECT projections will break row scanning in some loaders (`LoadByControlID`, `LoadByRiskID`, `LoadByMeasureID`).</violation>
</file>
<file name="pkg/probo/statement_of_applicability_service.go">
<violation number="1" location="pkg/probo/statement_of_applicability_service.go:239">
P2: Validate that each DefaultApproverID belongs to the statement’s organization before merging. Without this check, profiles from other organizations in the tenant can be attached as default approvers.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
4eba208 to
77e3231
Compare
Contributor
Author
|
@cubic-dev-ai review please |
Contributor
@SachaProbo I have started the AI code review. It will take a few minutes to complete. |
Contributor
There was a problem hiding this comment.
5 issues found across 54 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="pkg/coredata/snapshot.go">
<violation number="1" location="pkg/coredata/snapshot.go:166">
P2: `LoadByOrganizationID` now excludes `STATEMENTS_OF_APPLICABILITY`, but `CountByOrganizationID` does not. This creates inconsistent list vs total-count results for snapshot pagination.</violation>
</file>
<file name="pkg/coredata/migrations/20260410T120000Z.sql">
<violation number="1" location="pkg/coredata/migrations/20260410T120000Z.sql:36">
P2: Enforce uniqueness on `document_id` to preserve a one-to-one SOA↔Document relationship for documentId-based lookups.</violation>
</file>
<file name="pkg/server/api/mcp/v1/specification.yaml">
<violation number="1" location="pkg/server/api/mcp/v1/specification.yaml:6152">
P2: The SOA list filter still documents `snapshot_id` semantics even though SOA now links to `document_id`, leaving an inconsistent API contract.</violation>
<violation number="2" location="pkg/server/api/mcp/v1/specification.yaml:6235">
P2: `default_approver_ids` is write-only in the schema, so clients cannot read saved default approvers from SOA responses.</violation>
</file>
<file name="pkg/probo/generated_document_service.go">
<violation number="1" location="pkg/probo/generated_document_service.go:53">
P2: External I/O (`GetFileBase64` to object storage) and pure computation (`BuildStatementOfApplicabilityProseMirrorDocument`) both execute inside the database transaction, holding the DB connection open unnecessarily. Consider restructuring: fetch data (including logo) and build the ProseMirror document *before* the transaction, then pass the result into a shorter write-only transaction for inserts/updates.
(Based on your team's feedback about splitting data fetching from generation and keeping transactions short-lived.) [FEEDBACK_USED]</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
c9d64ed to
671dbc5
Compare
Contributor
There was a problem hiding this comment.
2 issues found across 65 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="cmd/migrate-soa-snapshots-to-documents/main.go">
<violation number="1" location="cmd/migrate-soa-snapshots-to-documents/main.go:476">
P1: Custom agent: **Avoid Logging Sensitive Information**
Database password can leak to stderr when DSN parsing fails. `url.Parse` embeds the full URL (including credentials) in its error output, and this error is printed to stderr in `main()`. Redact the DSN or return a generic error instead of wrapping `url.Parse`'s error directly.</violation>
</file>
<file name="pkg/probo/generated_document_service.go">
<violation number="1" location="pkg/probo/generated_document_service.go:429">
P2: Non-applicable controls incorrectly show a "not implemented" justification. The `implemented` column correctly displays "-" for non-applicable controls, but `notImplJustification` doesn't check applicability, so it can still show justification text — contradicting the annex definition on line 603 ("This field is empty … when the control is not applicable").</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
05527e1 to
a5a080a
Compare
edcf71f to
7242f2b
Compare
codenem
reviewed
Apr 15, 2026
codenem
reviewed
Apr 15, 2026
codenem
reviewed
Apr 15, 2026
codenem
reviewed
Apr 15, 2026
codenem
reviewed
Apr 15, 2026
7d299e1 to
35a4956
Compare
Statements of Applicability are no longer exported as one-off PDFs. Instead, each SOA owns a persistent document that accumulates versions over time, following the same publish/approve lifecycle as authored documents. Publishing without approvers publishes immediately; publishing with approvers creates a draft pending approval via the existing quorum system. SOAs can also store default approvers that are pre-populated in the publish dialog. The SOA is removed from the snapshot system — applicability statements are now queried directly (snapshot_id IS NULL) rather than through snapshot copies. A standalone migration script (cmd/migrate-soa-snapshots-to-documents) converts existing SOA snapshots into documents with proper ProseMirror content, preserving version history and approval decisions. Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
35a4956 to
c635492
Compare
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.
Statements of Applicability are no longer exported as one-off PDFs. Instead, each SOA owns a persistent document that accumulates versions over time, following the same publish/approve lifecycle as authored documents.
Publishing without approvers publishes immediately; publishing with approvers creates a draft pending approval via the existing quorum system. SOAs can also store default approvers that are pre-populated in the publish dialog.
The SOA is removed from the snapshot system — applicability statements are now queried directly (snapshot_id IS NULL) rather than through snapshot copies.
A standalone migration script (cmd/migrate-soa-snapshots-to-documents) converts existing SOA snapshots into documents with proper ProseMirror content, preserving version history and approval decisions.
Summary by cubic
Replaces one-off SOA PDF exports with persistent, generated documents that follow the publish/approve workflow. SOAs now version like other documents and can be published immediately or sent for approval; snapshots and export are removed.
New Features
STATEMENT_OF_APPLICABILITYdocument withGENERATEDwrite mode; generated versions aren’t editable.DocumentWriteMode(defaultAUTHORED) andDocumentVersionOrientation;GeneratedDocumentServicerenders SOA content fromtemplates/statement_of_applicability.json.tmpland supports landscape output.writeMode=GENERATED.STATEMENT_OF_APPLICABILITY), write mode, and orientation; document queries (incl. control/measure/risk) support write‑mode filtering; SOA exposes itsdocument; electronic signatures include SOA type.probo soa publish;probo document list --write-mode;n8naddsstatementOfApplicabilityresource (create/get/list/update/delete/publish) and document listing supports SOA type; new SOA publish E2E tests.Migration
cmd/migrate-soa-snapshots-to-documentsconverts existing SOA snapshots into documents with preserved versions and approvals.Written for commit c635492. Summary will update on new commits.