fix(api): tolerate legacy service_api end-user type on load (#38271)

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Manan Bansal 2026-07-02 11:04:36 +05:30 committed by GitHub
parent 7fb797c121
commit 41fb484491
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 33 additions and 0 deletions

View File

@ -214,6 +214,18 @@ class EndUserType(StrEnum):
SERVICE_API = "service-api" SERVICE_API = "service-api"
TRIGGER = "trigger" TRIGGER = "trigger"
@classmethod
@override
def _missing_(cls, value):
# Legacy rows persisted the service-api type with an underscore before it
# was normalized to the hyphenated value. The
# `4f7b2c8d9a10_normalize_legacy_end_user_type` migration rewrites those
# rows, but tolerate the old value here as well so an unmigrated end user
# keeps loading instead of failing enum validation on every request.
if value == "service_api":
return cls.SERVICE_API
return super()._missing_(value)
class DocumentDocType(StrEnum): class DocumentDocType(StrEnum):
"""Document doc_type classification""" """Document doc_type classification"""

View File

@ -2,6 +2,9 @@ import ast
import inspect import inspect
from pathlib import Path from pathlib import Path
import pytest
from sqlalchemy.engine.default import DefaultDialect
from models.enums import EndUserType from models.enums import EndUserType
from models.model import EndUser from models.model import EndUser
from models.types import EnumText from models.types import EnumText
@ -24,6 +27,24 @@ def test_end_user_type_is_plain_persisted_value_enum():
assert not hasattr(EndUserType, "from_invoke_from") assert not hasattr(EndUserType, "from_invoke_from")
def test_end_user_type_accepts_legacy_service_api_value():
# Legacy rows stored the service-api type with an underscore before it was
# normalized to the hyphenated value; loading them must not raise. See #38201.
assert EndUserType("service_api") is EndUserType.SERVICE_API
assert EndUserType("service-api") is EndUserType.SERVICE_API
def test_end_user_type_still_rejects_unknown_values():
with pytest.raises(ValueError):
EndUserType("not-a-real-end-user-type")
def test_enum_text_deserializes_legacy_service_api_value():
# Exercises the actual column load path that raised for unmigrated rows.
column_type = EnumText(EndUserType)
assert column_type.process_result_value("service_api", DefaultDialect()) is EndUserType.SERVICE_API
def test_end_user_service_creation_methods_accept_end_user_type(): def test_end_user_service_creation_methods_accept_end_user_type():
assert inspect.signature(EndUserService.get_or_create_end_user_by_type).parameters["type"].annotation is EndUserType assert inspect.signature(EndUserService.get_or_create_end_user_by_type).parameters["type"].annotation is EndUserType
assert inspect.signature(EndUserService.create_end_user_batch).parameters["type"].annotation is EndUserType assert inspect.signature(EndUserService.create_end_user_batch).parameters["type"].annotation is EndUserType