feat(sync): wire up cf-core sync module for cross-device localStorage #120

Open
opened 2026-06-05 12:53:51 -07:00 by pyr0ball · 0 comments
Owner

Context

circuitforge_core.sync (cf-core #56 + #57) ships a shared opt-in localStorage sync module. Peregrine stores dismissed jobs and draft state in localStorage only — lost on browser clear, invisible on other devices.

What to wire up

  1. Install dep: pip install -e ../circuitforge-core[sync]
  2. In the FastAPI app, add:
from circuitforge_core.sync import make_sync_router, SyncConfig

sync_router = make_sync_router(
    product="peregrine",
    get_session=_sessions.dependency(),
    require_paid=_sessions.require_tier("paid"),
    config=SyncConfig.from_env("peregrine"),
)
app.include_router(sync_router, prefix="/sync", tags=["sync"])
  1. Add SYNC_DB_PATH / CLOUD_DATA_ROOT to .env.example
  2. Add frontend sync toggle UI — one toggle per data class:
    • peregrine:dismissed — dismissed job IDs
    • peregrine:drafts — local draft cover letter state
  3. Wire localStorage writes to call POST /sync/push after save (Paid+ only)
  4. On app load (Paid+), call GET /sync/pull and merge into localStorage

Notes

  • Prefs default to disabled — no pre-checked boxes, consent is per data class
  • DELETE /sync/all must be accessible from account settings (any tier)

References

  • cf-core sync module: circuitforge_core/sync/
  • cf-core #56 (storage), #57 (consent layer)
## Context `circuitforge_core.sync` (cf-core #56 + #57) ships a shared opt-in localStorage sync module. Peregrine stores dismissed jobs and draft state in localStorage only — lost on browser clear, invisible on other devices. ## What to wire up 1. Install dep: `pip install -e ../circuitforge-core[sync]` 2. In the FastAPI app, add: ```python from circuitforge_core.sync import make_sync_router, SyncConfig sync_router = make_sync_router( product="peregrine", get_session=_sessions.dependency(), require_paid=_sessions.require_tier("paid"), config=SyncConfig.from_env("peregrine"), ) app.include_router(sync_router, prefix="/sync", tags=["sync"]) ``` 3. Add `SYNC_DB_PATH` / `CLOUD_DATA_ROOT` to `.env.example` 4. Add frontend sync toggle UI — one toggle per data class: - `peregrine:dismissed` — dismissed job IDs - `peregrine:drafts` — local draft cover letter state 5. Wire localStorage writes to call `POST /sync/push` after save (Paid+ only) 6. On app load (Paid+), call `GET /sync/pull` and merge into localStorage ## Notes - Prefs default to disabled — no pre-checked boxes, consent is per data class - `DELETE /sync/all` must be accessible from account settings (any tier) ## References - cf-core sync module: `circuitforge_core/sync/` - cf-core #56 (storage), #57 (consent layer)
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: Circuit-Forge/peregrine#120
No description provided.