fix(lanes): stop archive/activate from clobbering feature title and links
archiveActiveFeature was overwriting a feature's own title with the LIVE lane's title on every clear/switch — a --title set on activation silently disappeared. activateFeature restored stage/status/gate/CI/ stages/notes onto the live lane when switching back to a past feature, but never links, so they vanished on reactivation. Both are fixed, with a regression test for each (full activate/archive/reactivate round trip for links). Also fixes server/routes/lanes.js: the doc comment explaining GET /:id/git's rationale had been left sitting above the newly-inserted /:id/features routes instead of its own route. docs/API.md's Lane features section described fields and behavior that don't exist in the real routes (an "active" boolean, a POST response containing "archivedPrevious", a "409 ESTALE" concurrency response) — rewritten to match the actual request/response shapes exactly.
This commit is contained in:
+20
-13
@@ -239,19 +239,11 @@ router.get("/:id/preflight", async (req, res) => {
|
||||
});
|
||||
|
||||
/**
|
||||
* A lane's working-copy facts: branch, short HEAD, that commit's subject, and
|
||||
* the uncommitted counts. Read-only, so no same-origin guard — that guard
|
||||
* exists for the destructive actions.
|
||||
*
|
||||
* Deliberately NOT part of `GET /api/lanes`: this shells out to git three
|
||||
* times, and that payload is polled and re-broadcast on every hook-driven
|
||||
* lane_update. Any failure — no such directory, not a repo, git itself
|
||||
* erroring — is reported as `available: false` rather than a 500, because a
|
||||
* lane pointing at a plain directory is a normal state, not a fault.
|
||||
*
|
||||
* The `/:id/:action` catch-all below cannot shadow this one — that route is a
|
||||
* POST and Express matches on method as well as path. Verified by moving this
|
||||
* registration after it: the suite stayed green.
|
||||
* Per-feature state and archive (B) — `lib/lane-features.js`. `GET
|
||||
* /:id/features` lists every feature the lane has ever activated (archived
|
||||
* or live); `GET /:id/features/:slug` shows one, including an archived
|
||||
* one's saved pipeline; `POST /:id/features/activate` switches the live
|
||||
* lane to a feature by slug, archiving whichever one was active first.
|
||||
*/
|
||||
router.get("/:id/features", (req, res) => {
|
||||
const lane = lanesLib.getLane(req.params.id);
|
||||
@@ -290,6 +282,21 @@ router.post("/:id/features/activate", sameOriginGuard, (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* A lane's working-copy facts: branch, short HEAD, that commit's subject, and
|
||||
* the uncommitted counts. Read-only, so no same-origin guard — that guard
|
||||
* exists for the destructive actions.
|
||||
*
|
||||
* Deliberately NOT part of `GET /api/lanes`: this shells out to git three
|
||||
* times, and that payload is polled and re-broadcast on every hook-driven
|
||||
* lane_update. Any failure — no such directory, not a repo, git itself
|
||||
* erroring — is reported as `available: false` rather than a 500, because a
|
||||
* lane pointing at a plain directory is a normal state, not a fault.
|
||||
*
|
||||
* The `/:id/:action` catch-all below cannot shadow this one — that route is a
|
||||
* POST and Express matches on method as well as path. Verified by moving this
|
||||
* registration after it: the suite stayed green.
|
||||
*/
|
||||
router.get("/:id/git", async (req, res) => {
|
||||
const lane = lanesLib.getLane(req.params.id);
|
||||
if (!lane) return res.status(404).json({ error: { code: "ENOLANE", message: "lane not found" } });
|
||||
|
||||
Reference in New Issue
Block a user