build_filter takes tenant_id: str and passes it straight through:
must: List[models.FieldCondition] = [
models.FieldCondition(key=TENANT_FIELD, match=models.MatchValue(value=tenant_id))
]
Nothing rejects "". A caller that reads the tenant from an unset environment variable, a missing header, or a stripped JWT claim gets tenant_id="", and the query runs happily against a tenant that does not exist. The result is an empty list, which reads as "this tenant has no matching documents".
That is the wrong answer to give. The right one is that the request was never scoped, and it should be an error at the boundary rather than a confusing empty result three layers up. The current behaviour also hides a genuine misconfiguration in production, where every search silently returns nothing.
Acceptance
build_filter and search raise on an empty or whitespace-only tenant_id, with a message saying the request was not scoped
- A test covers
"", " ", and a valid id that happens to contain spaces
- The API surface in
app.py returns a 4xx rather than an empty result set for this case
Good first issue: one guard, one error type, and a test.
build_filtertakestenant_id: strand passes it straight through:Nothing rejects
"". A caller that reads the tenant from an unset environment variable, a missing header, or a stripped JWT claim getstenant_id="", and the query runs happily against a tenant that does not exist. The result is an empty list, which reads as "this tenant has no matching documents".That is the wrong answer to give. The right one is that the request was never scoped, and it should be an error at the boundary rather than a confusing empty result three layers up. The current behaviour also hides a genuine misconfiguration in production, where every search silently returns nothing.
Acceptance
build_filterandsearchraise on an empty or whitespace-onlytenant_id, with a message saying the request was not scoped""," ", and a valid id that happens to contain spacesapp.pyreturns a 4xx rather than an empty result set for this caseGood first issue: one guard, one error type, and a test.