Data Models
Understanding the database structure
Data Models
The Habit Tracker API uses the following data models.
Habit
Represents a habit that a user wants to track.
Fields:
id(int): Unique identifieruser(ForeignKey): The user who owns this habitname(string): Name of the habit (max 100 characters)description(text): Detailed descriptioncreated_at(datetime): When the habit was created
Example:
{
"id": 1,
"name": "Morning Exercise",
"description": "30 minutes of exercise every morning",
"created_at": "2024-01-15T08:00:00Z"
}HabitEntry
Records daily completions for a habit.
Fields:
id(int): Unique identifierhabit(ForeignKey): The associated habitdate(date): The date of this entrycompleted(boolean): Whether the habit was completed
Constraints:
- Unique together:
habitanddate(one entry per habit per day)
Example:
{
"id": 42,
"date": "2024-01-15",
"completed": true
}StreakChallenge
Represents a challenge between two users to maintain a habit.
Fields:
id(int): Unique identifierhabit(ForeignKey): The habit being challengedcreator(ForeignKey): User who created the challengefriend(ForeignKey): User who was invitedstart_date(date): When the challenge startedend_date(date, nullable): When the challenge endedcurrent_streak(int): Current consecutive days both completedhighest_streak(int): Highest streak achieved during challengeis_active(boolean): Whether the challenge is ongoingstatus(string): Current status (pending/accepted/rejected/completed)winner(ForeignKey, nullable): User who won (if applicable)last_checked(date): Last time streak was updated
Status Values:
pending: Waiting for friend to acceptaccepted: Active challengerejected: Friend declinedcompleted: Challenge has ended
Example:
{
"id": 5,
"habit_id": 1,
"habit_name": "Morning Exercise",
"creator": "john_doe",
"friend": "jane_doe",
"current_streak": 7,
"highest_streak": 12,
"is_active": true,
"status": "accepted",
"start_date": "2024-01-01",
"end_date": null,
"winner": null
}StreakChallengeEntry
Records daily completions for a challenge participant.
Fields:
id(int): Unique identifierchallenge(ForeignKey): The associated challengeuser(ForeignKey): The participantdate(date): The date of this entrycompleted(boolean): Whether the user completed the habit
Constraints:
- Unique together:
challenge,user, anddate
ChallengeInvite
Tracks challenge invitations (for future features).
Fields:
id(int): Unique identifierchallenge(ForeignKey): The associated challengeinviter(ForeignKey): User who sent the inviteinvitee(ForeignKey): User who received the invitestatus(string): Invite status (pending/accepted/rejected)created_at(datetime): When the invite was sent
Constraints:
- Unique together:
challengeandinvitee
Relationships
User
├── Habit (one-to-many)
│ └── HabitEntry (one-to-many)
│
└── StreakChallenge (many-to-many via creator/friend)
└── StreakChallengeEntry (one-to-many)Streak Calculation
Streaks are calculated dynamically based on HabitEntry and StreakChallengeEntry records:
Personal Habit Streaks
- Current Streak: Consecutive days from today/yesterday backwards where
completed=True - Longest Streak: Maximum consecutive days with
completed=Truein history
Challenge Streaks
- Combined Streak: Consecutive days where BOTH participants completed
- Individual Streaks: Each participant's personal consecutive completions
- Highest Streak: Maximum combined streak achieved during the challenge
The system automatically updates streaks when entries are logged and checks for missed days to end inactive challenges.