- Overview
- Why these choices
- Getting Started
- Running Tests
- API
- Data Model
- Session Behavior (Task 3.4)
- Project Structure (key parts)
- Notes
- Database Dump
This project implements the assignment using a Spring Boot backend (Maven, Java 17) and an Angular frontend. It covers:
- Sectors seeded into a database and exposed via an API
- A form (Name, Sectors multi-select, Agree to terms)
- Validation (all fields are mandatory)
- Save to DB, auto-refill from stored data
- Session-based editing (update your submission during the session)
- Spring Boot 3 (Web, Data JPA): minimal boilerplate to expose REST.
- H2 (file mode): embedded DB persisting to disk - zero external setup.
- JPA entities:
Sector(id, name, parentId, sortOrder)UserSubmission(name, agreeTerms, sectors)with Many-to-Many sectors: one user can select many sectors; many users can select the same sector.
- Angular: reactive forms + HttpClient.
- Session identity: no login; server session cookie enables “edit during the session” as requested.
- Java 17 (e.g., Temurin 17)
- Node 18+ and npm
- Maven
From the project root:
mvn spring-boot:run- H2 database runs in file mode at
./data/appdb. - H2 console:
http://localhost:8080/h2-console(JDBC:jdbc:h2:file:./data/appdb, usersa, empty password).
From the project root:
cd frontend
npm startOpen http://localhost:4200.
- Dev proxy routes
/api/*tohttp://localhost:8080.
From the project root:
mvn test- Uses an in-memory H2 for tests (
jdbc:h2:mem:) andcreate-dropschema. - Includes:
SectorControllerTest: verifies/api/sectorsreturns ordered sectors.SubmissionControllerTest: validates input, persists submission, and refills via session (/api/submissions,/api/submissions/me).
From frontend/ directory:
npm test- Runs Karma with Chrome using Angular’s default test runner.
- Includes:
app.component.spec.ts: mocks/api/sectorsand/api/submissions/me, verifies reactive form validity and data load.
-
GET /api/sectors- Returns a flat, ordered list:
[{ id, name, parentId, sortOrder }] - The client computes indentation depth from
parentId.
- Returns a flat, ordered list:
-
GET /api/submissions/me- Returns current session’s submission, e.g.
{ id, name, agreeToTerms, sectorIds }, or empty if none exists yet.
- Returns current session’s submission, e.g.
-
POST /api/submissions- Request body (validated):
{ "name": "Alice", "sectorIds": [1, 18], "agreeToTerms": true }-
Returns the stored submission.
-
POST /api/submissions/new- Clears the current session’s submission and returns
204 No Content. - Use this to start creating a new entry.
- Clears the current session’s submission and returns
name: required, max length 200sectorIds: required (at least one)agreeToTerms: must be true
-
Sectorid: numeric ids from the original sector listparentId: preserves the hierarchy for indentationsortOrder: reproduces the original display order- Seeded at startup only if empty (idempotent)
-
UserSubmissionname: stringagreeTerms: booleansectors: Many-to-Many relation toSector
Seeding uses a Spring ApplicationRunner to avoid SQL-escaping pitfalls and ensure idempotency with the persistent H2 file DB.
- On first Save, a submission is created; its id is stored in the HTTP session.
- Subsequent Saves in the same session update that same record.
- Session ends when the browser is closed (default session cookie behavior). No login.
backend (Spring Boot, Maven)
└─ src/main/java/com/example/demo
├─ HelmesTechnicalApplication.java
├─ sector/
│ ├─ Sector.java
│ ├─ SectorRepository.java
│ └─ SectorDataLoader.java
└─ submission/
├─ UserSubmission.java
├─ UserSubmissionRepository.java
├─ SubmissionRequest.java
├─ SubmissionResponse.java
└─ SubmissionController.java
frontend (Angular)
└─ src/
├─ app/
│ ├─ app.component.ts
│ └─ app.component.html
├─ index.html
└─ styles.css
- Sectors are served from the backend and rendered by Angular with proper indentation computed client-side.
UML diagram
Data
Users
Sectors
Dump
appdb_dump.sql