mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-09-07 10:27:15 +02:00
docs: plan for request versioning
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
# Request versioning (IntelliJ Local History style)
|
||||
|
||||
Working plan for `feat/request-versioning`. Tracks
|
||||
[save-request-data-for-response-history](https://yaak.app/feedback/posts/save-request-data-for-response-history).
|
||||
|
||||
Selecting an old response should be able to show, and restore, the request that produced it.
|
||||
|
||||
## Model
|
||||
|
||||
One table, `model_versions`, versions every request type:
|
||||
|
||||
| column | meaning |
|
||||
| --- | --- |
|
||||
| `id`, `model`, `created_at`, `updated_at` | usual model columns |
|
||||
| `workspace_id` | owning workspace |
|
||||
| `model_type` | `http_request` / `grpc_request` / `websocket_request` |
|
||||
| `model_id` | the request the version belongs to |
|
||||
| `content_hash` | sha256 of the canonical document |
|
||||
| `document` | JSON of the request's editable content |
|
||||
| `reason` | `send` / `switch` / `idle` / `restore` / `manual` |
|
||||
|
||||
`http_responses`, `grpc_connections` and `websocket_connections` each gain a nullable
|
||||
`version_id`.
|
||||
|
||||
A version's `document` is the model's JSON with bookkeeping keys removed — `model`, `id`,
|
||||
`createdAt`, `updatedAt`, `workspaceId`, `folderId`, `sortPriority`. One rule, applied the same
|
||||
way to all three request types; the hash is taken over exactly what the document holds, so moving
|
||||
a request between folders or re-sorting it never mints a version.
|
||||
|
||||
`(model_id, content_hash)` is unique, so dedup is the database's job rather than a code path that
|
||||
can be forgotten. Sending an unchanged request ten times leaves one version and ten responses
|
||||
pointing at it.
|
||||
|
||||
## Snapshot
|
||||
|
||||
One primitive, `ClientDb::snapshot_request(request, reason)`: build the document, hash it, return
|
||||
the existing row for that hash or insert a new one, then prune. Everything calls it.
|
||||
|
||||
- **Sends.** `resolve_send_inputs` (HTTP, every host — desktop, CLI, plugin-triggered) snapshots
|
||||
before the response row is created, and the resulting id rides down to the response.
|
||||
gRPC and WebSocket connect paths do the same at their own connection upserts.
|
||||
- **Edit-session boundaries the frontend can see**, all through one RPC: switching to another
|
||||
request, window blur, app close, and a 60s idle timer after the last edit.
|
||||
|
||||
Over-triggering is free, so the trigger code stays dumb.
|
||||
|
||||
## Restore
|
||||
|
||||
`restore_request_version(version_id)`:
|
||||
|
||||
1. Snapshot the live request (reason `restore`), so anything newer than its last version is kept.
|
||||
2. Merge the version's document over the live model, keeping bookkeeping fields.
|
||||
3. Upsert. The written content's hash already exists, so no new version row appears.
|
||||
|
||||
The frontend calls `wasUpdatedExternally` afterwards so open editors reload.
|
||||
|
||||
## Retention
|
||||
|
||||
An unreferenced version survives only while it is among the newest 50 for its request *and* newer
|
||||
than 30 days. A version referenced by a response lives as long as that response. Deleting a
|
||||
request deletes its versions. Versions are local history: not synced to the filesystem, not in
|
||||
Git, not exported.
|
||||
|
||||
## UI (v1, HTTP)
|
||||
|
||||
When the selected response's version differs from the live request, the response header grows a
|
||||
state-labelled dropdown ("Request Changed", following the GraphQL editor's pattern) with **View
|
||||
Diff** and **Restore**. The diff reuses the Git dialog's `DiffViewer` over YAML renderings of the
|
||||
two documents. No versions timeline panel in v1; gRPC and WebSocket are wired on the backend from
|
||||
day one and their UI can follow.
|
||||
|
||||
## Status
|
||||
|
||||
- [ ] Migration + `ModelVersion` model + bindings
|
||||
- [ ] Hashing / document extraction, with tests
|
||||
- [ ] Queries: snapshot, prune, restore, cascade
|
||||
- [ ] Send pipelines: HTTP, gRPC, WebSocket
|
||||
- [ ] RPC commands + web/wasm host
|
||||
- [ ] Frontend: snapshot triggers, dropdown, diff dialog, restore
|
||||
Reference in New Issue
Block a user