7.1 KiB
Bonus Assignment 4 — Energy & AI Dashboard
This project builds a real-time interactive dashboard showing how AI datacenter buildout is driving regional electricity demand and energy prices across the US. Read SPEC.md in full before starting any work — it contains the business case, technical architecture, database schema, and implementation phases. Understanding why this dashboard exists (not just what it does) will make your code better.
Rules (NON-NEGOTIABLE)
- You will NOT create a github repository, push code, or deploy ANYTHING.
- You will NOT publish the code anywhere.
- You will NOT make this code public in any way.
This is the local development portion only. No deployment. No public repos. No exceptions.
Read the Spec
Before writing a single line of code, read SPEC.md cover to cover. Every agent on this project — orchestrator, builder, reviewer, tester — should understand:
- The business case: AI datacenters are reshaping US energy markets. This isn't a toy dashboard — it's a tool for people making billion-dollar infrastructure decisions.
- The user: Energy investors, utility analysts, datacenter site selectors. They need real-time visibility, not static reports.
- The real-time candy: The ticker tape, pulsing markers, GPU cost calculator, grid stress gauges — these are what make the dashboard feel alive. They're not afterthoughts.
Code that understands its purpose is better code. A developer who knows why the GPU cost calculator exists will make better implementation decisions than one who's just following a component spec.
Code Standards
Type Safety is Non-Negotiable
This project is end-to-end type-safe. Every boundary is validated:
- External APIs (EIA, FRED): Zod schemas validate every response. Never trust untyped JSON.
- Database: Prisma generates types for standard CRUD. TypedSQL generates typed wrappers for PostGIS queries.
- Server → Client: Server Actions and Server Components pass typed props. No
anyleaking across the boundary. - Serialization: Use
superjsonfor all server-to-client data passing. React's default serialization silently convertsDateobjects to strings,Mapto{},Setto{}, etc. — but TypeScript still thinks they're the original type. This is a silent type lie.superjsonpreservesDate,BigInt,Map,Set,RegExp,undefined, and other types across the wire. Wrap Server Action returns and component props through superjson serialize/deserialize. This is especially critical for this project — almost every data point has a timestamp. - No
any. Noas unknown as X. No@ts-ignore. No// @ts-expect-error. If you can't type it, you don't understand it well enough yet.
Write Clean Code
- Meaningful names.
getRegionPriceHeatmap, notgetData.datacenterMarkerPulseAnimation, notanim1. - Small functions. If a function does more than one thing, split it.
- Co-locate related code. A component's types, helpers, and styles should live near the component.
- No dead code. Don't comment things out "for later." Delete it. Git has history.
- Handle errors at the boundaries. Zod parse failures, API timeouts, database connection errors — handle them where they occur, with meaningful messages. Don't let errors propagate silently.
- Follow existing patterns. Before creating something new, check if there's already a pattern in the codebase for it. Consistency matters more than personal preference.
Styling
- Dark theme only. Every component should look great on a dark background.
- Tailwind 4 only. No inline styles. No CSS modules. Use Tailwind utility classes and shadcn/ui component variants.
- 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.
Performance
- Server Components by default. Only use
"use client"when you need interactivity (maps, charts, forms, animations). - Cache aggressively. Use Next.js 16's
"use cache"directive for data that doesn't change every request. - 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/dynamicwithssr: falsewhere appropriate.
Tech Stack & Constraints
| Concern | Choice | Notes |
|---|---|---|
| Package manager | bun |
Not npm, not yarn, not pnpm. Always bun. |
| Python | uv |
If any Python is needed, always use uv. |
| Framework | Next.js 16 | App Router. Turbopack. "use cache" directive. |
| Styling | Tailwind CSS 4 | CSS-first config. |
| Components | shadcn/ui | Latest, with tw-animate-css. |
| Maps | @vis.gl/react-google-maps |
Google's recommended React library. Use AdvancedMarker. |
| 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. |
| Animations | framer-motion |
For number transitions, pulse effects, etc. |
| Toasts | sonner |
For price spike notifications. |
Existing Files (Do NOT Overwrite)
These config files are already in the project root with the user's preferred settings:
.prettierrc.js— Prettier configurationeslint.config.js— ESLint configurationtsconfig.json— TypeScript configuration.env— API keys (Google Maps, 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.
Version Discipline
Use the latest stable versions of everything. There have been recent JS CVEs — do not pin to old versions out of habit. When installing a package, let bun resolve the latest. If a specific version is required for compatibility, document why.
Browser Automation
Use agent-browser for visual verification. Run agent-browser --help for all commands.
agent-browser connect 9222 # Connect to chromium
agent-browser open <url> # Navigate to page
agent-browser snapshot -i # Get interactive elements with refs
agent-browser click @e1 # Click element
agent-browser fill @e2 "text" # Fill input
Always re-snapshot after page changes to get fresh element refs.
Project Structure
See SPEC.md for the full directory tree. Key landmarks:
prisma/schema.prisma— Database schema (Prisma + PostGIS)prisma/sql/— TypedSQL query files for geospatial operationsprisma/seed.ts— Seed data (datacenter locations, grid boundaries, AI milestones)src/app/— Next.js App Router pagessrc/components/— React components (ui/, map/, charts/, dashboard/, layout/)src/lib/api/— EIA and FRED API clients with Zod schemassrc/actions/— Server Actions (typed server-to-client boundary)docker-compose.yml— PostgreSQL 18 + PostGIS 3.5