Finance — a Next.js 16 (App Router) stock research terminal from Chloei with two auth-gated surfaces:
/(home): market research workspace (watchlists, screeners, stock dossiers, calendars, breadth)/copilot: AI agent workspace (OpenRouter streaming with MCP tools)
- Framework: Next.js 16, React 19, TypeScript (strict)
- Styling: Tailwind CSS 4, shadcn/ui (radix-lyra), Lucide icons
- Database: PostgreSQL with Kysely
- Auth: Better Auth
- AI: Vercel AI SDK + OpenRouter + MCP (FMP, Tavily)
- Package manager: pnpm 10 (Node 20+)
# Install
pnpm install
# Copy env template (required before running migrations)
cp .env.example .env.local
# Dev server (port 3000)
pnpm dev
# Verification matrix — run before closing substantial work
pnpm test # Vitest unit tests
pnpm lint # ESLint (--max-warnings=0)
pnpm typecheck # next typegen && tsc --noEmit
pnpm build # Production build
# Individual tools
pnpm lint:fix # Auto-fix lint issues
pnpm format # Prettier
pnpm format:check # Check formatting
pnpm test:watch # Vitest watch mode
# E2E (Playwright, requires chromium)
pnpm test:e2e:install # Install browser
pnpm test:e2e # Run smoke tests
# Database migrations (run in order on fresh setup)
pnpm auth:migrate
pnpm threads:migrate
pnpm markets:migrate
# Market capability checks (after FMP/market changes)
pnpm markets:capabilitiessrc/
app/ # App Router pages and route handlers
(home)/ # Market workspace pages
(auth)/ # Auth pages (sign-in, sign-up)
copilot/ # Agent workspace
api/ # Route handlers
components/ # UI components by domain (markets, agent, auth, ui)
lib/
server/ # Server-only: auth, markets, threads, agent runtime
shared/ # Shared types and pure helpers (narrow imports, no barrels)
actions/ # Server actions
hooks/ # React hooks
types/ # Shared TypeScript types
docs/
architecture/ # Detailed system notes (markets.md, copilot.md)
agents/ # Agent-facing guidance (repo-map.md, verification.md)
e2e/ # Playwright tests
test/ # Shared test utilities and build-config tests (not domain tests)
- Server/client boundary: Client components must not import
server-onlymodules. - Route handlers: Keep thin — push domain logic into
src/lib/server/*. - Market dates: Always use
createMarketDateClock(), never raw Date math. - Market data:
src/lib/server/marketsowns FMP access, cache, storage, and market-time rules. - Copilot streaming: Lives under
src/app/api/agentandsrc/components/agent. - Tests: Prefer domain-local
__tests__folders; use the top-leveltest/directory only for repo-level infrastructure tests and shared test utilities. - Imports: Prefer narrow imports from
src/lib/shared/*— avoid adding new catch-all barrels. - Route contracts: Do not change route URLs or JSON response shapes unless explicitly required.
Check the nearest AGENTS.md when working in specialized areas:
src/app/api/AGENTS.md— route handler patternssrc/app/api/agent/AGENTS.md— streaming and thread statesrc/lib/server/markets/AGENTS.md— markets module patternssrc/components/agent/AGENTS.md— copilot component rules
Architecture docs: docs/architecture/markets.md, docs/architecture/copilot.md
Required env vars (see .env.example for full list):
DATABASE_URL— PostgreSQL connection stringBETTER_AUTH_SECRET— auth secretBETTER_AUTH_URL— app origin (defaulthttp://localhost:3000)
Feature-gating env vars (optional):
FMP_API_KEY— enables market data and FMP MCP toolsOPENROUTER_API_KEY— enables/copilotagent workspaceTAVILY_API_KEY— enables search tools in copilot
- Prettier: 80-char width, ES5 trailing commas, Tailwind plugin
- ESLint: zero warnings policy, simple-import-sort, jsx-a11y
- TypeScript: strict mode, no unchecked indexed access,
@/*path alias tosrc/ - No unnecessary barrels, no speculative abstractions