Summary
The recent session added `status=any` aliasing in two places:
- `apps/api/internal/rest/posts/handlers.go`
- `apps/api/internal/admin/comments/list.go`
A third handler accepts `status` and validates it: `apps/api/internal/admin/search/handler.go:94` — passes `status` unchecked to `pkgsearch.SearchOpts`. If the search package validates strictly, `?status=any` will 400 there too.
Fix
Extract a shared parser:
```go
// packages/go/util/queryparse/status.go
func ParseStatus(raw string, valid map[string]struct{}) (string, error) {
if raw == "" || raw == "any" { return "", nil } // empty = no filter
if _, ok := valid[raw]; !ok { return "", ErrInvalidStatus }
return raw, nil
}
```
Migrate posts/handlers.go, admin/comments/list.go, admin/search/handler.go to call it. Going forward every new list endpoint uses the same helper.
Files to touch
- New: `packages/go/util/queryparse/` (or similar)
- `apps/api/internal/rest/posts/handlers.go`
- `apps/api/internal/admin/comments/list.go`
- `apps/api/internal/admin/search/handler.go`
Summary
The recent session added `status=any` aliasing in two places:
A third handler accepts `status` and validates it: `apps/api/internal/admin/search/handler.go:94` — passes `status` unchecked to `pkgsearch.SearchOpts`. If the search package validates strictly, `?status=any` will 400 there too.
Fix
Extract a shared parser:
```go
// packages/go/util/queryparse/status.go
func ParseStatus(raw string, valid map[string]struct{}) (string, error) {
if raw == "" || raw == "any" { return "", nil } // empty = no filter
if _, ok := valid[raw]; !ok { return "", ErrInvalidStatus }
return raw, nil
}
```
Migrate posts/handlers.go, admin/comments/list.go, admin/search/handler.go to call it. Going forward every new list endpoint uses the same helper.
Files to touch