The tactical backlog: what's next, what's in progress, and what's done. For mission, principles, and milestone definitions, see GOALS.md.
Summary: 48 findings across 22 files. 2 shared utilities to extract.
packages/server/src/config/paths.ts— CentralizeDATA_DIR,FUNDS_DIR,BACKUP_DIRconstants. Replaces 7 duplicate declarations across funds.ts, backup.ts, platforms.ts, export.ts, import.ts, test-data.ts, utils/platforms.ts.packages/server/src/utils/derivatives-config.ts— ExtractgetDerivativesConfig(config)returning{ contractMultiplier, maintenanceMarginRate, initialMarginRate }. Replaces 7 duplicate 3-line blocks across funds.ts, fund-metrics.ts, dashboard-cache.ts.
| File | Primary Category | Reason |
|---|---|---|
packages/server/src/routes/import.ts |
Security | SSRF (CRITICAL) outranks code quality |
packages/server/src/index.ts |
Security | CORS (HIGH) outranks code quality |
packages/server/src/routes/funds.ts |
Bugs & Perf | .catch(next) pattern (CRITICAL) — NOT YET MODIFIED, pending future PR |
packages/server/src/services/websocket.ts |
Bugs & Perf | Missing await (CRITICAL) outranks code quality |
packages/storage/src/fund-store.ts |
Bugs & Perf | Null pointer in release (CRITICAL) |
packages/server/src/routes/platforms.ts |
Code Quality | Swallowed errors (CRITICAL) |
packages/server/src/routes/backup.ts |
Architecture | Inconsistent response envelope (HIGH) |
packages/server/src/routes/export.ts |
Architecture | Inconsistent error format (HIGH) |
packages/server/src/middleware/error-handler.ts |
Code Quality | Mixed logging (MEDIUM) |
packages/server/src/services/dashboard-cache.ts |
DRY | Derivatives config duplication (HIGH) |
packages/web/src/components/Layout.tsx |
Code Quality | Swallowed API errors (CRITICAL) |
packages/web/src/components/CreateFundModal.tsx |
Stack-Specific | Missing useEffect cleanup (HIGH) |
packages/web/src/components/ImportWizard.tsx |
Code Quality | Swallowed browser cleanup errors (HIGH) |
packages/web/src/api/utils.ts |
Bugs & Perf | Missing AbortController (HIGH) |
packages/web/src/api/funds.ts |
Bugs & Perf | Race condition in parallel fetch (HIGH) |
packages/web/src/pages/Dashboard.tsx |
Stack-Specific | window.location.href instead of navigate (CRITICAL) |
packages/web/src/contexts/DashboardContext.tsx |
Stack-Specific | Stale closure in useCallback (CRITICAL) |
packages/web/src/pages/Backtest.tsx |
Code Quality | IIFE error suppression (MEDIUM) |
packages/web/src/pages/Settings.tsx |
Code Quality | Try/catch without logging (MEDIUM) |
packages/web/src/components/ActionableFundsBanner.tsx |
Code Quality | Try/catch without logging (MEDIUM) |
packages/server/src/utils/fund-metrics.ts |
DRY | Derivatives config duplication (HIGH) |
packages/server/src/config/paths.ts |
DRY | New file (foundation utility) |
packages/server/src/utils/derivatives-config.ts |
DRY | New file (foundation utility) |
- [CRITICAL]
packages/server/src/routes/import.ts:1964— SSRF: cdpUrl accepts arbitrary URLs passed to Playwright connectOverCDP. Fix: Validate cdpUrl is localhost only. (Simple) - [HIGH]
packages/server/src/index.ts:23— Unrestricted CORS:cors()allows all origins. Fix: Restrict to localhost:5550 + configurable origins. (Simple) - [MEDIUM]
packages/server/src/routes/import.ts:1913— Child process spawning without platform validation. Fix: Validate platform against whitelist. (Simple) - [LOW] CVE: xlsx@0.18.5 has prototype pollution + ReDoS (devDep only)
- [LOW] CVE: pm2 ReDoS (no fix available)
- [CRITICAL]
packages/server/src/routes/platforms.ts:998-999— Swallowed errors in file deletion:.catch(() => {}). Fix: Log errors. (Simple) - [CRITICAL]
packages/web/src/components/Layout.tsx:67,70,85,94— Swallowed API errors in Layout with only console.warn. Fix: Add toast for critical load failures. (Medium) - [HIGH]
packages/web/src/components/ImportWizard.tsx:912,992— Swallowed browser cleanup:killBrowser().catch(() => {}). Fix: Log errors. (Simple) - [HIGH]
packages/server/src/routes/export.ts:95— Swallowed mkdir error. Fix: Log error. (Simple) - [MEDIUM]
packages/server/src/middleware/error-handler.ts:19-22— Uses console.warn/error instead of structured logger. Fix: Use createLogger. (Simple) - [MEDIUM]
packages/web/src/pages/Backtest.tsx:235— IIFE error suppression for JSON.parse. Fix: Add logging. (Simple) - [MEDIUM]
packages/web/src/pages/Settings.tsx:344-350— Try/catch without logging parse error. Fix: Log error. (Simple) - [MEDIUM]
packages/web/src/components/ActionableFundsBanner.tsx:25-40— Try/catch without logging. Fix: Log error. (Simple) - [MEDIUM]
packages/web/src/api/utils.ts:101-104— Silent BTC price fetch failure. Fix: Add logging. (Simple) — NOTE: file owned by Bugs & Perf, defer this fix there
- [CRITICAL]
7 files— DATA_DIR duplicated across 7 files. Fix: Extract to config/paths.ts (Foundation). (Simple) - [HIGH]
funds.ts, fund-metrics.ts, dashboard-cache.ts— Derivatives config (3 lines) duplicated 7x. Fix: Extract to derivatives-config.ts (Foundation). (Simple) - [MEDIUM]
export.ts, import.ts (23 occurrences)— Inlineres.status().json()instead of error handler. Fix: Use next(badRequest/notFound). (Simple) — NOTE: export.ts owned by Architecture, import.ts owned by Security
- [HIGH]
packages/server/src/routes/backup.ts— Inconsistent response envelope:{success, error}vs{error: {message, code}}. Fix: Standardize to error handler. (Simple) - [HIGH]
packages/server/src/routes/export.ts:61-126— Inconsistent error format: manualres.status(400).json()instead of middleware. Fix: Use next(badRequest(...)). (Simple) - [LOW]
packages/server/src/routes/funds.ts:65-120— List endpoint without pagination. (Medium) — tracked, not auto-remediated
- [CRITICAL]
packages/storage/src/fund-store.ts:78— Null pointer:release()called when undefined if lock acquisition fails. Fix: Guard withif (release) await release(). (Simple) - [CRITICAL]
packages/server/src/services/websocket.ts:156— MissingawaitonsendDashboardData(client)causing unhandled rejection. Fix: Add await. (Simple) - [CRITICAL]
packages/server/src/routes/funds.ts:66—.catch(next)anti-pattern: assignment gets undefined return of next(). Fix: Use try/catch with return next(err). (Medium) - [HIGH]
packages/web/src/api/utils.ts:92-115— Missing AbortController on external Coinbase API fetch. Fix: Add AbortController with 5s timeout. (Simple) - [HIGH]
packages/web/src/api/funds.ts:357-370— Unbounded parallel fetch without concurrency control. Fix: Add concurrency limit or use Promise.allSettled with logging. (Medium)
- [CRITICAL]
packages/web/src/pages/Dashboard.tsx:577—window.location.hrefcauses full page reload. Fix: Use React Router navigate(). (Simple) - [CRITICAL]
packages/web/src/contexts/DashboardContext.tsx:158— Stale closure: useCallback deps missing, causing WebSocket reconnect leaks. Fix: Stabilize deps. (Medium) - [HIGH]
packages/web/src/components/CreateFundModal.tsx:59-75— Missing cleanup in useEffect fetch. Fix: Add cancellation flag to prevent state updates after unmount. (Medium) - [HIGH] Missing
.env.examplefile. Fix: Create with documented env vars. (Simple) — new file
- [CRITICAL] No unit tests for server routes (funds.ts 2748 lines, import.ts 7176 lines)
- [CRITICAL] No unit tests for dashboard-cache.ts (765 lines) or websocket.ts
- [HIGH] No unit tests for fund-metrics.ts, calculations.ts, compute.ts, export.ts, backup.ts, platforms.ts
- [HIGH] No unit tests for engine/fund-type-config.ts (16 exported functions)
- [HIGH] storage/fund-store.ts: only helpers tested, not core I/O functions
See the docs/ folder for detailed documentation:
- Philosophy - Why this system exists (start here)
- Investment Strategy - DCA methodology
- Fund Management - Position and cash tracking
- Configuration Guide - All config options
- Data Format - TSV file structure
- System Architecture - Package structure and data flow
- Derivatives - Perpetual futures data model
- Project Goals - Mission, milestones, and non-goals
Allow per-fund configuration of which entry fields are shown and their order. Enables "quick entry" - configure a fund to show only date + value for a minimal Take Action form.
- Add
entry_fieldsconfig to fund JSON (array of field names + order) - Create field configuration UI in fund settings
- Update AddEntryModal to respect field visibility/ordering
- Preserve backwards compatibility (default shows all fields)
- Pre-fill date with today, value with latest value
Filter charts to specific time periods (1M, 3M, 6M, YTD, 1Y, All).
- Add date range buttons above charts
- Filter chart data to selected range
- Persist selection per fund in config
- Apply to all charts on the page
When tracking price/size, show additional charts on the fund dashboard.
- Add price history chart (price over time)
- Add share accumulation chart (total shares over time)
- Add cost basis vs current price comparison
- Only show charts when fund has price/size data
- Server route unit tests (
packages/server/test/routes/) - Visual regression tests for charts
- 95%+ feature coverage in E2E suite
- TWAP-based APY calculation verified across all edge cases (multi-cycle, idle gaps, partial liquidation)
- Recommendation engine handles every combination of fund config flags correctly
- Keyboard shortcuts (j/k navigation, Enter to open, Esc to close)
- Mobile-responsive layout
- Ticker Choices Guide (
docs/ticker-choices.md) - Why volatile assets like TQQQ work better for DCA than VTI - Getting Started Guide
- API Reference (OpenAPI/Swagger)
- Complete configuration reference with examples
- Add parameter inputs to Test/Demo Data settings section
- Integrate m1test generation into "Load Test Data" button
- Add preset configurations (Conservative, Moderate, Aggressive)
- Plugin system for custom DCA strategies beyond tiered min/mid/max
- Per-holding allocation within a fund (pie-style)
- Benchmark comparison (vs SPY, BTC, custom benchmark)
- Goal setting with target dates and amounts
- Performance attribution (break down gains by dividends, price appreciation, interest)
- Comparison mode (side-by-side fund analysis)
- Drawdown analysis and recovery time tracking
- Portfolio correlation matrix
- Currency support for non-USD funds with exchange rate conversion
- Multi-account aggregation (same ticker across platforms as single view)
- Split handling (adjust historical prices/shares automatically)
- CSV/PDF export for tax reporting
- Service worker for full offline access
- Installable as a desktop/mobile app
- Background sync when connectivity returns
- Shareable fund configurations (anonymized strategy templates)
- Backtesting engine with historical data for strategy validation before committing real capital
- Public backtest page with onboarding wizard (already started in
pages/)
Run npm run test:coverage to generate the coverage report, viewable in the app's Settings page.
| Suite | Files | Coverage |
|---|---|---|
| E2E | 8 spec files, 130+ tests | Fund configs, simulations, integrity, derivatives, UI, platforms, import/export, cash |
| Engine | 135 unit tests | Passing |
| Storage | 9 unit tests | Passing |
- Configurable entry form fields - Highest-value UX improvement; reduces friction for the most common action (adding entries)
- Chart date range selector - Second most requested feature; enables focused analysis of recent performance
- Price/size charts - Price history, share accumulation, and cost basis charts for funds with price/size data
- Server route unit tests - Largest testing gap; API routes have zero unit test coverage
- Ticker Choices documentation - Referenced in README and philosophy docs but doesn't exist yet
v0.40+ Fixes
- Liquidation detection refactored to triple-redundant logic (share-based, value-based, dollar-based) in
expected-equity.ts - DEPOSIT/WITHDRAW handling verified — correctly tracked via entries, empty cashflows array is intentional architecture
- Aggregate calculation tests (
packages/engine/test/aggregate.test.ts) - Inline platform creation in Add Fund form (v0.40.5)
v0.20+ Features
Replaced snapshot-based denominator with Time-Weighted Average Position (TWAP) for trading fund APY. Multi-cycle funds now reflect actual average capital deployed.
Removed redundant start_date from fund config (derived from first entry). APY calculated using active days (time with capital deployed) rather than calendar days.
Portfolio categorization with 4 pillars: Liquidity, Yield, Store of Value, Volatility. Margin tracked separately. See Philosophy docs.
Interactive 12-step intro wizard with animated D3 charts in the backtest app (pages/). Auto-shows for first-time visitors, shareable step URLs.
Dashboard banner and nav indicator showing funds past their configured action interval. Actionable funds sorted by priority (most overdue first), dismissible per session.
v0.1-0.6 Features
- Fetch and store 5 years of weekly price data (BTCUSD, TQQQ, SPXL)
- Test data generator utility with API endpoint and Settings UI button
- Blended price history (
pie-weekly.json), margin integrity warnings in UI
- Modal wrapper component, consolidated format utils, performance optimizations (React.memo, code splitting)
- Feature coverage tracking system (
e2e/coverage-matrix.ts) - Full E2E suites: derivatives, UI workflows, platforms, import/export, cash funds