|
| 1 | +# Guía para agentes (Claude Code / Codex / etc.) |
| 2 | + |
| 3 | +Contexto compartido para trabajar en **LibreAgro App** con asistentes de IA. |
| 4 | +Aplica tanto a Claude Code como a otras herramientas que lean `AGENTS.md`. |
| 5 | +(El archivo `CLAUDE.md` importa este mismo contenido.) |
| 6 | + |
| 7 | +## Qué es |
| 8 | + |
| 9 | +App React Native + **Expo SDK 54** (RN 0.81, React 19, New Architecture) que |
| 10 | +monitorea sensores y opera relés de hubs LibreAgro (ESP32). Ver |
| 11 | +[`README.md`](README.md) para detalle funcional y de build. |
| 12 | + |
| 13 | +## Comandos |
| 14 | + |
| 15 | +```bash |
| 16 | +npm ci # instalar (usa package-lock.json) |
| 17 | +npm start # desarrollo (Metro) — usa MOCKS por defecto |
| 18 | +npm test # jest |
| 19 | +npx tsc --noEmit # chequeo de tipos |
| 20 | +``` |
| 21 | + |
| 22 | +APK release (sin mocks) — ver README, sección "Armar el APK": |
| 23 | + |
| 24 | +```bash |
| 25 | +npx expo prebuild --platform android --no-install |
| 26 | +cd android && ./gradlew assembleRelease |
| 27 | +``` |
| 28 | + |
| 29 | +## Reglas de oro |
| 30 | + |
| 31 | +1. **Mocks en dev, HTTP solo en release.** El default del código es `mock`. Los |
| 32 | + servicios reales se activan vía `EXPO_PUBLIC_*` en builds de release |
| 33 | + (cargadas desde [`.env.production`](.env.production)). **No** pongas valores |
| 34 | + `http` en `.env`/`.env.development` ni hardcodees URLs en el código: romperías |
| 35 | + el desarrollo mock-first. |
| 36 | +2. **Respetá la capa de servicios `mock | http`.** Las pantallas/stores nunca |
| 37 | + conocen el transporte: van por `hubDataService` y los clientes en |
| 38 | + `services/*Api/`. Para conectar un backend nuevo, agregá la implementación |
| 39 | + HTTP detrás de la interfaz existente; no llames `fetch` desde la UI. |
| 40 | +3. **Verificá antes de pushear:** `npx tsc --noEmit` y `npm test` en verde. |
| 41 | +4. **Sin secretos en el repo.** Hoy no hay auth (hub ni ntfy), por eso |
| 42 | + `.env.production` se versiona. Si en el futuro hay tokens, van por |
| 43 | + variables/secrets del CI, nunca commiteados. |
| 44 | +5. **Estilo:** TypeScript estricto, datos inmutables (spread, sin mutación), |
| 45 | + archivos chicos y enfocados, manejo explícito de errores. Sin `console.log` |
| 46 | + en código de producción. |
| 47 | +6. **Tests:** este proyecto **no exige** TDD; escribí/actualizá tests solo si la |
| 48 | + tarea lo pide o si tu cambio rompe la suite. Si tocás algo cubierto, dejá la |
| 49 | + suite verde. |
| 50 | +7. **NO implementar el "Posponer" / snooze de alarmas.** Está **fuera del MVP** |
| 51 | + (ver sección "Fuera de alcance"). No agregar botón, handler, estado `snoozed` |
| 52 | + ni `snoozedUntil` aunque parezca natural o lo sugiera un test viejo. |
| 53 | + |
| 54 | +## Arquitectura (resumen) |
| 55 | + |
| 56 | +- `services/hubApi/` — cliente del hub (`MockHubApiClient` | `HttpHubApiClient`), |
| 57 | + `adapters.ts` (validación de respuestas), `alarmsParser.ts` (alarmas derivadas |
| 58 | + de `/actual.errors` y de mensajes ntfy), `backend.ts` (selector por env). |
| 59 | +- `services/notifyApi/` — push ntfy.sh (`/topic/json?poll=1`), mock | http. |
| 60 | +- `services/recommendationsApi/` — `/messages` (GET/POST), mock | http. |
| 61 | +- `services/connectivity.ts` — `resolveHubTarget(mode, hub)`: Directo → IP fija |
| 62 | + `192.168.4.1`; Online → `hash` (ruteo por backend, sin descubrir IP). |
| 63 | +- `services/hubDataService.ts` — fachada única que usan los stores. |
| 64 | +- `stores/` (zustand) — `hubStore`, `hubDataStore`, `cropStore`, `zoneStore`. |
| 65 | + |
| 66 | +## Cosas específicas que conviene saber |
| 67 | + |
| 68 | +- **`android/` e `ios/` son generados** (`expo prebuild`) y están en |
| 69 | + `.gitignore`. No los edites a mano ni los commitees. |
| 70 | +- **APK release** queda firmado con la **debug keystore** del template Expo → |
| 71 | + instalable por sideload, no apto para Play Store. |
| 72 | +- **Alarmas**: se derivan de `/actual.errors` (formato `"texto,timestamp"`, |
| 73 | + timestamp = epoch nanos → ISO). El push ntfy solo se consulta si |
| 74 | + `EXPO_PUBLIC_NOTIFY_BACKEND=http`. |
| 75 | +- **Zonas**: se asignan **localmente en el celular** (el hub no las expone). Ver |
| 76 | + `zoneStore` + `ZoneAssignSheet`. |
| 77 | +- **Posponer alarmas**: fuera del MVP — ver sección "Fuera de alcance". Alarmas |
| 78 | + solo soporta **Acknowledge**. |
| 79 | +- **Tests RN**: preset `jest-expo`; `jest.setup.js` mockea |
| 80 | + `react-native-safe-area-context` (los tests no montan `SafeAreaProvider`). |
| 81 | + |
| 82 | +## 🚫 Fuera de alcance — NO implementar (salvo pedido explícito) |
| 83 | + |
| 84 | +Funcionalidad que **quedó deliberadamente afuera del MVP**. No la implementes |
| 85 | +por iniciativa propia aunque parezca una mejora obvia, esté insinuada por código |
| 86 | +viejo, o un test la sugiera. Si el equipo decide reincorporarla, primero se |
| 87 | +actualiza esta sección. |
| 88 | + |
| 89 | +- **Posponer / snooze de alarmas.** La pantalla de Alarmas soporta **solo |
| 90 | + Acknowledge**. No agregar: |
| 91 | + - botón "Posponer" / "Posponer 1h" en `AlarmCard`, |
| 92 | + - prop `onSnooze` ni handler de snooze en `AlarmsScreen`, |
| 93 | + - el estado `"snoozed"` en `AlarmStatus` ni el campo `snoozedUntil` en `Alarm`. |
| 94 | + |
| 95 | + > Esta feature se eliminó a propósito. En sesiones anteriores se reintrodujo |
| 96 | + > por error varias veces — **no la vuelvas a agregar**. |
| 97 | +
|
| 98 | +## Contratos externos pendientes |
| 99 | + |
| 100 | +- **Backend de recomendaciones**: sin URL aún → `RECOMMENDATIONS_BACKEND=mock`. |
| 101 | + Cuando exista: setear `http` + `EXPO_PUBLIC_RECOMMENDATIONS_BASE_URL`. |
| 102 | +- **Zonas desde el hub**: por ahora 100% locales. |
| 103 | + |
| 104 | +## Commits |
| 105 | + |
| 106 | +Conventional Commits: `feat:`, `fix:`, `chore:`, `test:`, `docs:`, `refactor:`. |
| 107 | +Mensajes claros; commit en español está bien (el equipo es hispanohablante). |
0 commit comments