30 Commits
Author SHA1 Message Date
javier 80e4657b15 Mejoras en el mapa (satélite, ubicación), configuración de relación de aspecto en cámara y correcciones de estabilidad 2026-07-31 12:52:36 +02:00
javier 603a03946b Adjust dependencies to stable versions and clean android folder 2026-07-29 23:02:56 +02:00
javier 038cbc674c Implement system bars management and Edge-to-Edge layout 2026-07-29 14:02:35 +02:00
javier a12ec6ae2f Finalize background photo processing and orientation fixes 2026-07-29 12:29:01 +02:00
javier f2b359e515 Final fixes for photo overlay position and rotation 2026-07-29 09:39:12 +02:00
javier a9ba966176 Fix photo overlay positioning and rotation detection 2026-07-29 00:35:45 +02:00
javier 6d11434061 Implement custom camera with real-time overlay and resolution settings 2026-07-28 23:55:24 +02:00
javier c6240784ff UI improvements and prepare for OSM migration 2026-07-28 20:05:12 +02:00
javier 6ac78ea6a1 Environment fix for Android and UI preparations 2026-07-28 19:42:11 +02:00
javierandClaude Opus 4.8 31de1c1526 fix(deps): resincronizar package-lock.json con npm 10 (build EAS)
npm 11 (local) dedupe y omitía un typescript@5.9.3 anidado que npm 10.9.4
(el de EAS Build) exige, provocando `npm ci` EUSAGE "out of sync" y el fallo
en la fase Install dependencies. Regenerado con npm@10.9.4 para paridad.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 11:34:55 +02:00
javierandClaude Opus 4.8 a59ed64975 chore(eas): enlazar proyecto EAS (projectId)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 11:10:40 +02:00
javierandClaude Opus 4.8 7278c1363d feat(sync): prefetch del catálogo de plantillas para trabajar offline
Las plantillas solo llegaban a local en el bundle al abrir un proyecto
online. Ahora, al cargar la lista de proyectos con conexión, se prefetchan
TODAS las plantillas accesibles (GET /templates, antes sin usar) y se
guardan en local, para poder inspeccionar offline aunque el proyecto no se
haya abierto todavía. Tolerante a fallo: no bloquea la lista.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 14:08:40 +02:00
javierandClaude Opus 4.8 3ed07cae3c fix(sync): proyectar el valor del servidor en conflicto a columnas locales
El backend devuelve el modelo completo (toArray) en un conflicto: incluye
geometry como array y columnas inexistentes en local (uuid, created_at,
deleted_at, client_updated_at...). Volcarlo tal cual en SQLite lanzaba
"no such column"/error de bind y abortaba el ciclo de sync entero ante
cualquier edición concurrente. Ahora se proyecta por los mismos pick* del PULL.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 14:08:28 +02:00
javierandClaude Sonnet 4.6 72dea5954c chore: eliminar código muerto y activar purga del outbox
Auditoría de exports sin uso:
- Eliminados: getPhases, getLayers, getTemplate, countRows (repositories),
  setCursor (redundante: applyBundle escribe el cursor por SQL), y la
  constante TOKEN_ABILITY (config). getPhases/getTemplate quedaron huérfanos
  al quitar la pestaña Fases y cambiar el selector de plantillas.
- purgeSentOperations existía pero NADIE la llamaba (el outbox acumulaba
  filas 'sent' sin límite): ahora runSync la invoca al final del ciclo.

Sin mocks, TODOs ni simulaciones en el código. Typecheck limpio.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-14 12:05:14 +02:00
javierandClaude Sonnet 4.6 eee15819ac feat(sync): media en paralelo + visibilidad proactiva de problemas
- pushMedia sube en lotes de 3 en paralelo (Promise.all por chunk) en vez
  de una a una; contadores del report seguros al ser el runtime monohilo.
- SyncStatusBar: fondo rojo cuando hay conflictos/errores (prioridad sobre
  el estado de conexión), para que el problema salte a la vista.
- ProjectDetail: el auto-sync silencioso ahora avisa una vez con Alert
  cuando un ciclo produce conflictos/errores, con acceso directo a la cola.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-14 12:00:29 +02:00
javierandClaude Sonnet 4.6 5d1a4db42f refactor(sync): limpiar código muerto + timeout de red (post-review)
- Elimina recordProgressUpdate (quedó huérfano al quitar la pestaña Fases;
  el progreso se edita vía feature.update) y initialPull (redundante).
- ProjectsScreen: al abrir un proyecto siempre runSync — su fase de pull ya
  resuelve snapshot (sin cursor) y delta (con cursor), y el outbox está vacío
  la primera vez. Menos ramas, misma semántica.
- client.ts: AbortController con timeout (30s JSON / 120s multipart) y
  NetworkError que distingue timeout de error de red genérico.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-14 11:58:20 +02:00
javierandClaude Sonnet 4.6 a544818b5d fix(perms): 'manage all' concede todo (igual que Gate::before del backend)
Los botones (nueva incidencia, nueva inspección, editar, subir foto) se
ocultaban a usuarios Admin: el backend los autoriza vía el bypass de
super-admin (Gate::before → 'manage all'), pero el rol Admin no tiene los
permisos granulares (create issues, create inspections, edit issues,
upload media, view issues) asignados explícitamente, así que /me no los
devolvía. hasPermission ahora trata 'manage all' como comodín.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-08 11:16:44 +02:00
javierandClaude Sonnet 4.6 190b4f6f34 feat(ui): quitar pestaña Fases + selector de plantilla al inspeccionar
- ProjectDetail: pestañas reducidas a Features | Incidencias (Features por
  defecto); PhasesSection eliminada.
- InspectionForm en dos pasos: 1) selector de plantillas asignadas al
  proyecto (la de la feature marcada como sugerida ★, opción de inspección
  libre), 2) formulario dinámico. Enlace "Cambiar plantilla" para volver.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-08 10:50:20 +02:00
javierandClaude Sonnet 4.6 9c4c3b54ae feat(login): campo de dirección del servidor configurable
- config.ts: BASE_URL/ORIGIN dejan de ser constantes; ahora hay
  setServerOrigin/getBaseUrl/getServerOrigin con normalizeServerUrl
  (añade http:// si falta, quita barras finales y el sufijo /api/v1).
- client.ts: construye las URLs con getBaseUrl() en cada petición.
- session: signIn recibe la URL, la fija antes del login y la persiste
  en SecureStore (clave server_url); se rehidrata al arrancar junto al token.
- LoginScreen: campo "Servidor" precargado con el último valor usado.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-08 10:00:13 +02:00
javierandClaude Sonnet 4.6 04859c281d fix(projects): la lista salía vacía — el backend envuelve en {projects}
GET /projects responde { "projects": [...] } (ProjectApiController@index),
pero normalize() solo contemplaba un array o { data } → siempre [].
Ahora normalize acepta {projects}/{data}/array, los tipos de listProjects
y getTemplates reflejan la envoltura real ({projects}/{templates}), y el
fallback offline loguea el motivo en vez de tragarse el error.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-07 18:03:18 +02:00
javierandClaude Sonnet 4.6 fdf85e7cc9 feat(api): adaptar cliente al contrato v1.1
- feature_types: nueva tabla local + tipo FeatureType + upsert en applyBundle
  + getFeatureTypes(); FeatureDetail muestra badge del tipo con su color.
- feature: columnas feature_type_id + is_active (migración BD v3);
  feature.update acepta ambas; toggle "Activa" en el detalle con badge
  "inactiva" cuando corresponde.
- templates: ahora catálogo global asignado por pivot — getTemplates() ya no
  filtra por project_id (informativo); phase_id eliminado del tipo y del pick.
- Formulario de inspección: soporta fields[].group (secciones), question
  (etiqueta principal), help (texto de ayuda) y required (validación al
  guardar con aviso de campos faltantes).
- Bundle: tipa issue_tasks correctamente como IssueTask[].
- docs/: sincronizados openapi.yaml y MOBILE_APP_BRIEF.md v1.1 del backend.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-07 17:39:47 +02:00
javierandClaude Sonnet 4.6 c092052a1c feat(ios): preparar soporte iOS
- app.json: bundleIdentifier + buildNumber para iOS
- eas.json: perfiles iOS (development con simulador, preview ipa, production)
  y appleId para submit
- app.config.js: inyección de GOOGLE_MAPS_IOS_KEY (opcional; por defecto
  la app usa Apple Maps en iOS sin necesitar key)
- FeatureMap: MAP_PROVIDER = PROVIDER_GOOGLE en Android, PROVIDER_DEFAULT
  (Apple Maps) en iOS; elimina dependencia de Google Maps key en iOS

Pendiente: generar /ios con 'npx expo prebuild --platform ios' desde macOS.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-07 09:45:51 +02:00
javierandClaude Sonnet 4.6 fa27b22849 chore: añadir proyecto nativo Android al repositorio
Elimina /android del .gitignore y committea el resultado de
expo prebuild --platform android (Gradle, AndroidManifest, MainActivity,
recursos de icono/splash). Android Studio puede abrirlo directamente
desde la carpeta android/ sin necesidad de ejecutar prebuild.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-07 09:37:42 +02:00
javierandClaude Sonnet 4.6 9469e2351c chore: actualizar scripts android/ios tras prebuild
expo prebuild actualiza los scripts a expo run:android / expo run:ios
para compilar el proyecto nativo directamente.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-07 09:36:45 +02:00
javierandClaude Sonnet 4.6 504bbf1a3d feat(photo): pie de página georreferenciado + pantalla de configuración
- FooterOverlay: franja oscura (logo izquierda, campos derecha) superpuesta
  sobre la foto antes de encolarla; tamaños proporcionales a la resolución.
- MediaStrip: capta coordenadas GPS (expo-location) al abrir el picker,
  estampa el footer con react-native-view-shot (view off-screen + onLoad),
  y añade icono ⚙ → PhotoSettings. Fallback: usa foto original si el stamp falla.
- PhotoSettingsScreen (modal): toggle general, selector de logo cuadrado,
  activar/desactivar/editar etiqueta de cada campo (proyecto, fecha, coords)
  y añadir campos personalizados con etiqueta + valor estático.
- footerConfig: persiste en meta table (clave 'photo_footer_config').
- repositories: añade getProject(id).
- navigation: ruta PhotoSettings como modal.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-01 11:34:38 +02:00
javierandClaude Sonnet 4.6 e16f4585c2 docs: actualizar README con estado real de implementación
Elimina la sección "Pendiente" del scaffold inicial (ya todo implementado)
y la sustituye por tabla de estado con referencia a cada archivo, más la
lista real de próximos pasos (Maps key, test en dispositivo, background sync).
También añade .idea/ al .gitignore.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-01 10:05:05 +02:00
javierandClaude Opus 4.8 fa3671897f chore(build): add eas-cli for APK builds
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 18:44:47 +02:00
javierandClaude Opus 4.8 9bcc51e3b2 feat(android): app de campo móvil+tablet (UI, mapa, fotos, auto-sync, reconciliación)
Fase 0: config Android (package, permisos, orientación), eas.json (APK), deps
  nativas (react-native-maps, image-picker, location), app.config.js para la key
  de Google Maps por secreto EAS.
Fase 1: capa responsive (useLayout) + componente MasterDetail (dos paneles en
  tablet, navegación en móvil).
Fase 2: pantallas funcionales — detalle de proyecto con secciones Fases/Features/
  Incidencias, edición de progreso/estado, formulario de inspección dinámico
  desde plantilla, incidencias maestro-detalle (checklist + comentarios), alta de
  incidencia; gating por permisos Spatie.
Fase 3: fotos (cámara/galería) → cola de media, con miniaturas pendientes/sync.
Fase 4: mapa de features (Google Maps) con geometría GeoJSON y selección.
Fase 5: auto-sync (foreground/reconexión/intervalo, con candado) + reconciliación
  de creaciones offline (id temporal negativo → server_id, remapeo de FKs hijas).
Fase 6: revisión de conflictos/errores del outbox, indicadores y APK preview.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 18:30:44 +02:00
javierandClaude Opus 4.8 4e9c7d059f feat: scaffold offline-first mobile app (RN+Expo, expo-sqlite)
Capa API tipada de los 8 endpoints, BD local espejo del bundle + outbox
(operaciones y media) + cursor de sync, motor runSync (PUSH /sync ->
PUSH /media -> PULL bundle?since) con idempotencia por uuid y last-write-wins,
mutaciones de alto nivel (write local + encolar), sesion con token en
SecureStore, conectividad NetInfo y UI minima (Login -> Proyectos -> Detalle).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 17:43:48 +02:00
javier 3f454b59a5 Initial commit
Generated by create-expo-app 4.0.0.
2026-06-18 17:26:38 +02:00