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
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
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
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
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
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
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