Skip to content

Claude/fix sdk json lock rc2mp#41

Open
OliTamrat wants to merge 65 commits intomainfrom
claude/fix-sdk-json-lock-Rc2mp
Open

Claude/fix sdk json lock rc2mp#41
OliTamrat wants to merge 65 commits intomainfrom
claude/fix-sdk-json-lock-Rc2mp

Conversation

@OliTamrat
Copy link
Copy Markdown
Owner

No description provided.

…, CI/CD, and functional search

- Add React ErrorBoundary component wrapping the app in layout.tsx
- Add /api/health endpoint returning status, timestamp, version, uptime
- Set up Vitest with 10 passing tests (data integrity, error boundary, health API)
- Add GitHub Actions CI workflow (test + build on push/PR to main)
- Make Header search bar functional with station/research/page filtering
- Remove fake notification badge; add tooltips to placeholder buttons
- Add CLAUDE.md with full audit summary and phased improvement roadmap
…eployment docs

- Add client-side logger utility (src/lib/logger.ts) with buffered log entries
- Add input validation/sanitization library (src/lib/validation.ts) with XSS protection
- Apply sanitization to Header search input
- Add CSP, X-Content-Type-Options, X-Frame-Options, Referrer-Policy headers in next.config.ts
- Add deployment documentation to README (Docker, Vercel, health check, testing)
- Add 7 validation tests (17 total tests passing)
- Update CLAUDE.md marking Phase 1 and Phase 2 complete
…a export

- Add SQLite database (better-sqlite3) with stations, readings, ingestion_log tables
- Add seed script (npm run db:seed) that migrates static data to DB (12 stations, 144 readings)
- Add GET /api/stations — list all stations with latest readings
- Add GET /api/stations/:id/history — time-series data with date range filtering
- Add GET /api/export — CSV and JSON data export with optional station filter
- Add POST /api/ingest — USGS NWIS real-time data ingestion with logging
- Update CLAUDE.md with Phase 3 architecture and Azure migration plan
- Update .gitignore to exclude SQLite database files
Frontend migration (Phase 3):
- StationTable fetches from /api/stations with loading state and static fallback
- MetricCards fetches from /api/stations, computes averages dynamically
- Station detail page fetches from /api/stations/:id/history and /api/export
- Export CSV button now wired to real /api/export endpoint

Phase 4 deliverables:
- Dockerfile (multi-stage: deps → build → runner with standalone output)
- docker-compose.yml with persistent volume for SQLite database
- .dockerignore for clean Docker builds
- CONTRIBUTING.md with setup guide, coding standards, API docs, workflow
- Architecture diagram (ASCII) added to README
- Updated tech stack table in README with SQLite and Vitest

17 tests passing, production build verified.
- Add 12 integration tests for API routes (29 total tests, 7 suites):
  - /api/stations: list all, validate fields, verify last readings
  - /api/stations/:id/history: full data, field types, 404 handling, date range, limit
  - /api/export: JSON export, station filter, CSV format/headers, empty results
- Add .env.example documenting DB_PATH, INGEST_API_KEY, DATABASE_URL
- Add rate limiting middleware (100 req/min per IP) for all API routes
- Add CORS configuration with UDC origin allowlist
- Add HSTS header for production deployments
- Require INGEST_API_KEY in production (503 if missing)
- Add data source attribution banner on dashboard
- Replace misleading "Real-Time Data" and "Live monitoring" labels
  with accurate "USGS Data Integration" and source descriptions
- Fix metadata description to remove "Real-time" claim
…tent

- db.ts: Create data/ directory if missing before opening SQLite database
- seed.ts: Create data/ directory if missing, clear existing seed data before
  re-seeding to prevent duplicate records on repeated runs
- ci.yml: Add db:seed step before running tests so API tests have data
… check

- Remove output: "standalone" (incompatible with Vercel serverless)
- Add vercel.json to bundle data/ dir with serverless functions
- Fix db.ts to copy SQLite DB to /tmp on Vercel (read-only filesystem)
- Seed DB at build time so it's bundled in the deployment
- Enhance /api/health to verify DB connectivity and station count
- Add USGS and CartoDB to CSP connect-src for client-side requests
…s-jJXP2

Claude/audit production readiness j jxp2
Migrate database layer to support both SQLite (local) and Neon PostgreSQL
(production/Vercel) via a unified async DbClient interface. When DATABASE_URL
is set, the app connects to Neon; otherwise falls back to SQLite.

- Add @neondatabase/serverless and ws packages
- Rewrite src/lib/db.ts with dual-backend DbClient abstraction
- Update all API routes (stations, history, export, health, ingest) to use async getDbClient()
- Update seed script to support both SQLite and PostgreSQL
- Health endpoint now reports database provider (sqlite vs neon-postgresql)
- Keep legacy getDb() for local SQLite tests
Establishes rules for Claude Code to never expose credentials in commits,
logs, or output, and to always include session attribution in commit messages.
…ations

- Replace site 01651750 (discontinued Oct 2017) with 01649500 (NE Branch
  Anacostia at Riverdale, active WQ monitoring) and 01646500 (Potomac at
  Little Falls, active with DO/pH/temp/conductivity)
- Add logging when a site returns no time series data
- Remove ineffective ON CONFLICT DO NOTHING clause (auto-increment PK)
…s-jJXP2

Claude/audit production readiness j jxp2
- Add crons config to vercel.json (schedule: 0 */6 * * *)
- Add GET handler to ingest route for Vercel Cron (uses CRON_SECRET)
- Refactor POST/GET to share runIngest() logic
- POST still works for manual triggers with INGEST_API_KEY
USGS readings may have null for eColiCount, conductivity, turbidity,
etc. Add null checks before calling .toLocaleString() and comparisons
in StationTable, station detail page, and map popups. Show "—" for
missing values instead of crashing.
…s-jJXP2

Claude/audit production readiness j jxp2
- Add vercel.live to script-src, connect-src, and frame-src in CSP headers
- Guard eColiCount null check in MetricCards to prevent toLocaleString crash
…s-jJXP2

Fix CSP to allow Vercel Live and fix null eColiCount crash
- Add null guards to all .toLocaleString() calls across DCMap, StationTable,
  and station detail page to prevent crashes with USGS null data fields
- Fix getStationColor() to handle null eColiCount with ?? 0 fallback
- Add explicit script-src-elem CSP directive for Vercel Live toolbar
- Allow *.vercel.live subdomains and wss://ws-us3.pusher.com in CSP
- Add defensive null check in WaterQualityIndicator component

Root cause: USGS ingestion returns null for fields like eColiCount,
but multiple components assumed non-null values from the static seed data.
…s-jJXP2

Comprehensive null safety + CSP fix for Vercel deployment
Vercel Hobby accounts only allow daily cron jobs. Changed USGS ingestion
from every 6 hours (0 */6 * * *) to once daily at 6 AM UTC (0 6 * * *).
…s-jJXP2

Fix Vercel cron: use daily schedule for Hobby plan
…e UI, and accessibility

Research credibility & data integrity:
- EPA Water Quality Portal (WQX) integration: ingest historical Anacostia watershed
  data via POST /api/ingest?source=epa (HUC 02070010, 5+ years of data)
- Automated data validation: reject physically impossible readings (pH>14, negative DO,
  etc.) with warnings logged per reading
- Data provenance badges: source labels (USGS/EPA/Model/Manual) shown in StationTable
  and station detail pages so researchers can verify each data point's origin
- Citation metadata: CSV exports include citation header block; JSON exports include
  structured citation object with dataset name, publisher, and access URL
- Methodology & data dictionary page (/methodology): sampling protocols, QA/QC
  procedures, parameter definitions with EPA standards, validation ranges, and
  ingestion history table
- Ingestion log API: GET /api/ingestion-log exposes audit trail to users

Educational value:
- Python and R analysis templates (public/templates/) with API integration,
  EPA compliance checks, and publication-ready charts
- Templates linked from education page's new "Analysis Templates" section

WCAG 2.1 AA accessibility:
- Skip-to-content link in layout.tsx
- aria-label, aria-expanded, aria-haspopup on all interactive controls
- aria-hidden on decorative icons throughout Header, Sidebar, station detail
- role="search" on search container, scope="col" on table headers
- Keyboard-navigable StationTable rows (Enter/Space to select)
- Chart containers labeled with role="img" and descriptive aria-labels
- id="main-content" on all page main elements
- Sidebar as labeled navigation landmark

Also: CSP updated for waterqualitydata.us, tests updated for new export format.
…s-jJXP2

Add EPA WQX integration, data validation, methodology page, provenanc…
- Add reusable Modal component with ESC close, backdrop click, scroll lock
- Rewrite MetricCards: 8 clickable cards open rich modals with EPA context,
  station-level data, compliance indicators, and navigation
- Rewrite education page: interactive exercises, audience filtering,
  module detail modals, API access documentation
- Enhance research page: status badges, quick links for researchers,
  results count, methodology links
- Polish dashboard: descriptive section headers for Water Quality,
  Multi-Parameter, Environmental Justice, and Station Table sections
- Add EJ insight summary and open data links in footer
- All 29 tests passing, TypeScript clean
- Add SidebarContext for mobile sidebar state management
- Sidebar: hidden on mobile/tablet, slides in as overlay drawer with
  backdrop and close button when hamburger menu is tapped
- Header: add hamburger menu button (visible below lg breakpoint),
  show compact UDC logo badge on mobile, make search bar fluid-width,
  hide date on small screens, show short date on tablets, hide
  "Stakeholder" text label and "Live" indicator on small screens
- All pages: change ml-[240px] to lg:ml-[240px] so content fills
  full width on mobile/tablet
- Add slide-in-left CSS animation for mobile drawer
…s-jJXP2

Claude/audit production readiness j jxp2
Header:
- Tighter padding/gaps on small screens (px-2, gap-0.5)
- Hide bell and stakeholder buttons below sm breakpoint
- Hide stakeholder label below md (icon-only on tablets)
- Shorter search placeholder ("Search..." vs full text)
- Add overflow-hidden to prevent header from causing scroll

Footer:
- Redesigned as centered, stacked layout that works at any width
- Clear visual hierarchy: logo/name, institute info, data links, attribution
- Links use flex-wrap with dot separators instead of inline slashes
- Better spacing and readable font sizes on small screens

All pages:
- Add min-w-0 overflow-x-hidden to main content area
- Responsive padding: p-3 on mobile, p-4 on sm, p-6 on md+
- Hero section: responsive padding and border-radius
OliTamrat and others added 29 commits March 11, 2026 17:16
…ss-jJXP2

Claude/audit production readiness j jxp2
Footer:
- Create dedicated Footer component with 4-column responsive grid
- Add Institute section (WRRI, CURII, EQTL), contact info, address
- Add Quick Links (Research, Education, Methodology, Data Export)
- Add Data Sources with external links (USGS, EPA, DOEE, DC Open Data)
- Add professional attribution for Olink Technologies Inc, DAPS Analytics,
  and Dr. Tolessa Deksissa
- Add copyright and funding lines
- Fully responsive: stacks cleanly on mobile, 2-col tablet, 4-col desktop
- Replace inline footer in page.tsx with reusable component

Search:
- Fix search to query researcher name (pi), department, description,
  and funding fields — previously only searched title and tags
- When matching on PI name, show "Project Title (Researcher)" in results
- Add Methodology and Dashboard pages to searchable results
…ss-jJXP2

Redesign footer and fix search to include researcher names
Implements an AI chat assistant that helps researchers and students
interpret water quality data directly within the dashboard.

Architecture:
- POST /api/chat — Vercel AI SDK v6 streaming endpoint using Claude
  Sonnet with a domain-specific system prompt containing EPA water
  quality standards, seasonal patterns, station metadata, and
  UDC WRRI research context
- 3 tool-augmented functions: getStationData, getStationHistory,
  listAllStations — AI can query live dashboard APIs to answer
  data-specific questions with real readings
- ResearchAssistant.tsx — Floating chat panel (bottom-right FAB)
  with streaming responses, suggested questions, conversation
  history, clear/close controls, and graceful degradation when
  ANTHROPIC_API_KEY is not configured
- Loaded globally via layout.tsx with dynamic import (SSR disabled)

Packages: ai@6, @ai-sdk/react@3, @ai-sdk/anthropic, zod
WRRI faculty can now manage station data through /admin:
- CSV/JSON file upload with drag-and-drop and auto column mapping
- AI-assisted column mapping using Claude Haiku (with heuristic fallback)
- Full CRUD for stations (add, edit, delete) and readings (view, delete)
- Ingestion log viewer with ability to trigger USGS/EPA data pulls
- Protected with ADMIN_API_KEY env var (open access when unset for dev)
- Preview step shows AI column mapping before committing upload
- Sidebar nav link under ADMIN section
…ss-jJXP2

Claude/audit production readiness j jxp2
- Derive base URL from request headers instead of hardcoded localhost:3000,
  fixing tool calls (getStationData, getStationHistory, listAllStations)
  that failed on Vercel because localhost doesn't exist in serverless
- Add try/catch around streamText with proper 500 error response
- Add request body validation with 400 error for malformed requests
- Make chat panel responsive on mobile: use left-3/right-3 positioning
  instead of fixed 360px width that overflowed on small screens
…ss-jJXP2

Fix AI chat API error on Vercel and improve mobile chat panel
…ndling

Root cause: Zod v4 (4.3.6) schemas are not compatible with AI SDK v6's
tool() function which expects Zod v3 format internally. Replaced all
tool inputSchema definitions with jsonSchema() from the ai package,
which bypasses the Zod conversion entirely.

Additional fixes:
- Use x-forwarded-proto header for correct HTTPS base URL on Vercel
- Guard against empty messages array (used by API key preflight check)
- Wrap convertToModelMessages in try/catch with proper error response
- Show actual error message in chat UI instead of generic text
…ss-jJXP2

Fix AI chat: replace Zod v4 schemas with jsonSchema, improve error ha…
Add ANTHROPIC_API_KEY to the example environment file.
The real API key was accidentally committed to .env.example in 3166b9d.
Replace with placeholder and add missing ADMIN_API_KEY template.

SECURITY: The exposed key must be revoked immediately at console.anthropic.com.
The claude-sonnet-4-5-20250514 model was causing "Something went wrong"
errors on production. Switch to claude-haiku-4-5-20251001 which is
broadly available and cost-effective. Also improved error handling to
surface actual API error details instead of generic messages.
…panish i18n

Chat API improvements:
- Rate limiting (10 req/min per IP) with in-memory store
- CSRF/origin validation to block cross-origin requests
- Configurable model via CHAT_MODEL env var (default: claude-haiku-4-5)
- Token usage logging via onFinish callback
- Streaming error handling via onError callback
- Increased maxOutputTokens from 2048 to 4096

Multilingual (i18n) system:
- Translation dictionary (src/lib/i18n.ts) with ~120 keys in English and Spanish
- LanguageContext with localStorage persistence and document.lang update
- Language switcher in Header (globe icon with EN/ES flags)
- Integrated i18n into: layout, page, Header, Sidebar, Footer,
  StationTable, EnvironmentalJustice, and dashboard sections

All 29 tests pass, build succeeds.
Replace crude 7-point diamond with real DC boundary coordinates
sourced from US Districts GeoJSON data. Now properly traces the
NW/NE diagonal borders (Maryland line), east vertex, and ~100
detailed points along the Potomac River for the western/southern
border — making DC actually look like DC on the map.
…ss-jJXP2

Fix DC boundary outline with accurate 119-point polygon
Replace the attribution requirement with an explicit rule to never
include claude.ai session URLs in commits, PRs, or code.
On mobile (<640px): legend starts collapsed as a small "Legend"
button that toggles open/closed on tap. Smaller padding, font
sizes, and max-height with scroll for small screens. Prevents
map drag/zoom when interacting with legend. Layer controls panel
also slightly narrower on mobile.
…ss-jJXP2

Claude/audit production readiness j jxp2
Leaflet internally uses z-index values in the hundreds/thousands,
which caused the map to render above the chat panel when scrolling.
Bumped the chat button and panel from z-50 to z-[10000] so they
always float above map layers.
…ss-jJXP2

Fix AI chat panel z-index to stay above Leaflet map
- Settings: Replace placeholder sidebar link with a modal offering
  theme (light/dark/system) and language (EN/ES) selection, reusing
  the existing Modal component and ThemeContext/LanguageContext.
- Admin auth: Persist admin key in sessionStorage so it survives page
  refresh. Remove silent catch-based auto-auth that could bypass the
  login gate. Add a "Sign Out" button to the admin header. Show a
  loading state while the auth check runs on mount.
- i18n: Add settings.* translation keys for both EN and ES.
Set turbopack.root to "." so Next.js resolves dependencies from the
project directory instead of a parent directory that may contain its
own package.json (causing "Can't resolve tailwindcss" errors).
Wraps the /api/stations route in try-catch with descriptive error
messages for native module load failures (common on Windows when
binaries need rebuilding). Also adds a clear error message in
createSqliteClient() when better-sqlite3 fails to load.
…ss-jJXP2

Claude/audit production readiness j jxp2
- Enforce ADMIN_API_KEY in production across all 4 admin API routes
  (stations, readings, upload, ai-map-columns). Without the key set,
  admin access is now blocked with 503 instead of silently allowed.
- Show login error messages in admin UI instead of generic alert.
- Fix station detail page to average multiple readings per month
  instead of overwriting (USGS ingests many per day).
- Add "Baseline data" warning badge when station only has seed data.
- Add USGS site mappings for ANA-003 (Buzzard Point 01651827) and
  ANA-004 (Anacostia at Washington 01651750) to pull real sensor data.
- Update EPA station map with matching new site IDs.
Combines loginError state (our branch) with authChecked state and
sessionStorage persistence (from main). Both improvements are kept.
Next.js App Router statically caches GET route handlers that don't
read request parameters. This caused /api/stations to serve stale
seed data (12/15/2025) instead of fresh USGS-ingested readings from
the Neon database. Adding export const dynamic = "force-dynamic"
ensures every request queries the database live.
- Map Watts Branch (USGS 01651800) and Hickey Run (USGS 01651770)
  to WB-001 and HR-001 in both USGS and EPA ingestion configs
- Show "Baseline (modeled)" instead of misleading seed timestamps
  (12/15/2025) for stations with only seed data — affects station
  detail page, map popups, and dashboard table
- Stations with live USGS/EPA data continue showing real timestamps
@gitguardian
Copy link
Copy Markdown

gitguardian bot commented Mar 18, 2026

⚠️ GitGuardian has uncovered 1 secret following the scan of your pull request.

Please consider investigating the findings and remediating the incidents. Failure to do so may lead to compromising the associated services or software components.

🔎 Detected hardcoded secret in your pull request
GitGuardian id GitGuardian status Secret Commit Filename
28306168 Triggered Claude API Key e0722b9 .env.example View secret
🛠 Guidelines to remediate hardcoded secrets
  1. Understand the implications of revoking this secret by investigating where it is used in your code.
  2. Replace and store your secret safely. Learn here the best practices.
  3. Revoke and rotate this secret.
  4. If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.

To avoid such incidents in the future consider


🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants