Files
agiledancers/README.md

150 lines
5.3 KiB
Markdown

# 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 <http://localhost:8080/q/health/ready> or overall health at
<http://localhost:8080/q/health>. 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
```