add missing features

This commit is contained in:
m
2026-09-10 06:40:58 +02:00
parent 85b1871c18
commit 27d4eb6a65
4 changed files with 29 additions and 8 deletions
+1 -1
View File
@@ -47,7 +47,7 @@ cd mobile && npm run test:db
- `db/` — SQLite persistence, see `mobile/AGENTS.md` for the full contract (schema, migrations, repositories, tests) - `db/` — SQLite persistence, see `mobile/AGENTS.md` for the full contract (schema, migrations, repositories, tests)
- `localStorage.ts` — thin re-export of `services/db` (legacy alias) - `localStorage.ts` — thin re-export of `services/db` (legacy alias)
- `features/syncDevice.ts` — device sync orchestration (two-pass SAF walk, single transaction per root, `exists = 0` reconciliation) - `features/syncDevice.ts` — device sync orchestration (two-pass SAF walk, single transaction per root, `exists = 0` reconciliation)
- `context/AuthContext.tsx` — session context - `context/AuthContext.tsx` — session context: exposes `deviceUserId` (bootstrapped from `getDeviceUserId()`) and starts the background `syncDevice` loop
- No business logic on the client — heavy processing stays server-side - No business logic on the client — heavy processing stays server-side
- API base URL configured via `EXPO_PUBLIC_API_BASE_URL` env var (client + hooks not yet built) - API base URL configured via `EXPO_PUBLIC_API_BASE_URL` env var (client + hooks not yet built)
+21 -5
View File
@@ -1,19 +1,35 @@
import { createContext, useContext, useEffect, useMemo, useState } from 'react'; import { createContext, useContext, useEffect, useMemo, useState } from 'react';
import type { ReactNode } from 'react'; import type { ReactNode } from 'react';
import { useSyncDevice } from '../features/syncDevice'; import { useSyncDevice } from '../features/syncDevice';
import { getDeviceUserId } from '../services/localStorage';
import type { AuthContextValue, User } from './AuthContext.types'; import type { AuthContextValue, User } from './AuthContext.types';
const AuthContext = createContext<AuthContextValue | null>(null); const AuthContext = createContext<AuthContextValue | null>(null);
export function AuthProvider({ children }: { children: ReactNode }) { export function AuthProvider({ children }: { children: ReactNode }) {
useEffect(()=>{
const {} = useSyncDevice()
},[])
const [user, setUser] = useState<User | null>(null); const [user, setUser] = useState<User | null>(null);
const [deviceUserId, setDeviceUserId] = useState<string | null>(null);
const value = useMemo(() => ({ user }), [user]); useEffect(() => {
let active = true;
(async () => {
try {
const id = await getDeviceUserId();
if (active) setDeviceUserId(id);
} catch (error) {
console.warn('device identity unavailable', error);
}
})();
useSyncDevice();
return () => {
active = false;
};
}, []);
const value = useMemo(() => ({ user, deviceUserId }), [user, deviceUserId]);
return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>; return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
} }
+1
View File
@@ -2,4 +2,5 @@ export type User = {};
export type AuthContextValue = { export type AuthContextValue = {
user: User | null; user: User | null;
deviceUserId: string | null;
}; };
+6 -2
View File
@@ -122,8 +122,12 @@ export async function useSyncDevice(intervalMs = 30_000): Promise<void> {
if (preferences.syncMode === 'none') return; if (preferences.syncMode === 'none') return;
while (true) { while (true) {
const results = await syncDevice(); try {
console.info('syncDevice', JSON.stringify(results)); const results = await syncDevice();
console.info('syncDevice', JSON.stringify(results));
} catch (error) {
console.warn('syncDevice failed, retrying later', error);
}
await new Promise((resolve) => setTimeout(resolve, intervalMs)); await new Promise((resolve) => setTimeout(resolve, intervalMs));
} }
} }