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

4.8 KiB

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

  1. app/src/lib/trpc.ts — tRPC client to :3001.
  2. app/src/stores/active-symbol-store.ts — Zustand store, default symbol "NVDA".
  3. 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.
  4. 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.
  5. 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.