Files
investor-flow/.scratch/slice1-implement-prompt-v2.md

49 lines
4.8 KiB
Markdown

You are a CODE IMPLEMENTER for Slice 1 of "Investor Flow". Write code. Do not explore the task framework.
## HARD RULES
- DO NOT call automaton_status, automaton_transition, automaton_create_task, or ANY automaton_* tool. The orchestrator manages tasks. You only write code.
- DO NOT read PARENT_SPEC.md or DECOMPOSITION.md. Ignore the automaton task folders entirely.
- The task is already in "implement" phase — edits are allowed. Just build.
- Start writing code within your first 2 tool calls. Limit reading to the 3 files listed below, then build.
- Thinking: be concise. Plan the file list, then create files. Do not over-analyze the framework.
## READ EXACTLY THESE 3 FILES, THEN BUILD
1. `.automaton/tasks/tracer-bullet-1-signup-cached-nvda-overview/SPEC.md` (your scope)
2. `CONTEXT.md` (repo root — just the "Primary Rule" + "Ticker" sections)
3. `.automaton/tasks/investor-flow-platform-design/DESIGN.md` — read ONLY by grepping these sections: "Section 1 — Typed Schema" (Tier A + Tier D tables), "Section 3a" (CacheRepository + SourceAdapter interfaces). Use `grep -n` to find line numbers then read those ranges. Do NOT read the whole file.
## BUILD THIS EXACT FILE PLAN (Bun backend + Next panel), in order
### Backend: `app/server/` (new dir; `app/server/` already exists, empty)
1. `app/server/package.json` — deps: bun, better-sqlite3, @trpc/server, argon2, yfinance (use `yahoo-finance2` npm package, NOT python). scripts: `dev: bun run src/index.ts`, `test: bun test`.
2. `app/server/tsconfig.json`
3. `app/server/src/db/schema.sql` — tables: `users(id,email,pw_hash,complexity,created_at)`, `sessions(id,user_id,expires_at)`, `symbol_meta(symbol,name,sector,industry,exchange,ticker_kind)`, `price_quotes(symbol,price,bid,ask,change,change_pct,ts_observed,fetched_at)`, `price_candles(symbol,tf,ts,o,h,l,c,v,adj_close)`, `symbol_demand(symbol,refcount,protected)`.
4. `app/server/src/db/client.ts` — better-sqlite3 wrapper, runs schema.sql on init.
5. `app/server/src/cache/CacheRepository.ts` — interface `{get(key), set(key,val,ttl,provenance), stale(key)}` + SQLite impl. Staleness: quote 60s, sector weekly, candles daily-locked.
6. `app/server/src/adapters/SourceAdapter.ts` — interface `{fetch(symbol, kind, opts): Promise<CacheRecord[]>}` (the deep-module interface from DESIGN §3a).
7. `app/server/src/adapters/YFinanceAdapter.ts` — implements SourceAdapter using `yahoo-finance2`. Kinds: `quote`, `price_history` (daily, last 30 days for sparkline), `info/sector`.
8. `app/server/src/queue/AdapterQueue.ts` — token-bucket (1 req/s, burst 2), dedupe by `source|kind|symbol|paramsHash`, exponential backoff on 429 (2,4,8,16,60s, 5 tries→FAILED).
9. `app/server/src/trpc/router.ts` — procedures: `auth.signup({email,password})`, `auth.login({email,password})→session`, `market.snapshot({symbol})→{quote,symbolMeta,recentCandles}` (reads cache, enqueues refresh if stale).
10. `app/server/src/trpc/context.ts` — session guard.
11. `app/server/src/index.ts` — Bun.serve on :3001, mounts tRPC.
12. `app/server/src/__tests__/CacheRepository.test.ts` — in-memory SQLite, staleness asserts.
13. `app/server/src/__tests__/AdapterQueue.test.ts` — FakeSourceAdapter, dedupe collapses 2 calls→1, 429 backoff.
14. `app/server/src/__tests__/router.test.ts` — signup/login/market.snapshot integration with FakeSourceAdapter.
15. `app/server/src/__tests__/primary-rule-lint.test.ts` — grep curated UI strings for stoplist ["buy","sell","you should","add to your","rotate into","action needed"] (allow "buy-zone estimate"); FAIL on imperative trade directive.
### Frontend: reuse existing `app/` Next project
16. `app/src/lib/trpc.ts` — tRPC client to :3001.
17. `app/src/stores/active-symbol-store.ts` — Zustand store, default symbol "NVDA".
18. `app/src/components/OverviewPanel.tsx` — M1: name + sector + complexity badge (beginner) + price + day-change sparkline (Recharts, already installed) + one-line "why this matters" placeholder + ADR-0007 footer.
19. `app/src/app/page.tsx` — rewrite to render OverviewPanel bound to active-symbol store + a minimal login/signup form (calls auth.signup/login). Single-page, no extra routes.
20. `app/src/app/globals.css` — keep existing; ensure footer style.
## PRIMARY RULE (ADR-0007) — the lint test MUST pass
No UI string says "buy/sell/hold this". Footer text (in OverviewPanel): "Educational analysis, not investment advice. Verify the underlying data; you are responsible for your own decisions."
## WHEN DONE
Run `cd app/server && bun test`. If all green, run `cd app && npx tsc --noEmit` for the frontend. Print a summary: files created, test results, which acceptance criteria met. Then STOP.
## SCOPE GUARDRAILS — DO NOT BUILD
No 2FA/OAuth, no onboarding, no full max-history backfill (only last 30 days for sparkline), no other panels, no LLM calls, no Docker.