Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions docs/requirements.md
Original file line number Diff line number Diff line change
Expand Up @@ -584,8 +584,12 @@ The v0.2 review **reclassified several of these as blockers** (they gate a phase
- **OQ-C** Feature-definition source of truth for hot-reload (P6): config file + watch, admin API, or
a config table. Leaning: pluggable `FeatureDefinitionProvider` SPI. Interacts with version-skew
([§15 R10](#15-review-driven-revisions-v02)). *(Follow-on.)*
- **OQ-D 🔴 BLOCKER (phase 2)** Wire money representation (integer cents vs decimal string) — blocks
OpenAPI client generation (FR-27, acceptance #10). Resolve before AR-3. → [§15 R17](#15-review-driven-revisions-v02).
- **OQ-D ✅ RESOLVED** Wire money representation. Money — and every numeric `value` field (counts,
cardinalities, sums) — crosses the wire as a **JSON string of a decimal integer** (`^-?\d+$`),
money in integer cents (e.g. `"14950"` = $149.50), matching the SPI's `BigDecimal` scale-0 cents
(P3). Chosen over a JSON number to avoid precision loss above 2⁵³ and float coercion in generated
clients, and over a decimal string for uniformity with the integer-cent SPI. The OpenAPI spec at
`velocity-api` (`Money`/`Value` schemas) encodes it. → [§15 R17](#15-review-driven-revisions-v02).
- **OQ-E ✅ RESOLVED** DISTINCT dimension values are keyed-hashed at rest (per-namespace salt). →
[§15 R11](#15-review-driven-revisions-v02).
- **OQ-F 🔴 BLOCKER (SPI freeze, phase 1)** Seed/backfill schema — `seed()` is a *published* SPI
Expand Down
7 changes: 7 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ lettuce = "7.6.0.RELEASE"
# Testing — Testcontainers for the backend integration tests (Postgres now; Redis/LocalStack later).
testcontainers = "1.21.4"

# OpenAPI parsing — validates the committed velocity-api spec is well-formed OpenAPI 3.1 in a test
# (velocity-api OpenApiSpecTest). velocity-only; tracks the current latest 2.1.x.
swagger-parser = "2.1.22"

# Test bundle (wired in the test convention plugin). Pinned to pk-auth.
junit-jupiter = "6.1.2"
assertj = "3.27.7"
Expand Down Expand Up @@ -86,6 +90,9 @@ hikaricp = { module = "com.zaxxer:HikariCP", version.ref = "hikaricp" }
# Persistence — Redis / Lettuce (phase-2 sliding/hot-path backend).
lettuce-core = { module = "io.lettuce:lettuce-core", version.ref = "lettuce" }

# OpenAPI 3.1 parser — used only in velocity-api's spec-validity test.
swagger-parser = { module = "io.swagger.parser.v3:swagger-parser", version.ref = "swagger-parser" }

# Testcontainers (backend integration tests).
testcontainers-core = { module = "org.testcontainers:testcontainers", version.ref = "testcontainers" }
testcontainers-junit-jupiter = { module = "org.testcontainers:junit-jupiter", version.ref = "testcontainers" }
Expand Down
11 changes: 6 additions & 5 deletions velocity-api/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ plugins {
}

description =
"velocity-api: the OpenAPI 3.1 document (source of truth for client generation) and the shared" +
" API DTOs used by the service tier and the generated Java client."
"velocity-api: the OpenAPI 3.1 document (source of truth); API DTOs are generated from it" +
" downstream (openapi-generator, AR-3)."

dependencies {
// Shared API DTOs are Jackson-serialized (NFR-4) and nullability-annotated (NFR-17).
api(libs.jspecify)
api(libs.bundles.jackson)
// No hand-written DTOs live here — the yaml under src/main/resources/openapi is the source of
// truth and clients/DTOs are generated from it downstream (AR-3). The only dependency is the
// OpenAPI parser used by OpenApiSpecTest to prove the committed spec is valid OpenAPI 3.1.
testImplementation(libs.swagger.parser)

testRuntimeOnly(libs.logback.classic)
}
Loading
Loading