This section describes the core entities of the system and the reasoning behind their relationships.
{
"private": boolean,
"creator": User,
"title": string,
"status": "todo" | "in_progress" | "done",
"description": string,
"users": [User], // List of users assigned to this task
"teams": [Team], // List of teams associated with this task
"subtasks": [Task], // Child tasks (self-referencing relationship)
"created_at": Date,
"updated_at": Date,
"deadline": Date
}The creator field is separated from the users many-to-many field.
- The creator represents ownership.
- Assigned users represent collaboration.
- Deletion permissions depend on ownership, not assignment.
- A creator may not necessarily be the only collaborator.
This separation enables explicit and fine-grained authorization logic.
subtasks uses a directed self-referencing ManyToMany relationship.
- Allows hierarchical decomposition of work.
- Supports flexible task structures.
- Enables non-symmetrical parent → child relationships.
This models a directed graph rather than a strict tree structure.
No cycle detection is implemented; graph integrity is handled at the application level.
Tasks can be linked to teams.
- Teams act as permission groups.
- If a user belongs to a team assigned to a task, they inherit visibility and modification rights.
- Avoids duplicating user-task assignments for every team member.
This design enables scalable and centralized collaboration management.
{
"name": string,
"users": [User] // Members of the team
}Teams serve two roles:
- Organizational grouping
- Permission propagation unit
Tasks reference teams rather than duplicating individual team members.
- Centralizes permission logic at the team level.
- Prevents redundant user-task assignments.
- Ensures that changes in team membership automatically affect task visibility.
- Maintains consistency between collaboration structure and access control.
{
"id": int,
"username": string,
"email": string,
"password": string
}The built-in Django User model is used.
- Avoids reimplementing authentication logic.
- Leverages Django’s built-in password hashing and validation system.
- Maintains full compatibility with Django’s authentication framework.
{
"user": User, // One-to-one relationship with User
"description": string,
"image": *.png // Stored in the "pictures/profile_pictures" directory
}UserProfile extends Django’s built-in User model using a OneToOneField.
- Keeps authentication logic separate from profile-related data.
- Avoids modifying Django’s core
Usermodel. - Allows additional fields (e.g.,
description,image) without implementing a custom user model. - Maintains compatibility with Django’s built-in authentication system.
The UserProfile instance is automatically created via a Django signal when a new User is created.