[DEV TASK]: BE Legacy aggregate-command write endpoints with eventId persistence
- Dominant language
- TypeScript
- Stars
- 1
- Forks
- 1
- Avg merge
- 13h 44m
- Merged PRs (30d)
- 63
Description
### Task Summary
Implement Legacy-side aggregate-command write endpoints accepting a backend-controlled `eventId`: WAA create/update plus sponsor, requirement-indicator, attachment-metadata, status-audit, and waste-history compatibility writes, all in one Oracle transaction.
### Task Details
**Context**: this is the receiving contract for the outbox (#1232/#1233). Legacy schema evidence: `WASTE_ASSESSMENT_AREA` (~50 columns incl. parent/child, marks, areas, dates), `WASTE_SPONSOR` (split-source mapping into modern `submitter`+`sponsor` rows), a status-audit table, `WASTE_HISTORY (WAA_ID, VERSION_ID)`. `REVISION_COUNT` semantics are Legacy's own optimistic-lock-like column (NOT the same as modern JPA `@Version`) and must be set explicitly by this endpoint, not left to Oracle defaults.
**API Contract** (Legacy-side, called by the modern outbox relay):
| Method | Path | Success | Errors |
| --- | --- | --- | --- |
| `POST` | `/legacy/api/waste-assessment-area/commands` | `201 Created` (echoes generated Legacy identifiers) | `400`, `500` |
**Request body** (aggregate-command shape, matches outbox payload):
```json
{
"eventId": "550e8400-e29b-41d4-a716-446655440000",
"sourceRevision": 15,
"waa": { "...": "full WAA column mapping" },
"sponsors": [ { "...": "submitter+sponsor split mapped back to WASTE_SPONSOR shape" } ],
"requirementIndicators": { "...": "" },
"attachmentMetadata": [ { "...": "" } ]
}
```
**Business rules**:
1. `eventId` is persisted on the Legacy side for later read-after-timeout lookups (#1235) but is explicitly NOT trusted for deduplication — Legacy has no atomic dedup guarantee, so the modern side's outbox/idempotency layer is the only source of exactly-once intent.
2. All child-table writes (sponsor, requirement indicators, attachment metadata, status audit, waste history) happen in ONE Oracle transaction with the WAA write — partial persistence is not acceptable.
3. `REVISION_COUNT` is set explicitly by this endpoint's logic (incrementing from the current value), not relied upon as an automatic optimistic-lock column the way modern `@Version` works.
4. Natural-key realities are honored: represented RU/WAA natural-key indexes in Legacy are non-unique — this endpoint does not assume or enforce uniqueness Legacy itself doesn't have.
5. JWT role filtering on the Legacy side remains unchanged by this work.
**Implementation steps**:
1. Add the Legacy-side controller/endpoint accepting the aggregate-command payload shape.
2. Map the payload to `WASTE_ASSESSMENT_AREA` plus child table inserts/updates within one `@Transactional` (Oracle) boundary.
3. Persist `eventId` on the Legacy row(s) for later lookup by #1235's classifier.
4. Explicitly compute and set `REVISION_COUNT`.
### Testing
| Check | Method |
| --- | --- |
| Atomic multi-table persistence | Integration test (Testcontainers Oracle where available, or the closest available Oracle-compatible test target): full aggregate-command persists all tables or none |
| Identifier echo | Response returns Legacy-generated identifiers for downstream classification lookups |
| `REVISION_COUNT` handling | Test asserting the value increments correctly across repeated updates |
| Round-trip mapping | Modern-command → Legacy rows compared against the documented Legacy column maps |
### Affected Environments
- [x] Development
- [ ] Test
- [ ] Production
### Additional Context
**Source**: District Average implementation plan — parent epic #625. Cross-links: depends on #1213 (HBS/Legacy discovery); consumed by #1232/#1233 (outbox), #1235 (classification lookup target).
**Estimate**: low 26h / expected 48h / high 76h — Fibonacci 8, confidence medium-low; unknowns: production Oracle DDL drift vs. reduced corpus.
Contributor guide
Assessment
This issue has not been assessed yet.