feat: add task assignment
This commit is contained in:
@ -29,6 +29,7 @@ Den ansvarar för:
|
||||
- hämtning och presentation av användare och uppgifter;
|
||||
- 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;
|
||||
- klientnära validering och begripliga felmeddelanden;
|
||||
- uppgiftsbrädan med kolumnerna Väntande, Pågående och Klart.
|
||||
|
||||
@ -60,6 +61,7 @@ Aktuella endpoints:
|
||||
- `POST /api/users`
|
||||
- `GET /api/tasks`
|
||||
- `POST /api/tasks`
|
||||
- `PUT /api/tasks/{taskId}/assignee`
|
||||
|
||||
### Databas och migreringar
|
||||
|
||||
@ -77,6 +79,7 @@ Flyway kör migreringarna:
|
||||
- `V1__create_users.sql`
|
||||
- `V2__create_tasks.sql`
|
||||
- `V3__add_task_points.sql`
|
||||
- `V4__add_task_assignee.sql`
|
||||
|
||||
Hibernate är konfigurerat med `ddl-auto=validate`; Flyway skapar schemat och
|
||||
Hibernate validerar entiteterna mot det.
|
||||
@ -104,12 +107,19 @@ En uppgift lagras i tabellen `task` med:
|
||||
- `description`: valfri beskrivning, högst 500 tecken;
|
||||
- `status`: `WAITING`, `IN_PROGRESS` eller `COMPLETED`;
|
||||
- `points`: obligatoriskt heltal mellan 1 och 99;
|
||||
- `assignee_id`: nullable främmande nyckel till `app_user`;
|
||||
- `created_at`: en `Instant`, lagrad som `TIMESTAMP WITH TIME ZONE`.
|
||||
|
||||
Status lagras som enumens textvärde genom `EnumType.STRING`. Nya uppgifter får
|
||||
alltid status `WAITING`. Poängintervallet skyddas i backend och med en
|
||||
databasconstraint. Det finns ingen relation mellan uppgifter och användare;
|
||||
alla aktiva användare ser samma uppgiftslista.
|
||||
databasconstraint. En uppgift kan vara otilldelad eller referera till exakt en
|
||||
ansvarig användare. Relationen hämtas tillsammans med uppgifterna när de listas,
|
||||
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.
|
||||
|
||||
### Aktiv användare
|
||||
|
||||
@ -124,8 +134,9 @@ lokalt per browser och utgör inte autentisering eller behörighetskontroll.
|
||||
### Felhantering
|
||||
|
||||
Backend använder ett litet gemensamt JSON-format med `code` och `message`.
|
||||
`ApiExceptionHandler` översätter kända valideringsfel till `400 Bad Request`
|
||||
och dubbletter av användarnamn till `409 Conflict`.
|
||||
`ApiExceptionHandler` översätter kända valideringsfel till `400 Bad Request`,
|
||||
saknade uppgifter eller användare till `404 Not Found` och dubbletter eller
|
||||
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
|
||||
|
||||
122
docs/features/004-task-assignment.md
Normal file
122
docs/features/004-task-assignment.md
Normal file
@ -0,0 +1,122 @@
|
||||
# Feature 4 – Tilldelning av uppgifter
|
||||
|
||||
## Status
|
||||
|
||||
Pågående.
|
||||
|
||||
## Bakgrund
|
||||
|
||||
HemHub har centralt lagrade användare och gemensamma uppgifter. För att senare
|
||||
kunna införa regler för pågående arbete behöver en uppgift kunna ha en ansvarig
|
||||
användare, utan att tilldelning samtidigt ändrar uppgiftens status.
|
||||
|
||||
## Mål
|
||||
|
||||
- välja en valfri ansvarig när en uppgift skapas;
|
||||
- visa ansvarig på uppgiftskortet;
|
||||
- tilldela, byta eller ta bort ansvarig på en väntande uppgift;
|
||||
- lagra tilldelningen centralt så att alla användare ser samma värde.
|
||||
|
||||
## Omfattning
|
||||
|
||||
En uppgift kan vara otilldelad eller tilldelad exakt en befintlig användare.
|
||||
`Ingen` är standard vid skapande och den aktiva browseranvändaren förväljs
|
||||
inte. Frontend återanvänder användarlistan som redan hämtas vid appstart.
|
||||
|
||||
På ett otilldelat väntande kort öppnar `Ta uppgift` ett användarval. Ett
|
||||
tilldelat väntande kort visar namnet och öppnar samma val. Ändringen skickas
|
||||
direkt till backend och kortet uppdateras först med den bekräftade responsen.
|
||||
Vid fel behålls den tidigare tilldelningen och ett lokalt felmeddelande visas.
|
||||
|
||||
För `IN_PROGRESS` och `COMPLETED` visas ansvarig eller `Otilldelad` utan
|
||||
redigerbar kontroll.
|
||||
|
||||
## Produktregler
|
||||
|
||||
- En uppgift har högst en ansvarig.
|
||||
- Ansvarig är valfri och måste motsvara en befintlig användare.
|
||||
- Endast uppgifter med status `WAITING` får få ändrad ansvarig.
|
||||
- Tilldelning ändrar aldrig status, titel, beskrivning eller poäng.
|
||||
- Vem som helst kan välja valfri ansvarig; aktiv användare är inte
|
||||
autentisering eller behörighetskontroll.
|
||||
|
||||
## API-förändringar
|
||||
|
||||
`POST /api/tasks` accepterar det valfria fältet `assigneeId`. Saknat fält eller
|
||||
`null` skapar en otilldelad uppgift. Ett UUID som inte motsvarar en användare
|
||||
ger `404 Not Found`.
|
||||
|
||||
`PUT /api/tasks/{taskId}/assignee` ändrar endast ansvarig:
|
||||
|
||||
```json
|
||||
{"assigneeId": "d56b54dd-31b0-4d71-8a10-82464be59a61"}
|
||||
```
|
||||
|
||||
`{"assigneeId": null}` tar bort tilldelningen. Fältet måste finnas i requesten.
|
||||
Responsen är den uppdaterade uppgiften. Task-responser innehåller:
|
||||
|
||||
```json
|
||||
{"assignee": {"id": "d56b54dd-31b0-4d71-8a10-82464be59a61", "name": "Anna"}}
|
||||
```
|
||||
|
||||
Otilldelade uppgifter har `"assignee": null`. Ogiltigt UUID eller saknat fält
|
||||
ger `400`, okänd uppgift eller användare ger `404` och ändring av en uppgift
|
||||
som inte väntar ger `409`. Felen använder det befintliga formatet med `code`
|
||||
och `message`.
|
||||
|
||||
## Databasförändringar
|
||||
|
||||
`V4__add_task_assignee.sql` lägger till `task.assignee_id UUID NULL` med en
|
||||
främmande nyckel till `app_user.id`. Befintliga uppgifter blir otilldelade.
|
||||
Migreringen använder varken `ON DELETE CASCADE` eller `ON DELETE SET NULL`.
|
||||
|
||||
JPA-modellen använder en lazy `ManyToOne`. Repositoryts listning och
|
||||
id-hämtning använder en entity graph för att hämta ansvarig tillsammans med
|
||||
uppgiften och undvika N+1-frågor när responsen byggs.
|
||||
|
||||
## Frontendförändringar
|
||||
|
||||
Skapandedialogen innehåller ett tilldelningsval med `Ingen` och samtliga
|
||||
användare. Valet bevaras tillsammans med övriga formulärvärden vid fel.
|
||||
|
||||
Väntande kort har en separat tilldelningskontroll. Kontrollen är inaktiverad
|
||||
medan just det kortets request pågår; övriga delar av brädan förblir
|
||||
interaktiva. Serverns task-respons ersätter motsvarande uppgift i den befintliga
|
||||
listan utan att ändra ordningen.
|
||||
|
||||
## Tester och verifiering
|
||||
|
||||
Backendens integrationstester täcker skapande med och utan ansvarig,
|
||||
responsformat, okända id:n, tilldelning, byte, av-tilldelning, statuskonflikt
|
||||
och att övriga uppgiftsfält inte ändras.
|
||||
|
||||
Frontendtesterna täcker standardval och användarlista i skapandedialogen,
|
||||
create-requestens `assigneeId`, kortens redigerbara och statiska lägen,
|
||||
tilldelningsrequest, vänteläge, serverbekräftad uppdatering, av-tilldelning och
|
||||
fel utan optimistisk ändring.
|
||||
|
||||
Manuell verifiering ska omfatta skapande med och utan ansvarig, tilldelning,
|
||||
byte, av-tilldelning, bevarad status, omladdning, statiska kontroller för andra
|
||||
statusar, felrespons och projektets normala desktop- och mobilbredder.
|
||||
|
||||
## Avgränsning mot Feature 5
|
||||
|
||||
Feature 4 inför inget API eller UI för statusändring och inte regeln att
|
||||
`IN_PROGRESS` måste ha en ansvarig. Tilldelning leder inte automatiskt till
|
||||
`IN_PROGRESS`, och av-tilldelning leder inte automatiskt till `WAITING`.
|
||||
|
||||
## Ingår inte
|
||||
|
||||
Flera ansvariga, statusändring, drag-and-drop, generell redigering, radering,
|
||||
deadlines, återkommande uppgifter, poänghistorik, användaradministration,
|
||||
autentisering, behörighetskontroll och automatisk tilldelning ingår inte.
|
||||
|
||||
## Kända begränsningar
|
||||
|
||||
Användare kan ännu inte raderas, så relationens framtida beteende vid
|
||||
användarradering är inte beslutat. Frontend har ingen optimistisk uppdatering;
|
||||
det tidigare värdet ligger kvar tills backend svarar.
|
||||
|
||||
## Relaterade commits
|
||||
|
||||
Fylls i när featuren har committats.
|
||||
@ -43,11 +43,12 @@ Feature 0–2 är klara. Den aktuella applikationen har:
|
||||
- en bräda med Väntande, Pågående och Klart;
|
||||
- nya uppgifter som alltid skapas med status `WAITING`.
|
||||
|
||||
Det finns ännu inga uppgiftstilldelningar, statusändringar, drag-and-drop,
|
||||
redigeringar, raderingar, deadlines eller återkommande uppgifter.
|
||||
Tilldelning av högst en ansvarig användare per uppgift är under utveckling. Det
|
||||
finns ännu inga statusändringar, drag-and-drop, redigeringar, raderingar,
|
||||
deadlines eller återkommande uppgifter.
|
||||
Nuvarande användarval är inte autentisering.
|
||||
|
||||
**Feature 3 – Uppgiftspoäng är pågående.**
|
||||
**Feature 4 – Tilldelning av uppgifter är pågående.**
|
||||
|
||||
## Featureöversikt
|
||||
|
||||
@ -57,7 +58,7 @@ Nuvarande användarval är inte autentisering.
|
||||
| 1 – Användarval | Klar | 0 | Centrala användare och lokalt aktivt användar-id |
|
||||
| 2 – Skapa uppgifter | Klar | 0–1 | Gemensamma uppgifter och trekolumnsbräda |
|
||||
| 3 – Uppgiftspoäng | Pågående | 2 | Poäng på uppgifter |
|
||||
| 4 – Tilldelning | Planerad | 1–2 | Valfri ansvarig användare |
|
||||
| 4 – Tilldelning | Pågående | 1–2 | Valfri ansvarig användare |
|
||||
| 5 – Statusändring | Planerad | 4 | Backendstyrda statusövergångar |
|
||||
| 6 – Drag-and-drop | Planerad | 5 | Kortflytt via status-API |
|
||||
| 7 – Radera uppgift | Planerad | 2 | Bekräftad radering |
|
||||
@ -130,7 +131,7 @@ databasen har inget permanent defaultvärde.
|
||||
|
||||
### Feature 4 – Tilldelning av uppgifter
|
||||
|
||||
**Status:** Planerad
|
||||
**Status:** Pågående
|
||||
|
||||
**Beroenden:** Feature 1 och Feature 2
|
||||
|
||||
@ -141,13 +142,10 @@ databasen har inget permanent defaultvärde.
|
||||
- visa ansvarig på uppgiftskort;
|
||||
- kunna ändra ansvarig på en befintlig uppgift.
|
||||
|
||||
En väntande uppgift får vara tilldelad eller otilldelad. Tilldelning införs före
|
||||
statusändring eftersom en pågående uppgift senare måste ha en ansvarig.
|
||||
|
||||
**Öppna frågor:**
|
||||
|
||||
- om en uppgift ska ha endast en ansvarig;
|
||||
- hur borttagna användare ska hanteras när användarradering införs.
|
||||
En väntande uppgift får vara tilldelad eller otilldelad och har högst en
|
||||
ansvarig. Tilldelning införs före statusändring eftersom en pågående uppgift
|
||||
senare måste ha en ansvarig. Hur borttagna användare ska hanteras är fortsatt
|
||||
öppet tills användarradering införs.
|
||||
|
||||
### Feature 5 – Statusändring och statusregler
|
||||
|
||||
|
||||
Reference in New Issue
Block a user