Commit Graph

261 Commits

Author SHA1 Message Date
Sacha Al Himdani
b6b1e801b1 Add third-party self-referential relations
Introduce a self-referential many-to-many relation table so a
third party can have child third parties. Each relation is
directional (parent to child); both directions can coexist as
independent rows.

Add a first_level boolean on third_parties (default true) with
a filter on the list page that defaults to showing only
first-level third parties.

Frontend adds a "Third Parties" tab on the detail page where
users can link existing third parties or create new ones from
the common third party catalog (created as non-first-level).
The list page gets a First Level/All toggle filter.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-05-26 15:21:38 +02:00
Sacha Al Himdani
eecbe4c46c Rename vendors to third parties
Renames the user-facing 'vendor' concept to 'third party' across the
entire codebase. The shared common_third_parties reference table is
unchanged.

Migration. Renames the vendor_category enum, the vendors and
vendor_<entity> tables (contacts, services, compliance_reports,
business_associate_agreements, data_privacy_agreements,
risk_assessments) and their vendor_id columns, the asset_vendors /
data_vendors / processing_activity_vendors junction tables,
generated_documents.vendors_document_id, the webhook_event_type
'vendor:<verb>' values, and the snapshots_type 'VENDORS' value.

Backend. Renames coredata models and SQL queries, probo services,
GraphQL / MCP API surface, console / trust / webhook resolvers and
types, the CLI (prb vendor* -> prb third-party*; pkg/cmd/vendormgmt
-> pkg/cmd/thirdpartymgmt), the document generator, vetting agent
prompts, and the common-third-parties-import command.

Frontend, packages, n8n, e2e. Renames apps/console pages, components,
hooks, routes, dialogs, and tabs; the shared @probo/vendors package
(now @probo/third-parties); the @probo/ui Vendors atoms (now
ThirdParties, VendorLogo -> ThirdPartyLogo); the n8n community node
actions/vendor folder (now actions/thirdParty); and the e2e Go test
suite (console and MCP). Filesystem and URL paths use kebab-case
(third-parties), GraphQL fields and TypeScript identifiers use
camelCase (thirdParty / thirdParties), Go types use PascalCase
(ThirdParty), and human-facing text uses 'third party' with a space.

Co-authored-by: Bryan Frimin <bryan@getprobo.com>
Signed-off-by: Bryan Frimin <bryan@getprobo.com>
Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-05-13 21:21:39 +02:00
Sacha Al Himdani
553901e4ad Add risk publish to document system
Replace the old snapshot-based system for risks with the publish
document system, mirroring the prior vendor / processing activity / DPIA
/ TIA migration. Includes the GraphQL mutation, MCP tool, CLI command,
n8n operation, frontend publish dialog, e2e tests, and a prosemirror
register template covering name, description, category, treatment,
owner, inherent and residual scoring, and notes.

The risk register lives as a generated DocumentTypeRegister document on
the organization, reused across publishes (the major version bumps on
every republish). Approvers can be passed in to create a draft pending
approval; otherwise the version is published immediately. The frontend
Risks page exposes a Publish button and a Document link button when the
document exists, and pre-fills the previous default approvers.

Risks was the last remaining snapshot type, so this commit also removes
the entire snapshot system: drop snapshotId from the Risk GraphQL type
and RiskFilter; remove RiskSnapshotter, Risks.Snapshot,
InsertRiskSnapshots, and the SnapshotID/SourceID fields on Risk; delete
Snapshot, ControlSnapshot, SnapshotsType, SnapshotOrderField,
Snapshottable, the SnapshotService, the Snapshot console resolvers and
GraphQL schema, the Snapshot MCP types and operations
(list/get/take/listControlSnapshots), the snapshot CLI (prb snapshot),
the snapshot frontend pages, routes, banner, LinkedSnapshotsCard,
SnapshotGraph, snapshot helpers, and the snapshot n8n resource and
control link/unlink snapshot operations. The snapshot_id columns remain
in the database but are now filtered out with snapshot_id IS NULL.

Add Get/Upsert/Clear GeneratedDocumentID methods on Risk backed by a new
risks_document_id column on generated_documents, matching the
ProcessingActivity/Finding/Vendor pattern. The migration command
migrate-risk-snapshots-to-documents uses raw SQL queries instead of the
Go snapshot types, since those are gone.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-05-04 14:13:42 +02:00
Sacha Al Himdani
bdb16d4abe Add finding and obligation publish to document system
Replace the old snapshot-based approach with the new publish document
system for findings and obligations. Includes GraphQL mutations, MCP
tools, CLI commands, e2e tests, frontend publish dialogs, and
snapshot-to-document migration tools.

Remove snapshot mode entirely from findings and obligations: drop
snapshotId from GraphQL schemas, filters, resolvers, MCP spec, frontend
routes, pages, and helpers. The snapshot_id column remains in the
database but is now filtered out with snapshot_id IS NULL.

Remove auditor's ability to publish SoA.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-04-28 13:12:58 +02:00
Émile Ré
272f63828f Add state to MCP profile and refactor contract filter
Add the profile state attribute (ACTIVE/INACTIVE) to the MCP
Profile schema so listUsers and getUser tools expose it, and
add a state filter to listUsers.

Rename excludeContractEnded to contractEnded across the entire
stack (MCP, GraphQL, CLI, frontend). The new boolean is two-way:
true returns only users with ended contracts, false returns only
users with active or no contract, and null returns all.

Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-27 16:06:44 +04:00
Sacha Al Himdani
b603d04d8d Assets as document: replace snapshot with publish workflow
Remove assets from the snapshot system and replace with a publish-based
document workflow that generates versioned ProseMirror documents.

- Remove snapshot_id/source_id from asset and asset_vendor models
- Delete AssetFilter (no longer needed without snapshot filtering)
- Add PublishAssetList service, GraphQL mutation, MCP tool, CLI command,
  and n8n operation
- Add asset_list_document_id column to generated_documents table
- Generate ProseMirror documents with asset inventory tables
  (name, type, amount, data types stored, owner, vendors)
- Add AssetListDocument resolver on Organization type
- Update frontend to remove snapshot routes/params and add publish dialog
- Add e2e tests for asset publish (immediate, with approvers, reuse, RBAC)
- Add migration script for converting legacy asset snapshots to documents
- Exclude ASSETS from snapshot type lists and e2e snapshot tests
- Move generated_documents SQL to coredata methods on Datum and Asset
- Clear generated document and SOA references on soft delete and archive

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-04-21 19:36:17 +02:00
Sacha Al Himdani
8ce429507b Bump langsmith to 0.5.20 and override @langchain/classic to fix CVE
langsmith <=0.5.18 leaks streamed LLM output past redaction controls
(GHSA-rr7j-v2q5-chgv). The transitive pin via @n8n/ai-utilities held
@langchain/classic at 1.0.5 which required langsmith ^0.3.64, blocking
the upgrade. Add npm overrides for @langchain/classic (^1.0.27) and
langsmith (^0.5.19) to resolve all three langsmith advisories.

The lockfile refresh bumps eslint-plugin-react-hooks from 7.0.1 to
7.1.0 which enables the react-hooks/refs and set-state-in-effect
rules. Fix the resulting lint errors:

- PDFPreview (console + trust): read currentPage through a ref synced
  via useEffect, keeping the setState updater pure and ref access
  outside of render
- MeasuresPage: remove redundant categoryFilter state that mirrored
  urlCategory, use a ref to detect URL changes and trigger refetch
  as the single source of category refetches
- WebhooksSettingsPage: defer loadEvents via requestAnimationFrame
  to avoid synchronous setState within the effect body

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-04-21 11:16:53 +02:00
Sacha Al Himdani
e1148f812e Replace implemented column with CMMI maturity level
Drop the boolean implemented/not-implemented state in favor of a
mandatory CMMI maturity level enum (NONE, INITIAL, MANAGED, DEFINED,
QUANTITATIVELY_MANAGED, OPTIMIZING) stored as a Postgres enum type.

The migration backfills existing rows (NOT_IMPLEMENTED → NONE,
IMPLEMENTED → INITIAL), makes the column NOT NULL, and drops the old
implemented column and its enum type.

- maturityLevel is required on CreateControlInput and non-nullable (!)
  in the GraphQL schema
- CLI displays human-readable CMMI labels instead of raw enum tokens
- SOA table and published document use a single Maturity column in
  place of the old Implemented + Maturity columns
- Remove ControlImplementationState type and all implemented references
  across backend, frontend, CLI, MCP, n8n, and E2E tests

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-04-21 11:06:36 +02:00
Alejandro Juan
da91afc2a7 Add CMMI maturity level to compliance controls
Adds an optional CMMI 0-5 maturity level field to Control to support
ISO 27001 clause 9.1 effectiveness measurement and HITRUST CSF maturity
requirements. The field is nullable, framework-agnostic, and exposed
across all four API surfaces (GraphQL, MCP, CLI, n8n) plus the
generated SoA document.

Signed-off-by: Alejandro Juan <alejandrojuan@alejandrojuan.com>
2026-04-21 11:06:36 +02:00
Sacha Al Himdani
b63f043849 Move document title ownership from document to version
Title is now owned by document_versions, following the same pattern as
classification and document_type. The documents.title column is made
nullable with a TODO to drop it. Backend loads title from a
latest_versions CTE for ordering purposes only. The frontend resolves
title from the latest version, and DocumentTitleForm now operates on
DocumentVersion using UpdateDocumentVersion mutation.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-04-09 20:01:32 +02:00
Sacha Al Himdani
5fd580e995 Rename State of Applicability to Statement of Applicability
Rename the entity across the full stack: database table
(states_of_applicability → statements_of_applicability), Go model,
GraphQL types, MCP specification, CLI commands, frontend components,
routes, and display labels. Includes a migration to rename the table
and its foreign key column.

Widen sidebar from 260px to 280px to fit the longer label.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-04-09 13:06:06 +02:00
Sacha Al Himdani
8adf26ad20 Add in-progress state to tasks
Introduce IN_PROGRESS as a new task state between TODO and DONE across
the full stack: database enum, Go backend, GraphQL, MCP, and frontend.

The task state icon now cycles forward on click (TODO → IN_PROGRESS →
DONE → TODO), and the action dropdown provides explicit "Move to"
options for any state transition. The "All" tab supports drag-and-drop
between state sections to change a task's state.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-04-03 08:33:37 +02:00
Sacha Al Himdani
9a418a7711 Move document type from document to document version
Follow the same pattern used for classification: document type now lives
exclusively on DocumentVersion. A migration copies existing values from
documents to their versions. The document filter uses a subquery on the
latest version. All three API surfaces (GraphQL, MCP, CLI), resolvers,
frontend, and e2e tests are updated accordingly.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-04-02 16:32:38 +02:00
Sacha Al Himdani
324f4ce793 Add task priority enum and rename priority to rank
The existing integer priority field represents positional ordering
within a state, not semantic importance. Rename it to rank and
introduce a new priority field with enum values URGENT, HIGH,
MEDIUM and LOW across the entire stack.

Rank is now scoped to (state, priority) so tasks are ordered
within each priority group. A generated priority_rank column
combines both fields into a single sortable integer for cursor
pagination.

Dragging a task across priority groups updates its priority
automatically based on the drop position neighbors. The backend
first moves the task to the new group then repositions it at the
target rank.

The migration defaults existing rows to MEDIUM priority and
backfills ranks per (state, priority) group.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-04-02 13:35:39 +02:00
Émile Ré
bd3869e0f0 Remove gif from allowed image types
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-03-31 19:05:46 +04:00
Émile Ré
687148e2c1 Unify dropzone accept prop with accept helpers
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-03-31 19:05:46 +04:00
Sacha Al Himdani
851e585b9b Add ISC license headers to Go, TypeScript, and SQL files
Add ISC license headers to all .go, .ts, .tsx, and .sql files
using each file's git history to determine the correct copyright
year or year range. Trademarked icons (brand logos, vendor logos,
compliance framework logos) are excluded.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-03-31 13:31:30 +02:00
Sacha Al Himdani
999171a626 Add document approval workflow
Introduce a complete approval system for document publishing. Document
versions can now require approval from selected reviewers before being
published, with automatic publishing once all approvers have approved.

- Add approval quorum and decision tables with backfill migration
- Implement request approval, approve, and reject flows with electronic
  signature support for approve decisions
- Add employee approvals page with dedicated tab and pending approvals view
- Add changelog field to publish and request approval flows
- Pre-select previous version's approvers in the publish dialog
- Show quorum approvers in document list with 100 approver hard limit
- Expose approval workflow through GraphQL, MCP, and CLI
- Remove legacy default approvers feature entirely
- Add comprehensive e2e test coverage for approval workflows

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-03-27 19:43:20 +01:00
Sacha Al Himdani
4a2d308da0 Add task drag-and-drop reordering
Order tasks by priority (ASC) by default. Enable drag-and-drop
on the TODO and DONE tabs using native HTML5 drag events,
following the compliance external URLs pattern. The "All" tab
remains read-only since priority is scoped per state.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-03-27 15:47:12 +01:00
Sacha Al Himdani
93c3b70ecc Fix frontend lint warnings in documents and references
- Remove unused `rank` field from CompliancePageReferenceListItemFragment;
  the parent list fragment already fetches it for drag-and-drop reordering.
  Thread `rank` through the onEdit call chain so the edit dialog can still
  pre-populate the field via a dedicated parameter instead of the fragment.
- Add missing `documentTypeFilter` dependency to the refetch useEffect in
  DocumentList so stale closure values are never used on tab change.
- Break overlong line in DocumentList (canSendAnySignatureNotifications).

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-03-26 10:47:33 +01:00
Sacha Al Himdani
1db8e7133e Add document archiving
Documents can be archived and unarchived. Archived documents are
read-only, excluded from the trust center, and moved to a dedicated
Archived tab in the document list.

- Add archived_at timestamp and status (ACTIVE/ARCHIVED) PG enum column
- Rename DocumentStatus → DocumentVersionStatus, introduce DocumentStatus
- Archive/unarchive mutations in GraphQL, MCP, and CLI
- Bulk archive/unarchive mutations with Active/Archived tabs in the list
- ABAC policies: write actions denied on archived docs, unarchive denied
  on active docs
- Remove control/risk mappings and reset trust center visibility on archive
- Exclude archived documents from mapping dialogs and trust center tab

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-03-19 14:15:54 +01:00
Bryan Frimin
0e0539f1f3 Replace console frontend with unified findings pages
Add FindingsPage, FindingDetailsPage, and CreateFindingDialog
supporting all finding kinds (nonconformity, observation, exception)
with filtering, sorting, and audit linking.

Remove the separate nonconformity and continual improvement pages,
routes, and graph hooks. Update sidebar navigation, routes, and
components for nullable audit framework field.

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-03-17 15:05:33 +01:00
Émile Ré
f62a2cb494 Fix build
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-03-16 16:50:57 +04:00
Bryan Frimin
13ca50df68 Fix relay lint in components and pages
Remove unused GraphQL fields (createdAt, updatedAt, totalCount,
__id, sourceId, etc.) from queries and fragments across 50+ files.

Add TypeScript generics to useMutation, usePaginationFragment,
useRefetchableFragment, and useLazyLoadQuery calls to satisfy
relay/generated-typescript-types.

Add justified eslint-disable comments for fields needed by Relay
cache normalization (id) or consumed by sibling components through
fragment spreads.

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-03-15 13:32:43 +01:00
Émile Ré
9da8cc2e3d Add nda signature middleware
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-03-03 22:07:01 +04:00
Bryan Frimin
ad1998a540 Fix no link button when list is empty
Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-02-23 15:36:03 +01:00
Émile Ré
c36156c18a Disable all inputs with disabled form prop
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-02-19 16:13:04 +04:00
Sacha Al Himdani
33dfcd26c2 Fix approvers ui
Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-02-17 10:48:44 +01:00
Émile Ré
f033338cda Keep both people and members pages
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-02-12 16:21:14 +04:00
Émile Ré
d235f4a86b Update frontend links to users
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-02-12 16:21:12 +04:00
Émile Ré
6b4185aa9b Make console buildable by removing people related GQL queries
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-02-12 16:21:10 +04:00
Émile Ré
a4cc5d6952 Do not set continue when not needed + infer organizationId to assume after pw sign in
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-02-12 10:13:28 +04:00
Émile Ré
e46c1d4894 Rename redirect-path to continue + handle redirection on forbidden from wrong org assume
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-02-12 09:37:07 +04:00
Émile Ré
795b0a8de2 Remove useAssume from layouts now that we have the /assume page that redirects
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-02-12 09:37:05 +04:00
Émile Ré
070000c46a Implement redirect-path for password method
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-02-12 09:37:05 +04:00
Émile Ré
5fa4477d5d Create assume page to redirect to when AssumptionRequired catched in boundary
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-02-12 09:37:04 +04:00
Émile Ré
ab497ad6a7 Add error boundaries for auth and assume
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-02-12 09:37:04 +04:00
Émile Ré
ce69899909 Catch assumption needed errors
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-02-12 09:37:03 +04:00
Émile Ré
42557e1640 Refactor compliance page vendors
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-01-28 19:17:27 +04:00
Émile Ré
c74631ae54 Refactor compliance page files page
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-01-28 18:37:44 +04:00
Émile Ré
36a936fcf4 Refactor compliance page documents page
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-01-28 16:52:17 +04:00
Émile Ré
3e3c3a8ebb Refactor compliance page audits page
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-01-28 16:17:45 +04:00
Émile Ré
07ea130536 Remove unused files
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-01-28 15:25:42 +04:00
Émile Ré
26a45f9c6f Add references page
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-01-28 15:21:44 +04:00
Émile Ré
fb09bed247 Refactor document detail to document layout
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-01-27 17:52:58 +04:00
Émile Ré
81dec2bc51 Fix lint issues after rebase
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-01-23 12:51:07 +04:00
Émile Ré
de93e39252 Fix apps/console lint issues
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-01-23 12:44:31 +04:00
Émile Ré
e143477d66 Remove extensions from import paths
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-01-23 12:42:34 +04:00
Bryan Frimin
4bdf941d3a Refactor SOA
Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-01-22 10:20:50 -08:00
Émile Ré
3b4f77c5e8 Change folder aliases
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-01-22 21:14:37 +04:00