ADR-0001Accepted2026-09-25
Stack
Context. Bullpen is a public prototype and blog demo — a paper-trading league where players compete with play money on real US stock and crypto prices, with a live leaderboard. It is not a commercial product: there is no billing, no SLA, and no expectation of production traffic beyond what a blog audience generates.
Decision. Use Vercel's Hobby plan as the deployment target, a Turborepo monorepo managed with pnpm workspaces, and TypeScript as the implementation language across apps and packages. Free-tier managed services (Neon, Upstash, Grafana Cloud) are planned integrations for later parts of the series and are not wired up in Part 1.
ADR-0002Accepted2026-09-25
Why Distribute at All
Context. The 2010s microservices wave was largely driven by one problem: a monolith couldn't scale its hot path independently of the rest of the system, so teams split services to scale them separately. On modern per-request serverless compute — Vercel Functions and equivalents — that problem is already solved by the platform: every function autoscales independently by default. Splitting a system into services purely to "scale the hot path" no longer buys what it used to, because the hot path already scales without a split.
Decision. Reject "split by default" and "monolith forever" alike. Start Bullpen as one deployable unit conceptually — in practice two simple Next.js apps (landing and trading app) that share packages, neither of which is a "distributed system" in the interesting sense the rest of this series will explore.
ADR-0003Accepted2026-09-25
Monorepo
Context. Bullpen already spans multiple deployables (a landing app and a trading app) and shared code (a data model, UI, config) that both depend on. Later parts of the series add more moving pieces — the order saga, the Rust ingestion service — that will need to evolve alongside shared contracts without every change becoming a multi-repo coordination exercise. The build/test tooling also needs to scale with the codebase: as more apps and packages are added, CI shouldn't have to rebuild and retest everything on every change.
Decision. One Turborepo monorepo, organized as `apps/` (the deployables) and `packages/` (shared libraries, starting with `packages/contracts` for the shared data model), managed with pnpm workspaces. This gets affected-only builds and tests via Turborepo's task graph, local and remote caching, and enforced dependency boundaries between apps and libraries via `turbo boundaries`.
ADR-0005Accepted2026-09-26
Crypto Market Data from CoinGecko Demo
Context. Issue #6 (one live symbol) originally proposed the Coinbase Exchange public REST API for BTC-USD. Before writing any code against it, we read Coinbase's [Market Data Terms of Use](https://www.coinbase.com/legal/market_data), which forbid redistributing or displaying Market Data — including from the free/public Exchange endpoints — to any third party outside the operator's own organization, and forbid building an application for end users other than the operator. A public Bullpen page serving BTC-USD prices to visitors is exactly the use those clauses block. Full detail in `docs/data-sources.md`. That ruled Coinbase out under this project's own guardrail ("if the market-data terms forbid public display, stop"), leaving issue #6 blocked pending a replacement provider whose terms explicitly permit public display with attribution.
Decision. Use CoinGecko's free Demo API (`api.coingecko.com/api/v3`) for BTC-USD. `docs/data-sources.md` records the terms version read (5 Sept 2025), the attribution rule, the no-redistribution clause, the cache-refresh rule, and the Demo plan's limits.