You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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`.
|`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 |
16
16
|`archive/`| Historical/point-in-time artifacts only — see `archive/README.md`|
17
17
|`wiki/`| Routing layer — rules in `wiki/README.md`, canonical agent rules in `AGENTS.md` (Repo Wiki section) |
Copy file name to clipboardExpand all lines: .github/copilot-instructions.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -28,7 +28,7 @@
28
28
- Tables should be designed with a `created_at` timestamp (default to now) and an `updated_at` timestamp (auto-updated on change) for auditing purposes.
29
29
- Table names should be singular (e.g., `User`, not `Users`) to align with Prisma conventions.
30
30
-**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`.
Copy file name to clipboardExpand all lines: CLAUDE.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -10,6 +10,6 @@
10
10
- 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).
11
11
- 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.
12
12
-**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.
14
14
- Repo wiki rules: see `AGENTS.md` (Repo Wiki section).
15
15
- 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.
|[auth/](auth/)| Authentication (OAuth/Keycloak, API keys) and group-based resource authorization |
11
11
|[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 |
|[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 |
Copy file name to clipboardExpand all lines: docs-md/architecture/AUDIT.md
+46-4Lines changed: 46 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -14,8 +14,10 @@ In addition to the event types listed below, **every user-initiated create, upda
14
14
15
15
| Domain | Service | Audit helper |
16
16
|--------|---------|--------------|
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.
19
21
20
22
### Placement rules
21
23
@@ -83,6 +85,41 @@ Known gaps and remediation priorities: [TRANSACTION_AND_AUDIT_AUDIT.md](./TRANSA
83
85
|`api_key_deleted`| API key revoked | api_key | key.id | key_prefix; `actor_id` from request context |
84
86
|`api_key_regenerated`| API key rotated in place | api_key | key.id | key_prefix, generating_user_id; `actor_id` from request context |
85
87
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}`).
|`system_bootstrap`| First-run bootstrap creates the initial user + group | system |`bootstrap`| user_email, group_name; recorded inside the bootstrap transaction (`tx`) |
|`document_deleted`| Document deleted via `DELETE /api/documents/:id`| document | document.id | title, status (+ context) |
192
230
193
231
### Document access
194
232
@@ -220,19 +258,23 @@ Known gaps and remediation priorities: [TRANSACTION_AND_AUDIT_AUDIT.md](./TRANSA
220
258
221
259
## Implementation
222
260
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:
224
262
-**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).
225
266
-**WorkflowService:** after creating, updating, or appending workflow versions; after creating benchmark candidate lineages.
226
267
-**BenchmarkDefinitionService:** after promoting or applying candidate workflows to the base lineage.
227
268
-**ApiKeyService:** after creating, deleting, or regenerating group API keys.
228
269
-**HitlService:** after creating a session, submitting corrections, approving, escalating, skipping, reopening a session, or deleting a correction.
229
270
-**TrainingService / TrainingPollerService:** after starting/cancelling training jobs and activating/deleting trained models (poller activation is system-initiated, no actor).
230
271
-**DatasetService:** after dataset/version/sample/split mutations and freezes.
231
272
-**BenchmarkProjectService:** after creating or deleting a project.
273
+
-**BenchmarkRunService:** after cancelling or deleting a run (`benchmark_run_cancelled` / `benchmark_run_deleted`).
232
274
-**ClassifierService / AzureController:** after classifier create/update/delete and training request.
233
275
-**ConfusionProfileService:** after create/update/delete (including derive-and-save create path).
234
276
-**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).
236
278
-**Migration:** the `audit_events` table is created in the squashed init migration `apps/shared/prisma/migrations/20260328205045_init/`.
237
279
-**Failure behavior:** If an audit insert fails, the service logs a warning and continues; the main operation is not failed.
-`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`)
0 commit comments