# HemHubs arkitektur Detta dokument beskriver den arkitektur som kan verifieras i repositoryts kod, tester och konfiguration. Historiska implementationssteg finns under [`features/`](features/) och övergripande beslut under [`decisions/`](decisions/). ## Aktuell implementation ### Monorepo HemHub ligger i ett Git-repository med två separata applikationer: ```text hemhub/ ├── backend/ ├── frontend/ └── docs/ ``` Applikationerna har egna byggverktyg och beroenden. De delar inte källkod eller byggprocess. ### Frontend Frontend finns i `frontend/` och använder React 19, TypeScript, Vite och pnpm. 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. Tillståndet hanteras lokalt i React-komponenter. Ingen router eller separat global state-lösning används. ### Backend Backend finns i `backend/` och använder Java 21, Spring Boot 4.1.0, Maven, Spring Web, Spring Data JPA och Flyway. Maven Wrapper ingår i repositoryt. Backend ansvarar för API, slutlig validering, skapande av UUID och tidsstämplar, persistens samt sortering av returnerade användare och uppgifter. ### Kommunikation Alla applikationsendpoints ligger under `/api`. Frontend använder enbart relativa adresser, exempelvis `/api/users` och `/api/tasks`. Vid lokal utveckling kör Vite normalt på port 5173 och proxar `/api` till `http://localhost:8080`, där Spring Boot körs. Ingen generell CORS-konfiguration finns i backend. Webbläsaren anropar därmed Vites origin, och utvecklingsservern vidarebefordrar API-anropen. Aktuella endpoints: - `GET /api/health` - `GET /api/users` - `POST /api/users` - `GET /api/tasks` - `POST /api/tasks` - `PUT /api/tasks/{taskId}/assignee` ### Databas och migreringar Lokal körning använder en H2-databas i minnet. Databasen finns under backendprocessens livstid och lokal utvecklingsdata återställs när backend startas om. Automatiska backendtester använder en separat H2-databas i minnet. Båda anslutningarna använder H2:s `MODE=PostgreSQL`, `DATABASE_TO_LOWER=TRUE` och `DEFAULT_NULL_ORDERING=HIGH`. Det är en verifierbar kompatibilitetsinställning, inte samma sak som att applikationen har verifierats mot PostgreSQL. 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. ### Domänmodell #### Användare En användare lagras i tabellen `app_user` med: - `id`: UUID; - `name`: visningsnamn, högst 50 tecken; - `normalized_name`: trimmat namn i gemener, internt och unikt; - `created_at`: en `Instant`, lagrad som `TIMESTAMP WITH TIME ZONE`. `normalized_name` exponeras inte via API. Användare returneras alfabetiskt efter visningsnamn med deterministiska sekundära jämförelser. #### Uppgift En uppgift lagras i tabellen `task` med: - `id`: UUID; - `title`: obligatorisk titel, högst 100 tecken; - `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. 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 Användarlistan hämtas från backend. Frontend lagrar endast den valda användarens UUID i webbläsarens `localStorage` under nyckeln `hemhub.activeUserId`. Vid start verifieras det lagrade id:t mot backendens aktuella användarlista. Ett giltigt val återanvänds i samma browser. Ett ogiltigt val tas bort. Valet är 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`, 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 misslyckade API-anrop. ### Teststrategi Backend har JUnit 5-tester: - ett fristående MockMvc-test för health-endpointen; - Spring Boot-integrationstester via MockMvc mot H2 in-memory för användar- och uppgifts-API. Frontend använder Vitest, jsdom och React Testing Library. `fetch` och `localStorage` ersätts i testerna, så frontendtesterna kräver inte en körande backend. Produktionsbygget kör TypeScript-kompilering följt av Vite. ### Produktionsdeployment Ingen produktionsdeployment är implementerad i repositoryt. Det finns inga Dockerfiler, pipelinefiler eller produktionsspecifika Nginx-, Watchtower- eller databaskonfigurationer. H2 används både lokalt och i automatiska tester; någon PostgreSQL-konfiguration finns ännu inte. ## Beslutad planerad riktning Repositoryt anger att affärsregler även framöver ska säkerställas i backend och att större arkitekturella beslut ska diskuteras innan de införs. Följande produktionsriktning är beslutad men ännu inte implementerad: - PostgreSQL ska användas som produktionsdatabas. - Frontend och backend ska paketeras som separata Docker-images. - Källkoden ligger i Gitea. - Drone ska bygga och publicera images till ett privat registry. - Watchtower ska uppdatera de körande tjänsterna när nya images publiceras. - Nginx kan användas som reverse proxy framför tjänsterna. - Produktionsmiljön ska köras på Ubuntu-servern Biff. Den planerade riktningen beskrivs även i [`005-production-deployment-direction.md`](decisions/005-production-deployment-direction.md). Punkterna ovan beskriver målbilden och ska inte tolkas som att motsvarande konfiguration redan finns eller har verifierats. ## Fortfarande öppna detaljer Följande har inte fastställts i dokumentationen och ska beslutas i samband med att produktionslösningen implementeras: - exakt containerstruktur och tjänsteindelning; - image-namn och taggningsstrategi; - produktions-URL; - hantering och distribution av secrets; - exakt Nginx-konfiguration; - exakt Drone-, registry-, Watchtower- och deploymentkonfiguration. Miljöspecifika adresser, credentials och secrets ska inte lagras i dessa arkitekturdokument.