Adds frontend/public/logo.svg as a placeholder (rendered at /build/logo.svg
after Vite build). Email template share_notification.html.twig swaps the
text "WeVisto" header for an <img> referencing /build/logo.svg via
absolute_url, so dropping in the final design swaps one file with no
template change.
bin/smoke.sh HOST now defaults to wevisto.com — legacy host still smoke-
testable via HOST=pictureframe.edholm.me bin/smoke.sh under the dual-
domain coexistence (Option C).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Step 2 was doing `curl -sI .../mercure?topic=ping` to verify the hub was
reachable. Over HTTP/2, that HEAD against the SSE endpoint apparently
leaves a connection state on Caddy/Mercure that causes the next subscribe
from the same source to receive zero bytes — making step 6's round-trip
fail every time. Took a careful bisect to find: minimal script worked,
adding step 2 broke it 100%.
The hub-reachable check is redundant anyway: step 5's full publish→
subscribe round-trip is a stronger proof of life. Renumbered to 5 steps,
removed the also-not-using set-uo-pipefail commentary too.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Runs after every deploy. Six checks against pictureframe.edholm.me:
1. Frontend reachable (302/200 expected).
2. Mercure hub reachable (200 expected).
3. All pictureframe-* containers Up/healthy.
4. No CRITICAL / Fatal / 5xx in last 5 min of php/worker/nginx logs.
5. Authenticated /api/devices round-trip via testbot.
6. Mercure publish→subscribe round-trip via no-op PATCH.
Catches the class of bug that just bit us today: nginx caching a stale
PHP container IP after `docker compose up -d`, and a silently-dropped
composer dep crash-looping the worker. Neither shows up in unit tests
because they're infra-level.
Per the new "post-deploy smoke check" rule: if a unit test doesn't
cover a change, run this script (or an equivalent cURL) before
declaring the deploy done.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>