Commit Graph

1148 Commits

Author SHA1 Message Date
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
Sacha Al Himdani
2b377a22e7 Sort employee signatures and approvals by most recently updated
Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-04-03 17:38:28 +02:00
Émile Ré
5359fe9931 Update rich editor style to be lighter and closer to printed doc
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-03 17:02:42 +04: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
Bryan Frimin
28cf3f167a Fix lint
Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-04-02 16:28:23 +02:00
Aurélien Sibiril
b396359162 Add access review frontend
Add campaign and source management pages with detail
views, bulk decision and flag controls, connector
provider dialog with OAuth/API-key/client-credentials
flows, vendor logos, shared helpers, and campaign
lifecycle UX (start, complete, cancel).

Signed-off-by: Aurélien Sibiril <81782+aureliensibiril@users.noreply.github.com>
2026-04-02 14:37:29 +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é
821f66cc20 Review fixes
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-01 19:53:25 +04:00
Émile Ré
679c18c548 Fix create draft condition and delete draft connections handling
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-01 18:04:36 +04:00
Émile Ré
3cba683707 Remove version update dialog
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-01 18:04:36 +04:00
Émile Ré
f3982f23f9 Sanitize upon saving
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-01 18:03:27 +04:00
Émile Ré
3181766885 Remove generated file
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-01 18:03:22 +04:00
Émile Ré
9ce510caa7 Add phosphor icons and improve menus UI
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-01 18:03:19 +04:00
Émile Ré
eede0b72f1 Make rich editor full height
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-01 18:03:17 +04:00
Émile Ré
b84eab4698 Disable RichEditor on non draft version
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-01 18:03:17 +04:00
Émile Ré
3a054c70ba Implement debounced auto save
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-01 18:03:17 +04:00
Émile Ré
a9f4ecacfa Install tip tap
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-04-01 18:03:17 +04:00
Sacha Al Himdani
1b811011eb Split employee document policy from core document actions
Introduce dedicated employee-scoped IAM actions and update all
resolvers and frontend mutations accordingly.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-04-01 15:00:54 +02:00
Sacha Al Himdani
2d11038232 Add document classification filter
Add classification as a filter-only field on documents, resolved from
the latest document version. Expose in GraphQL, MCP, and document list
UI with a selector alongside the document type filter.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-03-31 17:36:26 +02:00
Émile Ré
999874f33e Fix dropzone description
Signed-off-by: Émile Ré <emile@getprobo.com>
2026-03-31 19:05:46 +04: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
5d6d0bdd7f Move document classification from document to document version
Classification now lives exclusively on DocumentVersion. The field is
removed from the Document model, all SQL queries, GraphQL Document
type, SignableDocument type, UpdateDocumentInput, and MCP Document
schema.

New documents still accept classification in CreateDocumentInput,
applied to the first version. New drafts inherit classification from
the previous version. PDF generation uses the version classification.

The drawer allows editing classification on draft versions via the
updateDocumentVersion mutation. Classification is read-only on
published versions.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-03-31 14:11:57 +02: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
68bc8cf59a Add major.minor document versioning
Introduce a two-part version scheme (major.minor) for documents.
Drafts start at 0.1 and increment minor on each new draft. Publishing
as minor keeps the current version, publishing as major bumps to the
next major.0. Both current_published_major and current_published_minor
are tracked on the document for exact version lookups.

Signatures and approval quorums aggregate across all versions sharing
the same major number using CTE joins. Approval page mutations spread
the decision fragment so Relay updates the version row state without
requiring a page refresh.

GraphQL, MCP, and service layer expose separate publishMajor and
publishMinor mutations instead of a single mutation with a type enum.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-03-30 18:54:28 +02:00
Sacha Al Himdani
0920690816 Add ability to disconnect Slack channel from compliance page
Users could connect a Slack channel to their compliance page but had no
way to remove or change the connection afterward. This adds a disconnect
button with a confirmation dialog next to connected Slack channels.

- GraphQL: deleteSlackConnection mutation with resolver
- Frontend: Disconnect button using useMutation with @deleteEdge

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-03-30 15:40:21 +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
8bbed534a9 Fix batch signature dialog wording
Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-03-26 11:25:57 +01:00
Sacha Al Himdani
a3580a5647 Treat ESLint warnings as errors in all packages
Add --max-warnings 0 to every eslint lint script so that any warning
causes a non-zero exit code. This makes `make lint` and CI fail on
warnings, not just hard errors.

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-03-26 10:47:33 +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
8c02c53315 Update copyright headers across all Go files
Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
2026-03-25 17:38:32 +01:00
Bryan Frimin
81a4ec7c6e Remove useless card
Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-03-25 08:19:28 +01:00
Bryan Frimin
784c88895a Allow editing non-SCIM fields on SCIM-managed profiles
Contract start and end dates are never synced by SCIM, so they
should remain editable even when a profile is SCIM-managed.
The backend now skips overwriting SCIM-synced fields (fullName,
kind, position, additionalEmailAddresses) for SCIM profiles,
and the frontend disables only those fields instead of the
entire form.

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-03-24 16:44:53 +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
87c7552a35 Replace inline password form with link to dedicated sign-in page
The SignInPage now shows OIDC, SSO, and email buttons instead of
embedding the email/password form directly. Users clicking "Sign in
with email" are taken to the existing PasswordSignInPage.

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-03-23 14:17:46 +01:00
Bryan Frimin
d05367eeb2 Style
Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-03-23 14:17:46 +01:00
Bryan Frimin
887e994ff1 Refactor OIDC buttons: extract OIDCButton component, inline loops
Address PR review feedback:
- Remove OIDCButtons wrapper components that only loop, inline .map()
  directly in SignInPage and ConnectPage
- OIDCButton uses useTranslate() and useSafeContinueUrl() hooks
  internally instead of receiving hook results as props
- Move OIDCButton to local _components folders
- Fix eslint import grouping in SignInPage

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-03-23 14:17:46 +01:00
Bryan Frimin
0476cd2d87 Use preloaded query for SignInPage instead of lazy load
Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-03-23 14:17:46 +01:00
Bryan Frimin
42129f7ce2 Restore inline password form in SignInPage
Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-03-23 14:17:45 +01:00
Bryan Frimin
dcc08c42e3 Fix lint errors in SignInPage: use Relay fragment for OIDC providers
- Add blank line between import groups (import-x/order)
- Use Relay fragment in OIDCButtons to colocate field queries (relay/unused-fields)

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-03-23 14:17:45 +01:00
Bryan Frimin
f8e086a00b Address PR review feedback for OIDC sign-in pages
- Remove inline password form from SignInPage (use PasswordSignInPage)
- Extract Divider and OIDCButtons to _components folder
- Move OIDC providers into page queries instead of lazy-loaded queries
- Create useSafeContinueUrl hook for trust app using getPathPrefix
- Use safeContinueUrl.toString() for continue URL parameter
- Fix wg.Go style in IAM service Run method

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-03-23 14:17:44 +01:00
Bryan Frimin
29b41208f3 Address PR review feedback for OIDC login
- Remove sensitive nonce values from error messages to prevent logging leaks
- Guard ticker intervals against non-positive durations in SAML domain
  verifier and garbage collector to prevent panics
- Require both client ID and client secret for Google/Microsoft OIDC
  providers to be marked as enabled
- Replace http.DefaultClient with kit/httpclient for JWKS fetching to
  ensure proper timeouts
- Fix eslint indentation in SignInPage OIDC button click handler

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-03-23 14:17:43 +01:00
Bryan Frimin
3066e7d14c Fix eslint errors in sign-in page
Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-03-23 14:17:43 +01:00
Bryan Frimin
83468db034 Refactor sign-in page and IAM service lifecycle
Redesign the sign-in page to show email/password form inline
with OIDC provider buttons (with vendor icons) instead of
separate pages. Extract OIDCProvider type to its own file.

Replace errgroup with sync.WaitGroup + WithCancelCause for
graceful shutdown in IAM services. Refactor garbage collectors
to use functional options and time.Ticker instead of
time.After to avoid repeated allocations.

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-03-23 14:17:43 +01:00
Bryan Frimin
23084a72a2 Add OIDC login support for Google and Microsoft providers
Implements OpenID Connect authentication flow with PKCE, JWT verification, and enterprise-only account restrictions. Adds OIDC service with JWKS caching and state management, HTTP handlers for login/callback flows, GraphQL query for available providers, and sign-in UI integration.

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-03-23 14:17:43 +01:00
Bryan Frimin
3b5122da5e Style
Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-03-21 19:16:21 +01:00
Bryan Frimin
7b320916af Add audit log feature for recording all actions
Adds audit logging that records all authorized actions performed by
users and API keys. The audit log is automatically populated whenever
the authorizer approves an action, and is queryable via GraphQL, MCP,
and CLI interfaces. Permission checks are excluded via a dry-run flag
to avoid phantom entries on page loads.

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
2026-03-21 19:16:19 +01:00