Commit Graph

258 Commits

Author SHA1 Message Date
Cursor Agent
fe215efbd1 Add audit start and end dates to audits
ISO audits often span a window distinct from certificate validity.
Store optional audit_start_date and audit_end_date on the audit
record and expose them through GraphQL, MCP, CLI, n8n, and console.

Signed-off-by: Cursor Agent <cursoragent@cursor.com>

Co-authored-by: Bryan FRIMIN <bryan@frimin.fr>
2026-07-28 17:27:33 +02:00
Cursor Agent
51144d25fc Add Risk Accepted status to finding forms
Findings create and update views filtered out RISK_ACCEPTED
even though the API requires a linked risk for that status.
Restore the option, collect riskId via a searchable paginated
picker, and clear stale links when status changes.

Signed-off-by: Cursor Agent <cursoragent@cursor.com>

Co-authored-by: Bryan FRIMIN <bryan@frimin.fr>
2026-07-27 14:14:43 +02:00
Jonathan
a7ff5f07bc Add react i18next to console
Signed-off-by: Jonathan <contact@grafikart.fr>
2026-07-27 11:52:31 +02:00
Émile Ré
0d832508c9 Replace portal title with entity name
Store a short entity name instead of the full home
heading so orgs can brand portals for sub-entities.
Restore hero i18n composition and keep the English
document title composed from the entity name.

Signed-off-by: Émile Ré <emile@probo.com>
2026-07-22 13:08:02 +02:00
Bryan Frimin
53cc6c487e Update console for compliance portal
Point compliance-page screens and Relay graphs
at the renamed Compliance Portal API fields and
mutations.

Signed-off-by: Bryan Frimin <bryan@probo.com>
2026-07-21 15:44:26 +02:00
Bryan Frimin
43ce3a7c53 Harden compliance portal auth and TLS
Align console references and OAuth branding with the
compliance-page model, and fix certificate cache eviction,
portal OAuth handlers, and magic-link edge cases left after
the trust-center rename.

Signed-off-by: Bryan Frimin <bryan@probo.com>
2026-07-21 15:44:22 +02:00
Bryan Frimin
89f999d55c Restore TrustCenter reference hooks in console
Keep GraphQL-aligned TrustCenterReferenceGraph naming, drop the
unused domain redirect route, and tighten related compliance
page UI review nits around magic-link navigation and links.

Signed-off-by: Bryan Frimin <bryan@probo.com>
2026-07-21 15:44:18 +02:00
Bryan Frimin
36bc636a08 Unify console sign-in for connect authorize
Remove the separate portal login page, show OAuth client branding on
sign-in, and preserve authorize continue URLs across auth methods.

Signed-off-by: Bryan Frimin <bryan@probo.com>
2026-07-21 15:44:18 +02:00
Bryan Frimin
ba53c94bdc Move trust center profile onto the page
Store website, email, and headquarters on the trust center so
public and admin surfaces read branding from one place. Drop the
trust API organization type and wire console, MCP, CLI, and apps
through the updated schema.

Signed-off-by: Bryan Frimin <bryan@probo.com>
2026-07-21 15:44:10 +02:00
Bryan Frimin
db24d17455 Add console useMutation and rename compliance graphs
Introduce the app-bound useMutation primitive and rename the trust center
graph and reference hooks to compliance page, moving the shared reference
dialogs alongside them. Sweep the compliance page subpages onto the new
mutation hook and the compliance-portal permission strings, and strip the
profile fields from the organization settings form.

Signed-off-by: Bryan Frimin <bryan@probo.com>
2026-07-21 15:44:09 +02:00
Sacha Al Himdani
4c57d201a4 Make license declarations consistently MIT
The source headers, LICENSE files, and license metadata had drifted
apart. Align the entire project to MIT:

- Convert every source-file header to the MIT text across all comment
  styles (Go, TS, TSX, JS, MJS, SQL, CSS, GraphQL, shell), including
  SPDX-License-Identifier tags
- Set the root and cookie-banner LICENSE files to the MIT text with a
  "MIT License" title line
- Switch the package.json license fields, Docker image label, and
  cookie-banner README to MIT
- Update docs and the genmodels header generator accordingly
- Normalize copyright lines to a single format
  (Copyright (c) <year(s)> Probo Inc <hello@probo.com>.): unify the
  hello@getprobo.com and hello@probo.inc emails to hello@probo.com and
  the comma-separated years to a hyphenated range

Genuine third-party references are intentionally left untouched: the
Lucide icon attributions (Lucide is ISC) and the trivy dependency
license allowlist.

Signed-off-by: Sacha Al Himdani <sacha@probo.com>
2026-07-13 16:21:14 +02:00
dependabot[bot]
dcf3221bb9 Bump the npm-dependencies group with 28 updates
Bumps the npm-dependencies group with 28 updates:

| Package | From | To |
| --- | --- | --- |
| [eslint](https://github.com/eslint/eslint) | `9.39.4` | `10.6.0` |
| [turbo](https://github.com/vercel/turborepo) | `2.10.0` | `2.10.2` |
| [i18next](https://github.com/i18next/i18next) | `26.3.3` | `26.3.4` |
| [react-router](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router) | `8.0.1` | `8.1.0` |
| [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) | `7.29.7` | `8.0.1` |
| [@tailwindcss/vite](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-vite) | `4.3.1` | `4.3.2` |
| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `24.13.2` | `26.1.0` |
| [tailwindcss](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss) | `4.3.1` | `4.3.2` |
| [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) | `8.1.0` | `8.1.2` |
| [react-dropzone](https://github.com/react-dropzone/react-dropzone) | `14.4.1` | `15.0.0` |
| [zod](https://github.com/colinhacks/zod) | `3.25.76` | `4.4.3` |
| [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) | `8.62.0` | `8.62.1` |
| [@n8n/node-cli](https://github.com/n8n-io/n8n) | `0.37.1` | `0.37.2` |
| [marked](https://github.com/markedjs/marked) | `15.0.12` | `18.0.5` |
| [@ariakit/react](https://github.com/ariakit/ariakit/tree/HEAD/packages/ariakit-react) | `0.4.30` | `0.4.31` |
| [@radix-ui/react-alert-dialog](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/alert-dialog) | `1.1.17` | `1.1.18` |
| [@radix-ui/react-dropdown-menu](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/dropdown-menu) | `2.1.18` | `2.1.19` |
| [@radix-ui/react-label](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/label) | `2.1.10` | `2.1.11` |
| [@radix-ui/react-popover](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/popover) | `1.1.17` | `1.1.18` |
| [@radix-ui/react-portal](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/portal) | `1.1.12` | `1.1.13` |
| [@radix-ui/react-scroll-area](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/scroll-area) | `1.2.12` | `1.2.13` |
| [@radix-ui/react-select](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/select) | `2.3.1` | `2.3.2` |
| [@radix-ui/react-tabs](https://github.com/radix-ui/primitives/tree/HEAD/packages/react/tabs) | `1.1.15` | `1.1.16` |
| [react-intersection-observer](https://github.com/thebuilder/react-intersection-observer) | `9.16.0` | `10.0.3` |
| [@vitest/browser](https://github.com/vitest-dev/vitest/tree/HEAD/packages/browser) | `4.1.8` | `4.1.9` |
| [@vitest/coverage-v8](https://github.com/vitest-dev/vitest/tree/HEAD/packages/coverage-v8) | `4.1.8` | `4.1.9` |
| [react-docgen](https://github.com/reactjs/react-docgen/tree/HEAD/packages/react-docgen) | `7.1.1` | `8.0.3` |
| [posthog-js](https://github.com/PostHog/posthog-js) | `1.396.1` | `1.396.4` |

Updates `eslint` from 9.39.4 to 10.6.0
- [Release notes](https://github.com/eslint/eslint/releases)
- [Commits](https://github.com/eslint/eslint/compare/v9.39.4...v10.6.0)

Updates `turbo` from 2.10.0 to 2.10.2
- [Release notes](https://github.com/vercel/turborepo/releases)
- [Changelog](https://github.com/vercel/turborepo/blob/main/RELEASE.md)
- [Commits](https://github.com/vercel/turborepo/compare/v2.10.0...v2.10.2)

Updates `i18next` from 26.3.3 to 26.3.4
- [Release notes](https://github.com/i18next/i18next/releases)
- [Changelog](https://github.com/i18next/i18next/blob/master/CHANGELOG.md)
- [Commits](https://github.com/i18next/i18next/compare/v26.3.3...v26.3.4)

Updates `react-router` from 8.0.1 to 8.1.0
- [Release notes](https://github.com/remix-run/react-router/releases)
- [Changelog](https://github.com/remix-run/react-router/blob/main/packages/react-router/CHANGELOG.md)
- [Commits](https://github.com/remix-run/react-router/commits/react-router@8.1.0/packages/react-router)

Updates `@babel/core` from 7.29.7 to 8.0.1
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v8.0.1/packages/babel-core)

Updates `@tailwindcss/vite` from 4.3.1 to 4.3.2
- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases)
- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.3.2/packages/@tailwindcss-vite)

Updates `@types/node` from 24.13.2 to 26.1.0
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `tailwindcss` from 4.3.1 to 4.3.2
- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases)
- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.3.2/packages/tailwindcss)

Updates `vite` from 8.1.0 to 8.1.2
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v8.1.2/packages/vite)

Updates `react-dropzone` from 14.4.1 to 15.0.0
- [Release notes](https://github.com/react-dropzone/react-dropzone/releases)
- [Commits](https://github.com/react-dropzone/react-dropzone/compare/v14.4.1...v15.0.0)

Updates `zod` from 3.25.76 to 4.4.3
- [Release notes](https://github.com/colinhacks/zod/releases)
- [Commits](https://github.com/colinhacks/zod/compare/v3.25.76...v4.4.3)

Updates `typescript-eslint` from 8.62.0 to 8.62.1
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.62.1/packages/typescript-eslint)

Updates `@n8n/node-cli` from 0.37.1 to 0.37.2
- [Release notes](https://github.com/n8n-io/n8n/releases)
- [Commits](https://github.com/n8n-io/n8n/commits)

Updates `marked` from 15.0.12 to 18.0.5
- [Release notes](https://github.com/markedjs/marked/releases)
- [Commits](https://github.com/markedjs/marked/compare/v15.0.12...v18.0.5)

Updates `@ariakit/react` from 0.4.30 to 0.4.31
- [Release notes](https://github.com/ariakit/ariakit/releases)
- [Changelog](https://github.com/ariakit/ariakit/blob/main/packages/ariakit-react/CHANGELOG.md)
- [Commits](https://github.com/ariakit/ariakit/commits/@ariakit/react@0.4.31/packages/ariakit-react)

Updates `@radix-ui/react-alert-dialog` from 1.1.17 to 1.1.18
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/alert-dialog/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/alert-dialog)

Updates `@radix-ui/react-dropdown-menu` from 2.1.18 to 2.1.19
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/dropdown-menu/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/dropdown-menu)

Updates `@radix-ui/react-label` from 2.1.10 to 2.1.11
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/label/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/label)

Updates `@radix-ui/react-popover` from 1.1.17 to 1.1.18
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/popover/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/popover)

Updates `@radix-ui/react-portal` from 1.1.12 to 1.1.13
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/portal/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/portal)

Updates `@radix-ui/react-scroll-area` from 1.2.12 to 1.2.13
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/scroll-area/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/scroll-area)

Updates `@radix-ui/react-select` from 2.3.1 to 2.3.2
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/select/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/select)

Updates `@radix-ui/react-tabs` from 1.1.15 to 1.1.16
- [Changelog](https://github.com/radix-ui/primitives/blob/main/packages/react/tabs/CHANGELOG.md)
- [Commits](https://github.com/radix-ui/primitives/commits/HEAD/packages/react/tabs)

Updates `react-intersection-observer` from 9.16.0 to 10.0.3
- [Release notes](https://github.com/thebuilder/react-intersection-observer/releases)
- [Commits](https://github.com/thebuilder/react-intersection-observer/compare/v9.16.0...v10.0.3)

Updates `@vitest/browser` from 4.1.8 to 4.1.9
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.9/packages/browser)

Updates `@vitest/coverage-v8` from 4.1.8 to 4.1.9
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.9/packages/coverage-v8)

Updates `react-docgen` from 7.1.1 to 8.0.3
- [Release notes](https://github.com/reactjs/react-docgen/releases)
- [Changelog](https://github.com/reactjs/react-docgen/blob/main/packages/react-docgen/CHANGELOG.md)
- [Commits](https://github.com/reactjs/react-docgen/commits/react-docgen@8.0.3/packages/react-docgen)

Updates `posthog-js` from 1.396.1 to 1.396.4
- [Release notes](https://github.com/PostHog/posthog-js/releases)
- [Changelog](https://github.com/PostHog/posthog-js/blob/main/CHANGELOG.md)
- [Commits](https://github.com/PostHog/posthog-js/compare/posthog-js@1.396.1...posthog-js@1.396.4)

---
updated-dependencies:
- dependency-name: eslint
  dependency-version: 10.6.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: npm-dependencies
- dependency-name: turbo
  dependency-version: 2.10.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: i18next
  dependency-version: 26.3.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: react-router
  dependency-version: 8.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: npm-dependencies
- dependency-name: "@babel/core"
  dependency-version: 8.0.1
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: npm-dependencies
- dependency-name: "@tailwindcss/vite"
  dependency-version: 4.3.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: "@types/node"
  dependency-version: 26.1.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: npm-dependencies
- dependency-name: tailwindcss
  dependency-version: 4.3.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: vite
  dependency-version: 8.1.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: react-dropzone
  dependency-version: 15.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-dependencies
- dependency-name: zod
  dependency-version: 4.4.3
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-dependencies
- dependency-name: typescript-eslint
  dependency-version: 8.62.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: "@n8n/node-cli"
  dependency-version: 0.37.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: marked
  dependency-version: 18.0.5
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-dependencies
- dependency-name: "@ariakit/react"
  dependency-version: 0.4.31
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: "@radix-ui/react-alert-dialog"
  dependency-version: 1.1.18
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: "@radix-ui/react-dropdown-menu"
  dependency-version: 2.1.19
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: "@radix-ui/react-label"
  dependency-version: 2.1.11
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: "@radix-ui/react-popover"
  dependency-version: 1.1.18
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: "@radix-ui/react-portal"
  dependency-version: 1.1.13
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: "@radix-ui/react-scroll-area"
  dependency-version: 1.2.13
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: "@radix-ui/react-select"
  dependency-version: 2.3.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: "@radix-ui/react-tabs"
  dependency-version: 1.1.16
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: react-intersection-observer
  dependency-version: 10.0.3
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-dependencies
- dependency-name: "@vitest/browser"
  dependency-version: 4.1.9
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: "@vitest/coverage-v8"
  dependency-version: 4.1.9
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
- dependency-name: react-docgen
  dependency-version: 8.0.3
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: npm-dependencies
- dependency-name: posthog-js
  dependency-version: 1.396.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Sacha Al Himdani <sacha@probo.com>
2026-07-02 19:16:47 +02:00
Sacha Al Himdani
a651d56c8c Refactor third parties frontend to page arborescence
Mirror the risks refactor (c78a713): colocate routes.ts, split the
detail layout query so each child route owns its Loader + Page, rename
tabs/*Tab to resource folders with *Page, move dialogs into
_components/, and extract ThirdPartyRow with its own fragment.

Remove outlet context data passing and deprecated
loaderFromQueryLoader. Delete the monolithic ThirdPartyGraph hook,
colocating each GraphQL operation with its consumer: the create
mutation in CreateThirdPartyDialog (now useMutation + useToast) and
the third-party list queries in ThirdPartiesCell and
ThirdPartiesMultiSelectField (now useQueryLoader + usePreloadedQuery).

Signed-off-by: Sacha Al Himdani <sacha@probo.com>
2026-07-01 17:43:45 +02:00
Émile Ré
f98b73f073 Upgrade frontend toolchain to latest majors
Bump React 19.2, Relay 21, React Router 8, Vite 8 with
@vitejs/plugin-react 6, ESLint 10, GraphQL 17, TypeScript 6,
@types/node 24, and Tailwind 4.3 across the workspaces.

vite-plugin-react 6 (Vite 8) no longer runs Babel, so the Relay
tagged-template transform now runs through @rolldown/plugin-babel
in the console and trust Vite configs.

Relay 21 ships first-party types and enables the ambiguous-alias
check by default; disable that flag to preserve existing queries
and add explicit usePreloadedQuery type arguments where the new
types no longer infer the operation. TypeScript 6 deprecations and
stricter inference are addressed in tsconfigs and call sites.

Keep n8n-node on ESLint 9 and eslint-plugin-react on 7.37.5, the
newest releases compatible with their toolchains.

Signed-off-by: Émile Ré <emile@probo.com>
2026-06-19 13:51:17 +02:00
Sacha Al Himdani
f462b124e6 Batch signature and approval notifications via debounced worker
Replace the immediate per-document approval email and the manual
"send signing notifications" action with a single debounced worker that
batches pending requests per recipient and organization.

The worker (go.gearno.de/kit/worker) polls on an interval (default 5m)
and claims one (organization, recipient) group at a time, sending one
consolidated signing email and/or one approval email per recipient/org
that lists every document awaiting their signature or approval. The
claim is a conditional UPDATE that doubles as concurrency-safe dedup, so
several workers never email the same group twice.

Each request is notified once it has been pending past the debounce
delay (default 15m), then reminded at 1x, 2x and 3x the reminder
interval (default 1 day) after the previous email, after which it stops.
New last_notified_at and notification_count columns on signatures and
approval decisions drive the debounce, the widening reminder cadence and
the four-email cap.

Email copy lists each document with its title, type and a deep link to
the employee page. Removed the inline approval-on-publish email, the
SendSigningNotifications service method/mutation/MCP tool, its IAM action,
and the related console UI and n8n operation.

Signed-off-by: Sacha Al Himdani <sacha@probo.com>
2026-06-18 15:39:04 +02:00
Ludovic Vielle
3475dd0560 Switch console file fields to File download URLs
Replace presigned URL string fields (logoUrl, fileUrl, ndaFileName,
etc.) with nested File references resolved through /api/files/v1/.
Update console Relay queries and e2e coverage accordingly.

Route NDA upload through filemanager.PutFile and return stable IAM
org logo URLs for consistency with the files API.

Signed-off-by: Ludovic Vielle <ludovic@probo.com>
2026-06-11 10:47:28 +02:00
Sacha Al Himdani
b6781d3de0 Scope sub-third-parties per parent
Replace the many-to-many junction table with a direct
parent_third_party_id foreign key on third_parties. Each
sub-third-party now belongs to exactly one parent, making
duplicates across parents independent entities.

Replace the firstLevel boolean with an integer level field
(1 = direct, 2+ = parent level + 1) to support arbitrary
nesting depth.

Remove the createThirdPartyThirdPartyMapping and
deleteThirdPartyThirdPartyMapping mutations, the CLI
link/unlink commands, and the corresponding MCP tools.
Creating a child third party now just requires passing
parentThirdPartyId on the existing createThirdParty mutation.

The frontend walks the parentThirdParty chain to build
display names like "Name (Ancestor1/Ancestor2)" and shows
clickable ancestor links on the detail page.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-06-10 14:15:01 +02:00
Sacha Al Himdani
9ac71f948f Update contact email to hello@probo.com
Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-06-09 16:45:23 +02:00
Ludovic Vielle
c1c351ff81 Update frontend to use reportFile on Audit
Signed-off-by: Ludovic Vielle <ludovic@probo.com>
2026-06-05 16:16:52 +02:00
Sacha Al Himdani
6e7c96732f Add async third-party vetting
Queue vetting on third_parties with PENDING, PROCESSING,
COMPLETED, and FAILED states. Expose enqueue and status through
GraphQL, MCP, CLI, and n8n, validate vet requests, tune the
worker via config, and poll the detail page while vetting runs.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-06-02 11:39:51 +02:00
Sacha Al Himdani
c78a713adf Refactor risks frontend to follow page arborescence conventions
- Split layout's monolithic query: each child route now owns its query
  via its own *PageLoader + *Page (overview/measures/documents/controls/
  obligations/scenarios).
- Rename tabs/RiskXTab.tsx -> <resource>/RiskXPage.tsx; drop UI-named
  tabs/ and dialogs/ folders.
- Move FormRiskDialog, PublishRiskListDialog and the extracted RiskRow
  into _components/ as named exports.
- Move risk form fragment ownership into FormRiskDialog: define
  FormRiskDialog_risk in the dialog and pass plain data to useRiskForm
  so spread sites colocate cleanly without disable comments.
- Align risk components with react-components.md naming: rename Relay
  fragments to ComponentName_typeName and replace 'type Props' aliases
  with 'interface ComponentNameProps'.
- Guard risk pages against null node and mutation errors: add
  __typename narrowing to every node(id) query, surface deleteRisk
  errors via toast, and resolve the confirm promise on error so the
  dialog no longer hangs.
- Replace deprecated useMutationWithToasts (FormRiskDialog) and
  useLazyLoadQuery (LinkScenarioDialog) with useMutation+useToast and
  useQueryLoader+usePreloadedQuery.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-05-28 15:02:09 +02:00
Sacha Al Himdani
6dfdd7ca49 Link measures to third parties
Add a many-to-many relationship between measures and third parties,
surfaced as a measures tab on the third party detail page and a third
parties tab on the measure detail page. Each side gets a paginated
list with a link/unlink dialog.

Also remove the right-hand drawer on the measure detail page and
expose the state as a badge in the page header, mirroring how the
compliance page surfaces its active flag.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-05-26 15:49:17 +02:00
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
b9262b5150 Add risk assessment system
Introduce a hierarchical risk assessment model with six entity types:

- Risk Assessment: top-level container scoped to an organization
- Risk Assessment Scope: sub-container for scoping threat modeling
  exercises within an assessment
- Risk Assessment Node: DFD elements typed as ENTITY, BOUNDARY,
  ASSET, or DATA within a scope
- Risk Assessment Process: directed data flows between two nodes
- Risk Assessment Threat: descriptive threats attached to a process
  with a free-text category (e.g. Confidentiality, Integrity)
- Risk Scenario: thin join linking a threat to a risk from the
  register, carrying only a name and description

Risk scoring (likelihood, impact, treatment) remains on the existing
Risk entity. Threats are purely descriptive. Risk Scenarios connect
the threat model to the risk register without duplicating scores.

Backend: migration with PG enum for node types, coredata structs,
service layer with full CRUD and validation, GraphQL schema with
18 mutations and paginated connections, authorization actions and
policies, and base_resolvers.go Node dispatch for all entity types.

Frontend: Risk Assessments list page with create dialog, detail page
showing scopes as cards with nodes/processes/threats tables, inline
create/edit/delete actions on all entities, and a Scenarios tab on
the Risk detail page linking threats to risks. Existing RiskGraph.ts
hook file removed in favor of colocated queries in page files.

E2E tests cover CRUD for all entity types, RBAC, and tenant
isolation.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-05-19 21:44:27 +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
Émile Ré
7099a3d702 Replace vendor JSON with common third parties API
The CreateVendorDialog previously loaded the entire @probo/vendors
JSON bundle client-side and used MiniSearch for fuzzy search. This
replaces it with a GraphQL query against the common_third_parties
database table, searched server-side via ILIKE filtering.

Backend: adds CommonThirdParty GraphQL type, a pkg/thirdparty
service, and a commonThirdParties(name) root query. Frontend:
splits into CommonThirdPartyCombobox (display) and an @inline
fragment read on selection via readInlineData.

Signed-off-by: Émile Ré <emile@getprobo.com>
2026-05-12 16:43:36 +04: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
c026f67bd9 Add vendor publish to document system
Replace the old snapshot-based system for vendors with the publish
document system, mirroring the prior 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 vendor profile fields plus per-vendor
sections for services, contacts, risk assessments, compliance reports,
BAA and DPA agreements.

The vendor 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 Vendors page exposes a Publish button and a Document link
button when the document exists, and pre-fills the previous default
approvers.

Remove snapshot mode entirely from vendors and their sub-entities: drop
snapshotId/sourceId from GraphQL Vendor type and VendorFilter; remove
SnapshotsTypeVendors from the snapshot registry and delete
Vendors.Snapshot, VendorSnapshotter interface and all
*.InsertVendorSnapshots methods on contacts, services, risk
assessments, compliance reports, BAA and DPA. Drop the snapshot routes
and banner from the frontend. 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 Vendor backed by a
new vendors_document_id column on generated_documents, matching the
ProcessingActivity/Finding/Obligation pattern.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-04-29 16:24:29 +02:00
Sacha Al Himdani
ba8bce2ad3 Add processing activity, DPIA and TIA publish to document system
Replace the old PDF/snapshot-based exports for processing activities,
Data Protection Impact Assessments and Transfer Impact Assessments with
the publish document system. Includes GraphQL mutations, MCP tools, CLI
commands, n8n operations, frontend publish dialogs, e2e tests, and
prosemirror register templates that mirror the previous PDF layouts.

Each 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
ProcessingActivities page exposes a Publish dropdown per register and a
Document link button per active tab, pre-fills the previous default
approvers, and navigates to the published document on success.

Remove snapshot mode entirely from these three entities: drop snapshotId
and sourceId from GraphQL schemas, types, filters, resolvers, MCP spec,
frontend routes and pages; remove SnapshotsTypeProcessingActivities from
the snapshot registry and delete the ProcessingActivities.Snapshot,
ProcessingActivitySnapshotter interface and *.InsertProcessingActivitySnapshots
methods. 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 each entity type
(ProcessingActivity, DataProtectionImpactAssessment,
TransferImpactAssessment) backed by new columns in the generated_documents
table, matching the Finding/Obligation pattern.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-04-28 18:07:46 +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
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
55563226cb Data as document: replace snapshot with publish workflow
Mirror the SOA-to-document migration for the data list. Remove data
from the snapshot system and add a publish workflow that generates a
ProseMirror document for the full organization data inventory.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-04-20 14:44:00 +02:00
Sacha Al Himdani
524f209df7 Filter people with ended contracts from signature request dialog
Move the paginated people query from PeopleGraph.ts into
SignatureDocumentsDialog.tsx following colocated query conventions
and pass excludeContractEnded: true to hide people whose contract has ended.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-04-15 14:05:34 +02:00
Sacha Al Himdani
808fdffc9b Return computed risk scores after update
Add inherentRiskScore and residualRiskScore to the mutation fragment so
the Relay store gets updated scores. On the backend, use RETURNING to
get the recomputed values from the database generated columns.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-04-14 18:09:01 +02:00
Sacha Al Himdani
03708d45c3 Consolidate document draft management into updateDocument
Replace the three separate draft mutations (createDraftDocumentVersion,
updateDocumentVersion, deleteDraftDocumentVersion) with automatic draft
lifecycle management inside updateDocument. The backend now auto-creates
a draft when a published document is edited, updates the existing draft
on subsequent edits, and auto-deletes the draft when content reverts to
match the published version.

A new deleteDocumentDraft mutation provides explicit draft deletion.

Backend:
- Merge version-level fields (content, title, classification,
  documentType) into UpdateDocumentRequest
- Convert CreateDraft, UpdateVersion, DeleteDraft into private
  transaction helpers called from Update
- Update returns (*Document, *DocumentVersion, error) with the version
  present only when a draft exists

Frontend:
- Remove all create/update/delete draft mutations from components
- Auto-save via updateDocument with layout refetch on draft status
  transitions while preserving editor cursor (data-generation key)
- Title, type, and classification editable on published versions
  (backend auto-creates draft)
- Forms use react-hook-form values option to stay synced with Relay
  fragment data across draft/publish transitions

API surface (GraphQL, MCP, CLI, n8n) updated consistently:
- Removed: createDraftDocumentVersion, updateDocumentVersion,
  deleteDraftDocumentVersion
- Added: deleteDocumentDraft (document-level)
- Updated: updateDocument accepts content, classification, documentType

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-04-14 15:01:20 +02:00
Sacha Al Himdani
ef2e99d86c Add measure-document linking
Introduce the ability to link measures to documents, following the
existing pattern used by controls and risks. This includes:

- Database migration for measures_documents join table
- Coredata MeasureDocument struct with insert/delete operations
- Document service methods for listing/counting by measure ID
- Measure service CreateDocumentMapping/DeleteDocumentMapping methods
- Cleanup of measure-document mappings on document archive
- GraphQL mutations, inputs, payloads, and Measure.documents field
- DocumentConnection.TotalCount support for measure resolver
- MCP linkMeasure/unlinkMeasure updated to support documents
- MCP listMeasureDocuments tool
- Frontend MeasureDocumentsTab with LinkedDocumentsCard integration
- Authorization actions for measure document mapping
- E2e tests for measure document mapping

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-04-03 17:51:31 +02:00
Émile Ré
3a054c70ba Implement debounced auto save
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-01 18:03:17 +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
Bryan Frimin
619ec7b882 Add AI-powered evidence description generation
Introduce a background worker that automatically generates
compliance-focused descriptions for uploaded evidence files
using configurable LLM providers. Descriptions are surfaced
across all interfaces: GraphQL API, MCP API, CLI, and the
console UI.

Key changes:
- Multi-provider LLM config with per-agent settings (pointer
  types for Temperature/MaxTokens to preserve zero values)
- Evidence description worker with bounded concurrency
- EvidenceDescriptionStatus typed enum with PostgreSQL enum type
- New `prb evidence` CLI commands (list, view, delete)
- Evidence description displayed in console table and preview
- Migration only marks evidences without files as completed

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-03-26 14:32:41 +01:00
Bryan Frimin
359f85f5da Add SEO controls and sitemap for compliance pages
Add search engine indexing toggle, robots.txt, and sitemap.xml
generation for compliance pages. Replace checkboxes with toggle
components in the compliance page UI and add an "Open" button
in the page header to quickly access the live compliance page.
The search engine indexing toggle is disabled when the compliance
page is inactive.

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-03-24 15:55:31 +01:00
Bryan Frimin
a9ebeef0fa Transform meetings page into context page with tabs
Add structured organization context with 5 markdown sections (Product, Architecture, Team, Processes, Customers) editable inline. Meetings are now a tab within the context page. Moved all GraphQL queries from hooks/graph/MeetingGraph.ts into colocated components following new best practices. Updated database schema, backend services, GraphQL resolvers, and MCP API to support the new context fields and structure.

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-03-19 19:02:50 +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
4f54241382 Add document types filtering and rename ISMS to GOVERNANCE
Adds 5 new document types (PLAN, REGISTER, RECORD, REPORT, TEMPLATE), renames ISMS to GOVERNANCE, and implements type-based filtering across GraphQL, MCP, and frontend. Includes migration, enum updates, filter implementation with SQL array support, and frontend dropdown UI with Relay refetch pattern.

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-03-19 12:31:39 +01:00
Bryan Frimin
82f241628c Refactor MeasuresPage to use Relay fragments
Replace the client-side grouped-by-category view (fetching 500 items)
with a flat table using server-side filtering and cursor-based
pagination. Colocate GraphQL queries, fragments, and mutations in the
component file per console CLAUDE.md conventions.

Backend changes add a category filter to the measure list endpoints
(GraphQL, MCP) and a new measureCategories field on Organization.

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-03-19 09:54:33 +01:00
Bryan Frimin
32cc4a4f9c WIP
Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-03-19 09:39:39 +01:00