Add planning documents for Forte music store platform

17 domain design docs covering architecture, accounts, inventory,
rentals, lessons, repairs, POS, payments, batch repairs, delivery,
billing, accounting, deployment, licensing, installer, and backend
tech architecture. Plus implementation roadmap (doc 18) and
personnel management (doc 19).

Key design decisions documented:
- company/location model (multi-tenant + multi-location)
- member entity (renamed from student to support multiple adults)
- Stripe vs Global Payments billing ownership differences
- User/location/terminal licensing model
- Valkey 8 instead of Redis
This commit is contained in:
Ryan Moon
2026-03-27 14:51:23 -05:00
commit 5f8726ee4e
36 changed files with 9558 additions and 0 deletions

View File

@@ -0,0 +1,359 @@
Music Store Management Platform
Domain Design: Accounts & Customers
# 1. Overview
The Accounts & Customers domain is the foundational entity model for the platform. All billing, lessons, rentals, repairs, and sales link back to an Account. This domain handles the distinction between the billing entity (Account) and the individual people (Students/Contacts) associated with it.
# 2. Core Concepts
## 2.1 Account
An Account is the billing entity. It holds the Stripe customer reference and payment preferences. An account may represent a single adult customer, a parent/guardian paying for children, or a business customer.
- One Stripe customer ID per account
- Holds billing preferences (consolidated vs split)
- Has one or more associated members
- All invoices and statements roll up to the account level
## 2.2 Member
A Member is an individual person associated with an account — adults, children, or anyone who takes lessons, rents instruments, or needs to be tracked under the account. Multiple members per account supports family billing (e.g. two parents and three children all on one account). For a single adult managing their own billing, the account holder and member are the same person.
- Linked to account for billing
- Has their own lesson enrollments, rental history, and repair history
- Multiple members per account (family billing — any mix of adults and minors)
- `is_minor` flag derived from `date_of_birth` — controls whether parent/guardian consent and portal access rules apply
- Each member can have their own email and phone — useful for adult members receiving their own notifications
# 3. Database Schema
## 3.1 account
Column
Type
Notes
id
uuid PK
Primary key
company_id
uuid FK
Tenant scoping — identifies which company owns this record
account_number
varchar
Human-readable account ID
name
varchar
Account/business name
email
varchar
Primary contact email
phone
varchar
Primary phone
address
jsonb
Street, city, state, zip
stripe_customer_id
varchar
Stripe customer reference
billing_mode
enum
consolidated | split
notes
text
Internal staff notes
legacy_id
varchar
AIM original customer ID
legacy_source
varchar
'aim' for migrated records
migrated_at
timestamptz
When record was imported
created_at
timestamptz
Record creation timestamp
updated_at
timestamptz
Last update timestamp
## 3.2 member
Column
Type
Notes
id
uuid PK
Primary key
account_id
uuid FK
Billing account
company_id
uuid FK
Tenant scoping — identifies which company owns this record
first_name
varchar
last_name
varchar
date_of_birth
date
Used to derive is_minor status
is_minor
boolean
True if under 18 — derived from date_of_birth, controls consent and portal access rules
email
varchar
Member's own email — each adult can have their own
phone
varchar
Member's contact number
notes
text
Staff notes
legacy_id
varchar
AIM original ID
created_at
timestamptz
## 3.3 account_payment_method
Tracks payment methods on file. The actual card data lives in Stripe — this table only stores references.
Column
Type
Notes
id
uuid PK
account_id
uuid FK
processor
enum
stripe | legacy
stripe_payment_method_id
varchar
pm_xxx reference
card_brand
varchar
visa, mastercard, etc.
last_four
char(4)
Display only
exp_month
integer
exp_year
integer
is_default
boolean
Default payment method for account
requires_update
boolean
True if still on legacy processor
created_at
timestamptz
# 4. Business Rules
- Every member must belong to exactly one account
- An account must have at least one member (can be the account holder themselves)
- Billing always targets the account, never the member directly
- An account can have multiple payment methods but only one default
- Consolidated billing: all active subscriptions on one account roll to one Stripe customer
- Split billing: each enrollment/rental can have its own billing date and subscription
- Account deletion is soft-delete only — financial history must be retained
- Duplicate account detection on email and phone during creation
# 5. Key Workflows
## 5.1 New Account Creation (Walk-in)
- Staff searches by name/phone/email to check for existing account
- If none found, creates new account with contact details
- Adds member record(s) — could be same person, spouse, or children
- Optionally captures payment method via Stripe Elements
- Stripe customer created in background, ID stored on account
## 5.2 Account Lookup at POS
- Search by account number, name, phone, or email
- Returns account summary: members, active rentals, active lessons, balance
- Staff selects account to attach transaction
## 5.3 AIM Migration
- AIM customer records imported with legacy_id and legacy_source='aim'
- Duplicate detection run before import — staff reviews conflicts
- Payment methods flagged requires_update=true until customer re-enters card in Stripe