fix(prompts): match the wire shapes the prompt version routes use - #355
Merged
Conversation
Editing a prompt's body was impossible against any server, and promoting a
version reported failure on success.
`POST /api/prompts/groups/{id}/prompts` nests the version under `prompt` in
both directions. The client sent it flat, so the route read the text where it
expected an object and answered 400 on every body edit; its response is
`{ prompt }` rather than a bare prompt, which would have failed to decode next.
`savePrompt` answers `{ message }` with HTTP 200 when the write fails, so the
wrapper's field is non-nullable and that body reports the failure it is.
`PATCH /api/prompts/{id}/tags/production` promotes `req.params.promptId` and
never reads a body, and answers `{ message }`, not the prompt. Decoding it as a
prompt threw, which turned an accepted promotion into a `Result.Error` and with
it skipped the repository's revision bump — so the composer's `/` picker went on
offering the superseded body until the app restarted. It now sends no body, like
the web client: a body naming a different prompt was silently ignored while
reading as though it chose which version went live.
Adding a version also does not make it live. A body edit now promotes the
version it just wrote and reports the save on both calls, so the edit reaches
the library row, the picker and the editor rather than being stored where
nothing reads it. Web promotes on save the same way (`alwaysMakeProd`).
`PromptsApiWireShapeTest` pins live captures of both bodies, since nothing above
`:core:network` can see a JSON key.
Contributor
Android debug APKArtifact:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Editing a prompt's body never worked against a real server, and promoting a version
reported failure when it had succeeded. Both are wire-shape mismatches on the two
prompt-version routes. Neither was visible from inside the app: the client compiled,
and the
Result.Erroreach produced was handled exactly as designed.Closes #317. The picker's remaining stale case is an edit, and it needed both fixes
here: the edited body had to reach the server at all, and the promotion that makes it
live had to report success so the repository's revision bump ran.
Changes
core:model/core:networkPOST /api/prompts/groups/{id}/promptsnests the version underpromptin bothdirections. The request was sent flat, so the route read the text where it expected
an object and answered HTTP 400 to every body edit.
AddPromptToGroupRequestnownests, reusing
CreatePromptData.{ prompt }rather than a bare prompt;AddPromptToGroupResponseunwraps it. Its field is non-nullable deliberately —
savePromptanswers{ message }with HTTP 200 when the write fails, so that body fails to decode and reports the failure
rather than a success carrying nothing the caller then promotes on.
PATCH /api/prompts/{id}/tags/productionanswers{ message }, not the prompt.Decoding it as a prompt threw, turning an accepted promotion into a
Result.Error.req.params.promptIdand never reads a body, so the client nolonger sends one and
UpdatePromptTagRequestis removed. It carried aproductionPromptIdthat was silently ignored while reading as though it chose whichversion went live.
core:dataupdatePromptProductionTagdrops its request parameter and returnsResult<Unit>.The decode failure happened before the revision bump, so an accepted promotion never
announced itself and the composer's
/picker went on offering the superseded bodyuntil the app restarted.
feature:chatproductionIdon the old one, so without the promotion the edit is stored where nothingreads it — the library row, the
/picker and the editor all show the production body.publishNewVersionreports the save only when both calls land, using the id from theadd's response. Web promotes on save the same way (
alwaysMakeProd, default on).Testing
PromptsApiWireShapeTestpins both routes against live response captures from av0.8.7 server: the nested request, the unwrapped response, the HTTP-200 failure body,
and the promotion's empty request. Nothing above
:core:networkcan see a JSON key,which is why these survived.
PromptEditorSaveOutcomeTestgains cases for the promotion — that it happens, that afailed promotion is not reported as saved, that an id-less response is not reported as
saved, and that an unchanged body writes no version.
production-tag decode, and the promotion each fails exactly the intended tests.
:core:network,:core:dataand:feature:chatunit suites,:app:assembleDebug, anddetekt commonMain on all four modules pass.
saves and reaches the library, the
/picker and insertion with no restart; "SetProduction" on an older version closes the sheet, moves the tag, and the picker follows
with no restart.