- Create AGENTS.md: comprehensive agent guide covering architecture, data flow, error bar convention (90% intervals), D3 usage patterns, null safety pitfalls, deployment checklist, and related repos - Update HANDOFF.md: mark CORS as resolved, document chart improvements (Chart 5 ridgeline rewrite with synthetic draws + smooth rendering) - Refresh README.md: accurate tech stack (D3 v7), updated file structure with new chart files, corrected API endpoint table
3.6 KiB
Handoff: Fix CORS for CRDC Arrests API Demo App
Current Status
RESOLVED: The demo app at https://pages.civilytics.org/crdc-demo/ is fully functional. All charts render correctly and there are no blocking errors in the console.
The original CORS issue was resolved by deploying updated plumber.R with CORS headers to the running API server (crdc-api.civilytics.org).
Historical Context (resolved)
Original Problem
The demo app loaded HTML correctly but showed a blank white screen because browser-based fetch requests to the CRDC API were blocked by CORS (the API didn't send Access-Control-Allow-Origin headers).
Resolution
The CORS issue was fixed at the API source:
- Updated
crdc-arrests/api/plumber.Rwith CORS headers (Access-Control-Allow-Origin: *) in the existingcacheHeadersfilter and OPTIONS preflight handling. - Deployed to the running API server so it took effect at https://crdc-api.civilytics.org/.
The app now calls the public read-only API directly from the browser without requiring a proxy.
Current Work (completed)
Since resolving CORS, additional improvements were made:
What's Done
- ✅ CORS resolved: API server (
crdc-api.civilytics.org) now sendsAccess-Control-Allow-Origin: *headers — deployed via updatedplumber.R - ✅ App code: React + Vite app fully built with 6 charts, Civilytics visual identity (wordmark from civilyticsR package), loading animation, district search
- ✅ Git Pages deployment: Gitea Actions workflow (
.gitea/workflows/pages.yml) successfully buildsdist/and deploys to apagesbranch onCivilytics/crdc-demorepo at gitea.civilytics.org - ✅ Chart 5 rewrite: Replaced interval-proxy ridgeline with proper D3 density ridges (
RateDensityRidgeline.jsx) using synthetic draws from normal approximation of posterior intervals, smoothcurveBasisrendering, and diamond markers for observed rates - ✅ Chart 4 enhancement: Added D3-based quadrant visualization in
ModelDrawsComparison.jsxshowing error bars with proper null safety
Remaining Proxy Code (optional)
The CORS proxy fallback code (proxy.php, nginx reverse proxy config, VITE_PROXY_URL support) was added but is not needed since the API now sends CORS headers. It remains as a safety net for environments where the API can't be modified.
What Needs to Be Done Next
Future Enhancements
- Raw posterior draws: The
/api/v1/draws?...endpoint returns Parquet shard URLs for bulk processing, not browser-friendly draw data. If actual posterior distributions are needed in Chart 5 (instead of synthetic normal approximation), a new API endpoint would be required. - Automated testing: No test suite exists; consider adding basic tests for chart rendering and API error handling.
Key Files
- API fix:
/home/jared/Nextcloud/Civilytics/Code/Civilytics/crdc-arrests/api/plumber.R(CORS headers added to cacheHeaders filter) - App code:
/home/jared/Nextcloud/Civilytics/Code/Civilytics/crdc-demo/src/— fully built, deployed to pages branch - Proxy fallback:
proxy.php, nginx.conf with reverse proxy config
Verification Steps After Fix
- Visit https://pages.civilytics.org/crdc-demo/
- Select a state → search for "Denver" → should see district results
- Click a district → loading animation runs, then 6 charts appear
- Check browser dev tools → no CORS errors in console
Git Status
crdc-arrestsrepo: plumber.R modified (CORS headers added), not yet committed/pushed to API deploymentcrdc-demorepo: All fixes pushed and deployed via Gitea Actions, awaiting CORS resolution at API or server level