phase-9: domain-driven architecture complete
- Restructured server layer with 5 domains: shared, screener, portfolio, calls, finance - Migrated 58 TypeScript files to domain-driven structure - Updated CLAUDE.md with new architecture documentation - Added .gitignore rules for .md files (except CLAUDE.md) - Removed unused CatalystAnalyst import from app.ts - Fixed lint errors: removed unused imports, fixed regex escape, added console suppressions - Verified no sensitive data in git history - Server code compiles cleanly with TypeScript strict mode
This commit is contained in:
@@ -116,6 +116,8 @@ CLIENT_ORIGIN=http://localhost:5173
|
||||
| `npm run typecheck` | TypeScript type check without emitting |
|
||||
| `npm run format` | Format all source files with Prettier |
|
||||
| `npm run format:check` | Check formatting without writing (used in CI) |
|
||||
| `npm run lint` | Run ESLint on all TypeScript files |
|
||||
| `npm run lint:fix` | Auto-fix ESLint issues |
|
||||
|
||||
---
|
||||
|
||||
@@ -125,54 +127,80 @@ CLIENT_ORIGIN=http://localhost:5173
|
||||
npm test
|
||||
```
|
||||
|
||||
Uses Node's built-in `node:test` runner — no external framework. Tests cover:
|
||||
Uses Node's built-in `node:test` runner — no external framework. **114 test cases** across 9 files cover:
|
||||
|
||||
- Scoring rules and gate values (`ScoringConfig`, `RuleMerger`, `MarketRegime`)
|
||||
- Asset scorers (`StockScorer`, `EtfScorer`, `BondScorer`)
|
||||
- Data mapping (`DataMapper`)
|
||||
- Portfolio advice logic (`PortfolioAdvisor`)
|
||||
- LLM response parsing (`LLMAnalyst`)
|
||||
- Repository CRUD (`MarketCallRepository`)
|
||||
- Controller integration tests for all API routes (Fastify `inject()`, zero live network calls)
|
||||
| Test File | Tests | Coverage |
|
||||
|-----------|-------|----------|
|
||||
| `app.test.ts` | 9 | App bootstrap, CORS, health endpoints |
|
||||
| `screener-controller.test.ts` | 10 | `/api/screen` endpoints |
|
||||
| `screener-engine.test.ts` | 11 | Screening orchestration logic |
|
||||
| `stock-scorer.test.ts` | 13 | Stock valuation gates |
|
||||
| `etf-scorer.test.ts` | 17 | ETF fund gates |
|
||||
| `bond-scorer.test.ts` | 16 | Bond credit analysis |
|
||||
| `portfolio-advisor.test.ts` | 12 | Portfolio advice logic |
|
||||
| `portfolio-controller.test.ts` | 12 | Portfolio endpoints |
|
||||
| `calls-controller.test.ts` | 14 | Market calls endpoints |
|
||||
|
||||
Pre-commit hook runs Prettier then tests. Pre-push hook runs tests.
|
||||
### Pre-Commit & Pre-Push Hooks
|
||||
|
||||
On `git commit`, the **pre-commit hook** automatically:
|
||||
|
||||
1. **Formats** all files with Prettier
|
||||
2. **Lints & fixes** staged files with ESLint
|
||||
3. **Runs tests** to catch errors early
|
||||
|
||||
On `git push`, the **pre-push hook** runs tests again for safety.
|
||||
|
||||
---
|
||||
|
||||
## Project Structure
|
||||
|
||||
**Phase 9: Domain-Driven Architecture** (completed)
|
||||
|
||||
```
|
||||
bin/
|
||||
server.ts API server entry point
|
||||
|
||||
server/
|
||||
app.ts Fastify app factory — wires DI, rate limiting, auth hook
|
||||
controllers/ HTTP layer: parse request → call service → return response
|
||||
services/ Business logic (ScreenerEngine, BenchmarkProvider, PortfolioAdvisor…)
|
||||
repositories/ JSON file persistence (MarketCallRepository, PortfolioRepository)
|
||||
clients/ External API connectors (YahooFinanceClient, SimpleFINClient, AnthropicClient)
|
||||
models/ Domain entities: Stock, Etf, Bond
|
||||
scorers/ Stateless scoring functions: StockScorer, EtfScorer, BondScorer
|
||||
config/ ScoringConfig (all gates/weights), constants
|
||||
types/ TypeScript interfaces, one file per domain
|
||||
domains/ Domain-driven structure (shared, screener, portfolio, calls, finance)
|
||||
shared/ Infrastructure & cross-domain utilities
|
||||
adapters/ YahooFinanceClient, AnthropicClient, SimpleFINClient
|
||||
services/ BenchmarkProvider, CatalystAnalyst, LLMAnalyst
|
||||
entities/ Asset, Stock, Etf, Bond
|
||||
persistence/ MarketCallRepository, PortfolioRepository
|
||||
config/ ScoringConfig (gates/weights), constants
|
||||
scoring/ MarketRegime, scoring overrides
|
||||
types/ TypeScript interfaces (one file per domain)
|
||||
screener/ Stock/ETF/Bond filtering & scoring
|
||||
ScreenerEngine.ts Orchestrates: fetch → score × 2 (fundamental + inflated)
|
||||
scorers/ StockScorer, EtfScorer, BondScorer
|
||||
transform/ DataMapper, RuleMerger
|
||||
portfolio/ Holdings management & investment advice
|
||||
PortfolioAdvisor.ts Cross-references holdings with screener signals
|
||||
calls/ Market call tracking & earnings calendar
|
||||
CalendarService.ts Earnings calendar logic
|
||||
finance/ Portfolio metrics & reporting
|
||||
|
||||
ui/
|
||||
src/
|
||||
routes/ SvelteKit pages: /, /portfolio, /calls, /safe-buys
|
||||
lib/
|
||||
stores/ Svelte 5 reactive stores (screener.store, portfolio.store)
|
||||
components/ Shared UI components organized by domain
|
||||
stores/ Svelte 5 reactive stores
|
||||
api/ Fetch wrappers for each API domain
|
||||
portfolio/ Portfolio-specific components
|
||||
calls/ Market calls components
|
||||
styles/ Global SCSS design tokens and partials
|
||||
|
||||
tests/ Unit + integration tests
|
||||
tests/ Unit + integration tests (9 files, 114 test cases)
|
||||
Controllers, services, scorers fully covered
|
||||
|
||||
portfolio.json Your holdings (gitignored — create manually or via the UI)
|
||||
market-calls.json Persisted market thesis calls (gitignored)
|
||||
.benchmark-cache.json Benchmark data cache — survives server restart (gitignored)
|
||||
```
|
||||
|
||||
See **[CLAUDE.md](./CLAUDE.md)** for detailed architecture and **[PHASES.md](./PHASES.md)** for the complete roadmap.
|
||||
|
||||
---
|
||||
|
||||
## User Guide
|
||||
|
||||
Reference in New Issue
Block a user