Parent: Aligner Tracker Api


Entity Relationship Diagram


erDiagram

User ||--o{ Journey : "has"

User ||--o{ ProgressEvent : "has"

User ||--o{ UserImage : "uploads"

User ||--o{ Notification : "receives"

Journey ||--o{ ProgressEvent : "contains"

Journey ||--o{ UserImage : "contains"

Journey ||--o{ Notification : "contains"

ProgressEvent ||--o| Notification : "schedules next"

  

User {

int id PK

datetime created_at

datetime updated_at

string email UK

string first_name

string last_name

string postal_code

int jarvis_id

string hubspot_id UK

int assigned_dentist_id

bool has_pending_dentist_change

bool terms_accepted

string cognito_sub_identifier UK

}

  

Journey {

int id PK

int user_id FK

string product

string status

int current_progress_stage

int total_progress_stages

date date_of_starting_treatment

string aftercare_stage

datetime created_at

}

  

ProgressEvent {

int id PK

int user_id FK

int journey_id FK

datetime start_date

int progress_stage

datetime end_date

int next_notification_id FK

string type

string reason

}

  

UserImage {

int id PK

int user_id FK

int journey_id FK

string s3_key

datetime date_uploaded

int progress_stage

}

  

Notification {

int id PK

datetime created_at

int user_id FK

int journey_id FK

text content

enum status

enum source

datetime scheduled_for

string onesignal_id

}

Table Details

users

The central entity representing an app user (patient).

FieldTypeNotes
idintPrimary key
emailstringUnique, used as Cognito username
first_namestringPatient’s first name
last_namestringPatient’s last name
postal_codestrPatient’s postal code
cognito_sub_identifierstringUnique, links to Cognito identity
jarvis_idintExternal Jarvis system ID
hubspot_idstringHubSpot CRM ID
assigned_dentist_idintFK to dentist (external)
has_pending_dentist_changeboolWhether a dentist change is pending
terms_acceptedboolWhether T&Cs accepted

journeys

Represents a user’s treatment cycle for a specific product. A user can have multiple journeys over time but only one active journey at any time.

FieldTypeNotes
idintPrimary key
user_idintFK to users
productstringProduct type: aligners, clear_braces
statusstringJourney status: active, completed
current_progress_stageintCurrent progress stage number
total_progress_stagesintTotal stages in treatment plan
date_of_starting_treatmentdateSet on first progress event
aftercare_stagestringHubSpot aftercare stage: scan_appointment_booked, aligner_journey_underway, journey_complete
created_atdatetimeWhen the journey was created

progress_events

Records progress events of different types (progress, pause, delay, continue).

FieldTypeNotes
idintPrimary key
user_idintFK to users
journey_idintFK to journeys
start_datedatetimeWhen the event was created
progress_stageintProgress stage number at time of event
end_datedatetimeScheduled next action (nullable)
next_notification_idintFK to scheduled notification
typestringEvent type: progress, pause, delay, continue
reasonstringReason for pause/delay events (nullable)

user_images

Progress photos uploaded by users.

FieldTypeNotes
idintPrimary key
user_idintFK to users
journey_idintFK to journeys
s3_keystringS3 object key
date_uploadeddatetimeUpload timestamp
progress_stageintProgress stage number at upload

notifications

Push notification records.

FieldTypeNotes
idintPrimary key
user_idintFK to users
journey_idintFK to journeys (nullable)
contenttextNotification message
statusenumpending, sent, cancelled
sourceenumprogress, other
scheduled_fordatetimeWhen to send (null = immediate)
onesignal_idstringOneSignal notification ID for cancellation

Indexes

Key indexes for query performance:

  • users.email (unique)

  • users.cognito_sub_identifier (unique)

  • users.jarvis_id

  • users.hubspot_id (unique)

  • journeys.user_id

  • progress_events.user_id

  • progress_events.journey_id

  • user_images.user_id

  • user_images.journey_id

  • notifications.user_id

  • notifications.journey_id

  • notifications.scheduled_for (for notification worker queries)