Release notes
Reverse-chronological summary of significant shipped changes. This page is the "what actually changed" companion to the full docs — if you're returning to a codebase you haven't touched in a while, skim here first.
2026-07 · Launch-readiness pass
Themed pass to close the punch list from the readiness audit.
Notifications channel (in-app)
- Backend:
tenant_notifications+tenant_notification_recipientstables. Audience kinds:all_clients,clients,pets,recent_visitors(last N days, N configurable 1–365), andstaff(activetenant_userrows). - Admin SPA: Notifications sidebar entry + composer + sent history + bell icon in the topbar (personal inbox).
- vetdoctor: megaphone + bell icons in the dashboard AppBar.
- vetyy: bell in the app bar + inbox screen with swipe-to-delete + deeplink routing.
/me/notifications/*— tenant-agnostic personal inbox endpoints reused across owner + staff.- Deploy fix:
deploy.shrunsRolePermissionSeederon every deploy sonotification.*permission drift can't recur.
See Notifications for the full design.
Operator console
- New Filament panel at
/operatorfor the SaaS platform provider. Runs alongside the existing/systemadminpanel using the samesystem_adminsguard. - Cross-tenant analytics widgets: RevenueTrendChart (6-month line), TopTenantsByActivity (top 10 by appointments this week), OperatorOverview stats.
- Cross-tenant user lookup page (search across all users + memberships + last-login).
- Tenant suspend / activate + impersonate actions on the shared TenantResource.
SystemAdmin::canAccessPanel()enforcesis_activeon every request — suspension is instant, no session invalidation dance.SystemAdminSeeder+php artisan operator:createfor production-safe first-operator bootstrap.- Post-deploy
smoke-operator.shruns fromdeploy.shto catch regressions in the operator surface.
See Operator Console for the full breakdown.
Owner-side appointment booking (vetyy)
Owner picks reason + preferred date/time + optional note on the
pet-detail action menu → POST /owner/me/appointments creates a
scheduled appointment with booking_source='owner_app'. Clinic
sees it in their queue and confirms via the standard flow. Throttled
at 20 requests / hour.
Encryption at rest for ServiceSetting secrets
Rows where is_secret=true (Twilio, Msg91, SMTP, WhatsApp
credentials) are now encrypted via Crypt::encryptString wrapped in
a {"__enc": "…"} envelope. Transparent to callers.
service-settings:encrypt artisan command backfills existing rows;
deploy.sh runs it automatically.
Sentry (Laravel side) as opt-in
bootstrap/app.php registers a Sentry exception reporter, gated on
BOTH SENTRY_LARAVEL_DSN env var AND
class_exists(Sentry\Laravel\Integration::class). Install with
composer require sentry/sentry-laravel when you want it; the deploy
keeps working without.
Docs site + phpMyAdmin services
vetty-docs(Docusaurus → static nginx) at${DOCS_HOSTNAME}.vetty-phpmyadminat${DB_HOSTNAME}, gated by theadmincompose profile — off by default.
See Deployment architecture for the full runtime picture.
Admin SPA hardening
ModuleErrorBoundarywraps each lazy module so one crashing chunk doesn't blank the whole SPA.useDialogA11yhook adds ARIA + focus-trap to hand-rolled modals without a full rewrite. Modal.js primitive stays for new dialogs.- Mock-mode detection now uses
NODE_ENV+ explicitREACT_APP_ENABLE_MOCK=truerather than a hard-codedlocalhost:3000check — works behind tunnels / proxies. - i18n foundation with English + Hindi seed strings in
ui/src/lib/i18n.js.
Deploy pipeline hardening
- Traefik dynamic-config pre-flight in
deploy.shfails loud if thevetty-headersmiddleware isn't installed — kills a class of "API ships without security headers because Traefik silently stripped the chain" bugs. optimize:clearbeforeroute:cacheon every api boot so a stale cache file can't poison a new container.Dockerfilescrubs any leftover cachedroutes-v7.php/config.phpbeforecomposer dump-autoload.- Operator smoke test runs automatically after every deploy.
Flutter env-var validation
Both vetyy and vetdoctor refuse to boot a release build that
didn't pass *_API_BASE_OVERRIDDEN=true at build time — misconfigured
CI ship catches on first launch instead of silent-fallback to
staging.
Older releases
Older releases (Weeks 1 through 6, pre-launch remediation) are in the
git log with docs/AUDIT_REMEDIATION.md as a matching artifact.