From 0a64b87707351d45fc899db93f98a367e7a3d1c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B9=BE=E7=94=B0=E7=B4=94=E5=B9=B3?= Date: Mon, 23 Feb 2026 17:08:10 +0900 Subject: [PATCH] fix: validate effective_at against new invalid_at when both updated (Closes stayforge/Stayforge-API#6) Co-Authored-By: Claude Opus 4.6 --- openapi.json | 6 +++--- openapi.yaml | 16 ++++++++++++++-- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/openapi.json b/openapi.json index 0eaa63b..ff0e198 100644 --- a/openapi.json +++ b/openapi.json @@ -657,7 +657,7 @@ } }, "422": { - "description": "Unprocessable Entity - Request is well-formed but contains semantic errors.\nError codes: `unprocessable_entity`\n", + "description": "Unprocessable Entity - Request is well-formed but contains semantic errors.\nFor time validation: `effective_at` must be earlier than `invalid_at`. When both fields are provided in the same request, they are validated against each other (the new values), not against the currently stored values.\nError codes: `unprocessable_entity`\n", "content": { "application/json": { "schema": { @@ -7090,13 +7090,13 @@ "type": "string", "format": "date-time", "nullable": true, - "description": "Effective time (when the card becomes active).\nMust be the current time or a future time.\n**⚠️Default: `UTC`**, recommended to use the format `2025-02-16T12:00:00+01:00` to ensure the correct time zone.\nAbout ISO 8601: https://en.wikipedia.org/wiki/ISO_8601\n" + "description": "Effective time (when the card becomes active).\nMust be the current time or a future time, and must be earlier than `invalid_at`.\nWhen updating both `effective_at` and `invalid_at` in a single PATCH request, `effective_at` is validated against the new `invalid_at` value provided in the request body (not the currently stored `invalid_at`).\n**⚠️Default: `UTC`**, recommended to use the format `2025-02-16T12:00:00+01:00` to ensure the correct time zone.\nAbout ISO 8601: https://en.wikipedia.org/wiki/ISO_8601\n" }, "invalid_at": { "type": "string", "format": "date-time", "nullable": true, - "description": "Invalidation time (when the card becomes invalid/expires).\nMust be the current time or a future time.\n**⚠️Default: `UTC`**, recommended to use the format `2025-02-16T12:00:00+01:00` to ensure the correct time zone.\nAbout ISO 8601: https://en.wikipedia.org/wiki/ISO_8601\n" + "description": "Invalidation time (when the card becomes invalid/expires).\nMust be the current time or a future time, and must be later than `effective_at`.\nWhen updating both `effective_at` and `invalid_at` in a single PATCH request, `invalid_at` is validated against the new `effective_at` value provided in the request body (not the currently stored `effective_at`).\n**⚠️Default: `UTC`**, recommended to use the format `2025-02-16T12:00:00+01:00` to ensure the correct time zone.\nAbout ISO 8601: https://en.wikipedia.org/wiki/ISO_8601\n" }, "barcode_type": { "type": "string", diff --git a/openapi.yaml b/openapi.yaml index 44affef..8adbc05 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -502,6 +502,10 @@ paths: description: 'Unprocessable Entity - Request is well-formed but contains semantic errors. + For time validation: `effective_at` must be earlier than `invalid_at`. + When both fields are provided in the same request, they are validated + against each other (the new values), not against the currently stored values. + Error codes: `unprocessable_entity` ' @@ -5536,7 +5540,11 @@ components: nullable: true description: 'Effective time (when the card becomes active). - Must be the current time or a future time. + Must be the current time or a future time, and must be earlier than `invalid_at`. + + When updating both `effective_at` and `invalid_at` in a single PATCH request, + `effective_at` is validated against the new `invalid_at` value provided in + the request body (not the currently stored `invalid_at`). **⚠️Default: `UTC`**, recommended to use the format `2025-02-16T12:00:00+01:00` to ensure the correct time zone. @@ -5550,7 +5558,11 @@ components: nullable: true description: 'Invalidation time (when the card becomes invalid/expires). - Must be the current time or a future time. + Must be the current time or a future time, and must be later than `effective_at`. + + When updating both `effective_at` and `invalid_at` in a single PATCH request, + `invalid_at` is validated against the new `effective_at` value provided in + the request body (not the currently stored `effective_at`). **⚠️Default: `UTC`**, recommended to use the format `2025-02-16T12:00:00+01:00` to ensure the correct time zone.