diff --git a/rfcs/088-folio-identity-requesting-migration/README.md b/rfcs/088-folio-identity-requesting-migration/README.md index 0324d0aa..5977c9d8 100644 --- a/rfcs/088-folio-identity-requesting-migration/README.md +++ b/rfcs/088-folio-identity-requesting-migration/README.md @@ -9,7 +9,7 @@ identity API fronted by Auth0), the embedded API contract, the migration plan (a website toggle plus lazy patron migration, culminating in a single coordinated cutover), and the questions still open before cutover. -**Last modified:** 2026-06-22T14:33:26+00:00 +**Last modified:** 2026-06-26T00:00:00+00:00 **Related RFCs:** @@ -225,6 +225,12 @@ the `app_metadata` for Auth0 to persist and surface to the app. FOLIO is the sou name: a name changed in FOLIO propagates to Auth0 on the next login. Enrichment failures fail closed (login is denied rather than letting a user through in an inconsistent state). +Enrichment also mints the patron's library-card barcode. If the resolved FOLIO record has no +barcode, `/m2m/enrich` allocates a numeric card number from the patron-barcode sequence (see [open +question 4](#open-questions)) and writes it to the record. This is allocate-once (a migrated patron +already carries a barcode, so it only fires for new signups) and best-effort: a sequence failure is +logged and retried on the next login rather than blocking the current one. + ```mermaid sequenceDiagram autonumber @@ -396,6 +402,7 @@ catalogue error shape on item-requests). Each v1 operation has one of these disp | Route | Disposition | Notes | |---|---|---| | `POST /m2m/register`, `POST /m2m/enrich` | new-in-v2 | Called by the Auth0 actions; central to registration and lazy migration. | +| `POST /m2m/sequences/{name}/next` | new-in-v2 | Mints the next value from a named sequence (a DynamoDB atomic counter), returned as a barcode. Used in-process by `/m2m/enrich` to assign a new patron's card number, and exposed for standalone allocation; M2M `enrich:read` scope. An unprovisioned sequence returns 404. See [open question 4](#open-questions). | | `GET /items` | new-in-v2 | Catalogue availability; API-key only. Overlaps the existing v2 catalogue API items endpoint; how the two run in parallel is [open question 5](#open-questions). | | Per-patron requestability (allowed-service-points) and hold cancellation | new-in-v2 (planned) | No v1 analogue: v1 never shipped cancel, and per-patron requestability is new. Both will be added to the `/users/{userId}` surface before cutover (cancellation as `DELETE /users/{userId}/item-requests/{requestId}`); not yet in the contract above. | @@ -570,12 +577,17 @@ integration point. nothing. *Open:* confirm event-integration options with the LMS vendor, and decide the mechanism before cutover (this is GDPR-relevant). -4. **Barcode and role.** New users receive the bare Auth0 id as their initial barcode (backfilled at - first login); migrated users keep their card number; `role` is the FOLIO patron-group name mapped - to the legacy vocabulary by a table the API owns (unmapped groups fall back to `Reader` with a - warning). *Open:* verify the 24-character barcode format against the systems that consume barcodes - (physical cards and scanners, OpenAthens), and confirm the patron-group-to-role assignment for the - currently-unmapped groups with the LMS workstream. +4. **Barcode and role.** New users are minted a numeric, sequential card number by a barcode + **sequence service** (a DynamoDB atomic counter: a configurable prefix plus the counter + zero-padded to a fixed width, no check digit), allocated at first login by `/m2m/enrich` and + seeded above the maximum Sierra patron number so a minted number never collides with a migrated + patron's physical card. Migrated users keep their existing card number. `role` is the FOLIO + patron-group name mapped to the legacy vocabulary by a table the API owns (unmapped groups fall + back to `Reader` with a warning). Keeping the value numeric, rather than the bare Auth0 id, leaves + the printed and scanned card representation unchanged by the migration. *Open:* agree the concrete + seed, prefix and width with the LMS migration and the card supplier, and confirm the reading-room + scanners and self-issue kiosks accept the chosen format and range; and confirm the + patron-group-to-role assignment for the currently-unmapped groups with the LMS workstream. 5. **Running the new items API alongside the existing catalogue API.** The new `GET /items` route serves item availability and requestability from FOLIO and will be built as part of this project. diff --git a/rfcs/088-folio-identity-requesting-migration/openapi.md b/rfcs/088-folio-identity-requesting-migration/openapi.md index 1c5b5a6d..40769d81 100644 --- a/rfcs/088-folio-identity-requesting-migration/openapi.md +++ b/rfcs/088-folio-identity-requesting-migration/openapi.md @@ -356,6 +356,7 @@ Machine-to-machine endpoints for the Auth0 actions |---|---|---| | `POST` | `/m2m/register` | Create a Folio patron for a new Auth0 signup | | `POST` | `/m2m/enrich` | Login-time enrichment and reconciliation | +| `POST` | `/m2m/sequences/{name}/next` | Allocate the next value from a named sequence | #### `POST /m2m/register` @@ -422,6 +423,36 @@ token with scope `enrich:read`. | `200` | [`EnrichResponse`](#enrichresponse) | Enrichment payload for the Auth0 action. | | `404` | [`IdentityError`](#identityerror) | No Folio user could be resolved. | +#### `POST /m2m/sequences/{name}/next` + +_Allocate the next value from a named sequence_ + +Mints the next value from the named sequence and returns it formatted as +a barcode (`prefix` + the counter zero-padded to the configured width; no +check digit). Backed by a DynamoDB atomic counter, so concurrent callers +each receive a distinct, strictly increasing value; gaps are possible and +acceptable. The sequence (its prefix, width and seed) must be provisioned +out of band first; an unprovisioned `name` returns 404. Used in-process by +`/m2m/enrich` to assign a new patron's library-card barcode, and exposed +here for standalone allocation and smoke tests. Requires an M2M token with +scope `enrich:read`. + +**Security:** `ApiKey` + `Auth0M2MToken` (enrich:read) + +**Parameters:** + +| Name | In | Required | Type | Description | +|---|---|---|---|---| +| `name` | path | yes | string | The provisioned sequence name, e.g. `patron-barcode`. | + +**Responses:** + +| Status | Body | Description | +|---|---|---| +| `200` | object | The allocated value and its formatted barcode. | +| `404` | [`IdentityError`](#identityerror) | No such provisioned sequence. | +| `500` | n/a | | + ### Tag: items Catalogue availability (API-key only; no user data) diff --git a/rfcs/088-folio-identity-requesting-migration/openapi.yaml b/rfcs/088-folio-identity-requesting-migration/openapi.yaml index 0abad256..4ffb016e 100644 --- a/rfcs/088-folio-identity-requesting-migration/openapi.yaml +++ b/rfcs/088-folio-identity-requesting-migration/openapi.yaml @@ -485,6 +485,54 @@ paths: schema: $ref: '#/components/schemas/IdentityError' + /m2m/sequences/{name}/next: + post: + tags: [m2m] + operationId: m2mSequenceNext + summary: Allocate the next value from a named sequence + description: | + Mints the next value from the named sequence and returns it formatted as + a barcode (`prefix` + the counter zero-padded to the configured width; no + check digit). Backed by a DynamoDB atomic counter, so concurrent callers + each receive a distinct, strictly increasing value; gaps are possible and + acceptable. The sequence (its prefix, width and seed) must be provisioned + out of band first; an unprovisioned `name` returns 404. Used in-process by + `/m2m/enrich` to assign a new patron's library-card barcode, and exposed + here for standalone allocation and smoke tests. Requires an M2M token with + scope `enrich:read`. + security: + - ApiKey: [] + Auth0M2MToken: [enrich:read] + parameters: + - name: name + in: path + required: true + schema: + type: string + description: The provisioned sequence name, e.g. `patron-barcode`. + responses: + '200': + description: The allocated value and its formatted barcode. + content: + application/json: + schema: + type: object + required: [value, barcode] + properties: + value: + type: integer + description: The raw counter value allocated. + barcode: + type: string + description: prefix + the value zero-padded to the configured width. + '404': + description: No such provisioned sequence. + content: + application/json: + schema: + $ref: '#/components/schemas/IdentityError' + '500': { $ref: '#/components/responses/InternalError' } + # ---------------------------------------------------------------- items /items: diff --git a/rfcs/README.md b/rfcs/README.md index a0e13068..a988ead6 100644 --- a/rfcs/README.md +++ b/rfcs/README.md @@ -74,7 +74,7 @@ _This is generated from the RFCs in this directory using `.scripts/create_table_ | RFC ID | Summary | Next Line | Last Modified | |--------|---------|-----------|---------------| -| [088-folio-identity-requesting-migration](088-folio-identity-requesting-migration/README.md) | RFC 088: Migrating identity, requesting and items APIs from Sierra to FOLIO | This RFC describes how we move the identity, requesting and item-availability APIs that power `wellcomecollection.org` from our current Library Management System (LMS), **Sierra**, to its replacement, **FOLIO**. It sets out the proposed architecture (a parallel, FOLIO-backed **v2** identity API fronted by Auth0), the embedded API contract, the migration plan (a per-request website toggle plus lazy patron migration, culminating in a single coordinated cutover), and the questions still open before cutover. | 22 Jun 2026 | +| [088-folio-identity-requesting-migration](088-folio-identity-requesting-migration/README.md) | RFC 088: Migrating identity, requesting and items APIs from Sierra to FOLIO | This RFC describes how we move the identity, requesting and item-availability APIs that power `wellcomecollection.org` from our current Library Management System (LMS), **Sierra**, to its replacement, **FOLIO**. It sets out the proposed architecture (a parallel, FOLIO-backed **v2** identity API fronted by Auth0), the embedded API contract, the migration plan (a per-request website toggle plus lazy patron migration, culminating in a single coordinated cutover), and the questions still open before cutover. | 26 Jun 2026 | | [087-kiosk-mode](087-kiosk-mode/README.md) | RFC 087: wellcomecollection.org in kiosk mode | This RFC serves to outline how we propose to offer in-venue experiences using our current website, while optimising it for a different experience than usual. | 13 May 2026 | | [086-item-viewer-refactor](086-item-viewer-refactor/README.md) | RFC 086: IIIF Viewer Context Refactoring | This folder contains a comprehensive plan to refactor the IIIF Viewer context to eliminate code duplication and centralise derived state calculations. | 14 Apr 2026 | | [084-shopify-integration-strategies](084-shopify-integration-strategies/README.md) | RFC 084: Shopify Integration Approaches for Wellcome Collection | This research outlines five approaches for integrating Shopify with the Wellcome Collection website, ranging from simple embedded solutions to fully headless implementations. | 16 Feb 2026 |