diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..18e59cd7 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,437 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +**K-ArtSell Aegis v16.0** is a complex financial/investment advisory system built on a **Modular Monolith** with **Vertical Slice** architecture. It enforces strict execution completeness, evidence preservation, and controlled model operations—not production-ready until all validation gates (252+ trading days shadow, OOS testing, PBO/DSR verification) pass. + +**Status:** `IMPLEMENTATION_TEMPLATE / STATIC_VALIDATED / BUILD_DB_E2E_SHADOW_REHEARSAL_REQUIRED` + +## Quick Start + +### Prerequisites +- .NET 10 SDK +- Node.js 22 / pnpm 10 +- PostgreSQL 17 (local via Docker Compose) +- Docker & Docker Compose + +### Local Development Environment + +```bash +# Start PostgreSQL +docker-compose up -d + +# Backend: restore, build, migrate, test +dotnet restore KArtSell.sln +dotnet build KArtSell.sln -c Release +dotnet run --project src/KArtSell.DbMigrator -c Release + +# Run backend tests +dotnet test KArtSell.sln -c Release --logger trx + +# Run a single test +dotnet test --filter "FullyQualifiedName=MyNamespace.MyTest.TestMethod" -c Release + +# Frontend: install, typecheck, test, build +cd frontend +pnpm install --frozen-lockfile +pnpm typecheck +pnpm test +pnpm build + +# Run frontend E2E tests +pnpm exec playwright install --with-deps chromium +pnpm e2e + +# Run dev server (watch mode, hot reload) +pnpm dev # Backend in another terminal +``` + +### Database Connection +``` +Host: localhost +Port: 5432 +Database: kartsell +User: kartsell +Password: kartsell +``` + +Environment variable: `KARTSELL_POSTGRES=Host=localhost;Port=5432;Database=kartsell;Username=kartsell;Password=kartsell` + +## Architecture + +### Backend: Modular Monolith + Vertical Slices + +#### Module Structure +``` +src/ + KArtSell.Host/ # Main ASP.NET Core app + KArtSell.BuildingBlocks/ # Shared infrastructure (logging, serialization, extensions) + KArtSell.DbMigrator/ # DbUp migrations + KArtSell.Modules.ModelOperations/ # Model lifecycle, validation, activation + KArtSell.Modules.SignalEngine/ # Trading signal generation +``` + +#### Vertical Slice Template +Each feature is a complete, self-contained slice from HTTP endpoint to database, located under `Features//`: + +``` +Features// + Endpoint.cs # FastEndpoints route handler (HTTP/contract/status codes) + Request.cs # Input model with validation via Zod-like pattern + Response.cs # Output model (DTO) + Validator.cs # Fluent/Policy validation rules + Handler.cs # Use case orchestration (Application layer) + Policy.cs # Pure business decision logic (Domain layer) + Sql.cs # Dapper queries (Data layer) + Mapper.cs # Entity ↔ DTO mapping + Jobs/ # Related Hangfire jobs + Contracts/ # Event/Job contract definitions + Tests/ # Unit/integration tests specific to this slice + README.md # Traceability: requirements, ADRs, assumptions +``` + +**Key rule:** Endpoint handles HTTP concerns (routing, negotiation); Handler handles transaction boundaries; Policy makes decisions; Sql uses Dapper for explicit, schema-qualified queries. + +#### Design Principles +- **No Generic Repository:** Each slice writes its own Dapper queries; promotes clarity. +- **No Service Layer:** Handler + Policy + Sql replaces it; keeps flow visible. +- **Module Isolation:** Modules do not query each other's source tables directly. + - Synchronous: Use narrow Read Port services. + - Asynchronous: Use Outbox/Inbox event patterns. +- **PIT (Point-in-Time) Queries:** Must include `WHERE published_at <= cutoff` and revision resolver. +- **Evidence & Audit:** Update/delete are blocked; new state appended as new revision. +- **Migrations:** `src/KArtSell.DbMigrator` uses DbUp; file naming: `NNNN_description.sql`. Each module has ordered, checksummed migrations. + +### Frontend: Vue 3 + Vite + Modular Feature Structure + +#### Directory Layout +``` +frontend/src/ + app/ # Core app initialization, routing, config + features/ # Feature modules (one per business capability) + / + components/ # Scoped to this feature + pages/ # Route-level pages + stores/ # Pinia stores (state management) + composables/ # Reusable logic (Vue 3 hooks) + types/ # TS interfaces for this feature + shared/ + ui/ + adapter/ # PrimeVue/AG Grid wrappers (mandatory boundary) + components/ # Common components (QueryStateBoundary, PermissionGuard, CrudForm, etc.) + layouts/ # Page layout templates + crud/ # Generic CRUD form logic + composables/ # Global composables (useFetch, useAuth, etc.) + types/ # Global types, contracts + stores/ # Global Pinia stores (auth, user, preferences) + design-system/ # Design tokens, typography, color scales (PrimeVue theme overrides) +``` + +#### State Management Rules +| State | Owner | Tool | +|-------|-------|------| +| API responses, cache, stale, retry | TanStack Query | @tanstack/vue-query | +| Session, role, UI preferences | Global store | Pinia | +| Form values, errors, touched | Form library | vee-validate + Zod | +| URL filters, pagination, sorting | Router | vue-router query/params | +| Large data tables, virtual scroll | Server-side row model | AG Grid server mode | + +**Anti-patterns:** +- Do NOT duplicate API responses in Pinia. +- Do NOT write 401/409/422/429/503 error handling in every screen. +- Do NOT manage query cache manually; let TanStack Query handle it. + +#### Component Elevation Criteria +Promote to `shared/ui/components/` only when: +1. **Same business meaning & permissions** (not just visual similarity). +2. **Repeated state/error handling logic** across 3+ consumers. +3. **Accessibility & testing** already fully implemented. + +**Always-shared components:** +- `QueryStateBoundary` (loading/error/empty states) +- `PermissionGuard` (RBAC enforcement) +- `CrudForm` (standard CRUD form) +- `VersionConflictDialog` (optimistic concurrency) +- `DataFreshnessBadge` (cache/stale indicators) +- `DataGridShell` (AG Grid wrapper with sorting, filtering, export) + +### Database & Migrations + +#### DbUp +- **Run at startup:** `KArtSell.DbMigrator` is the single source of truth. +- **Schema ownership:** Each module owns its schema (e.g., `model_operations.*`, `signal_engine.*`). +- **Safety:** Migrations are idempotent and checksummed; failed migration rolls back and waits for manual intervention. +- **Test:** Each migration has fresh/upgrade/re-run/failure-recovery tests in CI. + +#### Query Patterns +```csharp +// DO: Schema-qualified, explicit columns, cancellation token +const string sql = """ + SELECT id, name, created_at + FROM model_operations.signals + WHERE published_at <= @cutoff + AND status = @status + ORDER BY created_at DESC +"""; + +// DON'T: SELECT *, generic repository, no token +const string sql = "SELECT * FROM signals WHERE status = @status"; +``` + +#### Async Coupling: Outbox/Inbox +- **Outbox:** When a command succeeds, events are inserted into `outbox` in the same transaction. +- **Inbox:** A Hangfire job polls the outbox, publishes events, and marks them as processed. +- **Idempotency:** Each inbox handler is idempotent; replayed events are no-ops. + +### Hangfire (Background Jobs & Scheduling) + +#### Job Design +- **Not a business decision maker:** Hangfire executes approved Application Commands, not policies. +- **Idempotency key:** Each job must be replayable without side effects. +- **Watermark & version set:** Track input/output state across retries. +- **Queue isolation:** `q-customer-sla` (business SLA) is separate from `q-research` (non-critical). +- **Retry classification:** + - `transient` (network glitch, retry immediately) + - `permanent` (bad input, log & alert) + - `dq` (data quality issue, quarantine for manual review) + - `business-hold` (awaiting approval or external event) + +#### Example Job Structure +```csharp +public class MyJobCommand : ICommand +{ + public string IdempotencyKey { get; set; } + public Guid JobRunId { get; set; } + public Guid CorrelationId { get; set; } +} +``` + +Jobs do not call other jobs directly; instead, they emit events or check readiness gates. + +### SignalR (Real-Time Push) + +Used for live notifications (model activation events, approval notifications). Follows Hub/Group pattern with correlation to `CorrelationId` for traceability. + +## Testing Strategy + +### xUnit Backend Tests + +#### Test Organization +``` +tests/ + KArtSell.ArchitectureTests/ # Compile-time architecture rules + KArtSell.ModelOperations.UnitTests/ + KArtSell.SignalEngine.UnitTests/ + KArtSell.Integration.Tests/ # E2E with real DB (if exists) +``` + +#### Test Levels +1. **Unit:** Pure functions (Policy, Mapper), no I/O. Fast, deterministic. +2. **Integration:** Handler + Dapper + real PostgreSQL. Validates transaction boundaries, Outbox/Inbox. +3. **Data:** SQL query validation, schema conformance, index effectiveness. +4. **E2E:** Full HTTP stack; used sparingly for critical paths. +5. **Golden/Frozen OOS:** Before merging algorithm changes, lock baseline and diff against new run. + +#### Run Tests +```bash +dotnet test KArtSell.sln -c Release +dotnet test --filter "Category=Integration" -c Release +dotnet test --filter "FullyQualifiedName~UnitTests" -c Release --verbosity quiet +``` + +### Vitest Frontend Tests + +```bash +cd frontend +pnpm test # Run all tests +pnpm test -- --reporter=verbose # Verbose output +pnpm test -- # Run subset +pnpm test -- --coverage # Coverage report +``` + +### Playwright E2E + +```bash +cd frontend +pnpm e2e # Run all E2E tests headless +pnpm e2e -- --debug # Debug mode (browser stays open) +pnpm exec playwright test --headed # Run with browser UI +``` + +## Observability + +### Logging +- **Tool:** Serilog with structured properties. +- **Correlation:** All logs are tagged with `CorrelationId`, `JobRunId`, `EvidenceId`. +- **Sensitive data:** PII, tokens, API keys are NEVER logged (use redaction middleware). +- **Levels:** INFO (user actions), DEBUG (internal flow), WARN (recoverable issues), ERROR (unrecoverable, alert required). + +### Tracing & Metrics +- **Tool:** OpenTelemetry for distributed tracing and metrics. +- **Spans:** HTTP requests, database queries, job execution, event processing. +- **Alerts:** Send to Telegram integration (configured in `KArtSell.Host` startup). + +### Operational Dashboards (Priority Order) +1. **Batch SLA:** Job completion times, queue depths (q-customer-sla vs q-research). +2. **Data Quality Quarantine:** Jobs marked `dq` by retry classifier. +3. **Duplicate Detection:** Outbox duplicate events. +4. **Reconciliation Breaks:** Mismatch between expected and actual state (Evidence vs current). +5. **Model Drift:** OOS (out-of-sample) performance metrics. + +## Common Workflows + +### Adding a New Vertical Slice + +1. **Scaffold the structure:** + ```bash + python tools/scaffold_vertical_slice.py --name MyFeature --module ModelOperations + ``` + +2. **Define the contract** (before code): + - Request/Response DTOs in `Contracts/` + - Event schema in `Contracts/Events/` if async coupling needed + - Validation rules (vee-validate schema on FE, Fluent on BE) + +3. **Implement backend slice:** + - `Handler.cs`: Orchestration, transaction handling + - `Policy.cs`: Pure business logic + - `Sql.cs`: Dapper queries (schema-qualified, no SELECT *) + - `Endpoint.cs`: HTTP routing & status codes + - `README.md`: Traceability link to requirement/ADR + +4. **Write tests:** + - Unit: Policy, Mapper logic + - Integration: Handler + Dapper + real DB + - Verify Outbox events are created if async + +5. **Implement frontend feature:** + - Feature module under `features//` + - Use `features//pages/` for route-level components + - Use `shared/ui/adapter/` for any UI component usage + - Form validation with vee-validate + Zod schema from BE contract + +6. **Validation gates (pre-merge):** + - Architecture tests pass + - DB migration is idempotent (fresh/upgrade test) + - No SELECT *, no direct cross-module queries + - Outbox/Inbox tests if async + - Frontend typecheck + test + build + - E2E smoke test (if user-facing) + +### Refactoring (Characterized, Isolated, Verified) + +1. **Characterize:** Lock current behavior with tests + perf baseline + Golden data. +2. **Isolate:** Separate I/O (Dapper queries, HTTP) from logic (Policy). +3. **Transform:** One small change at a time (rename, extract, move). +4. **Verify:** All tests pass, no perf regression, backtest algorithm changes against Golden. +5. **Simplify:** Delete dead abstractions, feature flags, branches. +6. **Observe:** Post-release SLO/DQ/model drift monitoring. +7. **Close Debt:** Update Debt ID, leave ADR for future maintainers. + +### Creating a Background Job + +1. **Define the command:** + ```csharp + public class MyJobCommand : ICommand + { + public Guid IdempotencyKey { get; set; } + public Guid CorrelationId { get; set; } + public string InputData { get; set; } + } + ``` + +2. **Implement the handler:** + - Idempotent: Re-run should be safe and produce same result. + - Classify failures: transient/permanent/dq/business-hold. + - Emit events to Outbox for async notifications. + +3. **Schedule via Hangfire:** + ```csharp + await backgroundJobClient.EnqueueAsync(h => h.Handle(command)); + ``` + +4. **Test retry & replay scenarios:** + - Job runs successfully. + - Job fails and is retried (verify idempotency). + - Job is replayed from cold state (verify determinism). + +## Guardrails & Anti-Patterns + +### Coding Standards (from VIBE_CODING_GUARDRAILS.md) + +**Before requesting code changes, ensure these 8 inputs are present:** +1. **Source:** Reference policy, ADR, data contract, requirement ID +2. **Slice Spec:** User goal, non-goal, state transitions, RBAC +3. **Screen Spec:** Component tree, state management, a11y +4. **Contract:** Endpoint paths, event schemas, HTTP status codes, ETag/idempotency handling +5. **Data:** Schema, columns, PIT conditions, migration, index plan +6. **Tests:** Unit/integration/data/E2E/Golden scenarios + failure cases +7. **Ops:** Metrics, alerts, runbooks, rollback procedure, on-call owner +8. **Output Rule:** Changed files, commands to verify, assumptions, residual risks + +### Blocking Rules +- **No undocumented policy IDs or thresholds.** Every numeric constant must trace to a requirement. +- **Pending decisions:** Mark with `DECISION_REQUIRED` or `DESIGN_PROPOSAL` comment. +- **One PR = one slice or one refactoring goal.** No mixing feature work + unrelated cleanup. +- **Feature changes ≠ refactoring.** Separate PRs: feature, then refactoring, then verify. +- **Never hide failing/skipped tests.** If a test fails, fix it or raise an issue. +- **SQL review:** Generated SQL must pass schema owner review, PIT validation, index analysis. +- **Algorithm changes:** Never merge without Golden/Frozen OOS diff showing no regression. +- **Real customer data:** Never include in prompts, fixtures, or logs. + +### Model Operations Specifics +- **Model lifecycle:** Freeze → Mature → Score → Diagnose → Hypothesis → Challenger → Validate → Review → Manual Activation. No auto-learning, auto-promotion, or auto-ordering. +- **Sell priority:** `HARD_IMPAIRMENT → PORTFOLIO_SURVIVAL → DYNAMIC_PROFIT_FLOOR → CONCENTRATION/LIQUIDITY → OPPORTUNITY_COST → REENTRY_OPTION` (immutable). +- **Non-value-loss sell:** Requires ReentryWatch, new CycleId/Lot, step intervals, expiry, dedup. +- **Activation gating:** Every model activation requires ModelCard, OOS/PBO/DSR evidence, maker-checker approval, effective_at timestamp, rollback justification. + +## Tools & Scripts + +### Scaffolding +```bash +python tools/scaffold_vertical_slice.py --name MyFeature --module ModelOperations +python tools/scaffold_ui_screen.py --name MyScreen --feature MyFeature +``` + +### Validation +```bash +python tools/validate_v16.py # Full v16 validation (contracts, migrations, Python tests) +python -m unittest discover # Run all Python unit tests +``` + +### FastEndpoints +- Docs: [FastEndpoints GitHub](https://github.com/FastEndpoints/FastEndpoints) +- Pattern: Each endpoint maps to a Vertical Slice; routes are discovered automatically. + +## Documentation & Resources + +### Key Documents +- `docs/03_ARCHITECTURE_BE_FE.md` — Modular Monolith, Vertical Slice, Dapper, Hangfire, FE state ownership rules. +- `docs/06_VIBE_CODING_GUARDRAILS.md` — AI input packets, blocking rules, refactoring methodology. +- `contracts/ui/ui-adapter.v3.json` — FE adapter contract (PrimeVue/AG Grid wrapper boundaries). +- `contracts/schedules/model-operations.v3.json` — Job scheduling contract. +- `README.md` — Project status, v16 delta, validation gates. + +### Contracts Directory +``` +contracts/ + ui/ # Frontend adapter & component contracts + schedules/ # Job scheduling contracts + data/ # Domain data models (PIT envelope, projection) + events/ # Async event schemas + metrics/ # Outcome metrics schema +``` + +## Validation Gates (Not Yet Passed) + +Do NOT claim production readiness until: +- `.NET 10 restore/build/test` on CI passes consistently +- `pnpm frozen install/typecheck/Vitest/build/Playwright` on CI passes +- PostgreSQL DbUp fresh/upgrade/re-run/failure-recovery tests pass +- Outbox/Inbox crash-recovery & audit reconciliation rehearsal passes +- 252+ trading-day shadow run with OOS at multiple market phases +- PBO (probability of backtest overfit) and DSR (daily sharpe ratio) evidence + +Before all gates pass: **No production deployment, no advisory-with-automation, no auto-ordering, no auto-model-promotion.**