|
| 1 | +# Red-CORAL — AI Agent Guidelines |
| 2 | + |
| 3 | +Interactive map of organized crime incidents in South America, built for the Harvard T.H. Chan School of Public Health's Atrocity Prevention Lab. **All UI strings are in Spanish** — never introduce English-language UI text. |
| 4 | + |
| 5 | +## Code Style |
| 6 | + |
| 7 | +- **TypeScript strict mode** with zero unused locals/params (prefix unused args with `_`) |
| 8 | +- **ESLint**: `--max-warnings 0` — no warnings tolerated. `react-hooks/exhaustive-deps` is OFF. |
| 9 | +- **Imports**: both bare (`from 'types'`) via `baseUrl: "src"` and aliased (`from '@/types'`) work; match existing imports in the file you're editing. |
| 10 | +- **Styling**: Tailwind CSS with custom `harvard-*`, `shade`, `tint` palette and `merriweather`/`proxima-nova` fonts defined in `tailwind.config.js`. |
| 11 | +- **Icons**: `lucide-react` exclusively. |
| 12 | +- **Dropdowns/popovers**: `@floating-ui/react` — no component library. See `src/components/filters/BaseFilter.tsx` for the pattern. |
| 13 | + |
| 14 | +## Architecture |
| 15 | + |
| 16 | +- **Single context**: `src/context/DBContext.tsx` holds all app data (Categories, Types, Incidents). No Redux. Access via `useDB()` hook. A raw `db` export exists for use outside React (e.g., cluster icon functions in `IncidentLayer`). |
| 17 | +- **Data flow**: Firebase Storage JSON snapshots → `DBContext` → components. Admins also get Firestore delta updates for docs modified after the snapshot's `readAt` timestamp. |
| 18 | +- **User tiers**: `'public' | 'paid' | 'admin'` — resolved from Firestore `Permissions` collection. |
| 19 | +- **Caching**: IndexedDB with 24-hour TTL for public/paid tiers. Admin data is never cached. See `src/utils/indexedDB.ts`. |
| 20 | +- **Soft deletes**: Docs marked `deleted: true` with `updatedAt` timestamp; purged during publish. |
| 21 | +- **CRUD mutations** intentionally mutate state without full rerender to avoid resetting the map view (marked with 🚨 in code). |
| 22 | +- **`typeID`** on `Incident` can be `string | string[]` — always handle both cases. |
| 23 | +- **Lazy loading**: Admin pages use `React.lazy()` + `Suspense`. |
| 24 | + |
| 25 | +## Dual Filter Systems |
| 26 | + |
| 27 | +1. **Map page** (`src/pages/Map.tsx`): Simple `MarkerFilters` object via `useState` + `filterIncidents()` utility. |
| 28 | +2. **Stats/Publish pages** (`src/filters/filterReducer.ts`): Reducer-based composable filters with `NOT`/`OR` meta-filters. Each filter type has a component (in `src/components/filters/`) and a predicate function. State persists to `localStorage`. |
| 29 | + |
| 30 | +## Build & Commands |
| 31 | + |
| 32 | +```sh |
| 33 | +pnpm install # Install deps (pnpm 10.9.0 required) |
| 34 | +pnpm dev # Vite dev server |
| 35 | +pnpm build # tsc type-check + vite build |
| 36 | +pnpm lint # ESLint (zero warnings) |
| 37 | +pnpm format # Prettier |
| 38 | +``` |
| 39 | + |
| 40 | +No test framework is configured — there are no test files. |
| 41 | + |
| 42 | +## Firebase & Environment |
| 43 | + |
| 44 | +Firestore collections: `Incidents`, `Categories`, `Types`, `Permissions`. |
| 45 | +Publish workflow (`src/utils/publish.ts`): snapshots Firestore → uploads tiered JSON files (`publicState.json`, `state.json`, `adminCheckpointState.json`) to Cloud Storage → deletes soft-deleted docs. |
| 46 | + |
| 47 | +Required env vars (all `VITE_` prefixed): `FIREBASE_API_KEY`, `FIREBASE_AUTH_DOMAIN`, `FIREBASE_PROJECT_ID`, `FIREBASE_STORAGE_BUCKET`, `FIREBASE_MESSAGING_SENDER_ID`, `FIREBASE_APP_ID`, `STADIA_KEY`, `ANALYTICS_URL`. |
| 48 | + |
| 49 | +## Key Files |
| 50 | + |
| 51 | +| Area | Files | |
| 52 | +|---|---| |
| 53 | +| Data layer | `src/context/DBContext.tsx`, `src/types.ts`, `src/utils.ts` | |
| 54 | +| Map | `src/pages/Map.tsx`, `src/components/layers/IncidentLayer.tsx` | |
| 55 | +| Filters | `src/filters/filterReducer.ts`, `src/components/filters/` | |
| 56 | +| Admin | `src/pages/AdminCRUD.tsx`, `src/pages/PublishAdmin.tsx` | |
| 57 | +| Stats | `src/pages/StatsDashboard.tsx`, `src/components/graphs/` | |
| 58 | +| Caching | `src/utils/indexedDB.ts` | |
| 59 | +| Routing | `src/App.tsx` | |
0 commit comments