Back to Research Hub
Build guide
MVP Dashboard Build Guide - What We're Building, Steps, and AI Prompts
RWRaylen Williams · Sep 28, 2026
mvpdashboardarchitectureai-promptsbuild-planingestion
Summary
This is our #1 priority now: the dashboard Shell told us to build first. Before we hand anything to an AI coding tool, here's what FluxView v1 actually is, why it's built in this order, and the exact prompts to paste in for each piece - so we understand what we're shipping, not just what the AI wrote.
Key findings
- What FluxView actually is, in one sentence: a dashboard that ingests our 8 flux towers' CSV data, stores it cleanly, and shows it as simple current-conditions cards + historical trend charts - not a chatbot, and not the forecasting piece (that's phase 2, later).
- Every dashboard like this has 4 layers - knowing them is how we catch an AI getting something wrong instead of just trusting it: (1) Ingestion - turning raw CSV rows into clean database rows, (2) Storage/schema - the database table that remembers every reading with its timestamp, tower, and quality flag, (3) Data layer - code that answers a question like "give me tower 002's soil moisture for the last 30 days," (4) Frontend - the actual pages and charts a user sees.
- Step 1 - Stack: reuse what we already know from ProjectPulse (Next.js + Supabase Postgres + Vercel) instead of learning a brand new stack under time pressure.
- Step 2 - Schema: one single "readings" table with a tower_id column and a granularity column ('30min' or 'daily'), not 8 separate tables per tower - this is what makes a "compare Tower A vs Tower B" chart possible later without rebuilding anything.
- Step 3 - Ingestion: parse the daily CSVs first (small, ~150-250KB each) since that's all the home page needs; add the 30-min files later for zoomed-in detail views. Every row keeps its QC flag - never trust a raw number blindly.
- Step 4 - Current Conditions home view (FR3): one card per tower showing the latest reading for our 3 priority groups only - weather, soil moisture, carbon exchange - not a wall of every column in the CSV.
- Step 5 - Historical Trends view (FR4): pick a tower, pick a date range, see a line chart per priority variable, built off the daily data.
- Step 6 - Mobile-responsive from day one (FR8): check it on a phone-sized screen as you build each piece, don't leave it for the end.
- Step 7 - stretch goals, not this pass: CSV export (FR5) and alert thresholds (FR6/FR7). Get the core dashboard working and demo-able first.
- This exact order matches what Shell told us on the call: visualization before prediction, and weather/soil moisture/carbon exchange before every other variable.
- AI PROMPT 1 - Database schema + ingestion script (paste this whole line into Claude Code, Cursor, or similar): Design a Postgres schema and a TypeScript ingestion script for environmental sensor data from 8 flux towers (IDs 001, 002, 003, 004, 005, 006, 013, 014). Each tower has two CSV file types, a 30-minute file and a daily file, both sharing these columns: TIMESTAMP (30-min files also have STARTING_DATETIME, MIDPOINT_DATETIME, ENDING_DATETIME), NET_CARBON_DIOXIDE_FLUX, GPP, RECO, SENSIBLE_HEAT_FLUX, LATENT_HEAT_FLUX, EVAPOTRANSPIRATION, SOIL_HEAT_FLUX, NET_RADIATION, INCOMING_SHORTWAVE_RADIATION, OUTGOING_SHORTWAVE_RADIATION, INCOMING_LONGWAVE_RADIATION, OUTGOING_LONGWAVE_RADIATION, AIR_TEMPERATURE, SOIL_TEMPERATURE, AIR_PRESSURE, RELATIVE_HUMIDITY, VAPOUR_PRESSURE_DEFICIT, RAINFALL, SOIL_MOISTURE, WIND_SPEED, WIND_DIRECTION, plus a _FLAG column for several of those fields and the literal string "NA" for missing values. Create one single "readings" table with a tower_id column and a granularity column ('30min' or 'daily') instead of one table per tower, so we can query across towers later. Then write a script that reads a folder of these CSVs, keeps timestamps exactly as provided with no timezone conversion, inserts rows in batches, stores each _FLAG value alongside its reading, and null-flags or skips rows where a key field is "NA" instead of crashing. Explain each schema decision as you go so we understand why, not just what.
- AI PROMPT 2 - Current Conditions home page (paste this whole line): Build a Next.js dashboard home page called "Current Conditions" that shows, for each of our 8 flux towers, the single latest reading for air temperature, rainfall, relative humidity, soil moisture, and NET_CARBON_DIOXIDE_FLUX (label this last one "Carbon Exchange" with a short note that negative means the land is absorbing CO2 and positive means it's releasing it). Show each tower as its own card using the tower's plot name if we have one (e.g. "Sorghum Control", "Pasture-Treatment-1"), otherwise its tower ID. Include a clear "last updated" timestamp per card and a friendly empty state ("No data yet for this tower") instead of crashing when a tower has no rows. Make the layout fully responsive down to a phone-width screen with no horizontal scrolling.
- AI PROMPT 3 - Historical Trends page (paste this whole line): Build a "Historical Trends" page in the same Next.js app with a dropdown to pick one of our 8 flux towers, a date-range picker defaulting to the last 30 days, and a line chart for each of these variables plotted over the selected range: AIR_TEMPERATURE, RAINFALL, SOIL_MOISTURE, and NET_CARBON_DIOXIDE_FLUX. Pull data from the "readings" table filtered by tower_id, granularity = 'daily', and the selected date range. Filter out any row whose relevant _FLAG marks it as bad quality before charting it. Show a loading state while data is fetching and an empty state if the range has no data. Keep the page mobile-responsive like the home page.
- Before you paste any of these in: check what the AI gives back against the 4-layer breakdown above. If it invents a separate table per tower, ignores the QC flags, or skips the mobile layout, that's your cue to push back and ask it to redo that specific piece - not just accept it because it compiles.
Part of the Shell NET–PVAMU Research Hub.