← Highgate Studios

Rolliance Release Notes

What's new in Rolliance

Apr 3 – Apr 10, 2026 21 PRs merged

New Features

Member Billing Subscriptions & Invoicing

  • Subscription enrollment flow: studio owners can subscribe members to recurring plans via a payment link sent through Stripe Checkout. Supports billing date selection (signup date or fixed day), proration for mid-cycle starts, and family member selection. #159
  • Invoicing system with pending enrollment tracking, checkout URL generation via background Oban workers, and real-time status updates via PubSub. #159
  • Cancel-at-period-end support for memberships, allowing scheduled cancellations that preserve access until the billing period ends. #177
  • Cancellation request workflow: members can request cancellation, studio owners can approve or deny. #159
  • Cancel pending enrollments: studio owners can now cancel in-progress subscription enrollments, which expires the Stripe Checkout Session and marks the invoice as cancelled. #190

Family Billing

  • Unified family billing: subscribe multiple family members to a single plan with tiered pricing per dependent. #177
  • Dependent credit display and pass management from the family member detail view. #177

Discount Codes

  • Discount code member assignments: assign specific discount codes to individual members with studio owner email notifications. #186
  • Discount code validation and application during subscription enrollment with real-time price preview. #186

Member Portal

  • New Payments page in the member portal showing billing history and active subscriptions, gated behind Stripe Connect status. #185
  • Stripe Connect onboarding step added to the studio setup flow. #185

Blog CMS

  • Full blog content management system with admin CRUD, public-facing pages, and SEO infrastructure. #158

Multi-Rank System

  • Studios can create multiple rank/belt systems with tab navigation, rename, and delete support. #157
  • Soft-delete rank systems to preserve member rank display history. #157

Dev & Test Tooling

  • Admin studio seeder for dev/test environments with 10 member billing scenarios (power user, capped, pack user, paused, expired, etc.). #156, #163, #164

Improvements

Billing & Payments

  • Consolidated pricing source of truth onto PricingCache, dropped the subscription_plans database table. #188
  • Proration threshold and timezone-aware day counting for accurate billing anchors. #175, #176, #178, #184
  • Duplicate pass prevention and loading overlays during billing operations. #169, #179
  • Removed subscription-style cancellation options (End of Period) from non-recurring plan types. #183

UI/UX

  • Responsive layouts, split-pane messaging, simplified breadcrumbs, and compact controls. #168
  • Member pages polish: dropdowns, discount code chips, check-in status colors. #189
  • Email verification banner removed; studio owner emails rebranded. #186

Performance & Reliability

  • Optimized member portal LiveView performance with reduced re-renders. #167
  • Stripe integration security and architecture audit addressing uniqueness constraints and billing gaps. #160, #161

Bug Fixes

  • Fixed "Send Payment Link" button doing nothing due to nested HTML forms causing the browser to orphan the submit button. #190
  • Fixed subscription detection, phantom customer creation, and webhook correlation for platform billing. #187
  • Fixed raw database field names appearing in user-facing flash messages; changeset errors now show human-readable labels. #153
  • Fixed member portal bottom nav, messages panel, and new conversation modal breaking on certain routes. #174
  • Fixed class comment character counter not updating while typing. #173
  • Fixed Stripe Connect status refresh for v1 Express accounts. #172
  • Fixed duplicate panel mounts and gated billing behind Stripe Connect status. #170
  • Fixed 4 member billing bugs: GenServer crash, Stripe param error, dependent checkout, family visibility. #171
  • Fixed 6 member billing UX issues including discount pass type selector and design token migration. #165, #182
  • Fixed proration threshold off-by-one error and invoice PubSub broadcasting. #184
  • Fixed flaky timezone tests by using fixed reference datetimes instead of wall clock. #161
Mar 28 – Apr 3, 2026 8 PRs merged

New Features

Member Billing & Class Passes

  • New member billing system: studios can create class access passes (unlimited, limited, drop-in) with configurable credit tracking, expiration dates, and pricing. #136
  • Credit enforcement at check-in and enrollment with overage tracking and admin billing toggle. Walk-in override allows staff to bypass credit checks. #136
  • Purchase-for-dependent flow lets primary account holders buy passes on behalf of family members. #136
  • Route guards redirect members without active passes to the studio page with a flash message instead of a 404 loop. #136
  • Member Billing link added to the studio owner sidebar for managing passes and credits. #136

Stripe Connect Payments

  • Stripe Connect webhook processing for handling payment events (charges, refunds, disputes) on connected accounts. #144, #145
  • Connect payment end-to-end test suite with comprehensive coverage of webhook event handling. #144, #145

Stripe Integration Test Suite

  • Live integration test suite using Stripe Test Clocks to simulate subscription lifecycle scenarios (creation, upgrades, downgrades, cancellation, past_due grace periods). #142
  • 14-day grace period enforcement for past_due subscriptions before access revocation. #142
  • Deployed environment support for running manual test plans against staging. #140

Improvements

Design System Migration (Phase 2)

  • All studio-owner pages migrated from DaisyUI component classes to the new ds-* design system tokens. #151

Bug Fixes

  • Fixed mobile scroll being completely blocked after navigating via the hamburger menu. #155
  • Fixed mobile tooltip dismiss behavior on the achievement trophy case. #150
  • Fixed mixed-key map crash when creating pass types via the LiveView form. #149
  • Fixed progression diagram rendering all stripe colors as white. #141
  • Fixed flaky month calendar tests that break at date boundaries. #155
Mar 16 – Mar 28, 2026 30 PRs merged

New Features

Family Accounts

  • Primary members can add dependents (children or adults without credentials) to their family with configurable per-plan caps. #135
  • Family enrollment picker: enroll or unenroll dependents in classes from the class card with multi-select support. #135
  • Graduate flow: promote adult dependents to full accounts using the invitation system with consent tracking. #135
  • Family link requests: members can request to link existing accounts as dependents with owner approval workflow. #135
  • Non-participant toggle for staff to mark dependents who attend but don't participate (e.g., younger siblings). #135
  • Dependent achievements displayed in family section with expandable trophy carousels and real-time PubSub updates. #135
  • Studio settings for enabling family accounts and configuring dependent limits per plan tier. #135

Design System Foundation (Phase 1)

  • New ds-* design system tokens replacing DaisyUI component classes, establishing the foundation for full DaisyUI removal. #138
  • DaisyUI component classes replaced with plain Tailwind CSS across core components. #138

Belt & Rank Overhaul

  • Complete redesign of the belt & rank editor with visual timeline, collapsible belts, and inline editing for rank names, stripe colors, and gate requirements. #99
  • Bulk operations: select multiple ranks for bulk delete or bulk color override. #99
  • New belt creation wizard with style picker, live preview, sub-rank auto-creation, and smart color defaults. #91
  • Shared rank editor component used by both studio and admin contexts via adapter pattern. #129
  • Visual progression diagram showing rank-to-rank paths in the rank editor. #132

Onboarding Wizard Redesign

  • Post-payment onboarding redesigned as a 9-step split-panel wizard covering studio setup, belt & rank configuration, class creation, email preferences, and invitations. #89
  • Brand identity step added to onboarding: upload logo with client-side cropper, configure colors, and preview brand header. #100
  • Skip onboarding now preserves the user's partial changes instead of discarding them. #89
  • Comma-separated and pasted email lists supported in onboarding invitation steps. #89

Studio Theming

  • Studios can configure brand color, logo, tagline, and header style (solid, gradient, texture) applied across all member-facing pages and emails. #73
  • Admin-configurable accent color override for class schedule cards. #78

Member Class Schedule Redesign

  • Member class schedule redesigned with floating timeline layout, decoupled from DaisyUI. #68
  • Profile page redesigned with trophy shelf, compact class cards, and improved LiveView patching. #68

Messaging & Mobile UX

  • Studio conversation mobile UX overhauled: auto-growing textarea, hidden header on scroll, Enter key sends on desktop while adding newlines on mobile. #127, #131
  • Mobile messaging UX: fixed input visibility behind keyboard, improved studio nav breadcrumbs, and responsive layout. #125
  • Compact message headers, improved category buttons, and input border styling for member messaging. #131

Studio Settings

  • Studio name max length validation (50 chars) with UI truncation and slug sanitization. #128
  • Click-to-copy studio URL in owner settings with improved URL overflow handling. #128
  • Member signup visibility toggle: studios can hide/show class signup from member-facing pages with real-time PubSub updates. #116
  • Inline class description editing added to slide-over and detail pages. #114

Improvements

Instructor Dashboard

  • Instructor dashboard and class detail restyled with the new custom design system. #76
  • Today's Overview section moved above class list for better visibility. #78

Student Pages

  • Student profile and class pages refactored: decomposed into smaller components, CSS migrated from DaisyUI to Tailwind, and mobile spacing improved. #74
  • Security and performance audit on student /classes and /profile pages with studio-scoping guards. #72

Email & Auth

  • Brand header texture rendering fixed on member auth pages with consolidated styling. #75
  • Notification preferences moved from email settings to studio settings. #66
  • Emoji picker upgraded from limited built-in to full emoji-mart component on achievements pages. #66

Mobile UX

  • Mobile class card improvements: compact layout matching mockups, dark mode contrast fixes, and improved spacing. #78, #133
  • Real-time class count updates on student profile. #81
  • Walk-in enroll+check-in flow added to owner and instructor class detail pages. #135

Bug Fixes

  • Fixed onboarding invitation URLs, avatar re-upload failures, and class publish crash. #104
  • Fixed R2Storage double-resolving filename causing version suffix duplication. #98
  • Fixed activity feed bugs and added feed visibility toggle. #95
  • Fixed belt creation failures from stale belt icon name constraint. #91, #99
  • Fixed belt editor dark mode with theme-aware tokens replacing hardcoded colors. #119
  • Fixed LiveView custom select replacing native timezone dropdown. #118
  • Fixed cancelled invitations showing by default; added Show Canceled toggle. #117
  • Fixed onboarding email validation replacing invisible flash with inline errors. #112
  • Fixed long email addresses overflowing chip tags in onboarding invite steps. #111
  • Fixed attendance report filter dropdowns not responding to changes. #122
  • Fixed onboarding category dropdown showing empty options. #123
  • Fixed member sign-out returning a 404 (route was inside auth guard). #87
  • Fixed XSS vulnerability in CsToast component (used textContent instead of innerHTML). #68
  • Fixed GenServer crash from missing {:messages_read, _} handler in MemberLive.Show. #72
  • Fixed member detail page not updating on invitation acceptance via PubSub. #135
  • Fixed class roster crash when PubSub refresh missed primary_contact enrichment. #135
  • Fixed total_classes_override to be additive with actual attendance count. #81
  • Fixed deactivated members still able to log in or maintain sessions. #80

Infrastructure

  • File uploads migrated from Render persistent disk to Cloudflare R2 object storage with release eval migration support. #82, #83, #84
  • Avatar processing consolidated to Vix/libvips with client-side cropping via Cropper.js. #86
  • Stripe webhook handler integration tests and billing tests added to CI. #90
  • Worktree bootstrap script improved with port detection, named volumes, and cleanup. #87
Mar 8 – Mar 15, 2026 12 PRs merged

New Features

Studio Activity Feed

  • Real-time studio activity feed with emoji reactions, threaded comments, and PubSub-driven updates. #24
  • Activity notifications with unseen indicator badge on trophy icon. #24, #25
  • Configurable activity feed settings: toggle reactions and comments per studio. #25
  • Student activity feed hides awarder info and positions notification dot as badge. #24, #69

Toast Notifications

  • Auto-dismissing toast notification system for student enrollment pages, replacing flash messages. #52

New Class Badge

  • NEW badge displayed on recently added classes for members, with debounced last_seen tracking. Cancelled classes excluded. #53, #54

Enrollment Comments

  • Members can add an optional comment when enrolling in a class, visible to instructors on the roster. #50

Message Email Notifications

  • Batched email notifications sent to studio owners when they receive new messages, preventing notification flooding. #55

Messaging Improvements

  • Recipient info banner displayed in the new message modal showing who the message will be sent to. #49

Landing Page & Billing

  • Landing page redesigned with dark editorial theme applied to sign-in and signup pages. #56
  • Fixed plan selection not carrying over from landing page to the setup wizard. #58
  • Cancellation reasons tracked on enrollments and displayed in daily digest emails and on class rosters. #21

Improvements

  • Onboarding studio setup flow redesigned with extracted marketing theme system. #67
  • CANCELLED badge moved before class name; removed redundant cancelled button. #57
  • Login input styling unified across sign-in, sign-up, and reset-password pages. #59
  • Danger Zone archive button gated by studios:write permission; duplicates removed. #38
  • Daily digest recovery: DailyStudioDigestWorker scheduled on application startup. #30
  • Avatar images now lazy-loaded with cache headers for improved performance. #21

Bug Fixes

  • Fixed landing page sections invisible before LiveView JS connects. #45
  • Fixed landing page navigation, registration loading state, and auth redirect. #46
  • Fixed class disappearing on description update from duplicate PubSub broadcasts. #21
  • Fixed tier_for_price_id matching empty string to a tier in billing. #100

Infrastructure

  • Playwright browser tests added for signup flow and auth redirect. #60
  • Persistent disk and UPLOAD_STORAGE_PATH config added to Render deployment. #82
  • libvips added to all Dockerfiles for image upload processing. #27
Mar 1 – Mar 8, 2026 18 PRs merged

New Features

Recurring Email Campaigns

  • Create recurring email campaigns with weekly or biweekly scheduling, configurable send day and time per studio timezone. #17
  • Pause and resume recurring campaigns without losing send history. Active campaigns show next scheduled send date. #17
  • Dedicated Oban worker handles per-campaign scheduling with automatic rescheduling after each send and crash recovery on deploy. #17
  • Send history tracked via email logs with success/failure counts displayed on the campaign show page. #17
  • Existing studio digest settings automatically migrated to recurring campaigns, preserving all configuration. #17

Email Campaign UI Overhaul

  • Email category selector: choose between "Studio Update" and "Marketing" to control which member email preference is checked before sending. #17
  • Recipient exclusion modal: deselect specific members from a campaign with live opted-in count updates. #17
  • Campaign index redesigned with stats dashboard (Total Sent, Drafts, Scheduled, Recipients) and desktop table with mobile card fallback. #17
  • Campaign show page standardized to design guidelines: plain divs, correct button colors, badge sizing, and full email preview rendering. #17

Multi-Email Invitations

  • Invitation form now accepts comma-separated email addresses for sending multiple invitations at once. #17
  • Per-email validation: format checking, existing member detection, pending invite detection, and duplicate detection with clear error messages. #17
  • Member limit status banner shows remaining slots and pending invitation count against the studio's plan limit. #17

Studio Export & Import

  • New mix tasks to export a studio and all its related data (~40 tables) to a self-contained JSON file, and import it into any Rolliance database. #2, #3
  • Supports cross-environment migration (e.g. DojoFlow staging to Rolliance dev) with owner email override, slug override, and dry-run mode. #2
  • Conflict handling: slug collisions, existing owner reuse, duplicate user skip, missing table graceful skip, full transaction rollback on failure. #2
  • Remote database support via DATABASE_URL with SSL for Render-hosted databases. #2

Seed Data Tools

  • mix rolliance.seed_members: create random member accounts in a studio, bypassing billing checks, with configurable count and dry-run mode. #16
  • mix rolliance.seed_enrollments: randomly enroll members into upcoming classes with a configurable fill rate and realistic distribution curve. #16

Landing Page

  • Draft community-focused landing page added for review. #10

Improvements

Class Details & Instructor Views

  • Class details refactored from 3-tab layout to a unified single page with all information visible at once. #14
  • Responsive class details slide-over with lg breakpoint, inline instructor display, and enrollee list. #15
  • Inline description editing for instructors on their class detail page. #15
  • Instructor dashboard refactored to true server-side pagination with scheduled class support. #15, #16

Week-Based Publishing

  • New week_start_day studio setting with timezone-safe week boundaries for batch publishing. #16
  • Week-based range options for class schedules: "This Week", "Next Week", and "This & Next Week" replace raw day counts. #17
  • Publishing preview now shows which day the week starts on. #17

Email Settings

  • Schedule Digest configuration removed from email settings page (consolidated into the recurring campaigns system). #17
  • RFC-compliant List-Unsubscribe headers added to recurring campaign emails for Gmail one-click unsubscribe. #17

Bug Fixes

  • Fixed subscription plan price ID mismatch: original migration baked placeholder Stripe price IDs at compile time during mix release. New runtime migration syncs DB with actual env var values on deploy. #17
  • Fixed password reset emails not being sent; restyled password reset pages to match application design. #11
  • Locked down self-registration to prevent unauthorized account creation. #11
  • Fixed studio import using stale inserted_at timestamps that triggered spurious batch publishing catch-up runs. #4, #5
  • Fixed Release.seed/0 crashing because Repo was not started during release seed step. #4
  • Fixed staging Docker build by hardcoding MIX_ENV=staging in Dockerfile. #8

Admin & Internal

  • Admin studio detail page expanded with email statistics (total sent, success/failure breakdown by category), member opt-out tallies, and daily digest controls (toggle, time picker, manual send, reset). #17
  • Real-time PubSub updates on admin email stats when emails are sent. #17
  • Responsive admin improvements: overflow handling, mobile-friendly stat grids, sticky breadcrumbs, dropdown menus. #17

Infrastructure

  • Recurring campaign worker added to OTP supervision tree with crash recovery and automatic rescheduling. #17
  • Email logger module for tracking studio email stats and opt-out counts. #17
  • Playwright browser E2E test infrastructure added with devcontainer support. #3
  • Staging environment enabled in render.yaml with dedicated Dockerfile. #6, #7
  • Billing URLs now derived from Phoenix endpoint config instead of hardcoded values. #2
Feb 23 – Feb 28, 2026 21 PRs merged

New Features

Batch Publishing

  • Batch materialization: classes scheduled for batch publishing are now materialized and published by a dedicated Oban worker at the studio's configured publish time, with a summary email to the studio owner. #396
  • Same-day scheduling support: batch publish now handles classes scheduled for the current day, and draft classes are properly published during a batch run. #396
  • Batch publish notification opt-out: studio owners can disable the summary email from class settings. #396

Instructor Dashboard Redesign

  • Class schedule cards redesigned with a vertical timeline layout featuring colored left accent borders, opaque timeline dots, and time-based grouping. #393, #394
  • Enrollment indicators and attendee chips displayed directly on class cards with student avatars. #394
  • Expandable class cards now load full enrollment details on demand. #393

Improvements

Mobile & Responsive

  • Instructor dashboard mobile layout overhauled: improved card sizing, better text readability (10px → 12px base), and tighter timeline padding for small screens. #393, #394
  • Timeline dot and line alignment polished across breakpoints with proper offset calculations for left padding. #394
  • Badge alignment and spacing cleaned up on mobile class cards. #394

Class Management

  • Batch schedule preview now displays times in 12-hour format instead of 24-hour. #396
  • Fixed duplicate studio owner appearing in the instructor dropdown when the owner is also an instructor. #396

Bug Fixes

  • Fixed multi-tenant session isolation: all authenticated routes now enforce studio membership, preventing cross-studio data access via session manipulation. #391
  • Reduced login friction with sliding session windows and longer session durations so users aren't forced to re-authenticate frequently. #390

Admin & Internal

  • Removed legacy admin class management routes and studio dashboard that were superseded by newer pages. #395
Feb 8 – Feb 22, 2026 40 PRs merged · 180+ new tests

New Features

Recurring Classes

  • Create recurring class schedules (weekly, biweekly, and monthly) directly from the class creation form using a "Make Recurring" toggle. Standalone classes can also be converted to recurring when editing. #343, #364, #368
  • Future recurring class instances appear as virtual entries on the owner calendar beyond the publish window, giving a full schedule overview without premature database materialization. #341
  • Pause and resume recurring class generation without losing the template or any already-published classes. #347
  • Remove individual dates from a recurring series via "Remove from Schedule" on the calendar. Published classes notify enrolled members before removal. #373

Daily Studio Digest

  • New daily digest email for studio owners summarizing operational health, upcoming schedule, action items, and activity. Configurable send time with enable/disable toggle in admin settings. #358, #360, #369
  • Digest includes "Recent Achievements" section and a "Watch For Today" section highlighting members one attendance away from a milestone who are enrolled in today's classes. #378
  • Sign-up links per class row so owners can share enrollment links directly from the email. #369

Achievement System

  • When a member is un-checked-in, achievements that are no longer earned are soft-revoked — hidden from the member but preserved in the database. Re-earning restores the same record, avoiding duplicate notifications. All affected views refresh in real-time. #377

Instructor Dashboard

  • Dedicated instructor dashboard with stats cards (Your Classes, Your Students, This Week) and a class listing with clickable cards. #370
  • New class detail view replaces the old roster page, combining class info header with an inline roster featuring student avatars, check-in/undo buttons, and real-time updates. #370

Onboarding

  • New 4-step onboarding wizard (Welcome, Publishing Strategy, Email Notifications, Summary) runs after Stripe payment setup and before dashboard access. Pre-selects recommended defaults with skip option. #348

Member Management

  • Age classification filter (Youth/Adult) added to members list. #301
  • "Promotion Ready" filter evaluates gate progress in real-time and returns members who have met all requirements for their next rank. #300
  • Uniform sizing (Top/Bottom/Belt) can now be viewed and edited by both the member and the studio owner. #303
  • Studio owners can edit a member's first and last name through the Edit Member Data modal. #306

Invitations & Email

  • Member invitation limits enforced against the studio's plan. Bulk invitations auto-truncate to available slots with a warning. #298
  • Test email preview: send a real test email for any automated template directly from email settings. #372
  • Enrollment confirmation emails consolidated into a single digest when a member enrolls in multiple classes within a short window. #353

Improvements

Class & Template UX

  • Class publishing UX improved: expected publish date displayed in calendar slide-over, "Publish Now" actually publishes, and publishing rules auto-save. #354
  • Template form restructured into logical sections with toggle buttons for tags. #354
  • Shared form components extracted between class form and template form to prevent drift. #368
  • View toggle buttons (list/calendar) redesigned with more prominent pill-container styling. #351

Member Profile

  • Profile page redesigned with modern card-based layout: hero banner with avatar and stats, two-column grid, per-card edit states, and auto-saving email preferences. #302

Email & Timezone

  • Unsubscribe links now use signed, environment-aware URLs. Supports both inline preferences and RFC 8058 one-click unsubscribe (Gmail). #362
  • {studio_url} placeholder added to all automated email templates and campaign emails. #314
  • All datetime displays across owner, instructor, and student views now use the studio's configured timezone instead of UTC. #316

Bug Fixes

Recurring Classes

  • Fixed templates generating virtual instances for past dates. #351, #346
  • Fixed deactivated_at timestamp never being set on pause. #375
  • Fixed duplicate recurrence day validation error from event race condition. #367

Instructor & Class Management

  • Fixed instructor "is invalid" validation error when selecting the studio owner as instructor. #375
  • Fixed instructor demotion leaving stale class assignments on upcoming classes and templates. #322

Billing & Subscriptions

  • Fixed 8 Stripe webhook handling bugs causing subscription status to fall out of sync. #319

Member Data & Email

  • Fixed member name field losing the unchanged component when updating only first or last name. #306
  • Fixed State and Country dropdowns truncated in profile edit form. #305
  • Fixed unsubscribe URL placeholder in campaign emails left as literal text. #362
  • Fixed studio slug being regenerated when studio name changed, breaking existing email links. #314

UI

  • Fixed "Publish Now" button creating draft classes instead of publishing. #354
  • Fixed leap year crash in age calculation for Feb 29 birthdays. #368

Admin & Internal

  • Admin panel overhaul: collapsible sidebar, real activity feed dashboard, webhook event viewer, studio health diagnostics, data integrity scanner, real analytics, system configuration with feature flags. #337
  • Admin billing inspector rewritten with pagination, search, status filtering, CSV export, and per-user Stripe sync. #334
  • Full user detail page with profile card, studio listing, billing summary, audit logs, and admin actions. #335, #336
  • All 19 email templates now editable from admin panel with auto-generated plain text. #339
  • Email tracking system: logs all transactional, campaign, and system emails with success/failure status. #338

Infrastructure

  • Replaced fire-and-forget webhook processing with Oban worker providing retries and deduplication. #319
  • Added subscription sync cron job (every 6 hours) to reconcile statuses against Stripe. #319
  • Converted digest scheduling from hourly cron polling to per-studio Oban jobs that fire at the exact configured time. #360