- api/types.ts : SyncOperation, SyncResult (sémantique `applied` = INDEX documentée),
ResourcePermission (miroir docs/api-v1.md §6, consommé tel quel par saveResourcePermission)
- api/client.ts : syncOps (POST /sync/ops), getSyncPermissions (GET /sync/permissions?after=),
hasAuthToken() ; INVALID_RESPONSE documenté dans docs/api-v1.md §1/§4
- services/db/repositories/pendingOps.ts : listQueuedOperations(limit) (batch FIFO due)
+ scheduleRetries(ids, retryAt) qui ne modifie JAMAIS attempts (erreur transitoire,
contrairement à markPendingOperation('failed') qui incrémente + backoff)
- features/syncOutbox.ts (nouveau) :
* pushPendingOps : batch ≤ SYNC_BATCH_SIZE (50) → ops [0, applied) passent 'completed' ;
op à l'index applied refusée → 'failed' (backoff, dead-letter MAX_PENDING_ATTEMPTS) ;
ops suivantes intactes (re-soumission) ; réseau/5xx → scheduleRetries (retried) sans
dead-letter prématurée ; applied==0 && failed → rien commité, aucun compteur touché
* refreshPermissions : delta monotone en mémoire lastPermissionCachedAt → `after`,
upsert saveResourcePermission ; no-op sans token
- features/syncDevice.ts : le tick useSyncDevice() enchaîne SAF walk → pushPendingOps()
→ refreshPermissions(), tous deux gardés par hasAuthToken()
- tests/syncOutbox.test.ts : 12 cas (FIFO/limit, succès complet/partiel, applied=0,
transitoire réseau + 5xx sans incrément, dead-letter après MAX_PENDING_ATTEMPTS,
delta snapshot croisé) — npm run test:sync
- tests/e2e.live.test.ts : smoke real backend (register → push → relecture /files/folders →
snapshot), skip si serveur down, SORTI de npm test via npm run test:e2e
- gates : npx tsc --noEmit + npm run test → 56/56 verts (24 db + 20 api + 12 sync)
43 lines
1016 B
TypeScript
43 lines
1016 B
TypeScript
export {
|
|
saveFolder,
|
|
saveDirectory,
|
|
getFolders,
|
|
getFolderFolders,
|
|
getFolder,
|
|
removeFolder,
|
|
} from './folders';
|
|
export { saveFile, getFiles, getFile, removeFile } from './files';
|
|
export {
|
|
saveUserPreferences,
|
|
getUserPreferences,
|
|
getDeviceUserId,
|
|
getDeviceAuthToken,
|
|
saveDeviceAuthToken,
|
|
} from './preferences';
|
|
export {
|
|
getResourcePermission,
|
|
saveResourcePermission,
|
|
canAccess,
|
|
canWrite,
|
|
isOwner,
|
|
} from './permissions';
|
|
export { saveShare, getShare, getShares, removeShare, removeSharesForResource } from './shares';
|
|
export {
|
|
createShareLink,
|
|
getShareLinkById,
|
|
getShareLinkByToken,
|
|
getShareLinks,
|
|
incrementLinkDownloads,
|
|
revokeShareLink,
|
|
removeShareLinksForResource,
|
|
} from './shareLinks';
|
|
export { saveRecipient, getRecipients, setRecipientActive } from './recipients';
|
|
export {
|
|
enqueuePendingOperation,
|
|
getPendingOperations,
|
|
getNextQueuedOperation,
|
|
listQueuedOperations,
|
|
scheduleRetries,
|
|
markPendingOperation,
|
|
MAX_PENDING_ATTEMPTS,
|
|
} from './pendingOps'; |