Skip to content

feat(projects): project-level session heartbeat/lock endpoint (or decide locking is client-only) #106

Description

@pparage

Problem

The deployer-ui multi-tab lock design polls a backend endpoint that does not exist. In range42-deployer-ui, src/services/projectRepo/adapter.ts:231 starts a SharedWorker that does POST /v1/projects/{id}/heartbeat every 60s (the comment at :227 even calls it a "shim, spec §4"). There is no such route under app/routes/v1/projects/, so once the UI wires lock acquisition live, the worker will 404 every 60s.

Current state

  • Project routes implement list / create / patch / compose / validate only (app/routes/v1/projects/). No heartbeat / lock / unlock.
  • A DB-backed lock with heartbeat already exists, but only at deployment scope:
    • WorkspaceLock model — app/core/models.py:136 (owner, acquired_at, heartbeat_at, heartbeat_interval_s)
    • acquire_lock / release_lock / heartbeat / cleanup_stale_locksapp/core/locks.py:34-102 (stale threshold = 3 × interval)
    • Used during attempt start (app/core/deploy_trigger.py:63-82) but no HTTP surface exposes it.

So there is no server-side notion of "who is currently editing this project."

Decision needed

  1. Add project-scoped session endpoints, reusing app/core/locks.py:
    • POST /v1/projects/{id}/lock (acquire, returns owner/lease)
    • POST /v1/projects/{id}/heartbeat (refresh lease)
    • POST /v1/projects/{id}/unlock (release)
    • Lets the backend detect concurrent editors across browsers/devices (the git .lock file only coordinates within a shared repo).
  2. Or declare project locking purely client-side (git .lock file) and remove the heartbeat worker's backend dependency in the UI.

Option 1 is the smaller change given locks.py already has the machinery; it just needs a project-scoped table/owner key + 3 thin routes.

Related

Blocks the lock-heartbeat sub-task of range42-deployer-ui#96 (activate git-backed live editing). Surfaced during a cross-repo analysis of the git-backed-projects pipeline.

Metadata

Metadata

Assignees

No one assigned

    Labels

    feattrack_axis-01State management and operational integrity

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions