6.3 KiB
HemHubs arkitektur
Detta dokument beskriver den arkitektur som kan verifieras i repositoryts kod,
tester och konfiguration. Historiska implementationssteg finns under
features/ och övergripande beslut under
decisions/.
Aktuell implementation
Monorepo
HemHub ligger i ett Git-repository med två separata applikationer:
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;
- 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/healthGET /api/usersPOST /api/usersGET /api/tasksPOST /api/tasks
Databas och migreringar
Lokal körning använder en filbaserad H2-databas under backend/data. Katalogen
ignoreras av Git. 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.sqlV2__create_tasks.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: enInstant, lagrad somTIMESTAMP 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_PROGRESSellerCOMPLETED;created_at: enInstant, lagrad somTIMESTAMP WITH TIME ZONE.
Status lagras som enumens textvärde genom EnumType.STRING. Nya uppgifter får
alltid status WAITING. Det finns ingen relation mellan uppgifter och
användare; alla aktiva användare ser samma uppgiftslista.
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
och dubbletter av användarnamn 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.
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.