Skip to content

feat(projects): POST /v1/projects/{id}/heartbeat (#106) - #128

Merged
pparage merged 1 commit into
devfrom
feat/project-heartbeat
Aug 6, 2026
Merged

feat(projects): POST /v1/projects/{id}/heartbeat (#106)#128
pparage merged 1 commit into
devfrom
feat/project-heartbeat

Conversation

@pparage

@pparage pparage commented Aug 6, 2026

Copy link
Copy Markdown
Member

Closes #106.

ProjectRepoAdapter.startHeartbeatWorker (adapter.ts:231) points a SharedWorker at this path on a timer. No route existed, so every tick 404'd and once the stale threshold passed, each open editor was told its session had gone stale.

Why add the endpoint rather than make locking client-only

The issue framed it as either/or, but the two concerns are already separate in the code:

  • the edit lock lives in the git-backed project repo and is written by the client (ProjectRepoAdapter.writeLock) — the backend has no lock model and does not need one
  • the worker only asks "is the backend reachable, and does it still know this project?" — which a client genuinely cannot answer on its own, and is exactly what a stale-session banner should reflect

So the endpoint is liveness only. It deliberately does no writes: it runs per open editor on a short interval, and carries no state the lock file does not already hold.

204 when the project exists, 404 otherwise — the worker treats a failed tick as a step toward stale.

Tests

Known project → 204 with an empty body; unknown → 404 with the NOT_FOUND envelope; and five consecutive pings leave the project row byte-identical, pinning the no-writes property.

467 passed, ruff clean, openapi.json regenerated.

ProjectRepoAdapter.startHeartbeatWorker points a SharedWorker at this
path on a timer; no route existed, so every tick 404'd and after the
stale threshold each open editor was told its session had gone stale.

Chose 'add the endpoint' over 'locking is client-only' because the two
concerns are already separate: the edit lock lives in the git-backed
project repo and is written by the client, while the worker only needs
to know whether the backend is reachable and still knows the project.
That is a real signal a client cannot derive on its own, and it is what
the stale-session banner should reflect.

Deliberately does no writes — it runs per open editor on a short
interval, and carries no state the lock file does not already hold.
404 for an unknown project, which the worker treats as a failed tick.
@pparage
pparage merged commit cd3b178 into dev Aug 6, 2026
3 checks passed
@pparage
pparage deleted the feat/project-heartbeat branch August 6, 2026 10:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant