Skip to content

fix(monetize): drop available, use drainEndsAt as sole drain signal#548

Open
bussyjd wants to merge 1 commit into
mainfrom
fix/drain-additive-schema-reship
Open

fix(monetize): drop available, use drainEndsAt as sole drain signal#548
bussyjd wants to merge 1 commit into
mainfrom
fix/drain-additive-schema-reship

Conversation

@bussyjd
Copy link
Copy Markdown
Collaborator

@bussyjd bussyjd commented May 25, 2026

Summary

drain becomes purely additive — active offers serialize identically to pre-drain main. The only new wire field is drainEndsAt, set on draining offers only. Consumers detect drain with if (entry.drainEndsAt) { /* draining */ }. No schema-breaking change for any consumer that was reading the catalog before drain landed.

This re-ships an amendment that was originally pushed as commit dd89750 on feat/drain-replaces-pause for PR #535. The amendment didn't survive the bundle PR #536's merge into main, so the controller is shipping the un-amended Available bool shape today.

Diff summary

  • internal/schemas/service_catalog.go — remove Available bool from ServiceCatalogEntry; keep DrainEndsAt string omitempty`` as the sole drain marker.
  • internal/schemas/service-catalog.schema.json — drop available from required and from properties; tighten the drainEndsAt description to "present iff draining".
  • internal/serviceoffercontroller/render.go
    • buildServiceCatalogJSON: stop setting Available; only set DrainEndsAt when offer.IsDraining().
    • buildSkillCatalogMarkdown: rename the Available table column to Status (active rows show ; draining rows show draining · ends `<RFC3339>` ); drop the per-service - **Available**: bullet entirely (draining services keep only - **Drain ends at**:).
    • serviceDefWithDrain: stop setting the (already-additive) Available *bool on erc8004.ServiceDef during drain — signal drain via DrainEndsAt only.
  • internal/serviceoffercontroller/render_test.go
    • TestBuildServiceCatalogJSON_ExcludesNonReady: replace services[0].Available == true assertion with a raw-JSON map walk asserting available and drainEndsAt keys are absent on active entries.
    • TestBuildServiceCatalogJSON_DrainLifecycle: rewrite the lifecycle assertions to walk []map[string]any. Active entries: neither available nor drainEndsAt. Mid-drain: only drainEndsAt. Expired: filtered.
    • TestBuildRegistrationServices_IncludesDrainMetadata and TestBuildIdentityRegistrationServices_IncludesDrainMetadata: replace svc.Available == &false checks with svc.Available == nil (the helper no longer sets it; presence-of-DrainEndsAt is the sole drain marker).
    • NEW TestBuildSkillCatalogMarkdown_DrainAdditiveDetail: asserts no - **Available**: bullet appears for any offer, draining offers keep their - **Drain ends at**: bullet, and the table header uses Status not Available.

Test plan

  • go build ./... clean
  • go test ./internal/schemas/... ./internal/serviceoffercontroller/... ./internal/monetizeapi/... green
  • go test ./... green (full suite, including internal/stack)
  • TestBuildServiceCatalogJSON_ExcludesNonReady confirms active-offer JSON has no available key
  • TestBuildServiceCatalogJSON_DrainLifecycle confirms draining offer still emits drainEndsAt (and only drainEndsAt)
  • TestBuildSkillCatalogMarkdown_DrainAdditiveDetail confirms markdown surface is additive: no - **Available**: bullet, Status column header, - **Drain ends at**: retained on draining offers.

…e drain signal (re-amend of #535)

drain becomes purely additive — active offers serialize identically to
pre-drain main. The only new wire field is `drainEndsAt`, set on draining
offers only. Consumers detect drain with `if (entry.drainEndsAt) { /* draining */ }`.
No schema-breaking change for any consumer that was reading the catalog
before drain landed.

This re-ships an amendment that was originally pushed as commit dd89750 on
`feat/drain-replaces-pause` for PR #535. The amendment didn't survive the
bundle PR #536's merge into main, so the controller is shipping the
un-amended `Available bool` shape today.

- ServiceCatalogEntry: remove `Available bool`; keep `DrainEndsAt string omitempty`
- service-catalog.schema.json: drop `available` from `required` + `properties`
- buildServiceCatalogJSON: stop setting Available; only set DrainEndsAt on drain
- buildSkillCatalogMarkdown: rename `Available` table column to `Status` (active
  rows show `—`; draining rows show `draining · ends <RFC3339>`). Drop the
  per-service `- **Available**:` bullet entirely; draining services keep only
  the `- **Drain ends at**:` bullet.
- serviceDefWithDrain: stop setting the (already-additive) `Available *bool`
  on erc8004.ServiceDef during drain; signal via DrainEndsAt only.
- Tests:
  - TestBuildServiceCatalogJSON_ExcludesNonReady: replace
    `services[0].Available == true` with raw-JSON map walk asserting
    `available` and `drainEndsAt` keys are absent on active entries.
  - TestBuildServiceCatalogJSON_DrainLifecycle: rewrite to raw-map walk;
    assert active entries have neither `available` nor `drainEndsAt`, mid-drain
    entries have only `drainEndsAt` (no `available`).
  - TestBuildRegistration{,Identity}Services_IncludesDrainMetadata: replace
    `svc.Available == &false` checks with `svc.Available == nil` (DrainEndsAt
    is now the sole drain marker).
  - Add TestBuildSkillCatalogMarkdown_DrainAdditiveDetail: asserts no
    `- **Available**:` bullet appears for any offer, that draining offers
    keep their `- **Drain ends at**:` bullet, and that the table header
    uses `Status` not `Available`.
@bussyjd bussyjd mentioned this pull request May 25, 2026
10 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant