150 lines
5.3 KiB
Markdown
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
|
|
```
|