# Feature 3 – Uppgiftspoäng ## Status Planerad. ## Bakgrund HemHub ska på sikt kunna använda spelifiering för att uppmuntra familjemedlemmar att utföra uppgifter. Exempel på framtida funktioner kan vara mål, achievements och belöningar baserade på hur många poäng en användare samlar under en viss period. Feature 3 inför den grundläggande poänginformationen på uppgiften. Funktionen registrerar endast uppgiftens poängvärde. Intjäning av poäng och övrig spelifiering införs i senare features. ## Mål Feature 3 ska: - lägga till ett obligatoriskt poängvärde på varje uppgift; - låta användaren ange poäng när en uppgift skapas; - visa poängen på uppgiftskortet; - validera poängen konsekvent i frontend och backend; - dokumentera hur lokal utvecklingsdata hanteras. ## Betydelsen av poäng Poängen uttrycker uppgiftens samlade värde utifrån hur: - tidskrävande uppgiften är; - besvärlig uppgiften är; - viktig uppgiften är. När poängintjäning införs i en senare feature ska samma värde motsvara hur många poäng användaren får när uppgiften slutförs. Poängen är inte en exakt tidsuppskattning. En snabb men viktig uppgift kan därför ha ett högre poängvärde än en längre men mindre betydelsefull uppgift. Feature 3 registrerar endast poängvärdet. Den ska inte registrera: - vem som har tjänat poängen; - om poängen har delats ut; - när poängen har tjänats in; - någon historik över poäng. ## Poängskala Poäng ska vara ett heltal mellan 1 och 99, inklusive gränsvärdena. Alla heltal i intervallet är tillåtna. Feature 3 inför inte någon fast skala med fördefinierade steg. Giltiga exempel: - 1 - 7 - 25 - 99 Ogiltiga exempel: - inget värde; - `null`; - 0; - negativa tal; - 100 eller högre; - decimaltal; - text som inte kan tolkas som ett heltal. En fast poängskala kan införas senare om erfarenhet från användningen visar att det är lämpligt. ## Avgränsning Feature 3 omfattar endast: - uppgiftens titel; - uppgiftens valfria beskrivning; - uppgiftens obligatoriska poängvärde; - visning av poäng på uppgiftskortet. Feature 3 ska inte införa: - tilldelning av uppgifter; - ändring av uppgiftsstatus; - drag-and-drop; - redigering av befintliga uppgifter; - radering av uppgifter; - deadlines; - återkommande uppgifter; - poänghistorik; - användares poängsaldo; - topplistor; - statistik; - mål; - achievements; - belöningar; - automatisk utdelning av poäng när en uppgift slutförs. Dessa funktioner hanteras i senare features enligt roadmapen. ## Användarflöde När användaren öppnar dialogen för att skapa en uppgift ska formuläret innehålla: - titel; - beskrivning; - poäng. Poängfältet ska initialt innehålla värdet `1`. Användaren kan behålla standardvärdet eller ange ett annat heltal mellan 1 och 99. När uppgiften skapas ska frontend alltid skicka poängvärdet uttryckligen till backend. Backend ska inte själv fylla i ett saknat värde. Efter att en uppgift har skapats framgångsrikt ska formuläret återställas. Poängfältet ska då återgå till `1`. Om dialogen stängs och senare öppnas igen ska poängfältet också börja på `1`. ## Skapandedialog Poäng ska anges med ett vanligt numeriskt inmatningsfält. Fältet ska ha: - etiketten `Poäng`; - initialt värde `1`; - minsta värde `1`; - högsta värde `99`; - heltalssteg. En kort hjälptext kan visas: > 1–99 poäng beroende på hur tidskrävande, besvärlig eller viktig uppgiften är. Fältet får tillfälligt vara tomt medan användaren redigerar värdet. Frontend ska inte automatiskt återställa värdet till `1` medan användaren skriver. Validering ska främst ske när användaren försöker skicka formuläret. Avancerad validering vid varje tangenttryckning ingår inte i denna feature. ## Frontendvalidering Frontend ska blockera skapandeanropet om poängen inte är ett heltal mellan 1 och 99. Vid ett ogiltigt värde ska följande meddelande visas: > Poäng måste vara ett heltal mellan 1 och 99. Samma meddelande kan användas för: - tomt värde; - värde under 1; - värde över 99; - decimaltal; - annat ogiltigt innehåll. HTML-fältets attribut för minsta värde, högsta värde och heltalssteg får användas som stöd, men formulärlogiken ska också kontrollera värdet explicit. Backend är alltid den slutliga garanten för valideringsreglerna. ## Visning på uppgiftskortet Uppgiftens poäng ska visas på uppgiftskortet som en kompakt och dynamisk badge. Badgen ska: - renderas som en vanlig React- och HTML-komponent; - använda text och CSS; - läsa värdet från uppgiftens `points`; - visa värdet i formatet `{points} p`. Exempel: - `1 p` - `7 p` - `99 p` Ingen genererad bild eller statisk grafik ska användas för själva poängvärdet. Placering och visuell utformning ska följa projektets befintliga skärmbilder och nuvarande kortdesign. Poängindikatorn ska ligga i kortets metadataområde på motsvarande plats som poängindikatorn i designreferensen. Mindre justeringar får göras för att passa den faktiska kortimplementationen. Feature 3 ska däremot inte införa en ny övergripande design för uppgiftskortet. ## API Fältnamnet ska vara `points` genomgående i API, backend och frontend. ### Skapa uppgift Requesten för att skapa en uppgift ska innehålla: ```json { "title": "Töm diskmaskinen", "description": "Ställ in allt i rätt skåp", "points": 3 } ``` `points` är obligatoriskt. Backend ska inte tolka ett saknat värde som `1`. ### Uppgiftssvar API-svar som innehåller en uppgift ska också innehålla `points`. Exempel: ```json { "id": "00000000-0000-0000-0000-000000000000", "title": "Töm diskmaskinen", "description": "Ställ in allt i rätt skåp", "status": "WAITING", "points": 3, "createdAt": "2026-07-26T12:00:00Z" } ``` Det gäller både: - svaret efter att en uppgift skapats; - listning av uppgifter. Det exakta API-formatet ska i övrigt följa den befintliga implementationen. ## Backendregler En uppgift får aldrig existera med ett poängvärde utanför intervallet 1–99. Regeln ska skyddas genom hela backend, inte bara i HTTP-lagret. Beroende på repositoryts befintliga struktur ska valideringen tillämpas på relevanta nivåer, exempelvis: - requestvalidering; - applikations- eller domänlogik; - entitetsmodell; - databasens schema. Implementation ska följa projektets etablerade kodstruktur och inte introducera ett nytt arkitekturmönster enbart för denna feature. ## Felhantering Ett ogiltigt eller saknat `points` ska ge: ```text 400 Bad Request ``` Backend ska använda projektets befintliga felformat och befintliga felhantering. Feature 3 ska inte introducera en separat felmodell endast för poäng. Backend får ge mer precisa valideringsdetaljer för exempelvis: - saknat värde; - `null`; - värde under 1; - värde över 99. Frontend behöver inte återge varje backenddetalj separat, utan kan visa det gemensamma användarmeddelandet: > Poäng måste vara ett heltal mellan 1 och 99. Vid andra eller oväntade backendfel ska frontend fortsätta använda projektets befintliga generella felhantering. ## Databas Databasschemat ska innehålla ett obligatoriskt heltalsfält för uppgiftens poäng. Det logiska slutläget är: ```text points INTEGER NOT NULL ``` Databasen ska, om den befintliga schemahanteringen stödjer det, även skydda intervallet 1–99 med en motsvarande constraint. Databasen ska inte ha ett permanent defaultvärde för nya uppgifter. Nya uppgifter ska alltid få ett uttryckligt poängvärde från applikationen. Det förvalda värdet `1` är ett frontendbeteende och inte ett sätt för backend eller databasen att tyst komplettera ofullständiga anrop. ## Lokal utvecklingsdatabas Den lokala utvecklingsdatabasen ska vara en in-memory H2-databas. Databasen och dess innehåll ska återställas när backend startas om. Lokal utvecklingsdata betraktas därför som tillfällig. Användare och uppgifter som skapats manuellt under utveckling behöver inte bevaras mellan starter. Detta innebär att Feature 3 inte behöver migrera verkliga befintliga utvecklingsposter. En ny databas skapas direkt med det obligatoriska poängfältet. Codex ska kontrollera repositoryts faktiska konfiguration. Om H2 för närvarande är filbaserad ska den ändras till in-memory och relevant utvecklingsdokumentation ska uppdateras. ## Schemahantering och framtida migrering Att lokal utvecklingsdata inte bevaras innebär inte att framtida produktionsdata kan återställas vid varje release. När HemHub börjar använda en beständig Postgres-databas med data som ska bevaras måste schemaändringar hanteras med kontrollerade migreringar. Feature 3 behöver inte införa eller färdigställa hela den framtida produktionsstrategin om den ännu inte finns i repositoryt. Projektet använder redan Flyway och versionshanterade migreringar. Feature 3 ska därför lägga till en ny Flyway-migrering för poängfältet och inte ändra tidigare migreringar. Hibernate ska fortsatt validera schemat i stället för att skapa det. Bytet till in-memory H2 innebär att befintliga lokala utvecklingsposter inte behöver bevaras eller fyllas på med poäng. Själva schemaändringen ska ändå hanteras som en kontrollerad migrering så att migrationshistoriken förblir sammanhängande inför framtida beständig data. Repositoryts faktiska arkitektur och dokumentation har företräde. ## Backendtester Feature 3 ska minst verifiera att: - en uppgift kan skapas med ett giltigt `points`; - det skapade API-svaret innehåller samma `points`; - listning av uppgifter innehåller `points`; - gränsvärdet `1` accepteras; - gränsvärdet `99` accepteras; - saknat `points` ger `400 Bad Request`; - `points: null` ger `400 Bad Request`; - `points: 0` ger `400 Bad Request`; - negativa värden ger `400 Bad Request`; - `points: 100` ger `400 Bad Request`. Testerna ska följa befintlig teststil och utöka nuvarande tester där det är lämpligt. ## Frontendtester Feature 3 ska minst verifiera att: - skapandedialogen öppnas med poängvärdet `1`; - ett giltigt poängvärde skickas i create-anropet; - tomt poängfält blockerar submit; - ett värde under 1 blockerar submit; - ett värde över 99 blockerar submit; - ett ogiltigt värde visar felmeddelandet; - formuläret återställs till poängvärdet `1` efter lyckad skapning; - ett uppgiftskort visar uppgiftens dynamiska poängbadge; - badgen visar värdet från uppgiftsdata, exempelvis `7 p`. Testerna ska inte vara beroende av en viss pixelplacering eller detaljerad CSS. ## Manuell verifiering Följande ska verifieras manuellt: 1. Starta frontend och backend enligt projektets utvecklingsinstruktioner. 2. Skapa en uppgift utan att ändra poängfältet. 3. Verifiera att uppgiften får `1 p`. 4. Skapa en uppgift med ett mellanvärde, exempelvis `7`. 5. Verifiera att uppgiften får `7 p`. 6. Skapa en uppgift med `99`. 7. Verifiera att uppgiften får `99 p`. 8. Försök skapa en uppgift med tomt poängfält. 9. Verifiera att anropet blockeras och att rätt felmeddelande visas. 10. Försök använda värdena `0` och `100`. 11. Verifiera att båda avvisas. 12. Kontrollera att poängbadgen följer projektets designreferens och fungerar med ett- och tvåsiffriga värden. 13. Starta om backend. 14. Verifiera att den lokala utvecklingsdatan inte finns kvar. ## Acceptanskriterier Feature 3 är klar när: - varje ny uppgift har ett obligatoriskt `points`; - `points` är ett heltal mellan 1 och 99; - frontendens standardvärde är `1`; - frontend alltid skickar `points` uttryckligen; - backend avvisar saknat eller ogiltigt `points`; - backend fyller inte automatiskt i ett saknat värde; - uppgiftens poäng returneras av API:t; - uppgiftens poäng visas dynamiskt på uppgiftskortet; - frontend- och backendtester täcker centrala giltiga och ogiltiga fall; - lokal H2 körs som in-memory och återställs vid omstart; - relevant dokumentation är uppdaterad; - Feature 3 inte inför funktionalitet som hör till senare features. ## Implementationsprinciper När Feature 3 senare implementeras ska Codex först läsa: ```text AGENTS.md README.md docs/architecture.md docs/development.md docs/roadmap.md docs/decisions/ docs/features/ ``` Codex ska även läsa relevant backendkod, frontendkod och befintliga tester innan ändringar görs. Repositoryts faktiska kod och dokumentation har företräde framför antaganden i denna featurebeskrivning. Dokumentation, implementation och tester ska uppdateras tillsammans. Codex ska inte committa, pusha, skapa pull request eller merga utan uttrycklig instruktion.