|
25 | 25 | | Overdraft/Debt Model | — | 0 | |
26 | 26 | | Grace Period Handling | — | 0 | |
27 | 27 | | Test Coverage | — | 0 | |
| 28 | +| Tenant Default Config | — | 0 | |
28 | 29 |
|
29 | 30 | **All previously identified issues have been fixed. No remaining spec violations found.** |
30 | 31 |
|
@@ -149,15 +150,33 @@ Two-pass audit covering: |
149 | 150 | ### Test Coverage (above 98%) |
150 | 151 | - JaCoCo line coverage threshold raised from 90% to **95%** (enforced in parent pom.xml) |
151 | 152 | - **API module**: 209/209 lines covered — **100%** line coverage (93 unit tests) |
152 | | -- **Data module**: 770/782 lines covered — **98.5%** line coverage, 76% branch coverage (205 unit tests) |
| 153 | +- **Data module**: 770+ lines covered — **98.5%+** line coverage, 76%+ branch coverage (215 unit tests) |
153 | 154 | - Branch gaps: defensive null-check ternaries and unreachable `&&` short-circuit branches in `RedisReservationRepository` |
| 155 | + - Tenant default resolution: 10 unit tests covering all fallback paths, TTL capping, max extensions, malformed JSON recovery |
154 | 156 | - **Model module**: Coverage skipped (POJOs only, no business logic) |
155 | | -- Total unit test count: 93 (API) + 205 (Data) + 5 (Model) = **303 unit tests** |
156 | | -- **Integration tests**: 26 nested test classes covering all 9 endpoints, including: |
| 157 | +- Total unit test count: 93 (API) + 215 (Data) + 5 (Model) = **313 unit tests** |
| 158 | +- **Integration tests**: 27+ nested test classes covering all 9 endpoints, including: |
| 159 | + - Tenant Defaults (9 tests): overage policy resolution (ALLOW_IF_AVAILABLE, ALLOW_WITH_OVERDRAFT, REJECT), explicit override vs tenant default, TTL capping, max extensions enforcement, default TTL usage, no-tenant-record fallback |
157 | 160 | - Expiry Sweep (7 tests): end-to-end expire.lua execution, grace period skip, orphan TTL cleanup, multi-scope budget release, already-finalized skip |
158 | 161 | - Budget Status (2 tests): BUDGET_FROZEN and BUDGET_CLOSED enforcement on reserve |
159 | 162 | - All unit tests pass without Docker/Testcontainers (integration tests excluded by default) |
160 | 163 |
|
| 164 | +### Tenant Default Configuration (correct) |
| 165 | +- `default_commit_overage_policy`: resolved at reservation/event creation time |
| 166 | + - Resolution order: request-level `overage_policy` > tenant `default_commit_overage_policy` > hardcoded `REJECT` |
| 167 | + - Tenant config read from Redis `tenant:{tenant_id}` JSON record (shared with admin service) |
| 168 | + - Graceful fallback to `REJECT` on tenant read failure or missing record |
| 169 | +- `default_reservation_ttl_ms`: used when request omits `ttl_ms` (was hardcoded to 60000ms) |
| 170 | + - Resolution order: request `ttl_ms` > tenant `default_reservation_ttl_ms` > hardcoded 60000ms |
| 171 | +- `max_reservation_ttl_ms`: caps requested TTL to tenant maximum (default 3600000ms) |
| 172 | + - Applied after default resolution: `Math.min(effectiveTtl, maxTtl)` |
| 173 | +- `max_reservation_extensions`: stored on reservation at creation, enforced in extend.lua |
| 174 | + - `extension_count` tracked and incremented atomically in extend.lua |
| 175 | + - Returns `MAX_EXTENSIONS_EXCEEDED` (HTTP 409) when count reaches max |
| 176 | + - Default: 10 (spec default) |
| 177 | +- Request model fields (`overagePolicy`, `ttlMs`) changed from hardcoded defaults to `null` |
| 178 | + to allow tenant config resolution when client omits them |
| 179 | + |
161 | 180 | ### Overdraft/Debt Model (correct) |
162 | 181 | - `ALLOW_WITH_OVERDRAFT` policy supported on both commit and event |
163 | 182 | - Debt tracked per-scope, `is_over_limit` flag set when `debt > overdraft_limit` |
@@ -199,6 +218,19 @@ Two-pass audit covering: |
199 | 218 | - **Fix:** Added LIMIT of 1000 per sweep cycle via `zrangeByScore(key, 0, now, 0, SWEEP_BATCH_SIZE)` — backlog drains naturally across subsequent sweeps |
200 | 219 | - **Location:** `ReservationExpiryService.java:31,45` |
201 | 220 |
|
| 221 | +### Issue 8 [FIXED]: Tenant default configuration not honored by protocol server |
| 222 | +- **Was:** `default_commit_overage_policy`, `default_reservation_ttl_ms`, `max_reservation_ttl_ms`, and `max_reservation_extensions` were set via admin API but ignored by the protocol server. The request models hardcoded `overagePolicy = REJECT` and `ttlMs = 60000L` as field defaults, so when clients omitted these fields they always got hardcoded values — never the tenant's configured defaults. |
| 223 | +- **Fix:** |
| 224 | + 1. Removed hardcoded defaults from `ReservationCreateRequest.overagePolicy` (was `REJECT`), `ReservationCreateRequest.ttlMs` (was `60000L`), and `EventCreateRequest.overagePolicy` (was `REJECT`) — now `null` when omitted |
| 225 | + 2. Added `getTenantConfig()` to read tenant JSON from `tenant:{id}` Redis key |
| 226 | + 3. Added `resolveOveragePolicy()`: request > tenant `default_commit_overage_policy` > `REJECT` |
| 227 | + 4. Added `resolveReservationTtl()`: request > tenant `default_reservation_ttl_ms` > 60000ms, then `Math.min(ttl, max_reservation_ttl_ms)` |
| 228 | + 5. Added `resolveMaxExtensions()`: reads tenant `max_reservation_extensions` (default 10), stored on reservation, enforced in extend.lua |
| 229 | + 6. extend.lua: tracks `extension_count`, returns `MAX_EXTENSIONS_EXCEEDED` when limit reached |
| 230 | + 7. reserve.lua: accepts `max_extensions` as ARGV[14], stores on reservation hash |
| 231 | + 8. Added `MAX_EXTENSIONS_EXCEEDED` error code (HTTP 409) |
| 232 | +- **Location:** `RedisReservationRepository.java`, `ReservationCreateRequest.java`, `EventCreateRequest.java`, `reserve.lua`, `extend.lua`, `Enums.java` |
| 233 | + |
202 | 234 | ### Issue 7 [FIXED]: Clock skew between Java and Redis in expiry sweep candidate query |
203 | 235 | - **Was:** Java `System.currentTimeMillis()` used for the `zrangeByScore` query; all Lua scripts use `redis.call('TIME')` — clock drift could cause missed or premature candidate selection |
204 | 236 | - **Fix:** Replaced with `jedis.time()` to use Redis server clock, consistent with reserve/commit/release/extend/expire Lua scripts |
|
0 commit comments