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

4.8 KiB
Raw Permalink Blame History

You are implementing Slice 1 (tracer bullet) of the Investor Flow project. You are an implementer agent operating with read/bash/edit/write tools. The orchestrator will review your diff afterward.

READ THESE FIRST (in this order)

  1. .automaton/tasks/tracer-bullet-1-signup-cached-nvda-overview/SPEC.md — YOUR EXACT SCOPE. Build only what it lists.
  2. CONTEXT.md (repo root) — domain glossary + Primary Rule (Education, not investment advice).
  3. docs/adr/0001-local-first-multi-tenant.md, docs/adr/0004-shared-cache-vs-per-user-fetch.md, docs/adr/0007-education-not-investment-advice.md — the load-bearing ADRs for this slice.
  4. .automaton/tasks/investor-flow-platform-design/DESIGN.md — read Section 1 (Typed Schema, Tier A + Tier D only), Section 2 (API Surface, tRPC + auth seam + market.snapshot), Section 3a (CacheRepository + SourceAdapter interfaces — match these EXACTLY), Section 7 (test-seam map, FakeSourceAdapter, Primary-Rule lint).

Do NOT read all of DESIGN.md — only the sections above. It is 1379 lines; the rest is for later slices.

WHAT TO BUILD (from slice SPEC — do not over-build)

A Bun + SQLite backend + a single-page Next.js panel where a user signs up (email+password, argon2/bcrypt, NO 2FA), logs in, and sees a cached NVDA overview hydrated by one yfinance adapter behind CacheRepository + AdapterQueue, served via tRPC.

Concretely, establish the skeleton that every later slice extends:

  • SQLite schema: users, sessions, symbol_meta, price_quotes, price_candles (daily, permanent, with adj_close), symbol_demand (refcount). Match DESIGN.md §1 Tier A + Tier D.
  • yfinance SourceAdapter: kinds quote, price_history (daily), info/sector. Use the yfinance python package via a thin subprocess/HTTP bridge OR a JS yfinance client — pick the simpler one that works. No options/holders/fundamentals.
  • CacheRepository: get/set/stale with staleness (quote 60s market-hours / 15m after-hours; price_history daily locked EOD; sector weekly). Stale-while-revalidate (return cached immediately, enqueue background refresh).
  • AdapterQueue: token-bucket 1 req/sec sustained burst 2/sec; dedupe same source|kind|symbol|paramsHash; exponential backoff on 429 (2,4,8,16,60s, 5 attempts → FAILED).
  • tRPC: auth.signup, auth.login, market.snapshot(symbol).
  • SPA shell (reuse existing app/ Next project, do NOT create a new one): single-page, active-symbol Zustand signal (NVDA hardcoded), M1 Symbol Overview panel (name + sector + complexity badge default beginner + price + day-change sparkline + one-line "why this matters" placeholder + ADR-0007 footer).
  • Test infra: FakeSourceAdapter, in-memory SQLite fixture, tRPC integration test, Playwright contract test.
  • Primary-Rule lint test: grep curated UI strings for stoplist ["buy","sell","you should","add to your","rotate into","action needed"] outside approved noun phrases ("buy-zone estimate" allowed). FAIL on imperative trade directive.

SCOPE GUARDRAILS — DO NOT BUILD

2FA/OAuth (slice 2) · onboarding wizard (slice 3) · full period="max" backfill (slice 4 — only fetch latest quote + recent daily candles for the sparkline here) · any other panel M2–M20 · LLM Gateway/ornith (M1 "why this matters" is a placeholder STRING, not an LLM call) · Docker Compose (slice 26).

ENGINEERING DISCIPLINE (from installed skills — follow these)

  • tdd: vertical slices, red-green-refactor. One test → one impl → repeat. Do NOT write all tests then all impl.
  • codebase-design: CacheRepository and SourceAdapter are DEEP MODULES — small interface (match DESIGN.md §3a exactly), large implementation hidden behind it. The interface IS the test surface; tests cross the same seam as callers.
  • Tests use FakeSourceAdapter + in-memory SQLite. NO network calls in tests.

PRIMARY RULE (ADR-0007) — non-negotiable

No user-facing string says "buy/sell/hold this." ADR-0007 footer on the page: "Educational analysis, not investment advice. Verify the underlying data; you are responsible for your own decisions." Primary-Rule lint test must pass.

HOW TO WORK

  1. Read the files above.
  2. Check the existing app/ structure (Next 16, React 19, Tailwind v4, Zustand already present). Reuse it.
  3. Scaffold the Bun backend in a new app/server/ directory (or backend/ at repo root — pick one and be consistent). Install deps with bun.
  4. Implement TDD: write the schema + a failing test, make it pass; write CacheRepository interface + failing test, pass; etc.
  5. Run the test suite. Make it green. The Primary-Rule lint test must pass.
  6. When acceptance criteria in the slice SPEC are all green, STOP. Do not start slice 2.

OUTPUT

Write the code to disk using your edit/write tools. When done, print a concise summary: files created/modified, test command + result, and which acceptance criteria are met. The orchestrator (me) will review the diff.