3.6 KiB
You are a code implementer. Build ONE focused module. Write the code now.
HARD RULES
- Do NOT call any automaton_* tool. Do NOT read PARENT_SPEC.md or DECOMPOSITION.md.
- Start writing files within your first 2 tool calls. Read only what's listed, then build.
- You are building micro-slice 1a: the SQLite database foundation for the Investor Flow backend.
CONTEXT (read these, then build)
The project is "Investor Flow" — a Bun + SQLite backend serving a Next.js SPA. You are creating the database layer. The schema follows DESIGN.md Section 1 (Tier A shared market cache + Tier D system).
Read this ONE file for the exact schema:
grep -n "Tier D\|Tier A\|CREATE TABLE\|users\|sessions\|symbol_meta\|price_quotes\|price_candles\|symbol_demand" /Users/laptran/Documents/investor-flow/.automaton/tasks/investor-flow-platform-design/DESIGN.md | head -40
If the grep doesn't give enough, read lines 17-175 of that DESIGN.md.
BUILD EXACTLY THESE 4 FILES
1. app/server/package.json
{
"name": "investor-flow-server",
"version": "0.1.0",
"type": "module",
"scripts": {
"dev": "bun run src/index.ts",
"test": "bun test"
},
"dependencies": {
"better-sqlite3": "^11.0.0",
"@trpc/server": "^11.0.0",
"argon2": "^0.40.0",
"yahoo-finance2": "^2.0.0",
"zod": "^3.23.0"
},
"devDependencies": {
"@types/better-sqlite3": "^7.6.0",
"bun-types": "^1.1.0",
"typescript": "^5.0.0"
}
}
2. app/server/tsconfig.json
Standard Bun TypeScript config (target ESNext, module ESNext, moduleResolution bundler, strict true, types ["bun-types"], outDir ./dist).
3. app/server/src/db/schema.sql
SQLite DDL for these tables (match DESIGN.md Section 1 Tier A + Tier D):
users(id TEXT PK, email TEXT UNIQUE NOT NULL, pw_hash TEXT NOT NULL, complexity TEXT DEFAULT 'beginner', risk_tolerance TEXT, created_at TEXT NOT NULL)sessions(id TEXT PK, user_id TEXT NOT NULL REFERENCES users(id), expires_at TEXT NOT NULL, created_at TEXT NOT NULL)symbol_meta(symbol TEXT PK, name TEXT, sector TEXT, industry TEXT, exchange TEXT, ticker_kind TEXT NOT NULL DEFAULT 'equity', updated_at TEXT)price_quotes(symbol TEXT NOT NULL, price REAL, bid REAL, ask REAL, change REAL, change_pct REAL, ts_observed TEXT NOT NULL, fetched_at TEXT NOT NULL, PRIMARY KEY(symbol, ts_observed))price_candles(symbol TEXT NOT NULL, tf TEXT NOT NULL, ts TEXT NOT NULL, o REAL, h REAL, l REAL, c REAL, v REAL, adj_close REAL, PRIMARY KEY(symbol, tf, ts))symbol_demand(symbol TEXT PK, refcount INTEGER NOT NULL DEFAULT 0, protected INTEGER NOT NULL DEFAULT 0) Add indexes: on price_quotes(symbol), price_candles(symbol, ts), sessions(user_id).
4. app/server/src/db/client.ts
A DbClient class (or factory function) that:
- Opens a SQLite database (better-sqlite3). Accepts a path arg; default
./investor-flow.db. For tests, accept:memory:. - On init, reads and executes
schema.sql(useimport.meta.dirto resolve the path relative to the file). - Exposes the raw
Databaseinstance via adbproperty for other modules to use prepared statements. - Exports a
createDb(path?)factory. TypeScript throughout. Usebetter-sqlite3synchronous API.
THEN
Run cd /Users/laptran/Documents/investor-flow/app/server && bun install to install deps.
Then run a quick smoke test: bun -e "import {createDb} from './src/db/client'; const db = createDb(':memory:'); console.log(db.db.prepare('SELECT name FROM sqlite_master WHERE type=\"table\"').all());" to confirm tables exist.
Print the result. Then STOP — do not build anything else.
PRIMARY RULE
No user-facing strings in this micro-slice (it's the DB layer). Just clean typed code.