feat(tpagectl): implement preview list subcommand #575

Merged
fuzzy merged 2 commits from feat/cli-preview-list into main 2026-08-06 23:29:02 +00:00
Owner

What

Implements preview list end to end: the daemon's missing GET /api/v1/sites/{name}/previews endpoint plus the tpagectl preview list subcommand.

Daemon

  • SiteService.Previews(ctx, siteName) returns a site's preview deployments (branch-based versions) via the existing isPreviewDeployment helper; ErrNotFound when the site is missing.
  • New GET /api/v1/sites/{name}/previews handler (#218): owner-scoped (403), 404, 200 with []Deployment.
  • Tests: service (previews filtered to branch versions, production excluded; unknown site), handler 200/404.

CLI

  • Site arg (#217): positional SITE or --site flag (the shared --site issue was completed under deployment list).
  • GET (#218): /api/v1/sites/{name}/previews decoded into a previewRecord (yaml tags for snake_case structured output).
  • Table (#219): Branch, Path, Status, Last Updated — Path derived as /preview/{branch}.
  • --format (#220): table (default), json, yaml.
  • Friendly 404; missing site name error.
  • Tests: table columns + path derivation, --site/positional forms, JSON round-trip, YAML output, 404, missing arg.

Why

Phase 4 roadmap task #221.

Testing

  • Daemon: service Previews (filtered, unknown site), handler 200/404 tests
  • CLI: table columns/path, --site/positional, json/yaml, 404, missing arg
  • go test -race ./... passes (19 packages)
  • golangci-lint run clean
  • pre-commit hooks pass (gofmt, go mod tidy, go test)

Breaking Changes

None. SiteService gains Previews (already implemented by the concrete type).

Notes

The new previews endpoint also unblocks site get preview display (#181, previously deferred); that remains a separate follow-up. The remaining preview subcommands (deploy, delete, get) are still stubs tracked by their own issues.

Closes #217
Closes #218
Closes #219
Closes #220
Closes #221

## What Implements `preview list` end to end: the daemon's missing `GET /api/v1/sites/{name}/previews` endpoint plus the tpagectl `preview list` subcommand. **Daemon** - `SiteService.Previews(ctx, siteName)` returns a site's preview deployments (branch-based versions) via the existing `isPreviewDeployment` helper; `ErrNotFound` when the site is missing. - New `GET /api/v1/sites/{name}/previews` handler (#218): owner-scoped (403), 404, 200 with `[]Deployment`. - Tests: service (previews filtered to branch versions, production excluded; unknown site), handler 200/404. **CLI** - **Site arg** (#217): positional `SITE` or `--site` flag (the shared `--site` issue was completed under `deployment list`). - **GET** (#218): `/api/v1/sites/{name}/previews` decoded into a `previewRecord` (yaml tags for snake_case structured output). - **Table** (#219): Branch, Path, Status, Last Updated — Path derived as `/preview/{branch}`. - **`--format`** (#220): `table` (default), `json`, `yaml`. - Friendly 404; missing site name error. - Tests: table columns + path derivation, `--site`/positional forms, JSON round-trip, YAML output, 404, missing arg. ## Why Phase 4 roadmap task #221. ## Testing - [x] Daemon: service Previews (filtered, unknown site), handler 200/404 tests - [x] CLI: table columns/path, `--site`/positional, json/yaml, 404, missing arg - [x] `go test -race ./...` passes (19 packages) - [x] `golangci-lint run` clean - [x] pre-commit hooks pass (gofmt, go mod tidy, go test) ## Breaking Changes None. `SiteService` gains `Previews` (already implemented by the concrete type). ## Notes The new previews endpoint also unblocks `site get` preview display (#181, previously deferred); that remains a separate follow-up. The remaining preview subcommands (`deploy`, `delete`, `get`) are still stubs tracked by their own issues. Closes #217 Closes #218 Closes #219 Closes #220 Closes #221
Add the daemon GET /api/v1/sites/{name}/previews endpoint and the tpagectl
preview list subcommand.

Daemon: SiteService.Previews returns a site's preview deployments
(branch-based versions) via the existing isPreviewDeployment helper, 404
when the site is missing. The handler is owner-scoped and returns 200 with
the preview list.

CLI: preview list takes a positional site name or --site flag, fetches the
previews, and renders a table of branch, path, status, and last updated,
with --format (table, json, yaml). The preview path is derived as
/preview/{branch}.
docs(roadmap): mark preview list subcommand complete
All checks were successful
Test and Release / lint (pull_request) Successful in 7m7s
Test and Release / test (pull_request) Successful in 7m19s
c6c96e20bf
Record completion of the tpagectl preview list subcommand and its daemon
endpoint: positional site name or --site, GET
/api/v1/sites/{name}/previews, table of branch/path/status/last updated,
and --format. The shared --site subtask #217 was completed under
deployment list.

closes #217
closes #218
closes #219
closes #220
closes #221
fuzzy scheduled this pull request to auto merge when all checks succeed 2026-08-06 23:17:20 +00:00
the.auditor left a comment

Summary

preview list: daemon GET /api/v1/sites/{name}/previews + tpagectl subcommand. Verified: go test -race ./... passes (19 packages) and golangci-lint run ./... is clean. Closes #217-221.

Verified: previewRecord mirrors the daemon Deployment payload (JSON + yaml tags); the service returns an empty [] rather than null when a site has no previews; handler error mapping (403/404/500) is consistent with the other endpoints.

No blocking issues; no new issues filed (remaining items are recurring gaps already tracked).

Questions

  1. internal/site/service.go (Previews) filters with isPreviewDeployment (!HasPrefix("v")), while CleanupPreviews uses HasPrefix("test/"). A production deployment at a non-v tag (promotable via deployment promote --version <non-v-tag>, #568) would be misclassified and appear in preview list. Consider aligning the preview-vs-production convention (extends #568).

References (covered by existing issues)

  1. internal/tpagectl/preview/list.go – the 404→friendly mapping is now a seventh inline copy (extends #565/#561); invalid --format and non-404 passthrough remain untested (recurring gaps #566/#571).

Praise

  • Clean Previews service using the existing isPreviewDeployment helper, with production deployments explicitly excluded in tests
  • previewPath derivation is simple and correct
  • Solid coverage: filtered service, handler 200/404, CLI table columns/path, --site/positional, JSON round-trip, snake_case YAML, 404, missing-arg
## Summary `preview list`: daemon `GET /api/v1/sites/{name}/previews` + tpagectl subcommand. Verified: `go test -race ./...` passes (19 packages) and `golangci-lint run ./...` is clean. Closes #217-221. Verified: `previewRecord` mirrors the daemon `Deployment` payload (JSON + yaml tags); the service returns an empty `[]` rather than `null` when a site has no previews; handler error mapping (403/404/500) is consistent with the other endpoints. No blocking issues; no new issues filed (remaining items are recurring gaps already tracked). ## Questions 1. `internal/site/service.go` (`Previews`) filters with `isPreviewDeployment` (`!HasPrefix("v")`), while `CleanupPreviews` uses `HasPrefix("test/")`. A production deployment at a non-`v` tag (promotable via `deployment promote --version <non-v-tag>`, #568) would be misclassified and appear in `preview list`. Consider aligning the preview-vs-production convention (extends #568). ## References (covered by existing issues) 1. `internal/tpagectl/preview/list.go` – the 404→friendly mapping is now a seventh inline copy (extends #565/#561); invalid `--format` and non-404 passthrough remain untested (recurring gaps #566/#571). ## Praise - Clean `Previews` service using the existing `isPreviewDeployment` helper, with production deployments explicitly excluded in tests - `previewPath` derivation is simple and correct - Solid coverage: filtered service, handler 200/404, CLI table columns/path, `--site`/positional, JSON round-trip, snake_case YAML, 404, missing-arg
fuzzy merged commit c6c96e20bf into main 2026-08-06 23:29:02 +00:00
fuzzy deleted branch feat/cli-preview-list 2026-08-06 23:29:03 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
thwap/thwap-pagesd!575
No description provided.