Skip to content

v0.1.25.26 — bulk-action endpoints on tenants + webhooks

Choose a tag to compare

@amavashev amavashev released this 17 Apr 13:56
1378c03

v0.1.25.26 — bulk-action endpoints (tenants + webhooks)

Rolls up three admin-server patch versions that were built on main but never cut as their own releases (v0.1.25.24 server-side sort, v0.1.25.25 free-text search, v0.1.25.26 bulk-action). The published artifact's info.version and pom <revision> are 0.1.25.26.

Closes spec v0.1.25.21 gap (second bullet). Paired with cycles-protocol v0.1.25.23 (enum widening for COUNT_MISMATCH + LIMIT_EXCEEDED), which merged earlier today — cloud CI on this release is green.

New endpoints (AdminKeyAuth only)

  • POST /v1/admin/tenants/bulk-action — actions SUSPEND / REACTIVATE / CLOSE; filter {status?, parent_tenant_id?, observe_mode?, search?(≤128)}.
  • POST /v1/admin/webhooks/bulk-action — actions PAUSE / RESUME / DELETE; filter {tenant_id?, status?, event_type?, search?(≤128)}.

Safety gates (both endpoints)

  • Empty filter → 400 (must specify at least one property).
  • expected_count mismatch → 409 COUNT_MISMATCH (no writes).
  • 500 matching rows → 400 LIMIT_EXCEEDED (reports total_matched).

  • 15-minute idempotency replay via new Redis-backed IdempotencyStore (cycles-admin-service-data).
  • Per-row apply reads live status at apply-time so concurrent mutations land in the correct succeeded / failed / skipped bucket; overall HTTP 200 with per-row outcomes.

Design note — fund-path idempotency deliberately NOT migrated

BudgetController.fund idempotency lives inside a Redis Lua script atomic with the balance mutation. Externalising onto the new store would break atomicity (concurrent retry could slip between lookup and apply, double-applying the balance). Rationale documented inline in IdempotencyStore.java javadoc and in AUDIT.md.

Rolled-in content from v0.1.25.24 and v0.1.25.25

  • v0.1.25.24 — server-side sort on six admin list endpoints: listTenants, listBudgets, listApiKeys, listAuditLogs, listWebhookSubscriptions, listEvents. Cross-tenant sort hydration capped at SORTED_HYDRATE_CAP = 2000.
  • v0.1.25.25 — free-text search (≤128 chars, case-insensitive substring) on the same six endpoints. Match fields per endpoint match the spec.

Verification

  • mvn-proxy -B verify --file cycles-admin-service/pom.xml -Dtest='!*IntegrationTest': 646/646 tests pass.
  • JaCoCo LINE coverage ≥95% on both cycles-admin-service-data and cycles-admin-service-api.
  • OpenApiContractDiffTest + SpecCoverageReportTest allowlists emptied — bulk-action operations fully covered by contract tests.
  • Both cloud CI checks on PR #109 pass after cycles-protocol PR #51 merged (ContractSpecLoader picks up spec v0.1.25.23 from main).

Links

  • Server PR: #109 (merged)
  • Spec PR: cycles-protocol #51 (merged, v0.1.25.23)
  • Spec gap closed: v0.1.25.21 (search + bulk-action)