Files
KArtSell.Aegis/src/KArtSell.DbMigrator
kjh2064 2eeb16a240 Database Migrations: Inbox & Approval Queue tables
Completes async event coupling infrastructure for downstream consumers:

Migrations:
1. 0009_CreateInboxTable.sql
   - Deduplication: UNIQUE (outbox_id, consumer_id)
   - Status: Pending, Processed, Failed
   - Idempotent processing (each consumer once per event)
   - Constraint: If status=Processed, processed_at must be set
   - Indexes: status, created_at, consumer_id

2. 0010_CreateApprovalQueueTable.sql
   - Workflow: Pending → Approved/Rejected
   - References: run_id (FK shadow_run), model_id
   - Audit: requested_at, approved_at, rejected_at
   - Triggers: Enforce timestamp/reason consistency
   - Indexes: status, model_id, requested_at

Design Principles:
 Append-only: Records immutable (status transitions, not updates)
 PIT Safety: All records timestamped, no forward lookups
 Data Integrity: Check constraints enforce workflow rules
 Idempotency: UNIQUE constraint prevents duplicate processing
 Traceability: Full audit trail (requested_by, approved_by, timestamps)

Workflow:
ShadowRunJob
  ├─ Phase 6: Emit ShadowRunCompletedEvent to Outbox
  └─ Hangfire OutboxPoller (30s)
     ├─ Inbox fanout (INSERT inbox for each consumer)
     └─ InboxConsumers (fanout)
        └─ ApprovalQueueConsumer
           ├─ If AllGatesPassed: INSERT approval_queue (status='Pending')
           └─ Notify: approval_queue subscribers

Ready for:
1. ShadowRunJob event emission (Phase 6)
2. OutboxPollerJob + InboxProcessorJob Hangfire integration
3. Human approval workflow (Maker-Checker)

Test Status: 84/84 PASSING (no changes to app code)

AGENTS.md v16.0:
 Safety: Constraints enforce workflow invariants
 Audit: Complete audit trail (timestamps, user IDs)
 Simplicity: Clear schema, obvious workflow

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-02 12:27:02 +09:00
..