Project Requirements
Table of Contents
Understanding the Project
You are going to build a Task Management API. This is a backend-only project, so there is no user interface. Other applications, such as a web frontend, mobile app, or CLI tool, will talk to your API using HTTP.
The goal of this chapter is to define what the system should do, not how you will implement it. Think of this as the contract between you and anyone who wants to use your API.
Throughout this chapter, imagine you are building something similar to a simple version of Trello or Todoist, but focused on learning backend concepts, not on every real-world feature.
High-Level Overview
At a high level, the Task Management API will let users:
- Register and log in.
- Create, read, update, and delete tasks.
- Organize tasks with attributes such as status and priority.
- Filter and sort their tasks.
- Work with due dates.
- See basic metadata like when a task was created or last updated.
The API will be RESTful and will use JSON for requests and responses.
Most endpoints will be authenticated. Each user will only be able to manage their own tasks.
Core Entities and Data Model
You will focus mainly on two entities:
- User
- Task
You might later add more (for example projects or labels), but they are not required for this first project.
User
A user represents a person using the application.
Typical fields:
| Field | Type | Example | Notes |
|---|---|---|---|
id | integer / UUID | 1 or "67e..." | Unique identifier |
email | string | "alice@example.com" | Unique, used for login |
password_hash | string | "$2b$12$..." | Hashed password, not plain text |
created_at | datetime | "2026-01-01T10:23:45Z" | When the user registered |
updated_at | datetime | "2026-01-05T08:30:01Z" | Last profile update |
The API will never return the raw password or password hash to the client.
Task
A task is an item that the user wants to track and complete.
Typical fields:
| Field | Type | Example | Notes |
|---|---|---|---|
id | integer / UUID | 42 | Unique per task |
user_id | integer / UUID | 1 | Owner of the task |
title | string | "Buy groceries" | Short name, required |
description | string / null | "Milk, eggs, bread" | Optional details |
status | enum/string | "todo", "in_progress", "done" | Controls state of task |
priority | enum/string | "low", "medium", "high" | Simple priority system |
due_date | date / null | "2026-02-01" | Deadline if any |
created_at | datetime | "2026-01-10T14:21:30Z" | When the task was created |
updated_at | datetime | "2026-01-11T09:00:00Z" | Last time the task changed |
You will define allowed values for status and priority explicitly. For example:
Status values: todo, in_progress, done
Priority values: low, medium, high
Example task in JSON:
{
"id": 42,
"title": "Buy groceries",
"description": "Milk, eggs, bread",
"status": "todo",
"priority": "medium",
"due_date": "2026-02-01",
"created_at": "2026-01-10T14:21:30Z",
"updated_at": "2026-01-10T14:21:30Z"
}Functional Requirements
Functional requirements describe what the API must do.
User Registration
Users must be able to create an account.
- Endpoint (example):
POST /auth/register - Request body (JSON):
{
"email": "alice@example.com",
"password": "StrongPassword123"
}- Rules:
emailmust be valid and unique.passwordmust meet basic strength rules (you can define minimal ones).- The password must never be stored in plain text.
- Response:
- On success, return the created user data (without password) and maybe an access token.
- On failure, return clear error messages, for example if email is already used.
Example success response:
{
"id": 1,
"email": "alice@example.com",
"created_at": "2026-01-01T10:23:45Z"
}User Login
Users must be able to log in and receive an access token.
- Endpoint:
POST /auth/login - Request body:
{
"email": "alice@example.com",
"password": "StrongPassword123"
}- Behavior:
- Verify email exists.
- Verify password matches.
- Return an authentication token (for example a JWT) that the user will use when calling other endpoints.
Example response:
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI...",
"token_type": "bearer"
}Create Task
Authenticated users can create new tasks.
- Endpoint:
POST /tasks - Authentication: required
- Request body:
{
"title": "Buy groceries",
"description": "Milk, eggs, bread",
"status": "todo",
"priority": "medium",
"due_date": "2026-02-01"
}- Rules:
titleis required, non-empty.statusdefaults to"todo"if not specified.prioritydefaults to"medium"if not specified.due_dateis optional.- The task belongs to the authenticated user, not to a random
user_idfrom input.
Example success response:
{
"id": 42,
"title": "Buy groceries",
"description": "Milk, eggs, bread",
"status": "todo",
"priority": "medium",
"due_date": "2026-02-01",
"created_at": "2026-01-10T14:21:30Z",
"updated_at": "2026-01-10T14:21:30Z"
}List Tasks
Users can list their own tasks.
- Endpoint:
GET /tasks - Authentication: required
Basic behavior:
- Return a paginated list of tasks owned by the authenticated user.
- Allow optional filtering and sorting (detailed later).
Example response:
{
"items": [
{
"id": 42,
"title": "Buy groceries",
"status": "todo",
"priority": "medium",
"due_date": "2026-02-01",
"created_at": "2026-01-10T14:21:30Z",
"updated_at": "2026-01-10T14:21:30Z"
},
{
"id": 43,
"title": "Finish report",
"status": "in_progress",
"priority": "high",
"due_date": "2026-01-15",
"created_at": "2026-01-10T16:00:00Z",
"updated_at": "2026-01-11T09:00:00Z"
}
],
"total": 2,
"page": 1,
"page_size": 20
}Get Single Task
Users can retrieve details of a single task that they own.
- Endpoint:
GET /tasks/{task_id} - Authentication: required
Example successful response:
{
"id": 43,
"title": "Finish report",
"description": "Finish the financial report for Q1",
"status": "in_progress",
"priority": "high",
"due_date": "2026-01-15",
"created_at": "2026-01-10T16:00:00Z",
"updated_at": "2026-01-11T09:00:00Z"
}If the task does not exist or belongs to another user, return an appropriate error (for example 404).
Update Task
Users can update their tasks.
You will support:
- Full update with
PUT(client sends all fields). - Partial update with
PATCH(client sends only changed fields).
Example PATCH /tasks/43 request:
{
"status": "done",
"priority": "medium"
}Rules:
- Validate enum fields.
- Do not allow users to change
idoruser_id. - Update
updated_attimestamp.
Example response:
{
"id": 43,
"title": "Finish report",
"description": "Finish the financial report for Q1",
"status": "done",
"priority": "medium",
"due_date": "2026-01-15",
"created_at": "2026-01-10T16:00:00Z",
"updated_at": "2026-01-12T12:30:00Z"
}Delete Task
Users can delete tasks that they own.
- Endpoint:
DELETE /tasks/{task_id} - Authentication: required
Behavior:
- If task exists and belongs to user, delete it.
- Return either:
- HTTP 204 with no content, or
- A simple JSON confirmation like
{ "detail": "Task deleted" }.
Non-Functional Requirements
Non-functional requirements describe how well the system should perform its functions.
Reliability and Consistency
- When an API call returns success, the change must really be stored in the database.
- A task that is created must appear in subsequent list and get endpoints.
- Use transactions for operations that modify data to avoid partial updates.
Security (High Level)
- All state-changing endpoints must be authenticated.
- Users must not be able to access or modify other users' tasks.
- Passwords must be stored securely using proper hashing.
- Do not leak internal errors or stack traces in responses in production-like settings.
Performance
This is a learning project, so performance is not the main goal, but:
- The API should respond in a reasonable time for a small number of users.
- Basic indexes on primary keys should be used in the database.
- Pagination is required to avoid returning unbounded lists of tasks.
Maintainability
- The project structure must be clear, with separation between routes, models, and database logic.
- Code should follow consistent style and naming.
- Error handling should be centralized as much as possible.
API Design Overview
Here is a possible overview of the main endpoints. You will refine these in later chapters.
| Method | Path | Description | Auth required |
|---|---|---|---|
| POST | /auth/register | Register a new user | No |
| POST | /auth/login | Log in and get access token | No |
| GET | /tasks | List current user's tasks | Yes |
| POST | /tasks | Create a new task | Yes |
| GET | /tasks/{id} | Get a specific task | Yes |
| PUT | /tasks/{id} | Fully update a task | Yes |
| PATCH | /tasks/{id} | Partially update a task | Yes |
| DELETE | /tasks/{id} | Delete a task | Yes |
You may later add endpoints for user profile, health checks, or admin tasks, but they are optional for this project.
Authentication and Authorization Requirements
You will implement a simple token-based authentication flow.
- After login, clients receive an access token.
- Clients send this token with each protected request, usually in the
Authorizationheader, for example:
Authorization: Bearer <access_token>- The backend validates the token and identifies the user.
- All task endpoints use this identity to:
- Link new tasks to the correct user.
- Filter tasks by owner.
- Prevent access to other users' tasks.
Important: Every data access for tasks must be restricted to the authenticated user. Never let a user read, update, or delete tasks that do not belong to them.
You do not need extremely advanced security features for this first project, but you should:
- Validate tokens.
- Expire tokens after a certain time, or at least design your system with that in mind.
- Handle unauthenticated requests with a proper 401 status.
Validation and Error Handling Requirements
Requests must be validated so that the server never writes invalid data to the database.
Input Validation
Examples of validation rules:
title:- Required for task creation.
- Minimum length, for example 1 character.
- Maximum length, for example 200 characters.
status:- Must be one of
todo,in_progress,done. priority:- Must be one of
low,medium,high. due_date:- Must be a valid date in ISO 8601 format, for example
"2026-02-01". email:- Must look like a valid email address.
- Must be unique.
password:- Minimum length, for example 8 characters.
If validation fails, the API must return:
- An appropriate HTTP status code, usually 400.
- A clear error body.
Example error response:
{
"detail": [
{
"field": "title",
"message": "Title must not be empty"
},
{
"field": "priority",
"message": "Invalid priority, allowed: low, medium, high"
}
]
}Authentication and Authorization Errors
- If the
Authorizationheader is missing or invalid: - Return HTTP 401.
- If the user is authenticated but tries to access someone else's resource:
- Return HTTP 403 or 404, depending on your design.
Example 401 response:
{
"detail": "Not authenticated"
}Example 403/404 response:
{
"detail": "Task not found"
}Other Errors
- If a task ID does not exist: return 404.
- If the method is not allowed on a route: return 405.
- For unexpected server errors: return 500 with a generic message, not internal details.
Pagination, Filtering, and Sorting
The list endpoint for tasks must support basic pagination. Filtering and sorting are strongly recommended to make the API more practical.
Pagination
Use query parameters, for example:
GET /tasks?page=1&page_size=20
Rules:
pagedefaults to 1.page_sizedefaults to a reasonable number, for example 20.page_sizehas a maximum limit, for example 100.
Response should contain:
- The items for that page.
- Metadata:
total,page,page_size.
Example:
{
"items": [ /* tasks */ ],
"total": 57,
"page": 2,
"page_size": 20
}Filtering
Allow users to filter tasks by attributes using query parameters, for example:
GET /tasks?status=todoGET /tasks?priority=highGET /tasks?status=done&priority=low
You might also allow filtering by due date, for example:
GET /tasks?due_before=2026-02-01GET /tasks?due_after=2026-01-01
Sorting
Allow sorting by some fields, for example:
GET /tasks?sort_by=due_date&sort_order=ascGET /tasks?sort_by=created_at&sort_order=desc
Rules:
sort_byallowed values:due_date,created_at,priority, etc.sort_orderallowed values:asc,desc.
Example:
GET /tasks?status=todo&sort_by=due_date&sort_order=asc&page=1&page_size=10Example Usage Scenario
To make all requirements concrete, imagine the following scenario and how your API would be used.
- Alice registers
Request:
POST /auth/register
Content-Type: application/json
{
"email": "alice@example.com",
"password": "StrongPassword123"
}Response: user info.
- Alice logs in
POST /auth/login
Content-Type: application/json
{
"email": "alice@example.com",
"password": "StrongPassword123"
}Response:
{
"access_token": "eyJhbGciOiJIUzI1NiIs...",
"token_type": "bearer"
}- Alice creates a task
POST /tasks
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Content-Type: application/json
{
"title": "Buy groceries",
"description": "Milk, eggs, bread",
"priority": "medium",
"due_date": "2026-02-01"
}- Alice lists her tasks
GET /tasks?status=todo&sort_by=due_date&sort_order=asc
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...- Alice marks the task as done
PATCH /tasks/42
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Content-Type: application/json
{
"status": "done"
}- Alice deletes the task
DELETE /tasks/42
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...If Bob tries to access task 42 that belongs to Alice, he must receive an error and never see the task data.
Acceptance Criteria Checklist
Use this checklist to verify that your implementation meets the requirements:
Functional checklist
- [ ] Users can register with a unique email and password.
- [ ] Users can log in and receive an access token.
- [ ] Authenticated users can create tasks.
- [ ] Authenticated users can list only their tasks.
- [ ] Authenticated users can get, update, and delete their own tasks.
- [ ] Users cannot access other users' tasks.
- [ ] Task list endpoint supports pagination.
- [ ] Task list endpoint supports basic filtering and sorting.
- [ ] All input is validated and invalid data is rejected with clear errors.
You will implement these requirements step by step in the following chapters, where you will design the project structure, the database, and the actual CRUD operations.
Views: 6
KAHIBARO