# LocalSyncManager Refactor Plan

## Objectives
- ✅ Replace ad-hoc table sync logic with policy-driven configuration that governs cadence, retention, transport choice, and conflict handling per dataset.
- ✅ Introduce a shared event bus that reports sync/search/connection state so UI components, logging, and background services stay in sync without tight coupling.
- ✅ Support hybrid offline/online behaviour: queue writes offline, hydrate views progressively, and surface status to users.
- 🔄 Continue improving reliability with analytics, search helpers, and telemetry extensions.

## Architecture Overview (Current State)
- **Policy Registry** – resolved via `services/syncpolicies` with overrides; exposes `getPolicy`/`setPolicy`.
- **Sync Orchestrator** – policy-driven scheduler manages cadence, offline behaviour, and transport fallback.
- **Event Bus** – `services/eventbus` provides `subscribe`/`unsubscribe`, state snapshots, and emits `sync:*`, `queue:update`, `transport:changed`, etc.
- **Queue & Retry Layer** – `sync_queue` store captures outbound work, enforces policy retry strategy, and surfaces dead-letter events.
- **Progressive Data Hydration** – `requestDataSource` offers snapshot + auto-refresh; DataLoader hooks in via event bus.
- **Upcoming** – search helper, richer metrics overlay, conflict handler customisation.

## Policy Schema (Draft)
```json
{
  "table": "modules",
  "mode": "hybrid",          // alwaysOffline | pullOnly | pushPull | websocketOnly
  "priority": 50,             // higher runs sooner
  "syncIntervalMs": 180000,   // base cadence (3 min)
  "backgroundOffsetMs": 15000,// start delay to stagger tables
  "idleBackoffMs": 600000,    // increase interval when no changes detected
  "offlineIntervalMs": 900000,// cadence while offline
  "transport": {
    "preferred": "websocket",
    "fallback": "rest",
    "probeIntervalMs": 60000,
    "maxRestFallback": 5
  },
  "retentionDays": 14,
  "maxRecords": 2000,
  "pushStrategy": "batch",
  "retryStrategy": {
    "type": "exponential",
    "initialDelayMs": 5000,
    "maxDelayMs": 300000,
    "maxAttempts": 5
  },
  "queueOffline": true,
  "conflictHandler": "serverWins",
  "searchIndex": {
    "enabled": true,
    "columns": ["name", "description"],
    "tokenizer": "basic"
  }
}
```

## API Surface Changes
- `LocalSyncManager` constructor now accepts `{ policyResolver, eventBus, ... }`.
- New methods:
  - `subscribe(eventName, handler)` / `unsubscribe(token)`
  - `getPolicy(table)`, `setPolicy(table, overrides)`
  - `requestDataSource(config)` → returns handle `{ cancel, pause, resume }`
  - `getStatus(table)` returning metrics + last sync state
  - `triggerSync(table, reason)` to manually enqueue immediate sync respecting policy
- `services/syncservice` exports helpers (`onSyncUpdate`, `registerPolicy`, `requestData`) that delegate to singleton.
- Legacy methods (`autoSync`, `startBackgroundSync`) remain temporarily but issue deprecation warnings.

## Migration Plan (Status)
1. **Infrastructure (Phase 1)** ✅ complete
2. **Policy Enforcement (Phase 2)** ✅ complete
3. **Transport & Retry (Phase 3)** ✅ complete
4. **Search Helper (Phase 4)** 🔄 helper available (local + remote); integrate modules & advanced indexing next
5. **Progressive Hydration (Phase 5)** 🔄 partial (request API live; module adoption ongoing)
6. **Cleanup & Docs (Phase 6)** 🔄 ongoing

## Testing Strategy
- Remove legacy tests; build a slim baseline covering event bus contracts, scheduler timing (fake timers), queue persistence, and transport fallback.
- Reintroduce integration coverage incrementally (ModuleLoader/DataLoader, calendar/POS) using the new APIs.
- Add mocks for IndexedDB/fetch/websocket to exercise offline-first flows and progressive hydration.
- Expand to E2E smoke tests after search helper and hydration are finalised.

## Rollout & Feature Flags
- Introduce `syncPoliciesEnabled` flag with “shadow mode” where policies are computed but not enforced; event bus still emits metrics.
- Gradually enable per-table policies starting with low-risk tables (e.g., `modules`, `tenant_settings`).
- Provide migration utilities for modules directly instantiating `LocalSyncManager` to switch to singleton helpers.
- Coordinate backend updates (policy metadata endpoint, websocket enhancements) before full rollout.

## Open Questions / Follow-ups
- Conflict resolution customization: do we need per-table bespoke handlers or global plugin system?
- Policy storage: local overrides persisted in IndexedDB or localStorage?
- Telemetry integration: push metrics to server vs client-side logging only.
- Backward compatibility window for older clients without policies/event bus.

---

Use this document to drive implementation tasks, assign milestones, and keep track of remaining decisions before coding the refactor.
