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