|
| 1 | +# AGENTS.md |
| 2 | + |
| 3 | +Guidance for coding agents working in `USACE/cwms-data-api`. |
| 4 | + |
| 5 | +## Repository Identity |
| 6 | + |
| 7 | +- GitHub repository: `USACE/cwms-data-api` |
| 8 | +- Primary branch: `develop` |
| 9 | +- Product: CWMS Data API (CDA), formerly RADAR, a REST API for USACE CWMS water data. |
| 10 | +- Runtime/build target: Java 11. Newer JDKs may work, but do not introduce Java APIs beyond Java 11. |
| 11 | +- License/contribution model: MIT license with DCO sign-off expectations in `CONTRIBUTING.md` and `CONTRIBUTORS.md`. |
| 12 | +- Formal `CODEOWNERS` is not present. Treat maintainership/review routing as social context, not policy. Visible long-running contributors include Mike Neilson, Ryan Ripken/RMA, Adam Korynta, Bryson Spilman, Ryan Miles, Zach Olson, and Charles Graham. Verify current reviewers on GitHub before assigning or naming people in PR text. |
| 13 | + |
| 14 | +## Top-Level Structure |
| 15 | + |
| 16 | +- `cwms-data-api/`: main Java WAR service. Most API work happens here. |
| 17 | +- `access-manager-api/`: access/auth support library used by the service. |
| 18 | +- `cda-gui/`: frontend artifact bundled into the WAR as webjar content. |
| 19 | +- `cda-client/`: generated TypeScript fetch client from OpenAPI output. |
| 20 | +- `docs/`: Read the Docs content and documentation build. |
| 21 | +- `buildSrc/`: shared Gradle conventions, including Java 11, Checkstyle, JaCoCo, dependency repositories. |
| 22 | +- `gradle/libs.versions.toml`: dependency version catalog. |
| 23 | +- `compose_files/`, `docker-compose.yml`, `docker-compose.README.md`: local Oracle/CDA/Keycloak development stack. |
| 24 | +- `config/`, `load_data/`, `user_test/`: operational/configuration and testing support assets. |
| 25 | + |
| 26 | +## Main Java Layout |
| 27 | + |
| 28 | +Inside `cwms-data-api/src/main/java/cwms/cda`: |
| 29 | + |
| 30 | +- `api/`: Javalin controllers, route handlers, OpenAPI annotations, request parsing, response format selection, and HTTP errors. |
| 31 | +- `data/dao/`: database access. Prefer jOOQ and CWMS package wrappers here. Keep SQL and database-specific behavior out of controllers. |
| 32 | +- `data/dto/`: DTOs serialized by JSON/XML/CSV/TAB formatters. Preserve public API field names and backwards compatibility. |
| 33 | +- `datasource/`: data source and connection support. |
| 34 | +- `features/`: feature flag support, backed by `src/main/resources/features.properties`. |
| 35 | +- `formatters/`: response format machinery for JSON, XML, CSV, TAB, and related adapters. |
| 36 | +- `helpers/`: shared utility code and annotations. |
| 37 | +- `security/`: auth/security helpers. |
| 38 | + |
| 39 | +Common endpoint pattern: |
| 40 | + |
| 41 | +1. Controller in `cwms.cda.api`. |
| 42 | +2. DTO in `cwms.cda.data.dto` or a domain subpackage. |
| 43 | +3. DAO in `cwms.cda.data.dao` or a domain subpackage. |
| 44 | +4. OpenAPI annotations on the controller. |
| 45 | +5. Integration test under the corresponding `cwms-data-api/src/test/java/cwms/cda/...` package. |
| 46 | + |
| 47 | +## Build And Test Commands |
| 48 | + |
| 49 | +Use the wrapper from the repo root. |
| 50 | + |
| 51 | +```sh |
| 52 | +./gradlew build |
| 53 | +``` |
| 54 | + |
| 55 | +Runs compile, unit tests, Checkstyle, and default verification. |
| 56 | + |
| 57 | +```sh |
| 58 | +./gradlew :cwms-data-api:test |
| 59 | +``` |
| 60 | + |
| 61 | +Runs non-integration tests for the service module. |
| 62 | + |
| 63 | +```sh |
| 64 | +./gradlew :cwms-data-api:integrationTests |
| 65 | +``` |
| 66 | + |
| 67 | +Runs tests tagged `integration`. These require Oracle/CWMS test infrastructure. Without bypass properties, testcontainers may pull/install Oracle and CWMS schema and can take 30-40 minutes on the first run. |
| 68 | + |
| 69 | +Use filters for focused test cycles: |
| 70 | + |
| 71 | +```sh |
| 72 | +./gradlew :cwms-data-api:integrationTests --tests '*LocationControllerTestIT' |
| 73 | +./gradlew :cwms-data-api:test --tests '*RangeParserTest' |
| 74 | +``` |
| 75 | + |
| 76 | +Useful documentation/client tasks: |
| 77 | + |
| 78 | +```sh |
| 79 | +./gradlew :cwms-data-api:validateOpenApiSpec |
| 80 | +./gradlew :cwms-data-api:generateOpenApiDoc |
| 81 | +./gradlew :cwms-data-api:compileTypeScriptOpenApiSpec |
| 82 | +``` |
| 83 | + |
| 84 | +## Local Runtime |
| 85 | + |
| 86 | +For Gradle `run`, put secrets and machine-specific values in `~/.gradle/gradle.properties`; do not commit real credentials. Use `gradle.properties.example` as the template. |
| 87 | + |
| 88 | +```sh |
| 89 | +./gradlew :cwms-data-api:run |
| 90 | +``` |
| 91 | + |
| 92 | +The Docker Compose stack provides Oracle, CDA, and Keycloak for local development: |
| 93 | + |
| 94 | +```sh |
| 95 | +docker compose up -d --force-recreate |
| 96 | +``` |
| 97 | + |
| 98 | +See `docker-compose.README.md` for ports, bundled users, and service inventory. |
| 99 | + |
| 100 | +Never point integration tests at production or valued databases. The test suite assumes it can create and delete data. |
| 101 | + |
| 102 | +## Testing Conventions |
| 103 | + |
| 104 | +- Unit tests are normal JUnit 5 tests and are excluded from the `integration` tag. |
| 105 | +- Integration tests should extend `DataApiTestIT`; it wires testcontainers, Keycloak, MinIO, OpenAPI validation, and cleanup helpers. |
| 106 | +- Register locations and other created data through `DataApiTestIT` helpers where possible so tests can be rerun cleanly. |
| 107 | +- Use explicit office IDs in requests. The integration database is multi-office and tests should not rely on implicit office behavior. |
| 108 | +- RestAssured is the standard HTTP test client. Failures should log request/response details. |
| 109 | +- Prefer parameterized tests for repeated API cases. |
| 110 | +- Do not make integration tests parallel unless the shared fixtures are redesigned; `DataApiTestIT` notes that it is not thread safe. |
| 111 | + |
| 112 | +## Database And SQL Guidance |
| 113 | + |
| 114 | +- Prefer jOOQ wrappers and generated CWMS package bindings in DAOs. |
| 115 | +- Keep database joins in SQL/jOOQ; do not pull broad datasets into Java just to join in memory. |
| 116 | +- Limit by office early whenever possible. |
| 117 | +- If nested queries are needed, name derived tables to avoid unstable generated names and shared-memory pressure. |
| 118 | +- Gate features that require newer CWMS schema behavior behind schema/version checks with clear error messages. |
| 119 | +- Be careful with generated jOOQ codegen compatibility. The service shades legacy and latest CWMS DB codegen artifacts; preserve that pattern. |
| 120 | + |
| 121 | +## API Compatibility |
| 122 | + |
| 123 | +- CDA has public users. Treat DTO fields, response formats, status codes, route paths, query parameters, and OpenAPI docs as compatibility surfaces. |
| 124 | +- Preserve legacy format behavior unless the task explicitly changes it. |
| 125 | +- When adding an endpoint, update OpenAPI annotations and add tests that demonstrate expected client usage. |
| 126 | +- If an endpoint supports multiple formats, verify JSON and any relevant CSV/TAB/XML paths. |
| 127 | +- Use `CdaError` and existing error helpers rather than ad hoc error responses. |
| 128 | + |
| 129 | +## Style |
| 130 | + |
| 131 | +- Match the style of the file being edited. |
| 132 | +- New Java code must pass Checkstyle 9.3 and target Java 11. |
| 133 | +- Existing files commonly include MIT license headers; keep them when editing and follow local convention for new Java files. |
| 134 | +- Use `FluentLogger` where nearby code does. |
| 135 | +- Keep controllers thin: parse/validate request, call DAO/service logic, format response. |
| 136 | +- Keep DAOs responsible for CWMS schema details, jOOQ, and CWMS package calls. |
| 137 | + |
| 138 | +## Agent Workflow |
| 139 | + |
| 140 | +Before changing code: |
| 141 | + |
| 142 | +1. Identify the module and package that owns the behavior. |
| 143 | +2. Read the existing controller, DAO, DTO, and tests for the nearest similar endpoint. |
| 144 | +3. Check `README.md`, `CONTRIBUTING.md`, `gradle.properties.example`, and `docker-compose.README.md` if build/test/runtime behavior is involved. |
| 145 | +4. Check GitHub state if the task depends on current issues, PRs, releases, maintainers, or CI behavior. |
| 146 | + |
| 147 | +Before finishing: |
| 148 | + |
| 149 | +1. Run the narrowest relevant tests. |
| 150 | +2. Run `./gradlew build` when the change affects shared Java code, build logic, DTOs, controllers, or generated docs. |
| 151 | +3. State clearly if integration tests were skipped and why. |
| 152 | +4. Do not include generated client/docs artifacts unless the task requires them. |
| 153 | +5. Do not commit credentials, local Gradle properties, database URLs, API keys, or generated local compose data. |
| 154 | + |
0 commit comments