Skip to content

[0.9.0] Season seats: setAsideSeasonBlock, retrieveSeasonBlock, releaseSeasonBlock, inventoryMode - #14

Merged
pietechsolution merged 14 commits into
mainfrom
navin/season-block-0.10.0
Nov 11, 2026
Merged

pietechsolution merged 14 commits into
mainfrom
navin/season-block-0.10.0

Conversation

@pietechsolution

@pietechsolution pietechsolution commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

Season seats for @seatlayer/server, part of the 0.9.0 release. One release, 0.9.0, carries season 2a (#13) and this PR (decided 10 Nov).

  • Versions: old 0.8.0 (published) → new 0.9.0 (with season-2a, Season 2a server operations (part A) #13). Nothing is published yet: npm stops at 0.8.0 (latest is 0.8.0, checked 10 Nov).
  • 0.8.0 has the 48 season operations from 0.7.0/0.8.0. It has none of the season-2a calls and none of these.
  • The branch is cut from season-2a-server so it builds on the season-2a methods. Its name still says 0.10.0, from before the decision: renaming a head branch would close the PR.
  • No version bump, tag or publish is in this PR. package.json stays at 0.8.0.

What it adds

Built to docs/season-block-2026-11-08/contract.md in the app repo, §2, §5, §6 and §8 "Amendments, 9 Nov".

  • Methods, named by operationId (the repo's rule):

    • seasons.setAsideSeasonBlock(seasonKey, { expectedRevision, keepForSingleTickets? }, { idempotencyKey? }) → { job, block };
    • seasons.retrieveSeasonBlock(seasonKey) → { block };
    • seasons.releaseSeasonBlock(seasonKey, { expectedRevision, scope, eventKeys?, at?, reason? }, { idempotencyKey? }) → { job, block }.

    Both writes use header replay, so an Idempotency-Key is generated when none is given, as on refundSeasonPerformance.

  • inventoryMode (block | per_hold) on createSeason and updateSeason, sent only when given. block opts the season into season seats; the default stays per_hold. Every Season answer carries it. Type: SeasonInventoryMode.

  • Types:

    • SeasonBlock, SeasonBlockCounts, SeasonBlockJobAnswer, SetAsideSeasonBlockParams, ReleaseSeasonBlockParams, SeasonBlockReleaseScope, SeasonSeatSelection;
    • SeasonBulkJobKind + season_block_set_aside, season_block_release;
    • WebhookEventName + season.block.ready, season.block.released.
  • The 202 while a date leaves every season seat (createSeasonAmendment cancel, markSeasonPerformancePast): SeasonDateLeavePending and the guard isSeasonDateLeavePending(result).

    • The two methods' result types are unchanged. A union would break TypeScript callers on upgrade; if you want it, it belongs in a 1.0.
  • Errors: no new classes or constants. The new codes come through SeatLayerError with code (§8 item 4). The CHANGELOG lists them, now including every code the 3 calls and inventoryMode can send (SEASON_BLOCK_API_BUSINESS_ERRORS in the app repo).

  • Docs: a "Season seats" section at the end of the README's "Fixed Renewable Seasons": opt in with inventoryMode, set the seats aside, follow the job, read the block, release to single sale (now or at a set time), the two webhook names, the 202 guard, refusals through SeatLayerError with code, and partner seats staying out of the block.

  • CHANGELOG: the "Next: 0.9.0" section. The version PR joins it with the season-2a section under ## 0.9.0.

Files changed

CHANGELOG.md, README.md, src/index.ts, src/resources/seasons.ts, src/types.ts, test/sales-operations.test.ts, test/seasons.test.ts (7 files, +440 −5).

Checks

  • pnpm validate (typecheck, vitest, build, publint, attw), re-run 10 Nov on this commit: green, 123/123 tests in 4 files. Since season-2a-server, the season tests added:

    • the 3 calls with and without a key, and a season seats job read;
    • inventoryMode on create and update;
    • the typed error carrying each new code;
    • a job of an unknown kind still parsing;
    • the 202 guard.

    sales-operations.test.ts lists the two new webhook names (56 → 58), and the season operation count goes 87 → 90.

  • Mutation check (run before this amend; the code is unchanged since): 6/6 killed (paths, the caller key, the body, the guard).

  • The README sample isn't compiled by the repo. It was typechecked once (tsc --strict) against this commit's dist/ types.

  • Compat matrix (season-phase4-node-compat.mjs, in the app session's notes). The same fixtures, shaped as the phase 4 API answers, go through the stub transport; nothing is sent.

Build Result
published 0.8.0 (npm pack @seatlayer/server@0.8.0, re-run 10 Nov) all PASS where the method exists, 4 of 12: 409 date_leave_in_progress and the 202 block_date_leave_pending on createSeasonAmendment (through the generic error and as the result), a Season answer carrying inventoryMode, and 409 season_block_packages on updateSeason. The other 8 are n/a: 0.8.0 has neither the season-2a calls nor these
season-2a-server head all PASS (10 Nov run, not re-run): season seats jobs of both new kinds, a job list mixing old and new kinds, 409 season_block_set_aside, season_inventory_locked and date_leave_in_progress, the 202 returned as the result, inventoryMode and 409 season_block_packages
this build (0.9.0) all PASS, 12/12 (re-run 10 Nov on this commit's dist/), including the 3 new calls and 409 season_block_not_enabled
  • Not done yet: a live dev smoke of the 3 calls with the dev test key. The phase 4 API isn't on dev until the Orchestrator merges the stack. It is step 3 below.

Release steps for the owner

  1. The season-2a PR (Season 2a server operations (part A) #13) merges to main, with no tag.

  2. Rebase this PR onto main and retarget it to main; pnpm validate green; merge.

  3. Compat matrix again, once the phase 4 API is on dev:

    • run the compat script against published 0.8.0 and against main's build: both all PASS;
    • the live dev smoke of the 3 calls with the dev test key: opt in, set aside, follow the job to completed, read, release with at, read the release job.
  4. Version PR: npm version 0.9.0 --no-git-tag-version, and join the CHANGELOG's season-2a section ("Unreleased") and "Next: 0.9.0" under ## 0.9.0. Merge to main.

  5. Publish: only after the phase 4 API (paiteq/seatmap #2059 → #2086 → #2061 → #2062 → #2063 → #2066 → #2092) is live on production and the owner says yes: git tag v0.9.0 && git push origin v0.9.0. release.yml publishes to npm with provenance; the tag must equal the package version.

  6. Live re-check: npm view @seatlayer/server@0.9.0 version and npm view @seatlayer/server dist-tags, then install 0.9.0 in a scratch project and run the dev smoke again.

  7. Rollback (0.9.0 only adds; nothing in 0.8.0 changes):

    • npm dist-tag add @seatlayer/server@0.8.0 latest;
    • npm deprecate @seatlayer/server@0.9.0 "Use 0.8.0; 0.9.0 withdrawn".

    0.8.0 stays installable throughout. A rollback also withdraws season-2a: both ship in 0.9.0.

Failure modes

  • Publishing before the phase 4 API is on production: the 3 calls would answer 404, and inventoryMode would be ignored. Step 5 waits for production.
  • A caller skipping isSeasonDateLeavePending: it would read the 202 body as an amendment or performance list. The result types stay as they were, so the README and the doc comments point at the guard.
  • Old SDKs: 0.8.0 reads the new answers through its generic error and ignores inventoryMode (compat matrix). It can't call the 3 new routes.
  • README drift: the sample isn't compiled. A later signature change would leave it stale.

Open risks

  • No live dev smoke yet (step 3).
  • The README links to the docs' "Season seats" section (/server-api/seasons/#season-seats), which goes live with paiteq/seatmap #2063. Until then the link lands on the top of the Seasons page.
  • The README's existing season text still says version 0.7.0 and doesn't name the new calls; it was left as it was.

… settings, all 56 webhook names, events seriesKey
…tle (2.16c)

createEventSeries takes fromEventKey: an event already set up becomes the first date under its own key and every other date is a copy of it; name and chartKey are then left out. Every date of a series carries the series' plain name. Matches seatmap slice 2.16c.
Adds releaseSeasonLapsedOffers (POST /v1/seasons/{key}/renewal-offers/release-lapsed, no body, header replay, 202 with the job). retrieveSeasonHostedRenewals pages with cursor and limit (1-500) and answers nextCursor, and listSeasonRenewalOffers pages the same way (1-100). createSeasonRenewalOffers answers 201 {offers} for 100 contracts or fewer and 202 {job, batchId} above that. The bring-across (createSeasonHolderImportFromSeason) answers 202 with a holder_import job above 100 holders. Renewal emails take up to 20,000 offer ids; above that, 422 too_many_offer_ids.
…e_abandoned (p2b)

The public API changes in p2b (b88ed794e..ee7df2921): SeasonBulkJobKind adds date_cancel_void and seasonDateCancelVoidJobId names that job; seasonHolderImportRowsPerCall sizes an import call by its dates (a call over it answers 422 invalid_rows with maxRows); SeasonSingleTicketDates.jobRefused; createEventSeries documents 409 create_abandoned.
…b audit)

updateEventSeries sends only the prices that change: each date keeps its
own price for every category or tier left out. A season's null transfer
or return cut-off means the club default from Settings > Ticket site, or
until the date starts when the club has none. Holder transfers and
returns through the secret key are not stopped by the club's customer
switches; cut-offs still apply.
…part C)

A date its season cancelled never opens again: moving its sales to
testable or live, or reopening it, answers 409 season_date_cancelled,
and an event series "sales on" leaves it closed as a failed item of the
job (season_date_cancelled; not in failedDates). A cancelled date can't
be moved, postponed, replaced or marked as taken place: 409
performance_cancelled.
@pietechsolution
pietechsolution force-pushed the navin/season-block-0.10.0 branch 3 times, most recently from b9e42ec to d18db11 Compare November 10, 2026 02:29
…seSeasonBlock; season.block.ready/released webhook names; the 202 date-leave answer guard. No version bump: publish only once the phase 4 API is on production
@pietechsolution
pietechsolution force-pushed the navin/season-block-0.10.0 branch from d18db11 to baf1ee4 Compare November 10, 2026 05:48
@pietechsolution pietechsolution changed the title [0.10.0, NOT for 0.9.0] Season seats: setAsideSeasonBlock, retrieveSeasonBlock, releaseSeasonBlock [0.9.0] Season seats: setAsideSeasonBlock, retrieveSeasonBlock, releaseSeasonBlock, inventoryMode Nov 10, 2026
@pietechsolution pietechsolution mentioned this pull request Nov 11, 2026
@pietechsolution
pietechsolution changed the base branch from season-2a-server to main November 11, 2026 10:14
@pietechsolution
pietechsolution marked this pull request as ready for review November 11, 2026 10:14
@pietechsolution
pietechsolution merged commit 12286fd into main Nov 11, 2026
1 check passed
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.

2 participants