final spec.
This commit is contained in:
parent
7437f1b96b
commit
efb1eddf7a
16
CLAUDE.md
16
CLAUDE.md
@ -48,6 +48,12 @@ This project is end-to-end type-safe. Every boundary is validated:
|
||||
- **shadcn/ui first.** Before building a custom component, check if shadcn/ui has one. Use their chart components (Recharts wrappers) for all data visualization.
|
||||
- **Responsive.** Everything should work on desktop and tablet at minimum.
|
||||
|
||||
### Timestamps & Timezones
|
||||
|
||||
- **Store everything in UTC.** All `TIMESTAMPTZ` columns, all in-memory dates, all API responses — UTC.
|
||||
- **Display in market-local time.** ERCOT → Central, PJM → Eastern, CAISO → Pacific. Convert only at the render layer.
|
||||
- **Use `formatMarketTime(utcDate, regionCode)`** — a shared utility in `src/lib/utils.ts` for consistent display.
|
||||
|
||||
### Performance
|
||||
|
||||
- **Server Components by default.** Only use `"use client"` when you need interactivity (maps, charts, forms, animations).
|
||||
@ -55,6 +61,13 @@ This project is end-to-end type-safe. Every boundary is validated:
|
||||
- **Don't fetch in loops.** Batch database queries. Use PostGIS spatial joins instead of N+1 queries.
|
||||
- **Lazy load heavy components.** Google Maps, Recharts — use `next/dynamic` with `ssr: false` where appropriate.
|
||||
|
||||
### Testing
|
||||
|
||||
- **No unit tests.** They devolve into testing constants and mocking everything. Useless.
|
||||
- **Integration tests only.** Test the real pipeline: API → Zod → Postgres → query → typed result. Against the real database.
|
||||
- **E2E smoke tests.** Every page renders, map loads, charts display data, no console errors.
|
||||
- **The minimum bar** for any task: `bunx tsc --noEmit` passes, `bun run lint` passes, the page renders with real data.
|
||||
|
||||
## Tech Stack & Constraints
|
||||
|
||||
| Concern | Choice | Notes |
|
||||
@ -68,6 +81,7 @@ This project is end-to-end type-safe. Every boundary is validated:
|
||||
| **Database** | PostgreSQL 18 + PostGIS 3.5 | Docker Compose. **Port 5433** (5432 is taken). |
|
||||
| **ORM** | Prisma 7.x with TypedSQL | `.sql` files in `prisma/sql/` for geo queries. |
|
||||
| **Charts** | Recharts via shadcn/ui chart components | Consistent theming out of the box. |
|
||||
| **Serialization** | `superjson` | Preserves `Date`, `BigInt`, `Map`, `Set` across server→client. Required for all Server Actions and temporal data. |
|
||||
| **Animations** | `framer-motion` | For number transitions, pulse effects, etc. |
|
||||
| **Toasts** | `sonner` | For price spike notifications. |
|
||||
|
||||
@ -78,7 +92,7 @@ These config files are already in the project root with the user's preferred set
|
||||
- `.prettierrc.js` — Prettier configuration
|
||||
- `eslint.config.js` — ESLint configuration
|
||||
- `tsconfig.json` — TypeScript configuration
|
||||
- `.env` — API keys (Google Maps, EIA, FRED). **Never log, commit, or expose these.**
|
||||
- `.env` — API keys (Google Maps key, Google Maps Map ID, EIA, FRED). **Never log, commit, or expose these.**
|
||||
|
||||
When scaffolding the Next.js project, you must integrate with these existing configs, not replace them. Install whatever dependencies they require.
|
||||
|
||||
|
||||
103
ORCHESTRATOR.md
103
ORCHESTRATOR.md
@ -57,28 +57,63 @@ Spawn multiple builders working on independent tracks. Use one or two reviewers
|
||||
|
||||
If a teammate makes a creative decision that contradicts `SPEC.md`, the spec wins. If something isn't in the spec and the teammate adds it anyway, that's scope creep — redirect them. If the spec is genuinely wrong or incomplete, update the spec *first*, then proceed.
|
||||
|
||||
## Research First, Build Second
|
||||
|
||||
The single biggest cause of wasted work is a Builder starting a task without enough information. They guess at an API response format, write code around the guess, and then it all falls apart when the real data looks different. This applies everywhere:
|
||||
|
||||
- **APIs**: What does the EIA `/electricity/rto` endpoint actually return? What are the exact field names? What does pagination look like? Don't guess — send a Researcher to make a real request and document the response shape.
|
||||
- **Libraries**: How does `@vis.gl/react-google-maps` handle AdvancedMarker clustering? What props does it take? Don't guess — send a Researcher to read the docs and return a concrete code example.
|
||||
- **Data**: What do ISO/RTO boundary polygons actually look like in GeoJSON? How big are the files? What coordinate system? Don't guess — send a Researcher to find and download the actual files.
|
||||
- **Seed data**: Datacenter locations need real research — operator, capacity in MW, year opened, exact coordinates. This isn't something a Builder can make up. It requires scraping DataCenterMap.com, cross-referencing press releases, and producing a verified GeoJSON file.
|
||||
- **Compatibility**: Does Prisma 7.x TypedSQL work with PostGIS geography columns? Does `bun` resolve `@vis.gl/react-google-maps` peer dependencies correctly? Don't assume — verify before building.
|
||||
|
||||
**Rule: No Builder should start a task that depends on external data or library behavior unless a Researcher has already produced verified documentation for it.** This might feel slow. It is not slow — it prevents the much slower cycle of build → discover wrong assumption → debug → rewrite.
|
||||
|
||||
### The Persistent Researcher
|
||||
|
||||
Unlike Builders and Reviewers who work on specific tasks, the **Researcher** is a shared resource that should persist across the life of a team. Any teammate — Builder, Reviewer, or Tester — should be able to message the Researcher to ask questions:
|
||||
|
||||
- A Builder hitting an unfamiliar API can message the Researcher: "What does the EIA generation endpoint return for CAISO? I need the exact field names."
|
||||
- A Reviewer unsure if a TypedSQL pattern is correct can message the Researcher: "Can TypedSQL infer return types from `ST_AsGeoJSON()`? What type does it produce?"
|
||||
- A Tester seeing unexpected data can message the Researcher: "Is Henry Hub natural gas price supposed to be in $/MMBtu or $/MWh?"
|
||||
|
||||
**Spawn the Researcher early** in each phase and keep them alive for the duration. Give them this prompt context: "You are the team's Researcher. Any teammate can message you with questions about APIs, libraries, data formats, or compatibility. Your job is to investigate quickly and return concrete, verified answers — not guesses. Include source URLs. If you're unsure, say so and explain what you'd need to verify." The Researcher's name should be consistent (e.g., `researcher`) so teammates always know who to message.
|
||||
|
||||
### Pre-Phase Research Checklist
|
||||
|
||||
Before any build phase begins, ensure a Researcher has verified:
|
||||
|
||||
1. **API response shapes** — Real responses (not just docs), with exact field names and types
|
||||
2. **Library APIs** — Exact imports, component props, hook signatures, verified working examples
|
||||
3. **Data formats** — Actual file contents (not just descriptions), validated against what the code expects
|
||||
4. **Version compatibility** — That the specific versions of interacting libraries work together
|
||||
5. **Environment** — That required env vars exist and have valid values (e.g., `DATABASE_URL` should be `postgresql://energy:${POSTGRES_PASSWORD}@localhost:5433/energy_dashboard`)
|
||||
|
||||
If any of these are unverified, the build will hit surprises. Surprises waste time.
|
||||
|
||||
## Team Structure
|
||||
|
||||
### Hats
|
||||
|
||||
When spawning a teammate, include their hat in the prompt so they know their role:
|
||||
|
||||
**Builder** — Writes code. Implements features to spec. Reports what they built and any judgment calls they made. Does NOT verify their own work. Should read `SPEC.md` for context on what they're building and why.
|
||||
**Builder** — Writes code. Implements features to spec. Reports what they built and any judgment calls they made. Does NOT verify their own work. Should read `SPEC.md` for context on what they're building and why. Can message the Researcher when hitting unfamiliar territory.
|
||||
|
||||
**Reviewer** — Reads code written by others. Verifies it matches the spec. Runs `bunx tsc --noEmit` for type errors. Runs `bun run lint` for lint errors. Checks imports, checks that files exist, checks edge cases. Reports findings honestly — "it compiles and matches spec" or "three issues found: ..." A good reviewer is skeptical by default.
|
||||
**Reviewer** — Reads code written by others. Verifies it matches the spec. Runs `bunx tsc --noEmit` for type errors. Runs `bun run lint` for lint errors. Checks imports, checks that files exist, checks edge cases. Reports findings honestly — "it compiles and matches spec" or "three issues found: ..." A good reviewer is skeptical by default. Can message the Researcher to verify assumptions.
|
||||
|
||||
**Researcher** — Investigates external resources: API documentation, library docs, data formats, version compatibility. Returns structured findings (tables, code examples, concrete answers), not vague prose. Use researchers before a build phase to answer open questions.
|
||||
**Researcher** — The team's knowledge base. Investigates APIs, docs, data formats, version compatibility. Returns structured findings (tables, code examples, concrete answers with source URLs), not vague prose. Persists for the life of the team. Any teammate can message the Researcher directly for quick answers. Proactively investigates open questions at the start of each phase.
|
||||
|
||||
**Tester** — Runs the application and verifies behavior. Uses `agent-browser` to check that pages render, maps load, data appears, interactions work. Reports what they actually see (snapshots), not what they expect to see. A tester who says "looks good" without a snapshot is not doing their job.
|
||||
**Tester** — Runs the application and verifies behavior. Uses `agent-browser` to check that pages render, maps load, data appears, interactions work. Reports what they actually see (snapshots), not what they expect to see. A tester who says "looks good" without a snapshot is not doing their job. Can message the Researcher to clarify expected behavior.
|
||||
|
||||
### Team Sizing
|
||||
|
||||
- **Small phase** (2-3 tasks): 1 Builder + 1 Reviewer
|
||||
- **Medium phase** (4-6 tasks): 2 Builders + 1 Reviewer
|
||||
- **Large phase** (7+ tasks): 2-3 Builders + 1 Reviewer + 1 Tester
|
||||
- **Research-heavy prep**: 1-2 Researchers (before the build phase starts)
|
||||
- **Every team**: 1 Researcher (persistent, shared)
|
||||
- **Small phase** (2-3 tasks): + 1 Builder + 1 Reviewer
|
||||
- **Medium phase** (4-6 tasks): + 2 Builders + 1 Reviewer
|
||||
- **Large phase** (7+ tasks): + 2-3 Builders + 1 Reviewer + 1 Tester
|
||||
- **Research-heavy prep**: 2 Researchers running in parallel (e.g., one on APIs, one on seed data)
|
||||
|
||||
The Reviewer should be the most trusted agent on the team. They are your eyes. A weak reviewer means you're blind.
|
||||
The Reviewer should be the most trusted agent on the team. They are your eyes. A weak reviewer means you're blind. The Researcher is the foundation — bad research cascades into bad code everywhere.
|
||||
|
||||
## Verification Protocol
|
||||
|
||||
@ -130,7 +165,13 @@ For each phase from `SPEC.md`:
|
||||
- Fix issues before moving on
|
||||
- For UI phases, do a full browser test at the end
|
||||
|
||||
### 5. Close
|
||||
### 5. Commit
|
||||
- After verification passes, have the Reviewer (or a Builder) commit the phase's work with a clear message
|
||||
- Commit message should summarize the phase: `"phase 1: foundation — next.js 16 scaffold, prisma schema, docker compose, seed data"`
|
||||
- Commit at the *phase* boundary at minimum. For large phases, commit after each major track is verified.
|
||||
- Local commits only — **do NOT push**. These are rollback points, not publishing.
|
||||
|
||||
### 6. Close
|
||||
- Mark all tasks complete
|
||||
- Write a 2-3 sentence phase summary (what was built, any notable decisions)
|
||||
- Shut down the team
|
||||
@ -144,12 +185,42 @@ For each phase from `SPEC.md`:
|
||||
- **Stuck agent**: Get a status update. If they can't articulate what's blocking them, reassign the task to a fresh agent with clearer instructions.
|
||||
- **Flaky verification**: If a Reviewer keeps saying things are fine and they're not, replace the Reviewer. Your verification chain is only as strong as its weakest link.
|
||||
|
||||
## Environment Setup Note
|
||||
|
||||
The `.env` file has the Google Maps keys and API keys but will need database connection vars derived from the Docker Compose config. The Builder handling Docker Compose and Prisma setup should add these to `.env`:
|
||||
|
||||
```
|
||||
DATABASE_URL="postgresql://energy:${POSTGRES_PASSWORD}@localhost:5433/energy_dashboard"
|
||||
POSTGRES_PASSWORD="<generate a random password>"
|
||||
```
|
||||
|
||||
The `POSTGRES_PASSWORD` is used by both Docker Compose and the `DATABASE_URL`. Make sure they match.
|
||||
|
||||
## Phase Summary (from SPEC.md)
|
||||
|
||||
1. **Foundation** — Scaffold Next.js 16 in /tmp, copy into project dir, integrate existing configs, Docker Compose, Prisma schema, PostGIS extension, seed data
|
||||
2. **Data Layer** — EIA + FRED API clients with Zod, TypedSQL queries for PostGIS, Server Actions, ingestion routes
|
||||
3. **Dashboard UI** — Layout/nav, dashboard home with metrics + sparklines, Google Maps with markers and region overlays, click interactions
|
||||
4. **Charts & Analysis** — Price trends (Recharts), demand analysis, generation mix, AI milestone annotations, correlation views
|
||||
5. **Polish** — Real-time candy (ticker, pulses, gauges, calculator, toasts, countdown), responsive design, loading states, error boundaries, disclaimers, summary doc, README
|
||||
### Phase 1: Foundation
|
||||
**Research first**: Researcher(s) curate seed data (datacenter GeoJSON, ISO boundary GeoJSON, AI milestones JSON) in parallel with scaffold/config work.
|
||||
**Build**: Scaffold Next.js 16, integrate existing configs, Docker Compose, Prisma schema, seed script.
|
||||
**Verify**: Project builds, lints clean, dev server starts, database has seed data.
|
||||
|
||||
Each phase is its own team. Clean shutdown between phases. No cross-phase state leakage.
|
||||
### Phase 2: Data Layer
|
||||
**Research first**: Researcher makes real EIA and FRED API calls, documents exact response shapes, field names, pagination behavior. Verifies TypedSQL works with PostGIS column types.
|
||||
**Build**: API clients with Zod, TypedSQL queries, Server Actions with superjson, ingestion routes, backfill script.
|
||||
**Verify**: Integration test — full pipeline from API → Zod → Postgres → Server Action → typed result with correct dates.
|
||||
|
||||
### Phase 3: Dashboard UI
|
||||
**Research first**: Researcher verifies `@vis.gl/react-google-maps` AdvancedMarker API, clustering behavior, polygon overlay approach. Confirms Map ID and terrain dark styling work.
|
||||
**Build**: Layout, dashboard home, Google Maps with markers and region overlays, click interactions.
|
||||
**Verify**: E2E — every page renders, map loads with markers, regions are colored, click interactions work.
|
||||
|
||||
### Phase 4: Charts & Analysis
|
||||
**Research first**: Researcher verifies shadcn/ui chart component API, Recharts multi-axis support, annotation patterns.
|
||||
**Build**: Price trends, commodity overlay, demand analysis, generation mix, AI milestone annotations, correlation view.
|
||||
**Verify**: Charts render with real data, time range selectors work, annotations appear at correct dates.
|
||||
|
||||
### Phase 5: Polish & Real-Time Candy
|
||||
**Research first**: Researcher verifies framer-motion spring animation API, sonner toast configuration, requestAnimationFrame patterns for countdown.
|
||||
**Build**: Ticker tape, pulsing markers, GPU calculator, grid stress gauges, toasts, auto-refresh, ambient glow, responsive, loading/error states, disclaimer, README.
|
||||
**Verify**: Full E2E walkthrough — every page, every interaction, every animation, on desktop and tablet.
|
||||
|
||||
Each phase is its own team. Clean shutdown between phases. No cross-phase state leakage. **Every phase starts with research.**
|
||||
|
||||
133
SPEC.md
133
SPEC.md
@ -83,11 +83,13 @@ We use two categories of data: real-time feeds from government APIs (free, relia
|
||||
|
||||
### Static / Seed Data
|
||||
|
||||
| Source | Data | Why |
|
||||
|--------|------|-----|
|
||||
| **DataCenterMap / manual curation** | Datacenter locations (lat/lng, operator, capacity MW) | The core geospatial layer. PostGIS Point geometries enable spatial queries (nearby DCs, DCs in region, clustering). |
|
||||
| **EIA / ISO boundaries** | Grid region polygons (PJM, ERCOT, CAISO, etc.) | PostGIS MultiPolygon geometries enable the price heatmap overlay and spatial joins between DCs and regions. |
|
||||
| **AI milestones** | Timeline of major AI announcements | Chart annotations that tell the story — "here's when ChatGPT launched, here's when prices started climbing." Turns data into narrative. |
|
||||
This data requires upfront research and curation. A Researcher agent should compile these datasets during Phase 1, producing clean JSON/GeoJSON files that the seed script can ingest.
|
||||
|
||||
| Source | Data | Format | Why |
|
||||
|--------|------|--------|-----|
|
||||
| **DataCenterMap / manual curation** | Datacenter locations (lat/lng, operator, capacity MW, year opened) | GeoJSON `FeatureCollection` of Points | The core geospatial layer. PostGIS Point geometries enable spatial queries (nearby DCs, DCs in region, clustering). Needs real research — scrape DataCenterMap.com, cross-reference with public announcements for major hyperscaler facilities. |
|
||||
| **EIA / ISO boundaries** | Grid region polygons (PJM, ERCOT, CAISO, NYISO, ISONE, MISO, SPP) | GeoJSON `FeatureCollection` of MultiPolygons | PostGIS MultiPolygon geometries enable the price heatmap overlay and spatial joins between DCs and regions. EIA and HIFLD provide these boundary files. |
|
||||
| **AI milestones** | Timeline of major AI announcements with dates and descriptions | JSON array | Chart annotations that tell the story — "here's when ChatGPT launched, here's when prices started climbing." Turns data into narrative. |
|
||||
|
||||
## Database Schema (PostgreSQL + PostGIS)
|
||||
|
||||
@ -213,7 +215,7 @@ On the map, grid region polygons don't just use static fill colors — they have
|
||||
- **Quick map preview**: Thumbnail of the full map with DC hotspots
|
||||
|
||||
### 2. Interactive Map (`/map`)
|
||||
- **Google Maps** with custom styling (dark theme)
|
||||
- **Google Maps** with terrain dark styling (Map ID configured in Google Cloud Console, stored in `.env` as `NEXT_PUBLIC_GOOGLE_MAP_ID`)
|
||||
- **Datacenter markers**: Clustered markers sized by capacity (MW), colored by operator
|
||||
- **Regional overlays**: Grid region polygons colored by current electricity price (heatmap)
|
||||
- **Click interactions**: Click a region to see detail panel (prices, demand, generation mix, DC list)
|
||||
@ -314,7 +316,11 @@ bonus4/
|
||||
│ └── types/
|
||||
│ └── index.ts # Shared type definitions
|
||||
├── scripts/
|
||||
│ └── seed-datacenters.ts # One-time seed script for DC location data
|
||||
│ └── backfill.ts # One-time historical data backfill (idempotent)
|
||||
├── data/ # Curated seed data files
|
||||
│ ├── datacenters.geojson # Datacenter locations
|
||||
│ ├── grid-regions.geojson # ISO/RTO boundary polygons
|
||||
│ └── ai-milestones.json # Timeline of major AI announcements
|
||||
├── Assignment.md
|
||||
├── CLAUDE.md
|
||||
└── SPEC.md
|
||||
@ -341,6 +347,18 @@ volumes:
|
||||
|
||||
Port **5433** externally (5432 is occupied by another project).
|
||||
|
||||
## Timezone Strategy
|
||||
|
||||
All timestamps are stored and processed in **UTC**. Period.
|
||||
|
||||
- **Database**: All `TIMESTAMPTZ` columns store UTC. PostgreSQL handles this natively.
|
||||
- **EIA API**: Returns UTC — no conversion needed at ingestion.
|
||||
- **FRED API**: Returns date-only strings (no timezone) — treat as UTC midnight.
|
||||
- **Display**: Convert to the relevant market's local time only at render time. ERCOT → Central, PJM → Eastern, CAISO → Pacific. Use a shared `formatMarketTime(utcDate, regionCode)` utility.
|
||||
- **Charts**: X-axis labels show market-local time with timezone abbreviation (e.g., "2:00 PM CT").
|
||||
|
||||
Energy markets care deeply about local time — a 3pm demand spike in Texas means something different than 3pm UTC. But internal consistency requires UTC everywhere except the final display layer.
|
||||
|
||||
## Data Ingestion Strategy
|
||||
|
||||
The dashboard needs to feel live without hammering external APIs. The strategy is: fetch once, cache in Postgres, serve from cache, refresh on a schedule.
|
||||
@ -350,40 +368,93 @@ The dashboard needs to feel live without hammering external APIs. The strategy i
|
||||
3. **Seed data**: Datacenter locations and grid region boundaries are relatively static. Loaded via `prisma db seed` from curated JSON/GeoJSON files.
|
||||
4. **Rate limit awareness**: EIA allows ~9k req/hr (generous), FRED allows 120/min. With caching, we'll typically make <100 EIA requests/hour even under heavy use. The real bottleneck is EIA's 5,000-row-per-query limit — pagination handled in the API client.
|
||||
|
||||
### Historical Backfill
|
||||
|
||||
On first run, the database is empty and the charts have nothing to show. The ingestion routes must support a **backfill mode** that pulls 6-12 months of historical data:
|
||||
|
||||
- **EIA bulk download**: Use the EIA's bulk data endpoints (no API key required for bulk CSVs) to pull historical electricity prices, demand, and generation mix. Parse and upsert into Postgres. This is a one-time operation run via a script, not on every startup.
|
||||
- **FRED historical**: FRED supports date range queries — pull the full series in one request per commodity.
|
||||
- **Backfill script**: `scripts/backfill.ts` — a standalone script that populates historical data. Run once after the initial migration. Should be idempotent (safe to re-run).
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
**No unit tests.** Unit tests in a project like this devolve into testing constants and mocking everything — they verify nothing useful and waste time. Instead:
|
||||
|
||||
### Integration Tests
|
||||
- Test the real data pipeline: EIA API → Zod validation → Postgres upsert → query → typed result
|
||||
- Test TypedSQL queries against an actual PostGIS database (use the Docker Compose instance)
|
||||
- Test Server Actions return correctly shaped data with superjson serialization intact
|
||||
- Use `bun test` with the built-in test runner
|
||||
|
||||
### E2E Tests
|
||||
- Test that each page renders without crashing
|
||||
- Test that the map loads with markers
|
||||
- Test that charts render with data
|
||||
- Test navigation between pages
|
||||
- Use Playwright (or `agent-browser` for manual verification during development)
|
||||
|
||||
### Smoke Test (minimum bar)
|
||||
At the very least, every page must:
|
||||
1. Render without a React error boundary firing
|
||||
2. Show real data (not just loading spinners)
|
||||
3. Have no TypeScript errors (`bunx tsc --noEmit`)
|
||||
4. Have no lint errors (`bun run lint`)
|
||||
|
||||
The Reviewer and Tester agents enforce this on every task. This is the real test suite — humans (and agents) verifying actual behavior, not asserting that `true === true`.
|
||||
|
||||
## Implementation Phases
|
||||
|
||||
### Phase 1: Foundation
|
||||
- [ ] Scaffold Next.js 16 project
|
||||
- [ ] Copy into bonus4 dir, integrate existing prettier/eslint/tsconfig
|
||||
- [ ] Install and configure shadcn/ui + Tailwind 4
|
||||
- [ ] Docker Compose for PostgreSQL 18 + PostGIS
|
||||
- [ ] Prisma schema + initial migration (with PostGIS extension)
|
||||
- [ ] Seed datacenter locations + grid region boundaries
|
||||
- [ ] Scaffold Next.js 16 project (in /tmp, then copy into bonus4 dir)
|
||||
- [ ] Integrate existing prettier/eslint/tsconfig — install their deps, verify they work
|
||||
- [ ] Install and configure shadcn/ui + Tailwind 4 (dark theme)
|
||||
- [ ] Docker Compose for PostgreSQL 18 + PostGIS 3.5
|
||||
- [ ] Prisma schema + initial migration (with `CREATE EXTENSION postgis`)
|
||||
- [ ] **Research & curate seed data** (parallelizable with the above):
|
||||
- Datacenter locations GeoJSON (DataCenterMap.com, public announcements)
|
||||
- ISO/RTO boundary polygons GeoJSON (EIA, HIFLD)
|
||||
- AI milestones timeline JSON
|
||||
- [ ] Seed script (`prisma db seed`) to load curated data
|
||||
- [ ] `.gitignore` (node_modules, .next, .env, pgdata, etc.)
|
||||
- [ ] `git init` + initial commit
|
||||
- [ ] Verify: project builds, lints clean, database has seed data, dev server starts
|
||||
|
||||
### Phase 2: Data Layer
|
||||
- [ ] EIA API client with Zod validation
|
||||
- [ ] EIA API client with Zod validation (electricity prices, demand, generation)
|
||||
- [ ] EIA commodity client (natural gas, oil, coal)
|
||||
- [ ] FRED API client with Zod validation
|
||||
- [ ] Historical backfill script (`scripts/backfill.ts`) — bulk download 6-12 months, idempotent
|
||||
- [ ] TypedSQL queries for all geospatial operations
|
||||
- [ ] Server actions for data access (typed server→client boundary)
|
||||
- [ ] Ingestion API routes
|
||||
- [ ] Server Actions with superjson for typed server→client data passing
|
||||
- [ ] Ingestion API routes (`/api/ingest/*`)
|
||||
- [ ] Integration test: full pipeline from API fetch → Postgres → Server Action → typed result
|
||||
|
||||
### Phase 3: Dashboard UI
|
||||
- [ ] App layout (nav, sidebar, footer)
|
||||
- [ ] Dashboard home with metric cards + sparklines
|
||||
- [ ] Google Maps integration with datacenter markers
|
||||
- [ ] Region polygon overlays with price heatmap coloring
|
||||
- [ ] App layout (nav with ticker tape slot, sidebar, footer with disclaimer)
|
||||
- [ ] Dashboard home with metric cards + animated number transitions
|
||||
- [ ] Google Maps integration (terrain dark Map ID, centered on US)
|
||||
- [ ] Datacenter markers (AdvancedMarker, clustered, sized by capacity)
|
||||
- [ ] Region polygon overlays with price-based fill coloring
|
||||
- [ ] Click interactions (region detail panel, DC detail panel)
|
||||
- [ ] E2E smoke test: every page renders, map loads, markers visible
|
||||
|
||||
### Phase 4: Charts & Analysis
|
||||
- [ ] Price trend charts (Recharts via shadcn/ui)
|
||||
- [ ] Demand analysis views
|
||||
- [ ] Generation mix charts
|
||||
- [ ] AI milestone annotations
|
||||
- [ ] Correlation views
|
||||
- [ ] Price trend charts (Recharts via shadcn/ui, multi-line, time range selector)
|
||||
- [ ] Commodity overlay (natural gas / oil on secondary axis)
|
||||
- [ ] Demand analysis views (regional growth, peak tracking)
|
||||
- [ ] Generation mix charts (stacked area by fuel type)
|
||||
- [ ] AI milestone annotations (vertical markers on charts)
|
||||
- [ ] Correlation view (scatter: DC capacity vs regional price)
|
||||
|
||||
### Phase 5: Polish
|
||||
- [ ] Responsive design
|
||||
- [ ] Loading states + error boundaries
|
||||
- [ ] Disclaimers (educational/informational purposes)
|
||||
- [ ] One-page summary document
|
||||
- [ ] README with installation docs
|
||||
### Phase 5: Polish & Real-Time Candy
|
||||
- [ ] Live price ticker tape (scrolling banner, every page)
|
||||
- [ ] Pulsing map markers (price deviation triggers pulse)
|
||||
- [ ] GPU cost calculator widget (live, slider for GPU count)
|
||||
- [ ] Grid stress gauges (radial, per region)
|
||||
- [ ] Price spike toasts (sonner notifications)
|
||||
- [ ] Auto-refresh with countdown timer
|
||||
- [ ] Ambient region glow (breathing animation)
|
||||
- [ ] Responsive design (desktop + tablet)
|
||||
- [ ] Loading states (`loading.tsx`) + error boundaries (`error.tsx`)
|
||||
- [ ] Disclaimer footer (educational/informational purposes, not financial advice)
|
||||
- [ ] README with installation and setup docs
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user