From 4c94486156055862b69e1baec09527d81f1193b2 Mon Sep 17 00:00:00 2001 From: Igor Date: Sun, 31 May 2026 16:29:08 +0300 Subject: [PATCH 1/2] docs: replace Mermaid diagrams with PlantUML for IDEA preview Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- CONTRIBUTING.md | 58 +++++++++++-------- README.md | 54 ++++++++---------- backend/README.md | 45 +++++++-------- deploy/README.md | 22 +++++--- docs/ARCHITECTURE.md | 132 ++++++++++++++++++++----------------------- docs/CQRS_FLOW.md | 67 ++++++++++++---------- docs/ROADMAP.md | 91 +++++++++++++++++++---------- 7 files changed, 252 insertions(+), 217 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e92097a..4f7ca57 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -131,29 +131,40 @@ Invoke-WebRequest http://localhost:8545 -Method Post -ContentType "application/j ## Project Structure -```text -backend/ -|- common/ -| |- event-model/ -| `- shared-contracts/ -|- command-service/ -|- event-store-service/ -|- audit-writer-service/ -`- query-service/ - -blockchain/ -|- contracts/ -|- scripts/ -`- test/ - -deploy/ -|- docker-compose.yml -`- init-db.sql - -docs/ -|- ARCHITECTURE.md -|- CQRS_FLOW.md -`- DEPLOYMENT.md +```plantuml +@startuml +top to bottom direction + +folder "distributed-audit-ledger/" as Repo { + folder "backend/" as Backend { + folder "common/" as Common { + folder "event-model/" as EventModel + folder "shared-contracts/" as SharedContracts + } + folder "command-service/" as Command + folder "event-store-service/" as EventStore + folder "audit-writer-service/" as AuditWriter + folder "query-service/" as Query + } + + folder "blockchain/" as Blockchain { + folder "contracts/" as Contracts + folder "scripts/" as Scripts + folder "test/" as Tests + } + + folder "deploy/" as Deploy { + file "docker-compose.yml" as Compose + file "init-db.sql" as InitDb + } + + folder "docs/" as Docs { + file "ARCHITECTURE.md" as Arch + file "CQRS_FLOW.md" as Cqrs + file "DEPLOYMENT.md" as Deployment + } +} +@enduml ``` --- @@ -320,4 +331,3 @@ docker compose -f \deploy\docker-compose.yml logs ganache - [ ] Tests added or updated for behavior changes. - [ ] `mvn verify` (backend) and `npm test` (blockchain) pass locally. - [ ] Docs updated when architecture/workflow changed. - diff --git a/README.md b/README.md index ac8a7e5..87a8b06 100644 --- a/README.md +++ b/README.md @@ -19,37 +19,29 @@ A distributed, event‑sourced audit platform built on CQRS, Event Sourcing, Rea ## πŸ› High‑Level Architecture -```mermaid -graph LR - Client["🌐 Client (Angular UI)"] - - Client -->|"POST /commands/user/login"| CmdService["πŸ“€ Command Service (8081)"] - - CmdService -->|"Kafka: user.login.events"| Kafka["πŸ”„ Kafka"] - - Kafka -->|Consumer: event-store-consumer| EventStore["πŸ“Š Event Store Service (8082)
- Canonical hash
- PostgreSQL audit.events
- Flyway migrations"] - Kafka -->|Consumer: audit-writer-consumer| AuditWriter["⛓️ Audit Writer Service (8083)
- Canonical hash
- Web3j AuditLedger
- DLT: user.login.events.dlt"] - - EventStore -->|Persisted events| Postgres["🐘 PostgreSQL
audit.events"] - Blockchain["πŸ” Smart Contract
AuditLedger (Ganache)"] - AuditWriter -->|appendAuditRecord| Blockchain - - QueryService["πŸ“– Query Service (8084)
- GET /api/audit-logs
- GET /api/audit-logs/{id}
- GET /api/audit-logs/{id}/integrity-check"] - - AuditWriter -.->|"Read for integrity"| Blockchain - Postgres -->|Read Models| QueryService - Blockchain -->|Hash Verification| QueryService - - Client -->|"GET /api/audit-logs"| QueryService - - style Client fill:#e1f5ff - style CmdService fill:#fff3e0 - style EventStore fill:#f3e5f5 - style AuditWriter fill:#fce4ec - style QueryService fill:#e8f5e9 - style Blockchain fill:#ffe0b2 - style Postgres fill:#e3f2fd - style Kafka fill:#f0f4c3 +```plantuml +@startuml +left to right direction + +rectangle "Client" as Client +rectangle "command-service\n8081" as CommandService +queue "Kafka\ntopic user.login.events" as Kafka +rectangle "event-store-service\n8082" as EventStore +rectangle "audit-writer-service\n8083" as AuditWriter +database "PostgreSQL\naudit.events" as Postgres +rectangle "Ganache\nAuditLedger" as Blockchain +rectangle "query-service\n8084" as QueryService + +Client --> CommandService : POST /commands/user/login +CommandService --> Kafka : publish event +Kafka --> EventStore : event-store-consumer +Kafka --> AuditWriter : audit-writer-consumer +EventStore --> Postgres : persist payload and event_hash +AuditWriter --> Blockchain : appendAuditRecord +Client --> QueryService : GET /api/audit-logs +Postgres --> QueryService : read models +Blockchain --> QueryService : integrity verification +@enduml ``` Full architecture details are available in [**docs/ARCHITECTURE.md**](docs/ARCHITECTURE.md) and [**docs/CQRS_FLOW.md**](docs/CQRS_FLOW.md). diff --git a/backend/README.md b/backend/README.md index f75ee3c..a8d91db 100644 --- a/backend/README.md +++ b/backend/README.md @@ -80,28 +80,29 @@ The diagram below shows the **target integration flow** for upcoming backend iss (`#5` and beyond). In this PR (`#4`) only service skeletons and shared modules are bootstrapped. -``` -Client - β”‚ - β–Ό command API (planned) -command-service (8081) - β”‚ publishes UserLoggedInEvent - β–Ό -Kafka topic: user.login.events - β”‚ β”‚ - β–Ό β–Ό -event-store audit-writer - -service -service - (8082) (8083) - β”‚ persists β”‚ appendAuditRecord() - β–Ό to Postgres β–Ό -audit.events Ganache - β”‚ blockchain - β–Ό -query-service (8084) - β”‚ query API (planned) - β–Ό -Angular UI +```plantuml +@startuml +top to bottom direction + +rectangle "Client / Angular UI" as Client +rectangle "command-service (8081)" as Cmd +queue "Kafka: user.login.events" as Kafka +rectangle "event-store-service (8082)" as ES +rectangle "audit-writer-service (8083)" as AW +database "PostgreSQL audit.events" as DB +rectangle "Ganache / AuditLedger.sol" as BC +rectangle "query-service (8084)" as Q + +Client --> Cmd : command API +Cmd --> Kafka : UserLoggedInEvent +Kafka --> ES +Kafka --> AW +ES --> DB : persist +AW --> BC : appendAuditRecord +DB --> Q +BC --> Q +Q --> Client : query API +@enduml ``` ## Issue tracker diff --git a/deploy/README.md b/deploy/README.md index eff030b..b06d75a 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -87,15 +87,19 @@ curl -s -X POST http://localhost:8545 \ The schema is applied automatically from `init-db.sql` on first start. -``` -audit.events -β”œβ”€β”€ id BIGSERIAL PK -β”œβ”€β”€ aggregate_id VARCHAR(128) -β”œβ”€β”€ event_type VARCHAR(128) -β”œβ”€β”€ user_id VARCHAR(255) -β”œβ”€β”€ payload JSONB -β”œβ”€β”€ event_hash VARCHAR(64) -└── created_at TIMESTAMP +```plantuml +@startuml +entity "audit.events" as AUDIT_EVENTS { + * id : BIGSERIAL + -- + aggregate_id : VARCHAR(128) + event_type : VARCHAR(128) + user_id : VARCHAR(255) + payload : JSONB + event_hash : VARCHAR(64) + created_at : TIMESTAMP +} +@enduml ``` ## Environment Variables diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index a4f1e7e..635f6a8 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -4,46 +4,31 @@ This document describes the **Distributed Audit Ledger** system architecture usi ## System Overview Diagram -``` -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Client Applications β”‚ -β”‚ (Angular UI / REST API) β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ β”‚ - WRITE SIDE READ SIDE - β”‚ β”‚ - β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β” - β”‚ command-service β”‚ β”‚ query-service β”‚ - β”‚ (PORT 8081) β”‚ β”‚ (PORT 8084) β”‚ - β”‚ WebFlux API β”‚ β”‚ WebFlux API β”‚ - β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ - β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚ - β”‚ Kafka Message Flow β”‚ β”‚ Read Views β”‚β”‚ - β”‚ β”‚ β”‚(PostgreSQL) β”‚β”‚ - β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚ - β”‚ β–Ό β–Ό β”‚ β”‚ - β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ /api/audit-logsβ”‚ - β”‚ Event β”‚ β”‚ Audit β”‚ β”‚ /api/audit-logsβ”‚ - β”‚ Store β”‚ β”‚ Writer β”‚ β”‚ /{id}/integrity-checkβ”‚ - β”‚ Service β”‚ β”‚ Service β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ (PORT 8082) β”‚ β”‚ (PORT 8083) β”‚ - β”‚ WebFlux + β”‚ β”‚ Web3j Client β”‚ - β”‚ R2DBC β”‚ β”‚ + Ganache β”‚ - β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ user.login.events topic β”‚ - β”‚ β”‚ - β”‚ Persists β”‚ Anchors - β”‚ Event Hash β”‚ Hash - β”‚ β”‚ - β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” - β”‚ PostgreSQL β”‚ β”‚ Ganache RPC β”‚ - β”‚ audit.events β”‚ β”‚ AuditLedger.sol β”‚ - β”‚ β”œβ”€β”€ id β”‚ β”‚ (Blockchain) β”‚ - β”‚ β”œβ”€β”€ event_id β”‚ β”‚ β”‚ - β”‚ β”œβ”€β”€ payload β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ - β”‚ β”œβ”€β”€ event_hash β”‚ β”‚ β”‚Record Store β”‚ β”‚ - β”‚ └── created_at β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ - β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +```plantuml +@startuml +left to right direction + +rectangle "Client Applications" as Client +rectangle "command-service\n8081" as CommandService +queue "Kafka\ntopic user.login.events" as Kafka +rectangle "event-store-service\n8082" as EventStore +rectangle "audit-writer-service\n8083" as AuditWriter +database "PostgreSQL\naudit.events" as Postgres +rectangle "AuditLedger on Ganache" as Blockchain +rectangle "query-service\n8084" as QueryService +rectangle "GET audit logs\nand integrity-check" as ReadApi + +Client --> CommandService : POST /commands/user/login +CommandService --> Kafka : publish event +Kafka --> EventStore : event-store-consumer +Kafka --> AuditWriter : audit-writer-consumer +EventStore --> Postgres : persist canonical event_hash +AuditWriter --> Blockchain : anchor hash +Client --> QueryService : GET audit APIs +Postgres --> QueryService : read models +Blockchain --> QueryService : verify hash +QueryService --> ReadApi +@enduml ``` ## Core Pattern @@ -99,24 +84,25 @@ The platform implements a **CQRS + Event Sourcing** architecture with blockchain ### Event Topic -``` -Topic: user.login.events -β”œβ”€β”€ Partition Key: event.eventId (stable partition mapping per event record) -β”‚ └─ Note: this does not provide per-user ordering across multiple events -β”œβ”€β”€ Schema: UserLoggedInEvent (shared from event-model) -β”œβ”€β”€ Consumers: -β”‚ β”œβ”€β”€ event-store-service (group: event-store-consumer) -β”‚ β”‚ └─ Writes to audit.events with computed event_hash -β”‚ β”‚ -β”‚ └── audit-writer-service (group: audit-writer-consumer) -β”‚ β”œβ”€ Computes SHA-256 hash (using CanonicalObjectMapperFactory) -β”‚ β”œβ”€ Writes to blockchain via AuditLedger.appendAuditRecord() -β”‚ β”œβ”€ Retries via DefaultErrorHandler backoff -β”‚ └─ DLT only for recoverable/terminal failures -└── DLT: user.login.events.dlt - - Not all failures go to DLT: - - BlockchainNotConfiguredException -> rethrown, offset remains uncommitted - - ReceiptTimeoutException -> rethrown, offset remains uncommitted +```plantuml +@startuml +top to bottom direction + +queue "user.login.events" as Topic +rectangle "event-store-service\nconsumer" as EventStoreConsumer +rectangle "audit-writer-service\nconsumer" as AuditWriterConsumer +database "PostgreSQL audit.events" as Db +rectangle "AuditLedger" as Contract +queue "user.login.events.dlt" as Dlt +rectangle "Rethrow\n(offset uncommitted)" as Rethrow + +Topic --> EventStoreConsumer +Topic --> AuditWriterConsumer +EventStoreConsumer --> Db : write payload and event_hash +AuditWriterConsumer --> Contract : appendAuditRecord +AuditWriterConsumer --> Dlt : recoverable or terminal failures +AuditWriterConsumer --> Rethrow : BlockchainNotConfiguredException\nor ReceiptTimeoutException +@enduml ``` ### Database Schema @@ -194,18 +180,23 @@ function isHashExists(bytes32 _hash) public view returns (bool) { All backend services are **reactive-first** with Spring WebFlux + Project Reactor, with controlled blocking in Kafka listeners where offset semantics require completion guarantees: -``` -Client Request - β–Ό -WebFlux Controller (non-blocking) - β–Ό -Service Layer (Mono / Flux) - β–Ό -R2DBC Repository (async DB queries) - β–Ό -Connection Pool (reactive driver) - β–Ό -PostgreSQL +```plantuml +@startuml +top to bottom direction + +rectangle "Client Request" as A +rectangle "WebFlux Controller\nnon-blocking" as B +rectangle "Service Layer\nMono/Flux" as C +rectangle "R2DBC Repository\nasync queries" as D +rectangle "Reactive Connection Pool" as E +database "PostgreSQL" as F + +A --> B +B --> C +C --> D +D --> E +E --> F +@enduml ``` - **R2DBC** (Reactive Relational Database Connectivity) replaces JPA @@ -235,4 +226,3 @@ PostgreSQL 5. **Reactive Stack**: WebFlux + R2DBC minimize thread context switches and connection pool pressure 6. **Canonical JSON**: Deterministic serialization (sorted fields) ensures DB and blockchain hashes match 7. **Dead-Letter Topic**: DLT is used for recoverable/terminal errors; configuration/receipt-timeout failures are rethrown to keep source offsets uncommitted - diff --git a/docs/CQRS_FLOW.md b/docs/CQRS_FLOW.md index ea72a29..5a8a5b9 100644 --- a/docs/CQRS_FLOW.md +++ b/docs/CQRS_FLOW.md @@ -4,37 +4,42 @@ This document describes the runtime sequence from command ingestion through even ## End-to-End Sequence Diagram -```text -Client - | - | 1) POST /commands/user/login - v -command-service (8081) - |- validates UserLoginCommand - |- builds UserLoggedInEvent: - | eventId, eventType, occurredAt, sourceService, userId, ipAddress, userAgent - |- publishes to Kafka topic user.login.events - `- returns HTTP 202 with CommandResponse - -Kafka topic: user.login.events - |- consumer group: event-store-consumer -> event-store-service (8082) - `- consumer group: audit-writer-consumer -> audit-writer-service (8083) - -[event-store-service] - |- computes canonical SHA-256 hash - |- resolves aggregate_id (for login: user:) - |- persists into audit.events - `- listener calls persist(...).block() to keep offset handling aligned with DB result - -[audit-writer-service] - |- computes canonical SHA-256 hash - |- calls AuditLedger.appendAuditRecord(...) - `- failures handled by DefaultErrorHandler (retry/backoff + conditional DLT) - -query-service (8084) - |- GET /api/audit-logs - |- GET /api/audit-logs/{id} - `- GET /api/audit-logs/{id}/integrity-check +```plantuml +@startuml +autonumber +actor Client +participant "command-service (8081)" as CMD +participant "Kafka user.login.events" as K +participant "event-store-service (8082)" as ES +participant "audit-writer-service (8083)" as AW +database "PostgreSQL audit.events" as DB +participant "AuditLedger.sol (Ganache)" as BC +participant "query-service (8084)" as Q + +Client -> CMD : POST /commands/user/login +note over CMD +Validate command\nBuild UserLoggedInEvent\nReturn HTTP 202 CommandResponse +end note +CMD -> K : Publish UserLoggedInEvent + +par event-store-consumer + K -> ES : Consume event + note over ES + Compute canonical SHA-256 hash\naggregate_id = user: + end note + ES -> DB : Insert payload + event_hash +else audit-writer-consumer + K -> AW : Consume event + note over AW : Compute canonical SHA-256 hash + AW -> BC : appendAuditRecord(hash, timestamp, type, source) + note over AW : DefaultErrorHandler retry/backoff + conditional DLT +end + +Client -> Q : GET /api/audit-logs or /integrity-check +Q -> DB : Read event + hash +Q -> BC : Verify hash existence +Q --> Client : Audit data + integrity status +@enduml ``` ## Step-by-Step Flow diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index 16eab3b..c893a97 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -99,16 +99,29 @@ contract AuditLedger { Create a multi-module Maven project for the backend services. **Structure:** -``` -backend/ -β”œβ”€β”€ pom.xml (parent) -β”œβ”€β”€ common/ -β”‚ β”œβ”€β”€ event-model/ -β”‚ └── shared-contracts/ -β”œβ”€β”€ command-service/ -β”œβ”€β”€ event-store-service/ -β”œβ”€β”€ audit-writer-service/ -└── query-service/ +```plantuml +@startuml +top to bottom direction + +folder "backend/" as Root +file "pom.xml (parent)" as Pom +folder "common/" as Common +folder "event-model/" as EventModel +folder "shared-contracts/" as SharedContracts +folder "command-service/" as Command +folder "event-store-service/" as EventStore +folder "audit-writer-service/" as AuditWriter +folder "query-service/" as Query + +Root --> Pom +Root --> Common +Common --> EventModel +Common --> SharedContracts +Root --> Command +Root --> EventStore +Root --> AuditWriter +Root --> Query +@enduml ``` **Subtasks:** @@ -584,25 +597,45 @@ Prepare a polished demo scenario for interviews. ## Dependency Graph -``` -#1 (Setup) -β”œβ”€ #2 (Docker Compose) ──┬─ #3 (Smart Contract) ─┬─ #7 (Audit Writer) -β”‚ β”‚ └─ #9 (Integrity Check) -β”‚ β”‚ -β”œβ”€ #4 (Maven setup) ─────┬─ #5 (Command Service) ─ #6 (Event Store) -β”‚ β”‚ β”œβ”€ #8 (Query Service) -β”‚ β”‚ └─ #7 (Audit Writer) -β”‚ β”‚ -β”‚ └─ #6 (Event Store) ───────┬─ #8 (Query Service) -β”‚ └─ #9 (Integrity Check) -β”‚ -β”œβ”€ #8 (Query Service) ─── #10 (Frontend UI) ─ #11 (API Integration) -β”‚ β”œβ”€ #16 (Advanced Filtering) -β”‚ └─ #17 (Timeline) -β”‚ -β”œβ”€ #12 (Documentation) -β”‚ -└─ #13 (CI/CD) ──────── #14-20 (Phase 2) +```plantuml +@startuml +top to bottom direction + +rectangle "#1 Setup" as I1 +rectangle "#2 Docker Compose" as I2 +rectangle "#3 Smart Contract" as I3 +rectangle "#4 Maven setup" as I4 +rectangle "#5 Command Service" as I5 +rectangle "#6 Event Store" as I6 +rectangle "#7 Audit Writer" as I7 +rectangle "#8 Query Service" as I8 +rectangle "#9 Integrity Check" as I9 +rectangle "#10 Frontend UI" as I10 +rectangle "#11 API Integration" as I11 +rectangle "#12 Documentation" as I12 +rectangle "#13 CI/CD" as I13 +rectangle "#16 Advanced Filtering" as I16 +rectangle "#17 Timeline" as I17 +rectangle "#14-20 Phase 2" as I1420 + +I1 --> I2 +I1 --> I4 +I1 --> I12 +I1 --> I13 +I2 --> I3 +I3 --> I7 +I3 --> I9 +I4 --> I5 +I5 --> I6 +I6 --> I8 +I6 --> I7 +I6 --> I9 +I8 --> I10 +I10 --> I11 +I11 --> I16 +I11 --> I17 +I13 --> I1420 +@enduml ``` --- From b7aea1faf16c5b82eafe51e0db43b9cf324b3c2c Mon Sep 17 00:00:00 2001 From: Igor Date: Sun, 31 May 2026 16:39:00 +0300 Subject: [PATCH 2/2] docs: fix review findings in diagrams Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- deploy/README.md | 1 + docs/ROADMAP.md | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/deploy/README.md b/deploy/README.md index b06d75a..54c9989 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -92,6 +92,7 @@ The schema is applied automatically from `init-db.sql` on first start. entity "audit.events" as AUDIT_EVENTS { * id : BIGSERIAL -- + event_id : VARCHAR(36) UNIQUE aggregate_id : VARCHAR(128) event_type : VARCHAR(128) user_id : VARCHAR(255) diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index c893a97..11e4483 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -626,7 +626,7 @@ I2 --> I3 I3 --> I7 I3 --> I9 I4 --> I5 -I5 --> I6 +I4 --> I6 I6 --> I8 I6 --> I7 I6 --> I9