Skip to content

Commit 7863489

Browse files
committed
Reorganize docs and workflow package refs
Move scattered feature docs into the proper `docs-md` topic folders, fix internal links and agent-rule references, and refresh wiki/source routing to match the new taxonomy. This also updates architecture/workflow docs for current transaction and audit behavior, documents OCR result views and Temporal payload footprint handling, and removes the obsolete Temporal build step for the old `graph-workflow-config` package after its consolidation into `@ai-di/graph-workflow`.
1 parent 306a4b3 commit 7863489

27 files changed

Lines changed: 296 additions & 63 deletions

.claude/skills/docs-sync/CONVENTIONS.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@
44

55
| Folder | Scope |
66
| --- | --- |
7-
| `architecture/` | System-level design: HITL architecture, database services/roles, blob storage, reference data tables, template models, shared packages, audit table, HA |
7+
| `architecture/` | System-level design: HITL architecture, database services/roles, transaction/audit compliance, blob storage, document content hash, ephemeral document cleanup, reference data tables, template models, shared packages, audit table, HA |
88
| `auth/` | Authentication (OAuth/Keycloak, API keys) and group resource authorization |
99
| `groups/` | Group management APIs, membership requests, group frontend pages/context |
10-
| `workflows/` | DAG workflow engine, graph types, node/activity/OCR-provider guides, workflow builder, node catalog, lineage, config overrides, Temporal worker concurrency, `templates/` example configs |
11-
| `extraction/` | OCR/extraction: Azure AI models, classifiers, enrichment, field formatting, image normalization, confusion profiles/matrices, OCR improvement pipeline, ground truth, HITL datasets |
10+
| `workflows/` | DAG workflow engine, graph types, node/activity/OCR-provider guides, workflow builder, node catalog, lineage, config overrides, Temporal worker concurrency, Temporal payload footprint (gzip codec + OCR payload refs), `templates/` example configs |
11+
| `extraction/` | OCR/extraction: Azure AI models, classifiers, enrichment, field formatting, image normalization, confusion profiles/matrices, OCR improvement pipeline, OCR failure handling, OCR result views, ground truth, HITL datasets |
1212
| `operations/` | OpenShift deployment, environment configuration, backups, Azure infrastructure, secrets, npm hardening |
1313
| `monitoring/` | PLG stack, Helm charts, Promtail, dashboards, metrics, alerting, logging |
1414
| `benchmarking/` | Benchmarking system, load testing runbooks |
15-
| `frontend/` | Frontend-wide concerns: BC Design System migration, UI patterns not tied to one feature |
15+
| `frontend/` | Frontend-wide concerns: BC Design System migration, confirmation-modal and sentence-case standardization, header/upload UI, UI patterns not tied to one feature |
1616
| `archive/` | Historical/point-in-time artifacts only — see `archive/README.md` |
1717
| `wiki/` | Routing layer — rules in `wiki/README.md`, canonical agent rules in `AGENTS.md` (Repo Wiki section) |
1818

.github/copilot-instructions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
- Tables should be designed with a `created_at` timestamp (default to now) and an `updated_at` timestamp (auto-updated on change) for auditing purposes.
2929
- Table names should be singular (e.g., `User`, not `Users`) to align with Prisma conventions.
3030
- **Transactions:** Two or more database writes that must succeed or fail together MUST use a single Prisma transaction. Db-services take optional `tx?: Prisma.TransactionClient` as the last parameter (`const client = tx ?? this.prisma`). Services start cross-module transactions with `prismaService.transaction()` and pass `tx` through — services must not query `tx` directly. Controllers never use transactions. See `docs-md/DATABASE_SERVICES.md`.
31-
- **Audit on mutations:** Every user-initiated mutation and every service-layer mutation transaction MUST emit an audit event (`AuditService.recordEvent` or benchmark `AuditLogService`). Pass `tx` to audit when inside a transaction; otherwise audit after commit (best-effort, non-fatal). See `docs-md/AUDIT.md` and the compliance audit in `docs-md/TRANSACTION_AND_AUDIT_AUDIT.md`.
31+
- **Audit on mutations:** Every user-initiated mutation and every service-layer mutation transaction MUST emit an audit event (`AuditService.recordEvent` or benchmark `AuditLogService`). Pass `tx` to audit when inside a transaction; otherwise audit after commit (best-effort, non-fatal). See `docs-md/architecture/AUDIT.md` and the compliance audit in `docs-md/architecture/TRANSACTION_AND_AUDIT_AUDIT.md`.
3232

3333
## Repo Wiki
3434

CLAUDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@
1010
- To test API directly, use: `curl -H "x-api-key: $API_KEY" http://localhost:3002/api/...` (read the key from your local env/config; never paste or log secret values).
1111
- NEVER read secrets from .env files directly, they should not be leaked into chat, terminal, etc., do not operate with secret values directly, only indirectly through variables.
1212
- **Database transactions:** Any operation that performs two or more database writes that must stay consistent MUST run inside a single Prisma transaction. Db-services accept optional `tx?: Prisma.TransactionClient` as the last parameter and use `const client = tx ?? this.prisma`. Services initiate cross-module transactions via `prismaService.transaction(async (tx) => { ... })` and pass `tx` to db-services (and other services) — never query `tx` directly in services. Controllers never initiate or receive transactions. See [docs-md/architecture/DATABASE_SERVICES.md](docs-md/architecture/DATABASE_SERVICES.md).
13-
- **Audit on mutations:** Every user-initiated create/update/delete (and every service-layer mutation transaction) MUST record an audit event via `AuditService.recordEvent` (global) or `AuditLogService` / `AuditLogDbService` (benchmark). Pass the same `tx` into audit when the mutation is transactional; otherwise call audit immediately after a successful commit. Audit failures must not fail the main operation unless audit is intentionally in the same transaction. Read/access endpoints follow [docs-md/architecture/AUDIT.md](docs-md/architecture/AUDIT.md). When reviewing or adding backend code, check [docs-md/TRANSACTION_AND_AUDIT_AUDIT.md](docs-md/TRANSACTION_AND_AUDIT_AUDIT.md) for known gaps.
13+
- **Audit on mutations:** Every user-initiated create/update/delete (and every service-layer mutation transaction) MUST record an audit event via `AuditService.recordEvent` (global) or `AuditLogService` / `AuditLogDbService` (benchmark). Pass the same `tx` into audit when the mutation is transactional; otherwise call audit immediately after a successful commit. Audit failures must not fail the main operation unless audit is intentionally in the same transaction. Read/access endpoints follow [docs-md/architecture/AUDIT.md](docs-md/architecture/AUDIT.md). When reviewing or adding backend code, check [docs-md/architecture/TRANSACTION_AND_AUDIT_AUDIT.md](docs-md/architecture/TRANSACTION_AND_AUDIT_AUDIT.md) for known gaps.
1414
- Repo wiki rules: see `AGENTS.md` (Repo Wiki section).
1515
- Skills: see `AGENTS.md` (Skills section). Use `.claude/skills/documentation/` when updating docs or the wiki; use `.claude/skills/create-pr/` when opening a pull request.

apps/temporal/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
"lint:fix": "npm run lint -- --write",
1717
"pretest": "npm run build:logging && npm run build:graph-insertion-slots && npm run build:graph-workflow",
1818
"build:graph-workflow": "cd ../../packages/graph-workflow && npm run build",
19-
"build:graph-workflow-config": "cd ../../packages/graph-workflow-config && npm run build",
2019
"test": "jest",
2120
"build:graph-insertion-slots": "cd ../../packages/graph-insertion-slots && npm run build"
2221
},

docs-md/README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@ Canonical markdown documentation for the Document Intelligence platform, organiz
66

77
| Folder | Contents |
88
| --- | --- |
9-
| [architecture/](architecture/) | System-level design: HITL architecture, database services, blob storage, reference data tables, template models, shared packages, audit table, high availability, the workflow-node + configuration-UI extension pattern |
9+
| [architecture/](architecture/) | System-level design: HITL architecture, database services, transaction/audit compliance, blob storage, document content hash, ephemeral document cleanup, reference data tables, template models, shared packages, audit table, high availability, the workflow-node + configuration-UI extension pattern |
1010
| [auth/](auth/) | Authentication (OAuth/Keycloak, API keys) and group-based resource authorization |
1111
| [groups/](groups/) | Group management: APIs, membership requests, frontend pages and context |
12-
| [workflows/](workflows/) | DAG workflow engine, graph types, adding nodes/activities/OCR providers (incl. Mistral OCR), workflow builder guide and design brief, node catalog, lineage/versions, config overrides, Temporal worker concurrency, [templates/](workflows/templates/) example configs |
13-
| [extraction/](extraction/) | OCR and extraction: Azure AI models, classifiers, enrichment, field formatting, image normalization, confusion profiles/matrices, OCR improvement pipeline, ground truth and HITL datasets |
12+
| [workflows/](workflows/) | DAG workflow engine, graph types, adding nodes/activities/OCR providers (incl. Mistral OCR), workflow builder guide and design brief, node catalog, lineage/versions, config overrides, Temporal worker concurrency, Temporal payload footprint (gzip codec + OCR payload refs), [templates/](workflows/templates/) example configs |
13+
| [extraction/](extraction/) | OCR and extraction: Azure AI models, classifiers, enrichment, field formatting, image normalization, confusion profiles/matrices, OCR improvement pipeline, OCR failure handling, OCR result views, ground truth and HITL datasets |
1414
| [operations/](operations/) | OpenShift deployment, CI workflows overview, environment configuration, backups, Azure infrastructure, secrets management, npm hardening |
1515
| [monitoring/](monitoring/) | PLG stack (Prometheus, Loki, Grafana), Helm charts, Promtail sidecars, dashboards, metrics, alerting, logging |
1616
| [benchmarking/](benchmarking/) | Benchmarking system, load testing runbooks and stress run sheets |
17-
| [frontend/](frontend/) | BC Design System migration, reference data tables UI |
17+
| [frontend/](frontend/) | BC Design System migration, reference data tables UI, confirmation-modal and sentence-case standardization, header/upload UI |
1818
| [archive/](archive/) | Point-in-time artifacts (reports, audits, completed plans) — historical only, see [archive/README.md](archive/README.md) |
1919
| [wiki/](wiki/) | Repo wiki: routing map for humans and LLM agents — see [wiki/README.md](wiki/README.md) for rules |
2020

docs-md/architecture/AUDIT.md

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@ In addition to the event types listed below, **every user-initiated create, upda
1414

1515
| Domain | Service | Audit helper |
1616
|--------|---------|--------------|
17-
| Global (HITL, groups, tables, documents, workflows) | Feature service or controller | `AuditService.recordEvent` |
18-
| Benchmark (datasets, runs, definitions) | Feature service | `AuditLogService` or `AuditLogDbService` |
17+
| Global (HITL, groups, tables, documents, workflows, bootstrap, most benchmark lifecycle) | Feature service or controller | `AuditService.recordEvent` |
18+
| Benchmark `benchmark_audit_log` table (a small subset) | Feature service | `AuditLogService` or `AuditLogDbService` |
19+
20+
> **Hybrid benchmark audit.** Most benchmark/dataset lifecycle mutations record to the global `audit_events` table via `AuditService.recordEvent` (see the benchmark event-type tables below). Only a few actions still write the separate `benchmark_audit_log` table via `AuditLogService` / `AuditLogDbService` (`AuditAction`): `dataset_created` (`DatasetService.createDataset`), `version_published` (`HitlDatasetService.packageDocumentsIntoVersion`), `run_started` (`BenchmarkRunService.startRun`), and `baseline_promoted` (`BenchmarkRunService.promoteRunToBaseline`). The `run_completed` helper (`AuditLogService.logRunCompleted`) exists but is currently unused in production.
1921
2022
### Placement rules
2123

@@ -83,6 +85,41 @@ Known gaps and remediation priorities: [TRANSACTION_AND_AUDIT_AUDIT.md](./TRANSA
8385
| `api_key_deleted` | API key revoked | api_key | key.id | key_prefix; `actor_id` from request context |
8486
| `api_key_regenerated` | API key rotated in place | api_key | key.id | key_prefix, generating_user_id; `actor_id` from request context |
8587

88+
### Group and membership
89+
90+
Recorded by `GroupService` (`resource_id` for membership actions is the request id; for member actions it is `{userId}:{groupId}`).
91+
92+
| event_type | When | resource_type | resource_id | Payload / notes |
93+
|------------|------|---------------|-------------|-----------------|
94+
| `group_created` | Group created | group | group.id | name (+ metadata) |
95+
| `group_updated` | Group metadata updated | group | group.id | name (+ changed fields) |
96+
| `group_deleted` | Group deleted | group | group.id | group_name |
97+
| `membership_request_created` | User requests to join a group | group_membership_request | request.id | user_id, group_id |
98+
| `membership_request_cancelled` | Requester cancels their request | group_membership_request | request.id | reason |
99+
| `membership_request_approved` | Admin approves a request | group_membership_request | request.id | user_id, ... |
100+
| `membership_request_denied` | Admin denies a request | group_membership_request | request.id | user_id, reason |
101+
| `member_added` | User added to a group (direct or via approval) | user_group | `{userId}:{groupId}` | user_id (+ membership_request_id on approval) |
102+
| `member_removed` | User removed from a group | user_group | `{userId}:{groupId}` | removed_user_id |
103+
| `member_role_updated` | Member role changed | user_group | `{userId}:{groupId}` | user_id, new_role |
104+
| `user_left_group` | User leaves a group themselves | user_group | `{userId}:{groupId}` ||
105+
106+
### Reference data tables
107+
108+
Recorded by `TablesService`. Row-level events use `resource_type: "table_row"`; all others use `resource_type: "table"`.
109+
110+
| event_type | When | resource_type | resource_id |
111+
|------------|------|---------------|-------------|
112+
| `tables.created` / `tables.updated` / `tables.deleted` | Table create/update/delete | table | table.id |
113+
| `tables.column.added` / `tables.column.updated` / `tables.column.removed` | Column schema change | table | table.id |
114+
| `tables.lookup.added` / `tables.lookup.updated` / `tables.lookup.removed` | Lookup config change | table | table.id |
115+
| `tables.row.created` / `tables.row.updated` / `tables.row.deleted` | Row data change | table_row | row.id |
116+
117+
### System
118+
119+
| event_type | When | resource_type | resource_id | Payload / notes |
120+
|------------|------|---------------|-------------|-----------------|
121+
| `system_bootstrap` | First-run bootstrap creates the initial user + group | system | `bootstrap` | user_email, group_name; recorded inside the bootstrap transaction (`tx`) |
122+
86123
### HITL events
87124

88125
| event_type | When | resource_type | resource_id | Payload / notes |
@@ -189,6 +226,7 @@ Known gaps and remediation priorities: [TRANSACTION_AND_AUDIT_AUDIT.md](./TRANSA
189226
|------------|------|---------------|-------------|-----------------|
190227
| `document_uploaded` | Document uploaded via upload API | document | document.id | title, file_type, status |
191228
| `document_updated` | Document title/metadata updated | document | document.id | fields_updated |
229+
| `document_deleted` | Document deleted via `DELETE /api/documents/:id` | document | document.id | title, status (+ context) |
192230

193231
### Document access
194232

@@ -220,19 +258,23 @@ Known gaps and remediation priorities: [TRANSACTION_AND_AUDIT_AUDIT.md](./TRANSA
220258

221259
## Implementation
222260

223-
- **Backend:** `AuditService` (in `apps/backend-services/src/audit/`) provides `recordEvent(events)`. When `request_id` or `actor_id` are omitted in the input, they are filled from the current request context (AsyncLocalStorage) when available; `group_id` must be passed by the caller. It is called from:
261+
- **Backend:** `AuditService` (in `apps/backend-services/src/audit/`) provides `recordEvent(events, tx?: Prisma.TransactionClient)`. When `request_id` or `actor_id` are omitted in the input, they are filled from the current request context (AsyncLocalStorage) when available; `group_id` must be passed by the caller. When a `tx` is passed the audit insert participates in that transaction (and a failure rolls back with it); without `tx` it is best-effort and non-fatal. It is called from:
224262
- **OcrService:** after starting a graph workflow and updating the document (document update + audit in one transaction).
263+
- **GroupService:** after group create/update/delete, membership request create/cancel/approve/deny, and member add/remove/role-update/leave.
264+
- **TablesService:** after table, column, lookup, and row mutations.
265+
- **BootstrapService:** after first-run bootstrap creates the initial user + group (in the bootstrap transaction).
225266
- **WorkflowService:** after creating, updating, or appending workflow versions; after creating benchmark candidate lineages.
226267
- **BenchmarkDefinitionService:** after promoting or applying candidate workflows to the base lineage.
227268
- **ApiKeyService:** after creating, deleting, or regenerating group API keys.
228269
- **HitlService:** after creating a session, submitting corrections, approving, escalating, skipping, reopening a session, or deleting a correction.
229270
- **TrainingService / TrainingPollerService:** after starting/cancelling training jobs and activating/deleting trained models (poller activation is system-initiated, no actor).
230271
- **DatasetService:** after dataset/version/sample/split mutations and freezes.
231272
- **BenchmarkProjectService:** after creating or deleting a project.
273+
- **BenchmarkRunService:** after cancelling or deleting a run (`benchmark_run_cancelled` / `benchmark_run_deleted`).
232274
- **ClassifierService / AzureController:** after classifier create/update/delete and training request.
233275
- **ConfusionProfileService:** after create/update/delete (including derive-and-save create path).
234276
- **UploadController:** after successful document upload (`document_uploaded`).
235-
- **DocumentController:** after successfully sending the human approval signal to a workflow; after document update (`document_updated`); and after authorized delivery of document metadata, file bytes, or OCR to a user (see "Document access" above for the full list of controllers and endpoints).
277+
- **DocumentController:** after successfully sending the human approval signal to a workflow; after document update (`document_updated`) and delete (`document_deleted`); and after authorized delivery of document metadata, file bytes, or OCR to a user (see "Document access" above for the full list of controllers and endpoints).
236278
- **Migration:** the `audit_events` table is created in the squashed init migration `apps/shared/prisma/migrations/20260328205045_init/`.
237279
- **Failure behavior:** If an audit insert fails, the service logs a warning and continues; the main operation is not failed.
238280

docs-md/architecture/DATABASE_SERVICES.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,14 +85,14 @@ Types are defined in `document/document-db.types.ts`. Callers outside the module
8585
| `benchmark-run-db.service.ts` | `BenchmarkRunDbService` | Benchmark run creation, status updates, result storage |
8686
| `benchmark-definition-db.service.ts` | `BenchmarkDefinitionDbService` | Benchmark definition CRUD with dataset version, split, workflow joins |
8787
| `dataset-db.service.ts` | `DatasetDbService` | Dataset, `DatasetVersion`, and `Split` management including freeze/delete |
88-
| `audit-log-db.service.ts` | `AuditLogDbService` | `BenchmarkAuditLog` entries: create and paginated query |
88+
| `audit-log-db.service.ts` | `AuditLogDbService` | `BenchmarkAuditLog` entries: create (`createAuditLog(..., tx?)`) and paginated query (`findAllAuditLogs(..., tx?)`) |
8989
| `ground-truth-job-db.service.ts` | `GroundTruthJobDbService` | `DatasetGroundTruthJob` lifecycle: create, status updates, batch queries with document/review joins |
9090

9191
Service wiring in the benchmark module:
9292
- `BenchmarkProjectService``BenchmarkProjectDbService`
93-
- `BenchmarkRunService``BenchmarkRunDbService` (audit via `AuditLogService`)
94-
- `BenchmarkDefinitionService``BenchmarkDefinitionDbService`
95-
- `DatasetService``DatasetDbService`, `AuditLogDbService`, `GroundTruthJobDbService`
93+
- `BenchmarkRunService``BenchmarkRunDbService` (`benchmark_audit_log` via `AuditLogService` for `run_started`/`baseline_promoted`; global `AuditService.recordEvent` for `benchmark_run_cancelled`/`benchmark_run_deleted`)
94+
- `BenchmarkDefinitionService``BenchmarkDefinitionDbService` (lifecycle audit via global `AuditService`)
95+
- `DatasetService``DatasetDbService`, `AuditLogDbService` (only `dataset_created``benchmark_audit_log`), `GroundTruthJobDbService`, global `AuditService` (most dataset/version/split mutations)
9696
- `AuditLogService``AuditLogDbService`
9797
- `GroundTruthGenerationService``GroundTruthJobDbService`, `ReviewDbService` (cross-module, injected directly)
9898
- `HitlDatasetService``ReviewDbService` (cross-module, injected directly)

0 commit comments

Comments
 (0)