Standardize REST API #2 404/422 runtime bodies on ProblemDetails.
Make channel, collection, and smart-collection response metadata explicitly document ProblemDetails for generated clients.
Regenerate ErsatzTV/wwwroot/openapi/v1.json and document the chosen contract in docs/rest-api.md.
Add runtime, controller metadata, and static OpenAPI contract tests.
Contract Decision
ProblemDetails is the standard error body for #2a/#2b REST API 404/422 responses. /docs and the static OpenAPI document are intended as generated-client contracts, so runtime behavior now matches that schema instead of returning plain string error values.
## Summary
- Standardize REST API #2 404/422 runtime bodies on `ProblemDetails`.
- Make channel, collection, and smart-collection response metadata explicitly document `ProblemDetails` for generated clients.
- Regenerate `ErsatzTV/wwwroot/openapi/v1.json` and document the chosen contract in `docs/rest-api.md`.
- Add runtime, controller metadata, and static OpenAPI contract tests.
## Contract Decision
`ProblemDetails` is the standard error body for #2a/#2b REST API 404/422 responses. `/docs` and the static OpenAPI document are intended as generated-client contracts, so runtime behavior now matches that schema instead of returning plain string error values.
## Verification
- LSP diagnostics on changed C# files: clean.
- `dotnet build ErsatzTV.sln`: passed, 0 warnings/errors.
- `TZ=UTC dotnet test ErsatzTV.sln -v normal`: passed, build 0 warnings/errors.
- Adversarial subagent review: no findings.
Refs #46
CI status note after digging into Gitea internals:
The PR status API is misleading here because it returns both the initial pending commit_status rows and the later terminal rows for the same contexts. The current commit_status_summary for head c113142a3d07a6a17d00866925bc8c7d080144d4 is success.
Action run 174 task evidence from the Gitea DB:
Job
Task status
Runner
Started UTC
Stopped UTC
Build & test (.NET)
1 (success)
jazz-runner
2026-06-28 12:59:29
2026-06-28 13:03:03
EF migration integrity (SQLite + MySql)
1 (success)
jazz-runner
2026-06-28 12:59:29
2026-06-28 13:04:05
Build & push image (amd64)
4 (skipped)
jazz-runner
2026-06-28 13:04:08
2026-06-28 13:04:08
The skipped image job is expected on pull_request because the workflow has if: github.event_name != 'pull_request' for image push.
CI status note after digging into Gitea internals:
The PR status API is misleading here because it returns both the initial pending `commit_status` rows and the later terminal rows for the same contexts. The current `commit_status_summary` for head `c113142a3d07a6a17d00866925bc8c7d080144d4` is `success`.
Action run 174 task evidence from the Gitea DB:
| Job | Task status | Runner | Started UTC | Stopped UTC |
|---|---:|---|---|---|
| Build & test (.NET) | 1 (success) | jazz-runner | 2026-06-28 12:59:29 | 2026-06-28 13:03:03 |
| EF migration integrity (SQLite + MySql) | 1 (success) | jazz-runner | 2026-06-28 12:59:29 | 2026-06-28 13:04:05 |
| Build & push image (amd64) | 4 (skipped) | jazz-runner | 2026-06-28 13:04:08 | 2026-06-28 13:04:08 |
The skipped image job is expected on `pull_request` because the workflow has `if: github.event_name != 'pull_request'` for image push.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
ProblemDetails.ProblemDetailsfor generated clients.ErsatzTV/wwwroot/openapi/v1.jsonand document the chosen contract indocs/rest-api.md.Contract Decision
ProblemDetailsis the standard error body for #2a/#2b REST API 404/422 responses./docsand the static OpenAPI document are intended as generated-client contracts, so runtime behavior now matches that schema instead of returning plain string error values.Verification
dotnet build ErsatzTV.sln: passed, 0 warnings/errors.TZ=UTC dotnet test ErsatzTV.sln -v normal: passed, build 0 warnings/errors.Refs #46
CI status note after digging into Gitea internals:
The PR status API is misleading here because it returns both the initial pending
commit_statusrows and the later terminal rows for the same contexts. The currentcommit_status_summaryfor headc113142a3d07a6a17d00866925bc8c7d080144d4issuccess.Action run 174 task evidence from the Gitea DB:
The skipped image job is expected on
pull_requestbecause the workflow hasif: github.event_name != 'pull_request'for image push.