feat: add task status transitions

This commit is contained in:
Urban Modig
2026-07-27 00:46:37 +02:00
parent 6570aad4a2
commit 65a6488c0b
19 changed files with 893 additions and 125 deletions

View File

@ -30,6 +30,7 @@ Den ansvarar för:
- lokalt val av aktiv användare;
- formulär för att skapa användare och uppgifter;
- val och visning av ansvarig användare på uppgifter;
- serverbekräftade statusändringar genom knappar på uppgiftskorten;
- klientnära validering och begripliga felmeddelanden;
- uppgiftsbrädan med kolumnerna Väntande, Pågående och Klart.
@ -62,6 +63,7 @@ Aktuella endpoints:
- `GET /api/tasks`
- `POST /api/tasks`
- `PUT /api/tasks/{taskId}/assignee`
- `PUT /api/tasks/{taskId}/status`
### Databas och migreringar
@ -117,9 +119,14 @@ ansvarig användare. Relationen hämtas tillsammans med uppgifterna när de list
så API-responsen kan innehålla ansvarigs `id` och `name` utan separata
frontend-anrop. Alla aktiva användare ser samma uppgiftslista.
Ansvarig är valfri vid skapande. Endast väntande uppgifter kan få ändrad
ansvarig genom det särskilda tilldelnings-API:t. Tilldelning ändrar aldrig
uppgiftens status.
Ansvarig är valfri vid skapande. Tilldelnings-API:t kan tilldela eller byta
ansvarig i samtliga statusar. Ansvarig kan tas bort i `WAITING` och `COMPLETED`,
men inte i `IN_PROGRESS`. Tilldelning ändrar aldrig uppgiftens status.
Alla direkta statusövergångar är tillåtna och samma målstatus är idempotent.
`IN_PROGRESS` kräver en ansvarig. När en otilldelad uppgift påbörjas skickar
frontend aktiv användares id, och backend tilldelar användaren och ändrar status
i samma transaktion. En befintlig ansvarig byts aldrig av statusoperationen.
### Aktiv användare
@ -140,7 +147,8 @@ otillåtna tilldelningsändringar till `409 Conflict`.
Frontend skiljer mellan fel vid hämtning och skapande. Hämtfel kan
återförsökas. Formulärfel visas nära formuläret och inmatningen behålls vid
misslyckade API-anrop.
misslyckade API-anrop. Status- och tilldelningsfel visas lokalt på berört kort;
kortet uppdateras först med backendens bekräftade respons.
### Teststrategi

View File

@ -0,0 +1,123 @@
# Feature 5 Statusändring och statusregler
## Status
Färdig och verifierad på feature-branchen; ännu inte mergad till `main`.
## Bakgrund
Efter Feature 4 kan uppgifter vara otilldelade eller ha en ansvarig, men inget
API eller gränssnitt kan ändra status. Feature 5 inför ett enkelt knappflöde
före drag-and-drop och säkerställer statusreglerna i backend.
## Mål
- ändra status genom ett särskilt backend-API;
- tillåta direkta övergångar mellan `WAITING`, `IN_PROGRESS` och `COMPLETED`;
- kräva ansvarig för `IN_PROGRESS`;
- automatiskt tilldela aktiv browseranvändare när en otilldelad uppgift
påbörjas;
- tillåta statusberoende ändringar av ansvarig;
- använda serverbekräftade uppdateringar och vänteläge per kort.
## Status- och tilldelningsregler
Alla statusar får ändras direkt till varandra. Ett anrop med aktuell status som
mål är giltigt och idempotent. En uppgift behöver inte passera
`IN_PROGRESS` för att bli `COMPLETED`.
`WAITING` och `COMPLETED` får vara tilldelade eller otilldelade.
`IN_PROGRESS` måste alltid ha en ansvarig. Det befintliga tilldelnings-API:t
kan tilldela eller byta ansvarig i samtliga statusar och ta bort ansvarig i
`WAITING` och `COMPLETED`. Ett försök att ta bort ansvarig i `IN_PROGRESS`
avvisas med `409 TASK_REQUIRES_ASSIGNEE`. Tilldelning ändrar aldrig status.
När en otilldelad uppgift ändras till `IN_PROGRESS` skickar frontend aktiv
användares id. Backend verifierar användaren, tilldelar den och ändrar status i
samma transaktion. Om uppgiften redan har en ansvarig behålls den, och skickat
`activeUserId` används inte för att byta ansvarig.
## API-förändringar
Status ändras med:
```http
PUT /api/tasks/{taskId}/status
```
```json
{
"status": "IN_PROGRESS",
"activeUserId": "d56b54dd-31b0-4d71-8a10-82464be59a61"
}
```
`status` är obligatoriskt. `activeUserId` krävs endast när en otilldelad
uppgift ska bli `IN_PROGRESS`. Responsen använder samma fullständiga
task-format som övriga task-operationer.
Kända fel använder befintligt format med `code` och `message`:
- okänd uppgift: `404 TASK_NOT_FOUND`;
- saknad, null eller okänd status: `400 INVALID_TASK_STATUS`;
- okänd användare: `404 USER_NOT_FOUND`;
- otilldelad `IN_PROGRESS`: `409 TASK_REQUIRES_ASSIGNEE`;
- ogiltigt UUID-format: `400` med befintlig requestfelkod.
`USER_NOT_FOUND` och `INVALID_TASK_ASSIGNMENT` återanvänds från Feature 4 i
stället för att införa parallella felkoder för samma användar-id.
## Databasförändringar
Inga. Befintliga kolumner för status och ansvarig är tillräckliga.
## Frontendförändringar
Varje kort visar två statusknappar:
- `WAITING`: `Påbörja`, `Markera klar`;
- `IN_PROGRESS`: `Till Väntande`, `Markera klar`;
- `COMPLETED`: `Till Väntande`, `Påbörja igen`.
Tilldelningskontrollen är redigerbar i alla statusar. Alternativet `Ingen`
visas inte för `IN_PROGRESS`.
Status och tilldelning delar ett vänteläge per uppgift. Under ett anrop ligger
kortet kvar i sin kolumn och båda kontrollerna på kortet är inaktiverade.
Övriga kort är fortsatt interaktiva. Vid framgång ersätts uppgiften med
serverresponsen; vid fel behålls tidigare data och felet visas lokalt.
## Tester och verifiering
Backendtesterna omfattar samtliga direkta övergångar, idempotens, automatisk
tilldelning, bevarad ansvarig, statusvalidering, okända id:n, statusberoende
tilldelning och oförändrade uppgiftsfält.
Frontendtesterna omfattar knapparnas statusmappning, requestformat,
serverbekräftad flytt, automatisk tilldelning i responsen, lokalt vänteläge,
dubbelsubmitsskydd, fel utan optimistisk ändring och statusberoende
tilldelningsalternativ.
Manuell verifiering genomfördes genom ett sammanhängande flöde genom alla tre
statusar, automatisk tilldelning, byte och borttagning av ansvarig, omladdning
och centrala API-fel. Browserflödet verifierades i desktop- och mobilbredd utan
upptäckta problem.
## Avgränsningar
Ingen drag-and-drop, radering, generell redigering, sortering, deadline,
återkommande uppgift, status- eller poänghistorik, slutföranderegistrering,
statistik, användaradministration, autentisering eller behörighetskontroll
införs.
## Kända begränsningar
Aktiv användare är ett lokalt browserval och inte autentisering. Backend kan
verifiera att id:t finns, men inte vem som faktiskt använder browsern.
Statusknapparna är ett första gränssnitt före Feature 6. Det finns ingen
versionskontroll för konkurrerande uppdateringar utöver transaktioner och
aktuell serverlogik.
## Relaterade commits
Fylls i efter implementation och merge.

View File

@ -46,12 +46,12 @@ Feature 04 är klara. Den aktuella applikationen har:
- nya uppgifter som alltid skapas med status `WAITING`.
Tilldelning och status är separata egenskaper; tilldelningsflödet ändrar inte
uppgiftens status. Det finns ännu inga statusändringar, drag-and-drop,
redigeringar, raderingar, deadlines eller återkommande uppgifter.
uppgiftens status. Statusändring och regeln att `IN_PROGRESS` kräver ansvarig
är under utveckling. Det finns ännu ingen drag-and-drop, redigering, radering,
deadline eller återkommande uppgift.
Nuvarande användarval är inte autentisering.
**Feature 5 Statusändring och statusregler är nästa planerade
produktfeature.**
**Feature 5 Statusändring och statusregler är pågående.**
## Featureöversikt
@ -62,7 +62,7 @@ produktfeature.**
| 2 Skapa uppgifter | Klar | 01 | Gemensamma uppgifter och trekolumnsbräda |
| 3 Uppgiftspoäng | Klar | 2 | Poäng på uppgifter |
| 4 Tilldelning | Klar | 12 | Valfri ansvarig användare |
| 5 Statusändring | Planerad | 4 | Backendstyrda statusövergångar |
| 5 Statusändring | Pågående | 4 | Backendstyrda statusövergångar |
| 6 Drag-and-drop | Planerad | 5 | Kortflytt via status-API |
| 7 Radera uppgift | Planerad | 2 | Bekräftad radering |
| 8 Redigera uppgift | Planerad | 3 | Titel, beskrivning och poäng |
@ -152,7 +152,7 @@ senare måste ha en ansvarig. Hur borttagna användare ska hanteras är fortsatt
### Feature 5 Statusändring och statusregler
**Status:** Planerad
**Status:** Pågående
**Beroenden:** Feature 4
@ -169,11 +169,9 @@ bygga en komplex interaktion. Feature 5 återanvänder Feature 4:s
tilldelningsmodell och särskilda API för ansvarig; statusändring sker i ett
separat statusflöde.
**Öppna frågor:**
- vad som sker när en otilldelad uppgift sätts till `IN_PROGRESS`;
- om aktiv användare ska föreslås automatiskt;
- vad som sker om ansvarig tas bort från en pågående uppgift.
En otilldelad uppgift som sätts till `IN_PROGRESS` tilldelas automatiskt den
aktiva browseranvändaren. En befintlig ansvarig behålls. Ansvarig kan bytas men
inte tas bort medan uppgiften är pågående.
### Feature 6 Drag-and-drop