feat: drift och flyttade services i master-UI:t (Ledger) #28

Open
opened 2026-10-13 08:21:50 +00:00 by shcizo · 0 comments
Owner

Beskrivning

#10 lägger till backend för drift och merge: beräkning av drift, "restore desired", "accept running", förslag om flyttade services och merge. UI:t ingår inte där, eftersom sidorna skrivs om enligt Ledger-designen i #18. Den här issuen gör funktionerna synliga och klickbara i Ledger-stil.

Beror på #10 och #18. Påbörjas när båda är mergade.

Design

Ledger-designen i Claude Design: https://claude.ai/artifact/8ARU9MzvDVxWC3VPmdgix8. Den har badgen för drift, som #18 uttryckligen lämnade till fas 5.

  • Services (overview):
    • En drift-badge på rader där .Service.Drifted är true.
    • "Moved from A?" på den nya raden när ett flyttförslag finns, med en Merge-knapp.
  • Service-sidan:
    • Vid drift: desired- och running-ref sida vid sida, med knapparna "Restore desired" och "Accept running".
    • Om restore inte är tillåten (RestoreBlocked är satt): knappen inaktiverad, med anledningen i title eller i text.
    • "Moved from A?" med Merge på en levande rad (MoveFrom). "Moved to B" med länk på en borttagen rad (MoveTo).
    • En manuell merge: en väljare över MergeSources ("Merge history from…") med en bekräftelseruta i popover, som Revoke i #18.

Tekniska noteringar

  • Backend från #10:
    • POST /services/{id}/restore startar ett manuellt jobb till desired_ref och redirectar till jobbet.
    • POST /services/{id}/accept kräver formulärfältet actual={{.Service.RunningRef}} (det pinnade värdet som kommer att skrivas, inklusive digest). Fältet är bara ett skydd mot att acceptera en version användaren aldrig såg, och värdet som skrivs räknas alltid fram från raden.
    • POST /services/{id}/merge: {id} är den levande raden och formulärfältet from är den borttagna raden. Svaret redirectar till /services/{from}, eftersom den gamla raden behåller sitt ID.
    • Alla tre returnerar 409 och renderar service.html med .Error när åtgärden vägras.
    • accept stödjer return=overview, som setMode.
  • Fält i pageData:
    • RestoreBlocked string
    • MoveFrom *model.Move och MoveTo *model.Move. Move har FromID, ToID, FromAgent och ToAgent.
    • MergeSources []model.Service
  • Översikten behöver kopplas in: serviceData ska fylla en map[int64]model.Move från store.MoveCandidates, med ToID som nyckel. Det sköts medvetet inte i #10, eftersom #18 skriver om serviceData/groupServices.
  • Ändras inte:
    • CSRF på alla POST.
    • Inget template.HTML på värden som användare eller agenter styr. Refs och agentnamn är agentstyrda.
  • htmx/SSE som i #18: efter accept och merge publiceras events.Services, och efter merge även events.Jobs.

Scope

Ingår:

  • Drift-badge, restore och accept, flyttförslag med Merge, manuell merge.
  • Inkopplingen av översikten ovan.
  • Webbtester för de nya fragmenten.

Ingår inte:

  • Ändringar i drift- eller merge-logiken (#10).
  • Övriga badges och knappar i Ledger-stil från fas 2–4 (#18 eller egen issue).

Klart när:

  • Drift, restore, accept och merge går att utföra från UI:t.
  • Det är verifierat i webbläsare i båda teman, på desktop och vid 390 px bredd.
  • go test ./... passerar.
## Beskrivning #10 lägger till backend för drift och merge: beräkning av drift, "restore desired", "accept running", förslag om flyttade services och merge. UI:t ingår inte där, eftersom sidorna skrivs om enligt Ledger-designen i #18. Den här issuen gör funktionerna synliga och klickbara i Ledger-stil. Beror på #10 och #18. Påbörjas när båda är mergade. ## Design Ledger-designen i Claude Design: https://claude.ai/artifact/8ARU9MzvDVxWC3VPmdgix8. Den har badgen för drift, som #18 uttryckligen lämnade till fas 5. - **Services (overview):** - En drift-badge på rader där `.Service.Drifted` är true. - "Moved from A?" på den nya raden när ett flyttförslag finns, med en Merge-knapp. - **Service-sidan:** - Vid drift: desired- och running-ref sida vid sida, med knapparna "Restore desired" och "Accept running". - Om restore inte är tillåten (`RestoreBlocked` är satt): knappen inaktiverad, med anledningen i `title` eller i text. - "Moved from A?" med Merge på en levande rad (`MoveFrom`). "Moved to B" med länk på en borttagen rad (`MoveTo`). - En manuell merge: en väljare över `MergeSources` ("Merge history from…") med en bekräftelseruta i popover, som Revoke i #18. ## Tekniska noteringar - **Backend från #10:** - `POST /services/{id}/restore` startar ett manuellt jobb till `desired_ref` och redirectar till jobbet. - `POST /services/{id}/accept` kräver formulärfältet `actual={{.Service.RunningRef}}` (det pinnade värdet som kommer att skrivas, inklusive digest). Fältet är bara ett skydd mot att acceptera en version användaren aldrig såg, och värdet som skrivs räknas alltid fram från raden. - `POST /services/{id}/merge`: `{id}` är den levande raden och formulärfältet `from` är den borttagna raden. Svaret redirectar till `/services/{from}`, eftersom den gamla raden behåller sitt ID. - Alla tre returnerar 409 och renderar `service.html` med `.Error` när åtgärden vägras. - `accept` stödjer `return=overview`, som `setMode`. - **Fält i `pageData`:** - `RestoreBlocked string` - `MoveFrom *model.Move` och `MoveTo *model.Move`. `Move` har `FromID`, `ToID`, `FromAgent` och `ToAgent`. - `MergeSources []model.Service` - **Översikten behöver kopplas in:** `serviceData` ska fylla en `map[int64]model.Move` från `store.MoveCandidates`, med `ToID` som nyckel. Det sköts medvetet inte i #10, eftersom #18 skriver om `serviceData`/`groupServices`. - **Ändras inte:** - CSRF på alla POST. - Inget `template.HTML` på värden som användare eller agenter styr. Refs och agentnamn är agentstyrda. - htmx/SSE som i #18: efter accept och merge publiceras `events.Services`, och efter merge även `events.Jobs`. ## Scope **Ingår:** - Drift-badge, restore och accept, flyttförslag med Merge, manuell merge. - Inkopplingen av översikten ovan. - Webbtester för de nya fragmenten. **Ingår inte:** - Ändringar i drift- eller merge-logiken (#10). - Övriga badges och knappar i Ledger-stil från fas 2–4 (#18 eller egen issue). **Klart när:** - Drift, restore, accept och merge går att utföra från UI:t. - Det är verifierat i webbläsare i båda teman, på desktop och vid 390 px bredd. - `go test ./...` passerar.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: shcizo/package-updater#28