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>
This commit is contained in:
2026-07-14 11:58:20 +02:00
co-authored by Claude Sonnet 4.6
parent a544818b5d
commit 5d1a4db42f
4 changed files with 55 additions and 26 deletions
+5 -8
View File
@@ -12,9 +12,9 @@ import {
import * as api from '../api/endpoints';
import { Project } from '../api/types';
import { useSession } from '../auth/session';
import { getCursor, getProjects, saveProjectList, setActiveProjectId } from '../db/repositories';
import { getProjects, saveProjectList, setActiveProjectId } from '../db/repositories';
import { isOnline } from '../net/connectivity';
import { initialPull, runSync } from '../sync/engine';
import { runSync } from '../sync/engine';
import { RootStackParamList } from '../navigation/types';
type Props = NativeStackScreenProps<RootStackParamList, 'Projects'>;
@@ -57,12 +57,9 @@ export function ProjectsScreen({ navigation }: Props) {
setOpening(p.id);
try {
await setActiveProjectId(p.id);
const online = await isOnline();
if (online) {
const cursor = await getCursor(p.id);
if (cursor) await runSync(p.id);
else await initialPull(p.id);
}
// runSync ya resuelve ambos casos: sin cursor baja el snapshot completo,
// con cursor baja el delta (y vacía primero el outbox, vacío en la 1ª vez).
if (await isOnline()) await runSync(p.id);
navigation.navigate('ProjectDetail', { projectId: p.id, name: p.name });
} finally {
setOpening(null);