Deployment & Settings Changes - v1.65.0

Release: v1.65.0 Date: 2026-04-29


Summary

Impact Level: MEDIUM

Action Required: NO for SaaS prod (single instance), YES for federation-consumer instances (Helm value + secret)

Backward Compatible: YES


Quick Decision Matrix

Component/Area Change Type Risk Level Action Required Impact
Environment Variables New (2 optional) LOW YES for federation consumers, NO for SaaS prod SEATMAP_FEDERATION_SOURCE_URL and SEATMAP_FEDERATION_SOURCE_API_KEY for consumers
Database Schema Migrations (V104 + V105) LOW NO Two additive migrations; auto-applied on editor-service startup
Analytics Schema View recreated LOW YES (manual) v_bookings_log recreated with new columns; apply via seatmap_analytics role
Docker Images Standard upgrade NONE NO Tag bump only
Kubernetes/Helm New optional values + new Secret kind LOW YES for federation consumers New seatmap-helm-secrets keys federation.sourceApiKey, rendered into *-federation
Runtime Dependencies No changes NONE NO -
Monitoring/Logging New + modified Grafana dashboards NONE NO (auto-applied via observability Helm chart bump) Release Watch dashboard added; SaaS Fleet/Monthly + booking dashboards updated

Deployment Decision

Overall Risk: LOW

Recommended Action: APPROVE

Downtime Required: NO — zero-downtime rolling restart supported.

Rollback Risk: SAFE — V104 / V105 are additive. Downgrading editor-service to 1.64.0 with the new tables present is safe (unused columns and tables are ignored). Federation Helm values are optional; unsetting reverts to non-federated behavior.

Special Considerations: Federation-consumer instances (e.g. Timepad) need the new Helm value + secret applied before the editor pod restarts; otherwise the federation client stays inactive (no error, just no federated content).


Configuration Changes

Environment Variables

New Variables (editor-service)

Variable Required Default Description Example
SEATMAP_FEDERATION_SOURCE_URL No (consumer instances only) (empty) Base URL of the source instance to pull library content from. Activates the federation-consumer client. https://seatmap.pro
SEATMAP_FEDERATION_SOURCE_API_KEY No (consumer instances only) (empty) One-time API key issued by the source instance via /api/admin/federation/instances. Read from K8s Secret. fed_xxxxxxxxxxxxxxxxxxxxxxxxxxxx

Both are optional. SaaS prod (single instance, no federation upstream) leaves them unset.

Modified Variables

No modified variables in this release.

Removed Variables

No removed variables in this release.


Database Changes

Two Flyway migrations run automatically on editor-service startup. Booking-service does not run migrations and is unaffected.

V104__venues_library_and_federation.sql

Additive schema for the Venues Library + federation features.

organization:

  • library_publisher BOOLEAN NOT NULL DEFAULT FALSE — flag indicating the org may list venues in the library.

venue:

  • library_listed BOOLEAN NOT NULL DEFAULT FALSE
  • library_listed_at TIMESTAMP — set when a venue is listed.
  • library_origin_instance_url VARCHAR(255) — provenance: source instance URL for federated copies.
  • library_origin_venue_id VARCHAR(255) — provenance: source venue identifier.
  • library_origin_org_name VARCHAR(255) — provenance: source org name (display only).
  • library_imported_at TIMESTAMP — set when a venue is materialised from a library copy.
  • Partial index venue_library_listed_at_idx on (library_listed_at DESC) where library_listed = TRUE — drives the browse-by-recency query.
  • Partial index venue_library_imported_at_idx on (library_imported_at DESC) where library_imported_at IS NOT NULL.

New library_pull_log table — append-only audit of library copy / asset operations:

  • id, request_id UUID, instance_api_key_hash, user_id, organization_id, operation, venue_id, asset_id, status_code, bytes_transferred, duration_ms, user_agent, created_at.
  • Four indexes: created_at, venue_id, (instance_api_key_hash, created_at), (user_id, created_at).

New federation_instance table — federation API keys (consumer-facing):

  • id, key_hash VARCHAR(64) UNIQUE, label, created_at, created_by, revoked_at, last_used_at, rate_limit_rpm INTEGER NOT NULL DEFAULT 60.
  • Partial index federation_instance_active_idx on (key_hash) where revoked_at IS NULL.

Role seed:

  • ROLE_LIBRARY_SUBSCRIBER inserted into role if not present (idempotent).

V105__create_impersonation_audit.sql

New impersonation_audit table — append-only audit of global-admin impersonation sessions:

  • id, session_id UUID UNIQUE, admin_user_id and target_user_id (FK to registered_user, ON DELETE RESTRICT), started_at, ended_at, ended_reason, ip_address, user_agent.
  • Three indexes: (admin_user_id, started_at DESC), (target_user_id, started_at DESC), partial (ended_at) where ended_at IS NULL (active sessions).

Rollback

Both migrations are additive. Downgrading editor-service to 1.64.0 with the V104 / V105 tables present is safe (unused columns and tables are ignored). If a forced rollback is required, the operator can DROP TABLE federation_instance, library_pull_log, impersonation_audit and ALTER TABLE venue / organization DROP COLUMN ... after confirming no concurrent traffic — but this is not necessary for a normal version downgrade.

Analytics Schema (manual)

products/db-migrations/manual/analytics-schema.sql was updated. Recreate the affected views in the analytics schema before the analytics dashboards consume the new columns:

DROP VIEW IF EXISTS v_bookings_log;
-- then run the CREATE VIEW block from the updated analytics-schema.sql

Apply via the seatmap_analytics role on the analytics schema. This is a manual step (not Flyway-driven) per the existing analytics schema operating model.


Helm / Kubernetes Changes

deployment/helm/seatmap/values.yaml

New optional values block under editor.config.seatmap:

editor:
  config:
    seatmap:
      federation:
        source:
          url: ''

New optional values block under secrets:

secrets:
  federation:
    sourceApiKey: ''

deployment/helm/seatmap/templates/secrets.yaml

When both editor.config.seatmap.federation.source.url and secrets.federation.sourceApiKey are set, the chart renders an additional Secret {fullname}-federation with the key source-api-key.

deployment/helm/seatmap/templates/editor/deployment.yaml

When editor.config.seatmap.federation.source.url is non-empty, the editor deployment gains two env vars:

  • SEATMAP_FEDERATION_SOURCE_URL — from the chart value.
  • SEATMAP_FEDERATION_SOURCE_API_KEY — from the {fullname}-federation Secret.

Federation-consumer setup (operators)

Self-hosted operators that want to pull library content from another instance:

  1. Ask the source-instance global admin to issue a federation key via POST /api/admin/federation/instances with a labeled request. The source instance returns the plaintext key once — store it immediately.

  2. Add the key to the consumer cluster’s seatmap-helm-secrets Secret under federation-source-api-key.

  3. Add the federation block to the HelmRelease valuesFrom:

    - kind: Secret
      name: seatmap-helm-secrets
      valuesKey: federation-source-api-key
      targetPath: secrets.federation.sourceApiKey
    
  4. Set editor.config.seatmap.federation.source.url in the HelmRelease values to the source URL (e.g. https://seatmap.pro).

  5. Reconcile via Flux (flux reconcile helmrelease seatmap). The editor pod restart picks up the new env vars and the federation client activates.


Observability Changes

The deployment/helm/observability Helm chart was bumped (Chart.yaml version) to ship dashboard changes. Per the project memory: always bump the chart version on dashboard changes — Helm skips same-version upgrades.

Dashboards added / updated:

  • dashboard-release-watch.yaml — NEW. Real-time release health monitoring (deployment progress, pod readiness, error rates per component) for use during release rollouts.
  • dashboard-saas-fleet.yaml — UPDATED. Adds seat-state outbox panels (drain rate, drain lag, oldest unprocessed event age) and SOLD/LOCKED ClickHouse panels.
  • dashboard-saas-monthly.yaml — UPDATED. New columns / formatting for outbox-driven metrics; aligns with the recreated v_bookings_log view.
  • dashboard-booking.yaml — UPDATED. Outbox panel Grafana legend escaped to fix curly-brace rendering.

The chart is Flux-managed (clusters/internal/apps/observability.yaml HelmRelease in the flux repo). Force reconcile after merge if needed:

KUBECONFIG=~/seatmap-dev.config flux reconcile helmrelease observability -n observability

Service Configuration

No changes to application.yaml defaults in editor-service or booking-service. The seatmap.outbox and seatmap.hold-types.defaults blocks introduced in 1.64.0 remain unchanged.


Migration Guide

Standard SaaS (single instance, no federation)

  1. Standard rolling deployment.
  2. Flyway runs V104 + V105 automatically on editor-service startup.
  3. Apply the analytics schema view recreation (manual, see above).
  4. Bump deployment/helm/observability/Chart.yaml, push to the flux repo, let Flux reconcile.
  5. Verify the new dashboards render in Grafana.

Federation-consumer instance (e.g. Timepad)

  1. Source-instance admin issues a federation key for the consumer.
  2. Consumer operator adds federation-source-api-key to seatmap-helm-secrets and the federation block to the HelmRelease.
  3. Standard rolling deployment.
  4. Verify federation activation in editor-service logs (look for FederationClient initialized at startup) and by browsing the library — federated entries appear alongside in-instance entries.

Sign-off

  • DBA: V104 + V105 migrations reviewed and acceptable.
  • Analytics owner: v_bookings_log recreation scheduled after merge.
  • DevOps: Helm value injection for federation consumers verified (not applicable for SaaS prod).
  • SRE: Release Watch dashboard available before next deploy window.