927 lines
14 KiB
Markdown
927 lines
14 KiB
Markdown
# CampReg Data Model Specification
|
||
|
||
**Version:** 0.1
|
||
**Date:** 2026-06-01
|
||
|
||
---
|
||
|
||
## 1. Data Model Philosophy
|
||
|
||
CampReg should be designed around a marketplace-connected, multi-tenant, family-centered data model.
|
||
|
||
The core data model must support:
|
||
|
||
- Parent-owned child profiles
|
||
- Provider-owned operational records
|
||
- Marketplace listing data
|
||
- Multiple registration modes
|
||
- Multi-location providers
|
||
- Multiple seasons
|
||
- Multiple programs and sessions
|
||
- Payment and ledger history
|
||
- Forms and custom fields
|
||
- Staff roles and permissions
|
||
- Attendance and check-in/check-out
|
||
- Health and medication records with restricted access
|
||
- Marketing automation and campaign attribution
|
||
- Public API and webhooks
|
||
|
||
The model should assume that families may interact with multiple providers over time through the same parent account. This is a major advantage over isolated provider-only registration systems.
|
||
|
||
---
|
||
|
||
## 2. Tenancy Model
|
||
|
||
### 2.1 Platform Tenant Types
|
||
|
||
CampReg should distinguish between:
|
||
|
||
- Platform-level users
|
||
- Provider organizations
|
||
- Parent/family accounts
|
||
- Marketplace listings
|
||
- Staff users attached to provider organizations
|
||
|
||
### 2.2 Provider Organization
|
||
|
||
A provider organization is the primary operational tenant.
|
||
|
||
Examples:
|
||
|
||
- A summer camp company
|
||
- A school
|
||
- A sports club
|
||
- A nonprofit youth organization
|
||
- A multi-location camp operator
|
||
- A solo coach or instructor
|
||
|
||
Provider data should be isolated by organization unless intentionally exposed through marketplace listings or shared parent/family interactions.
|
||
|
||
### 2.3 Parent Account
|
||
|
||
A parent account can exist independently of a provider. This is important because CampMatch is a marketplace. A parent may search, save, compare, and create child profiles before registering.
|
||
|
||
### 2.4 Shared Family Identity
|
||
|
||
A family profile can register with multiple providers. Each provider sees only the data required for that provider’s registration, operations, and communication. The platform may maintain a broader family-level profile for parent convenience, consent, history, and matching.
|
||
|
||
---
|
||
|
||
## 3. Core Entities
|
||
|
||
## 3.1 User
|
||
|
||
Represents any authenticated person.
|
||
|
||
Fields:
|
||
|
||
- id
|
||
- email
|
||
- phone
|
||
- first_name
|
||
- last_name
|
||
- auth_provider
|
||
- email_verified_at
|
||
- phone_verified_at
|
||
- created_at
|
||
- updated_at
|
||
- last_login_at
|
||
- status
|
||
|
||
Relationships:
|
||
|
||
- May belong to one or more family accounts
|
||
- May belong to one or more provider organizations
|
||
- May have platform admin permissions
|
||
|
||
## 3.2 Family
|
||
|
||
Represents a parent-controlled household/account.
|
||
|
||
Fields:
|
||
|
||
- id
|
||
- primary_parent_user_id
|
||
- family_name
|
||
- primary_phone
|
||
- primary_email
|
||
- default_address_id
|
||
- marketing_consent_status
|
||
- operational_sms_consent_status
|
||
- created_at
|
||
- updated_at
|
||
|
||
Relationships:
|
||
|
||
- Has many parents/guardians
|
||
- Has many campers/kids
|
||
- Has many registrations
|
||
- Has many payment methods via processor tokens
|
||
- Has many emergency contacts
|
||
|
||
## 3.3 Parent / Guardian
|
||
|
||
Represents a user’s role within a family.
|
||
|
||
Fields:
|
||
|
||
- id
|
||
- family_id
|
||
- user_id
|
||
- relationship_to_child
|
||
- is_primary_guardian
|
||
- can_register
|
||
- can_pay
|
||
- can_manage_pickups
|
||
- can_receive_emergency_messages
|
||
- created_at
|
||
- updated_at
|
||
|
||
## 3.4 Camper / Kid
|
||
|
||
Represents a child profile controlled by a family.
|
||
|
||
Fields:
|
||
|
||
- id
|
||
- family_id
|
||
- first_name
|
||
- last_name
|
||
- preferred_name
|
||
- date_of_birth
|
||
- grade
|
||
- gender_optional
|
||
- pronouns_optional
|
||
- interests_json
|
||
- skill_levels_json
|
||
- accessibility_notes
|
||
- dietary_notes
|
||
- allergy_summary
|
||
- medical_flag_summary
|
||
- created_at
|
||
- updated_at
|
||
|
||
Sensitive fields must be permission-scoped and carefully separated where appropriate.
|
||
|
||
## 3.5 Provider Organization
|
||
|
||
Fields:
|
||
|
||
- id
|
||
- legal_name
|
||
- public_name
|
||
- organization_type
|
||
- website_url
|
||
- support_email
|
||
- support_phone
|
||
- billing_email
|
||
- verification_status
|
||
- claim_status
|
||
- created_at
|
||
- updated_at
|
||
|
||
Relationships:
|
||
|
||
- Has many locations
|
||
- Has many provider users
|
||
- Has many listings
|
||
- Has many seasons
|
||
- Has many programs
|
||
- Has many sessions
|
||
- Has many registrations
|
||
|
||
## 3.6 Provider Location
|
||
|
||
Fields:
|
||
|
||
- id
|
||
- provider_organization_id
|
||
- name
|
||
- address_line_1
|
||
- address_line_2
|
||
- city
|
||
- region
|
||
- postal_code
|
||
- country
|
||
- latitude
|
||
- longitude
|
||
- timezone
|
||
- created_at
|
||
- updated_at
|
||
|
||
## 3.7 Marketplace Listing
|
||
|
||
Represents the public CampMatch listing.
|
||
|
||
Fields:
|
||
|
||
- id
|
||
- provider_organization_id nullable
|
||
- claimed_by_provider_id nullable
|
||
- public_name
|
||
- slug
|
||
- description
|
||
- short_description
|
||
- categories_json
|
||
- age_min
|
||
- age_max
|
||
- location_id
|
||
- website_url
|
||
- external_registration_url
|
||
- registration_mode
|
||
- listing_status
|
||
- verification_status
|
||
- source
|
||
- seo_title
|
||
- seo_description
|
||
- created_at
|
||
- updated_at
|
||
|
||
Registration modes:
|
||
|
||
- external_link
|
||
- lead_capture
|
||
- campreg_registration
|
||
|
||
## 3.8 Season
|
||
|
||
Fields:
|
||
|
||
- id
|
||
- provider_organization_id
|
||
- name
|
||
- start_date
|
||
- end_date
|
||
- registration_open_at
|
||
- registration_close_at
|
||
- status
|
||
- created_at
|
||
- updated_at
|
||
|
||
## 3.9 Program
|
||
|
||
A program is a type of offering, such as Soccer Camp, Art Camp, STEM Camp.
|
||
|
||
Fields:
|
||
|
||
- id
|
||
- provider_organization_id
|
||
- season_id nullable
|
||
- name
|
||
- description
|
||
- category
|
||
- age_min
|
||
- age_max
|
||
- default_price
|
||
- default_capacity
|
||
- status
|
||
- created_at
|
||
- updated_at
|
||
|
||
## 3.10 Session
|
||
|
||
A session is a specific scheduled instance of a program.
|
||
|
||
Fields:
|
||
|
||
- id
|
||
- provider_organization_id
|
||
- program_id
|
||
- location_id
|
||
- name
|
||
- start_date
|
||
- end_date
|
||
- daily_start_time
|
||
- daily_end_time
|
||
- age_min
|
||
- age_max
|
||
- capacity
|
||
- price
|
||
- deposit_amount
|
||
- registration_status
|
||
- waitlist_enabled
|
||
- created_at
|
||
- updated_at
|
||
|
||
## 3.11 Registration
|
||
|
||
Represents a parent’s registration transaction/workflow.
|
||
|
||
Fields:
|
||
|
||
- id
|
||
- family_id
|
||
- provider_organization_id
|
||
- status
|
||
- registration_source
|
||
- marketplace_referral_id nullable
|
||
- started_at
|
||
- completed_at
|
||
- cancelled_at
|
||
- created_at
|
||
- updated_at
|
||
|
||
Statuses:
|
||
|
||
- started
|
||
- pending_forms
|
||
- pending_payment
|
||
- completed
|
||
- waitlisted
|
||
- cancelled
|
||
- refunded
|
||
|
||
## 3.12 Enrollment
|
||
|
||
Represents a camper enrolled in a specific session.
|
||
|
||
Fields:
|
||
|
||
- id
|
||
- registration_id
|
||
- camper_id
|
||
- session_id
|
||
- enrollment_status
|
||
- waitlist_position nullable
|
||
- price_charged
|
||
- discount_amount
|
||
- financial_aid_amount
|
||
- created_at
|
||
- updated_at
|
||
|
||
Statuses:
|
||
|
||
- enrolled
|
||
- waitlisted
|
||
- cancelled
|
||
- transferred
|
||
- completed
|
||
- no_show
|
||
|
||
## 3.13 Form Template
|
||
|
||
Fields:
|
||
|
||
- id
|
||
- provider_organization_id
|
||
- name
|
||
- description
|
||
- applies_to
|
||
- schema_json
|
||
- required
|
||
- version
|
||
- status
|
||
- created_at
|
||
- updated_at
|
||
|
||
Applies to:
|
||
|
||
- family
|
||
- parent
|
||
- camper
|
||
- registration
|
||
- staff
|
||
|
||
## 3.14 Form Submission
|
||
|
||
Fields:
|
||
|
||
- id
|
||
- form_template_id
|
||
- family_id nullable
|
||
- camper_id nullable
|
||
- registration_id nullable
|
||
- provider_organization_id
|
||
- submitted_by_user_id
|
||
- submission_json
|
||
- status
|
||
- submitted_at
|
||
- approved_at
|
||
- rejected_at
|
||
- created_at
|
||
- updated_at
|
||
|
||
## 3.15 Document
|
||
|
||
Fields:
|
||
|
||
- id
|
||
- provider_organization_id nullable
|
||
- family_id nullable
|
||
- camper_id nullable
|
||
- registration_id nullable
|
||
- uploaded_by_user_id
|
||
- file_url
|
||
- file_type
|
||
- document_type
|
||
- status
|
||
- created_at
|
||
- updated_at
|
||
|
||
## 3.16 Waiver / Agreement
|
||
|
||
Fields:
|
||
|
||
- id
|
||
- provider_organization_id
|
||
- title
|
||
- body_markdown
|
||
- version
|
||
- effective_date
|
||
- status
|
||
- created_at
|
||
- updated_at
|
||
|
||
## 3.17 Signature Record
|
||
|
||
Fields:
|
||
|
||
- id
|
||
- waiver_id
|
||
- user_id
|
||
- family_id
|
||
- camper_id nullable
|
||
- registration_id nullable
|
||
- signed_name
|
||
- signed_at
|
||
- ip_address
|
||
- user_agent
|
||
- created_at
|
||
|
||
## 3.18 Payment
|
||
|
||
Fields:
|
||
|
||
- id
|
||
- provider_organization_id
|
||
- family_id
|
||
- registration_id nullable
|
||
- processor
|
||
- processor_payment_id
|
||
- amount
|
||
- currency
|
||
- status
|
||
- payment_method_summary
|
||
- paid_at
|
||
- failed_at
|
||
- refunded_at
|
||
- created_at
|
||
- updated_at
|
||
|
||
## 3.19 Invoice
|
||
|
||
Fields:
|
||
|
||
- id
|
||
- provider_organization_id
|
||
- family_id
|
||
- registration_id nullable
|
||
- invoice_number
|
||
- subtotal
|
||
- discounts
|
||
- taxes
|
||
- fees
|
||
- total
|
||
- balance_due
|
||
- due_date
|
||
- status
|
||
- created_at
|
||
- updated_at
|
||
|
||
## 3.20 Ledger Entry
|
||
|
||
Fields:
|
||
|
||
- id
|
||
- provider_organization_id
|
||
- family_id
|
||
- registration_id nullable
|
||
- entry_type
|
||
- amount
|
||
- currency
|
||
- description
|
||
- related_payment_id nullable
|
||
- created_at
|
||
|
||
Entry types:
|
||
|
||
- invoice_created
|
||
- payment_received
|
||
- refund_issued
|
||
- discount_applied
|
||
- manual_adjustment
|
||
- failed_payment
|
||
|
||
## 3.21 Attendance Record
|
||
|
||
Fields:
|
||
|
||
- id
|
||
- provider_organization_id
|
||
- session_id
|
||
- camper_id
|
||
- date
|
||
- status
|
||
- checked_in_at
|
||
- checked_in_by_staff_id
|
||
- checked_out_at
|
||
- checked_out_by_staff_id
|
||
- pickup_person_id nullable
|
||
- notes
|
||
- created_at
|
||
- updated_at
|
||
|
||
Statuses:
|
||
|
||
- present
|
||
- absent
|
||
- checked_in
|
||
- checked_out
|
||
- late
|
||
- early_pickup
|
||
|
||
## 3.22 Authorized Pickup
|
||
|
||
Fields:
|
||
|
||
- id
|
||
- family_id
|
||
- camper_id nullable
|
||
- name
|
||
- relationship
|
||
- phone
|
||
- email
|
||
- photo_url optional
|
||
- authorized_by_user_id
|
||
- status
|
||
- valid_from
|
||
- valid_until
|
||
- created_at
|
||
- updated_at
|
||
|
||
## 3.23 Staff User
|
||
|
||
Fields:
|
||
|
||
- id
|
||
- provider_organization_id
|
||
- user_id
|
||
- role_id
|
||
- title
|
||
- department
|
||
- status
|
||
- created_at
|
||
- updated_at
|
||
|
||
## 3.24 Role
|
||
|
||
Fields:
|
||
|
||
- id
|
||
- provider_organization_id
|
||
- name
|
||
- description
|
||
- permissions_json
|
||
- created_at
|
||
- updated_at
|
||
|
||
Core roles:
|
||
|
||
- Provider Owner
|
||
- Camp Director
|
||
- Registrar/Admin
|
||
- Counselor
|
||
- Medical Staff
|
||
- Finance Staff
|
||
- Marketing Staff
|
||
|
||
## 3.25 Medication
|
||
|
||
Fields:
|
||
|
||
- id
|
||
- provider_organization_id
|
||
- camper_id
|
||
- name
|
||
- dosage
|
||
- frequency
|
||
- instructions
|
||
- prescribing_doctor optional
|
||
- start_date
|
||
- end_date
|
||
- status
|
||
- created_at
|
||
- updated_at
|
||
|
||
## 3.26 Medication Dispense
|
||
|
||
Fields:
|
||
|
||
- id
|
||
- medication_id
|
||
- camper_id
|
||
- provider_organization_id
|
||
- dispensed_at
|
||
- dispensed_by_staff_id
|
||
- dosage_given
|
||
- notes
|
||
- created_at
|
||
|
||
## 3.27 Incident Report
|
||
|
||
Fields:
|
||
|
||
- id
|
||
- provider_organization_id
|
||
- session_id nullable
|
||
- camper_id nullable
|
||
- reported_by_staff_id
|
||
- incident_type
|
||
- severity
|
||
- description
|
||
- action_taken
|
||
- parent_notified_at nullable
|
||
- status
|
||
- created_at
|
||
- updated_at
|
||
|
||
## 3.28 Message
|
||
|
||
Fields:
|
||
|
||
- id
|
||
- provider_organization_id nullable
|
||
- family_id nullable
|
||
- campaign_id nullable
|
||
- message_type
|
||
- channel
|
||
- subject
|
||
- body
|
||
- sent_by_user_id nullable
|
||
- sent_at
|
||
- status
|
||
- created_at
|
||
|
||
Channels:
|
||
|
||
- email
|
||
- sms
|
||
- push
|
||
- portal
|
||
|
||
## 3.29 Lead
|
||
|
||
Fields:
|
||
|
||
- id
|
||
- marketplace_listing_id
|
||
- provider_organization_id nullable
|
||
- parent_user_id nullable
|
||
- family_id nullable
|
||
- child_age
|
||
- interests_json
|
||
- requested_dates
|
||
- message
|
||
- source
|
||
- status
|
||
- assigned_to_staff_id nullable
|
||
- created_at
|
||
- updated_at
|
||
|
||
## 3.30 Campaign
|
||
|
||
Fields:
|
||
|
||
- id
|
||
- provider_organization_id
|
||
- campaign_type
|
||
- source_system
|
||
- title
|
||
- goal
|
||
- target_audience_json
|
||
- content_json
|
||
- approval_status
|
||
- missinglettr_campaign_id nullable
|
||
- scheduled_at nullable
|
||
- created_at
|
||
- updated_at
|
||
|
||
## 3.31 API Key
|
||
|
||
Fields:
|
||
|
||
- id
|
||
- provider_organization_id
|
||
- name
|
||
- key_hash
|
||
- scopes_json
|
||
- created_by_user_id
|
||
- last_used_at
|
||
- revoked_at
|
||
- created_at
|
||
|
||
## 3.32 Webhook Subscription
|
||
|
||
Fields:
|
||
|
||
- id
|
||
- provider_organization_id
|
||
- target_url
|
||
- event_types_json
|
||
- signing_secret_hash
|
||
- status
|
||
- created_at
|
||
- updated_at
|
||
|
||
## 3.33 Webhook Event
|
||
|
||
Fields:
|
||
|
||
- id
|
||
- provider_organization_id
|
||
- event_type
|
||
- payload_json
|
||
- delivery_status
|
||
- attempts
|
||
- last_attempt_at
|
||
- created_at
|
||
|
||
---
|
||
|
||
## 4. Audit Logging
|
||
|
||
Every sensitive or operationally important action should generate an audit record.
|
||
|
||
Required audit events:
|
||
|
||
- User login
|
||
- Permission change
|
||
- Provider claim approval
|
||
- Listing update
|
||
- Registration created/completed/cancelled
|
||
- Payment received/refunded/failed
|
||
- Form submitted/approved/rejected
|
||
- Camper medical data viewed
|
||
- Medication dispensed
|
||
- Attendance changed
|
||
- Pickup authorization changed
|
||
- Staff role changed
|
||
- API key created/revoked
|
||
- Webhook created/updated
|
||
|
||
Audit log fields:
|
||
|
||
- id
|
||
- actor_user_id
|
||
- provider_organization_id nullable
|
||
- family_id nullable
|
||
- entity_type
|
||
- entity_id
|
||
- action
|
||
- before_json nullable
|
||
- after_json nullable
|
||
- ip_address
|
||
- user_agent
|
||
- created_at
|
||
|
||
---
|
||
|
||
## 5. Data Access Rules
|
||
|
||
### 5.1 Parent Access
|
||
|
||
Parents can access:
|
||
|
||
- Their family profile
|
||
- Their children’s profiles
|
||
- Their registrations
|
||
- Their forms
|
||
- Their payments
|
||
- Their authorized pickups
|
||
- Provider messages sent to them
|
||
|
||
Parents cannot access:
|
||
|
||
- Other families
|
||
- Provider internal notes unless shared
|
||
- Staff-only incident notes unless shared
|
||
- Other campers
|
||
|
||
### 5.2 Provider Access
|
||
|
||
Providers can access:
|
||
|
||
- Registrations submitted to their organization
|
||
- Forms required by their organization
|
||
- Payment and ledger data for their registrations
|
||
- Attendance for their sessions
|
||
- Staff and operational data for their organization
|
||
|
||
Providers should only access child/family data necessary for the relationship and purpose.
|
||
|
||
### 5.3 Staff Access
|
||
|
||
Staff access depends on roles.
|
||
|
||
Counselor access:
|
||
|
||
- Session roster
|
||
- Attendance
|
||
- Pickup verification
|
||
- Emergency contacts
|
||
- Allergy flags if needed
|
||
|
||
Medical staff access:
|
||
|
||
- Medication records
|
||
- Medical notes
|
||
- Dispense records
|
||
- Health forms
|
||
|
||
Finance access:
|
||
|
||
- Invoices
|
||
- Payments
|
||
- Ledgers
|
||
- Refunds
|
||
|
||
Marketing access:
|
||
|
||
- Leads
|
||
- Campaign audiences
|
||
- Non-sensitive profile segments
|
||
- Consent-filtered parent communication lists
|
||
|
||
---
|
||
|
||
## 6. Data Retention
|
||
|
||
Required retention policies should be configurable by provider and jurisdiction.
|
||
|
||
Suggested categories:
|
||
|
||
- Parent/family profiles
|
||
- Child profiles
|
||
- Registration records
|
||
- Payment records
|
||
- Tax/receipt records
|
||
- Attendance records
|
||
- Medical records
|
||
- Incident records
|
||
- Marketing consent records
|
||
- Audit logs
|
||
|
||
Retention must support:
|
||
|
||
- Legal requirements
|
||
- Provider policies
|
||
- Parent deletion/export requests
|
||
- Child data minimization
|
||
- Backup retention windows
|
||
|
||
---
|
||
|
||
## 7. Reporting Model
|
||
|
||
Reporting should be built on clean operational tables plus an analytics layer.
|
||
|
||
Suggested approach:
|
||
|
||
- PostgreSQL for operational data
|
||
- Event table for behavioral and marketplace events
|
||
- BigQuery or analytics warehouse for reporting, marketplace trends, and growth automation
|
||
|
||
Important reporting dimensions:
|
||
|
||
- Provider
|
||
- Location
|
||
- Season
|
||
- Program
|
||
- Session
|
||
- Category
|
||
- Age group
|
||
- City/region
|
||
- Registration source
|
||
- Campaign source
|
||
- Parent status
|
||
- Child interest
|
||
|
||
---
|
||
|
||
## 8. Marketplace Events
|
||
|
||
Track events such as:
|
||
|
||
- search.performed
|
||
- listing.viewed
|
||
- listing.saved
|
||
- listing.compared
|
||
- registration.clicked
|
||
- lead.submitted
|
||
- registration.started
|
||
- registration.completed
|
||
- provider.claim_started
|
||
- provider.claim_completed
|
||
|
||
These events power marketplace analytics, provider reporting, and VibnAI growth recommendations.
|