feat: Artisan checklist for application commands, hints and coverage gate

- migrate, migrate:rollback and deferred:purge gain --pretend and --force;
  they and queue:clear confirm only in production on an interactive
  terminal, so deploys over SSH proceed as before
- result lines: Applied N migrations, Rolled back <id> of <plugin>,
  Cleared N jobs from <queue>
- --json for migrate:status, key:generate, route:list, admin:token:create,
  admin:token:list, admin:token:scopes and websockets:health; -q keeps the
  key and the token
- hints for an empty DSN, an unreachable database, an invalid app.key, a
  missing uploads bucket and an application binary run below its root
- flare and websockets:health return bonfire.Reported after printing
- long help and examples for every application command, greeter:hello and
  blog:publish; cmd/summer TestCommandsDocumented fails on any gap
This commit is contained in:
Jakub Zych
2026-10-21 13:16:21 +02:00
parent 168d65cd1b
commit 9d06a78f62
29 changed files with 831 additions and 77 deletions

View File

@@ -134,7 +134,7 @@ if err := app.Publish[flare.SubscriptionSource](blogSubscriptions{db: gdb}); err
| `websockets:generate-vapid-keys [--update] [--show-current]` | Shows the configured keys, truncated to the first 8 and last 4 characters with their length and a check mark when they decode to a valid pair. `--show-current` stops there. Otherwise it generates a new P-256 pair, validates its length and base64url alphabet and prints both keys. With `--update` the keys are saved through `compass.Config.Set` and `compass.Config.Persist` to `env/<environment>/overrides.yaml` in the config directory (mode 0600; other keys in the file are kept). Without it, the command prints `SUMMER_PUSH__PUBLIC_KEY=…` and `SUMMER_PUSH__PRIVATE_KEY=…` lines to set by hand. |
| `websockets:test-push <user_id> [--show-config]` | Prints the push configuration: enabled, whether each key is set with its length (never the value), the subject and its format. It then reads the user's subscriptions from the published `flare.SubscriptionSource`, lists them (endpoint shortened to 60 characters, user agent, when subscribed and last used) and asks `Send test notification?` (default yes; a non-interactive run takes the default). It sends one encrypted test push to each subscription and reports each result. `--show-config` is accepted for compatibility; the configuration is always shown. |
`websockets:test-push` exits 1 when no subscription source is published (`no subscription source registered`), when the user is unknown or has no subscriptions, when push is disabled (it lists the subscriptions but sends nothing), and when any send fails. The test payload is `{"title":"<app.name> test","body":"This is a test push notification sent at HH:MM:SS","data":{"test":true,"timestamp":<unix>}}`.
Both commands print their own failure messages and return `bonfire.Reported` errors, so the binary exits 1 without a second error block. `websockets:test-push` exits 1 when no subscription source is published (`no subscription source registered`), when the user is unknown or has no subscriptions, when push is disabled (it lists the subscriptions but sends nothing), and when any send fails. The test payload is `{"title":"<app.name> test","body":"This is a test push notification sent at HH:MM:SS","data":{"test":true,"timestamp":<unix>}}`.
## Dependencies