# agiledancers To map dance groups to performance days. The backend runs on Quarkus with Java 25. Requires JDK 25 and Maven 3.9.0 or newer. Set `JAVA_HOME` to your JDK 25 installation. Build and run all tests (including `*Sit` tests) from the repository root: ```sh mvn clean verify ``` Start development mode with live reload from the repository root: ```sh mvn -pl agiledancers-be quarkus:dev ``` Run the packaged application after building: ```sh java -jar agiledancers-be/target/quarkus-app/quarkus-run.jar ``` Build and run a Docker container from the repository root (only Docker is required): ```sh docker build -t agiledancers . docker run --rm --name agiledancers -p 8080:8080 agiledancers ``` The Docker build compiles the application and runs the tests in a Maven build stage, then copies the Quarkus application into a Java 25 runtime image running as a non-root user. Check readiness at or overall health at . For example: ```sh curl --fail http://localhost:8080/q/health/ready ``` Quarkus configuration can be overridden with environment variables, for example `docker run --rm -e QUARKUS_HTTP_PORT=9090 -p 9090:9090 agiledancers`. The REST API uses shared in-memory storage; data is lost when the process stops. Architecture checks run with the normal test suite, or separately with: ```sh mvn -pl agiledancers-be -Dtest=ArchitectureTest test ``` `ArchitectureTest` guards the following packages below `nl.agilecc.agiledancers`: | Package | Responsibility | Allowed dependencies within the application | | --- | --- | --- | | `model` | Domain entities and specifications | Model | | `service` | Application use cases and future ports | Model, repositories | | `repository` | Current in-memory persistence | Model | | `rest` | Future REST services | Services, model | | `solver` | Future OR-Tools calculations | Services (ports), model | REST and solver packages are optional until implemented. OR-Tools dependencies are allowed only in `solver`; JAX-RS and RESTEasy dependencies only in `rest`. The model may depend only on itself, Java and Lombok. Package cycles and production classes outside these packages fail the architecture tests. API models live in `rest.apimodel`, each in its own Java file as a public top-level class or record. Their names end in `Request`, `Response`, `View`, `Dto` or `DTO`. Architecture tests enforce this naming and location convention and require all records in the REST layer to reside in `rest.apimodel`. The current services instantiate concrete repositories, so this is not yet strict Onion architecture. That requires repository interfaces in the core and injected implementations in an outer adapter. For future calculations, define a port in `service.port` using domain types and implement it in `solver`; services must not depend on solver implementations or expose OR-Tools types. ## School management REST API All endpoints consume and produce JSON. Resources are scoped to their dance school. A dancer can belong to multiple dance groups within the same school. Memberships are managed separately from group details and survive updates to dancers and groups. | Resource collection | Item URL | | --- | --- | | `/api/dance-schools` | `/api/dance-schools/{schoolId}` | | `/api/dance-schools/{schoolId}/dancers` | `.../dancers/{dancerId}` | | `/api/dance-schools/{schoolId}/dance-groups` | `.../dance-groups/{groupId}` | | `/api/dance-schools/{schoolId}/shows` | `.../shows/{showId}` | Each collection supports `GET` (list) and `POST` (create). Each item supports `GET`, `PUT` (replace editable details), and `DELETE`. Creation returns `201` with a `Location` header; updates return `200`; deletion returns `204`. Invalid input returns `400`, and missing resources or resources belonging to another school return `404`. Client-supplied IDs are not used. Request bodies (dates use ISO `yyyy-MM-dd`): ```json {"name": "24 Dance Studio"} ``` ```json {"name": "Sam", "birthDate": "2010-05-12"} ``` ```json { "category": "Teens", "type": "REGULAR", "startAge": 12, "endAge": 18, "styles": ["HIPHOP", "JAZZ"] } ``` ```json {"name": "Annual show", "date": "2027-06-12"} ``` Names and categories must be nonblank. Birth dates cannot be in the future. Both ages must be nonnegative and `startAge <= endAge`; `styles` is required and may be empty. Group types are `SHOW_CASE`, `PRE_EDUCATION`, `SELECTION`, `REGULAR`, `PRE_SCHOOLER`. Styles are `HIPHOP`, `JAZZ`, `MODERN`, `STREETDANCE`, `CLASSIC`, `BREAKDANCE`. School responses include `dancerIds`, `danceGroupIds`, and `showIds`; group responses include `dancerIds`. To add or remove a dancer's group membership: ```sh curl -X PUT http://localhost:8080/api/dance-schools/0/dance-groups/0/dancers/0 curl -X DELETE http://localhost:8080/api/dance-schools/0/dance-groups/0/dancers/0 ``` Both operations return `204` and are idempotent for existing groups and dancers. Deleting a dancer removes all their memberships; deleting a group retains the dancers; deleting a school also deletes its dancers, groups and shows. Shows have a name, a date and three automatically created day parts: `MORNING`, `AFTERNOON`, `EVENING`. Each day part has an empty `danceGroupIds` list; assigning groups is not exposed yet. Multiple shows per year are allowed. Run the HTTP integration tests with: ```sh mvn -pl agiledancers-be -Dtest=SchoolManagementResourceTest test ``` ## Angular frontend The Angular 22 frontend is in [`agiledancers-fe`](agiledancers-fe/README.md), next to `agiledancers-be`. It provides Dutch-language screens to manage schools, dancers, groups, memberships and shows through the REST API. Use Node.js 22.22.3+ (22.x), 24.15.0+ (24.x), or 26+. Start the backend as described above, then run in a second terminal: ```sh cd agiledancers-fe npm ci npm start ``` Open . The development proxy forwards API requests to the backend on port 8080. Frontend builds and tests run independently of Maven: `npm run build` and `npm test`. See the frontend README for browser tests and production hosting requirements.