[IMP] pms_fastapi: guard free-text searches with min length (RFC 9457)#102
Draft
jesusVMayor wants to merge 1 commit into
Draft
[IMP] pms_fastapi: guard free-text searches with min length (RFC 9457)#102jesusVMayor wants to merge 1 commit into
jesusVMayor wants to merge 1 commit into
Conversation
Free-text search params shorter than MIN_SEARCH_TEXT_LENGTH (3) were only guarded ad-hoc (Query(min_length) on phone + a stray globalSearch check), which did not scale and surfaced a generic 422. Mark free-text query params with the new SearchText type; PmsApiRouter wraps any endpoint with a BaseSearch param and rejects too-short values with an RFC 9457 problem+json (/errors/search-text-too-short) before the endpoint runs. No per-field/per-endpoint code; future search endpoints are covered. Applied to contact, agency, customer, guest, supplier, invoice and folio searches (moved to Annotated[...] param style). Adds an end-to-end test and documents the convention in the roomdoo-fastapi-conventions skill.
Diff CoverageDiff: origin/16.0...HEAD, staged and unstaged changes
Summary
pms_fastapi/schemas/agency.pyLines 95-104 95 ("display_name", "ilike", self.globalSearch),
96 ("email", "ilike", self.globalSearch),
97 ("vat", "ilike", self.globalSearch),
98 ]
! 99 phone_domain = [("phone_mobile_search", "ilike", self.globalSearch)]
! 100 domain = expression.OR([domain, phone_domain])
101 if self.name:
102 domain.append(("display_name", "ilike", self.name))
103 if self.phone:
104 domain.append(("phone_mobile_search", "ilike", self.phone))pms_fastapi/schemas/contact.pyLines 362-371 362 ("email", "ilike", self.globalSearch),
363 ("vat", "ilike", self.globalSearch),
364 ("identification_number", "ilike", self.globalSearch),
365 ]
! 366 phone_domain = [("phone_mobile_search", "ilike", self.globalSearch)]
! 367 domain = expression.OR([domain, phone_domain])
368 if self.name:
369 domain.append(("display_name", "ilike", self.name))
370 if self.phone:
371 domain.append(("phone_mobile_search", "ilike", self.phone))pms_fastapi/schemas/customer.pyLines 114-123 114 ("display_name", "ilike", self.globalSearch),
115 ("email", "ilike", self.globalSearch),
116 ("vat", "ilike", self.globalSearch),
117 ]
! 118 phone_domain = [("phone_mobile_search", "ilike", self.globalSearch)]
! 119 domain = expression.OR([domain, phone_domain])
120 if self.vat:
121 domain.append(("vat", "ilike", self.vat))
122 if self.name:
123 domain.append(("display_name", "ilike", self.name))pms_fastapi/schemas/guest.pyLines 183-192 183 ("email", "ilike", self.globalSearch),
184 ("vat", "ilike", self.globalSearch),
185 ("identification_number", "ilike", self.globalSearch),
186 ]
! 187 phone_domain = [("phone_mobile_search", "ilike", self.globalSearch)]
! 188 domain = expression.OR([domain, phone_domain])
189 if self.vat:
190 id_numbers = (
191 env["res.partner.id_number"]
192 .sudo()pms_fastapi/schemas/supplier.pyLines 116-125 116 ("display_name", "ilike", self.globalSearch),
117 ("email", "ilike", self.globalSearch),
118 ("vat", "ilike", self.globalSearch),
119 ]
! 120 phone_domain = [("phone_mobile_search", "ilike", self.globalSearch)]
! 121 domain = expression.OR([domain, phone_domain])
122 if self.vat:
123 domain.append(("vat", "ilike", self.vat))
124 if self.name:
125 domain.append(("display_name", "ilike", self.name)) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Qué
Guarda escalable de longitud mínima para las búsquedas por texto de la API
(
pms_fastapi), con error en formato RFC 9457 problem+json para que el front puedadistinguir el caso "texto demasiado corto".
Antes solo
phoneteníaQuery(min_length=3)yglobalSearchunif len >= 3suelto:no escalaba a todos los campos y devolvía un 422 genérico de Pydantic.
Cómo
SearchText(schemas/base.py): se anota el parámetro de textolibre con
SearchTexten lugar destr | None.PmsApiRouter(models/fastapi_endpoint.py) envuelve automáticamente cualquierendpoint con un parámetro
BaseSearch: si un campo marcado trae un valor no vacío delongitud
< MIN_SEARCH_TEXT_LENGTH(3), devuelve un problem+json antes deejecutar el endpoint. Sin
ifpor campo, sin código por endpoint, y los endpoints debúsqueda futuros quedan cubiertos solos.
(params de texto migrados al estilo
Annotated[...]). Vacío/whitespace = sin filtro(no error).
Respuesta de error (ejemplo exacto)
GET /contacts?name=ab→{ "type": "/errors/search-text-too-short", "title": "Search text too short", "status": 400, "detail": "Search text must be at least 3 characters.", "field": "name", "minLength": 3 }fieldes el nombre del query param ofensor (p. ej.name,globalSearch,room).Para el front, la señal a detectar es
type == "/errors/search-text-too-short".Tests
tests/test_search_text_guard.py(end-to-end víaFastAPITransactionCase): casos 400(ambos estilos de anotación), 200, vacío, y param no marcado.
pms_fastapien verde: 0 failed, 0 error(s) of 56 tests.Convención documentada
Se actualiza la skill
roomdoo-fastapi-conventionscon la sección de errores RFC 9457 yla guarda de búsqueda.
Esta PR toca los schemas de búsqueda (
*Search) depms_fastapiy migra susparámetros de texto al estilo
Annotated[...]. Hay otras PR abiertas que tambiénmodifican endpoints/schemas de la API y que podrían:
SearchText),*Search(posibles conflictos de merge encontact/agency/customer/guest/supplier/invoice/folio),
Acción requerida antes del merge: revisar las PR de la API que estén en vuelo,
resolver conflictos y asegurar que los campos de texto nuevos quedan marcados con
SearchTexty que los errores siguen la convención problem+json. Se mantiene enDRAFT hasta esa reconciliación.
🤖 Generated with Claude Code