Skip to content

Commit a6b99bf

Browse files
authored
Merge pull request #5 from KayvanShah1/feat-api-update
feat(api): overhaul tasks & users API with bulk ops, nested tasks, and improved schemas
2 parents 970a031 + d876e90 commit a6b99bf

30 files changed

+2421
-598
lines changed

CHANGELOG.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# Changelog
2+
3+
All notable changes to this project are documented here. The format follows Keep a Changelog principles.
4+
5+
## [Unreleased]
6+
### Planned
7+
- Team collaboration features (shared tasks and roles).
8+
- Notification and reminder channels (email/Slack).
9+
- Rich text task descriptions and attachment support.
10+
- Vector search for semantic task discovery.
11+
- Enhanced observability with metrics and structured logs.
12+
13+
## [2025-09-29] Backend reliability & lifecycle polish
14+
### Added
15+
- Added complete user CRUD surface in the service layer and API, including secure self-delete endpoint helpers.
16+
- Added pytest utilities and scenarios that exercise nested task flows, user deletion, and authentication bootstrapping.
17+
- Added linting/formatting config to keep the backend style consistent.
18+
19+
### Changed
20+
- Reworked task CRUD to eagerly load full trees, offer shallow vs tree responses, and refresh cascades after updates.
21+
- Updated access token model to embed user IDs and refactored verification helpers to rely on IDs instead of usernames.
22+
- Hardened SQLAlchemy session pragmas and cascade handling for consistent SQLite/Postgres behaviour and developer hot reloads.
23+
- Opened up CORS defaults to support external dashboard clients during development.
24+
25+
### Fixed
26+
- Removed trailing slash mismatches from task endpoints and corrected `get_current_user` to validate by id.
27+
- Ensured orphaned subtasks are purged by enabling foreign key enforcement in tests and double-checking cascaded deletes.
28+
29+
### Documentation
30+
- Expanded FastAPI docstrings and README coverage for authentication, task endpoints, and local dev workflows.
31+
- Polished OpenAPI metadata and backend README feature lists.
32+
33+
## [2025-09-27] Authenticated dashboard & UI system
34+
### Added
35+
- Bootstrapped a Next.js App Router frontend with marketing landing, dashboard segment, and route groups for `home`, `tasks`, `agent`, and `settings`.
36+
- Implemented dedicated sign-in/sign-up pages powered by shared `AuthShell`, `PasswordField`, and `OAuthButtons` components plus validation hooks.
37+
- Integrated shadcn/ui primitives, thin-scrollbar utilities, and a marketing logo cloud block for consistent theming.
38+
- Added dashboard middleware, JWT client helpers, and API proxy route handlers to forward auth headers to the backend.
39+
- Authored an `AGENTS.md` integration guide describing how to wire the AskBar to backend MCP endpoints.
40+
41+
### Infrastructure
42+
- Added `vercel.json`, Dockerfiles for dev/prod, and `.env.local` scaffolding to support local/hosted frontend deployments.
43+
- Updated metadata, navigation config, and marketing assets (icons, logos) for the new UI.
44+
45+
## [2025-09-02] CI/CD & deployment pipeline
46+
### Added
47+
- Introduced Render deployment blueprint updates and GitHub Actions jobs to build, cache, and push backend Docker images before deployment.
48+
- Added Docker build caching and tag management to speed up container publishing.
49+
- Added `.dockerignore` / `.docker` tweaks and context fixes so backend and frontend images build from the correct paths.
50+
- Registered Vercel deployment configuration and telemetry settings for the Next.js app.
51+
52+
### Documentation
53+
- Added frontend configuration docs and expanded README badges for deployment/test workflows.
54+
55+
## [2025-08-31] Database & ops enhancements
56+
### Added
57+
- Added Postgres service to `docker-compose.yml` with health checks plus `asyncpg` support in the backend.
58+
- Added a global `.gitignore`, dev requirements fixes, and instructions for running GitHub Actions tests.
59+
- Documented project structure and agent setup guidance for contributors.
60+
61+
### Changed
62+
- Refined database engine initialization, path configuration, and README disclaimers to clarify setup steps.
63+
- Updated workflow configuration to ensure backend paths trigger CI from the new `backend/` root.
64+
65+
## [2025-07-31] Testing & tooling expansion
66+
### Added
67+
- Added comprehensive pytest coverage spanning auth failures, nested task lifecycle, and integration flows.
68+
- Added Postman collection, curl quickstart examples, and Docker instructions for running the API locally.
69+
- Added architecture diagrams and metadata updates to aid onboarding.
70+
71+
### Fixed
72+
- Ignored local SQLite data and other generated artefacts to keep repos clean.
73+
74+
## [2025-07-30] Initial API scaffold
75+
### Added
76+
- Bootstrapped the FastAPI application with configuration modules, routing skeleton, and OpenAPI metadata.
77+
- Added SQLAlchemy models for users and tasks with status/priority/category enums and relationships.
78+
- Implemented authentication utilities for password hashing, token creation/verification, and API key enforcement.
79+
- Delivered initial user signup/login endpoints and task create/list routes backed by async database sessions.
80+
- Added Docker configuration, environment files, and packaging metadata to support containerized development.

backend/README.md

Lines changed: 47 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@ Taskaza is a secure, async API built with FastAPI. It supports user sign-up/logi
77

88
## 📦 Features
99

10-
* User registration (`/signup`) and login (`/token`, OAuth2 password flow)
10+
* User registration (`/signup`), profile management (`/users/me`), and login (`/token`, OAuth2 password flow)
1111
* JWT authentication + secure password hashing
1212
* API key header (`X-API-Key: 123456`) on protected routes
13-
* Task CRUD (create, list, get, update status/full, delete)
14-
* Async SQLAlchemy + SQLite, Pydantic v2 validation
15-
* Thorough tests (unit + full-flow)
13+
* Hierarchical tasks with nested subtasks, priorities, categories, tags, and computed progress
14+
* Rich task querying (status filters, search, pagination, sorting, include/exclude subtasks) plus bulk create/status updates
15+
* Async SQLAlchemy + SQLite (extensible via `TSKZ_DATABASE_URL`), Pydantic v2 validation
16+
* Thorough async tests (unit + integration/auth flows)
1617

1718
[📊 View architecture diagram](docs/ARCHITECTURE.md)
1819

@@ -32,23 +33,39 @@ X-API-Key: 123456
3233

3334
## 📚 API Endpoints
3435

35-
### Users
36+
### Auth
3637

37-
| Method | Endpoint | Description |
38-
| ------ | --------- | ----------------------- |
39-
| POST | `/signup` | Register a new user |
40-
| POST | `/token` | Login and get JWT token |
38+
| Method | Endpoint | Description |
39+
| ------ | ----------- | ---------------------------------- |
40+
| POST | `/signup` | Register a new user |
41+
| POST | `/token` | Exchange username/password for JWT |
42+
43+
### Users (Protected)
44+
45+
| Method | Endpoint | Description |
46+
| ------ | ----------------- | ------------------------------------ |
47+
| GET | `/users/me` | Get the authenticated user's profile |
48+
| PUT | `/users/me` | Replace the authenticated user's profile |
49+
| PATCH | `/users/me` | Partially update your profile |
50+
| DELETE | `/users/{user_id}` | Delete your own account |
4151

4252
### Tasks (Protected)
4353

44-
| Method | Endpoint | Description |
45-
| ------ | ------------- | ---------------------- |
46-
| POST | `/tasks/` | Create a task |
47-
| GET | `/tasks/` | List your tasks |
48-
| GET | `/tasks/{id}` | Get a task by ID |
49-
| PATCH | `/tasks/{id}` | Update **status** only |
50-
| PUT | `/tasks/{id}` | Update **entire** task |
51-
| DELETE | `/tasks/{id}` | Delete a task |
54+
| Method | Endpoint | Description |
55+
| ------ | -------------------- | ------------------------------------------------- |
56+
| POST | `/tasks` | Create a task, optionally with nested subtasks |
57+
| GET | `/tasks` | List tasks with filtering, search, and pagination |
58+
| GET | `/tasks/{task_id}` | Retrieve a task (optionally include the subtree) |
59+
| PUT | `/tasks/{task_id}` | Update task fields (partial) |
60+
| PATCH | `/tasks/{task_id}` | Update only the task status |
61+
| DELETE | `/tasks/{task_id}` | Delete a task |
62+
| POST | `/tasks/bulk` | Bulk create tasks and/or change statuses |
63+
64+
**Extras**
65+
66+
- All `/tasks/*` and `/users/*` endpoints require both `Authorization: Bearer <token>` and `X-API-Key: 123456`.
67+
- `GET /tasks` supports `status`, `q`, `page`, `limit`, `sort`, `include_tree`, and `roots_only` query params.
68+
- `POST /tasks` accepts the `create_subtree` query flag (defaults to `true`) to cascade nested subtasks when provided.
5269

5370
---
5471

@@ -99,12 +116,22 @@ openssl rand -base64 32
99116

100117
### 4) Run locally
101118

102-
**Development:**
119+
**Development (auto-reload; tests excluded by default):**
103120

104121
```bash
105122
uv run fastapi dev app/main.py
106123
```
107124

125+
FastAPI already excludes the `tests/` directory from reloads via `pyproject.toml`. To be explicit or customise the ignore pattern:
126+
127+
```bash
128+
# macOS/Linux shells
129+
uv run fastapi dev app/main.py --reload-exclude 'tests/*'
130+
131+
# Windows PowerShell
132+
uv run fastapi dev app/main.py --reload-exclude "tests/*"
133+
```
134+
108135
**Production:**
109136

110137
```bash
@@ -119,6 +146,8 @@ docker compose up --build
119146

120147
App: [http://localhost:8000/](http://localhost:8000/)
121148

149+
Local SQLite data lives in `data/taskaza.db`. Delete the file to reset your environment or set `TSKZ_DATABASE_URL` to point at another database.
150+
122151
---
123152

124153
## 🔁 Export pip-style requirements (for CI/Render)

backend/app/api/v1/login.py

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,46 @@
1010
router = APIRouter(tags=["Login"])
1111

1212

13-
@router.post("/token", response_model=Token)
14-
async def login(form_data: OAuth2PasswordRequestForm = Depends(), db: AsyncSession = Depends(get_db)):
13+
@router.post(
14+
"/token",
15+
response_model=Token,
16+
summary="Login with username and password",
17+
description="""
18+
Obtain a **JWT access token** using the OAuth2 password flow.
19+
20+
### Authentication
21+
- Requires valid username and password.
22+
23+
### Usage
24+
- Use the returned `access_token` in the `Authorization` header for all protected endpoints:
25+
`Authorization: Bearer <access_token>`
26+
27+
### Notes
28+
- This endpoint does **not** require API Key.
29+
- Token expiration and lifetime are configured in `create_access_token`.
30+
""",
31+
)
32+
async def login_with_access_token(form_data: OAuth2PasswordRequestForm = Depends(), db: AsyncSession = Depends(get_db)):
33+
"""
34+
**Login with Access Token**
35+
36+
**Request Body (form-data)**
37+
- `username` (str): Registered username
38+
- `password` (str): Corresponding password
39+
40+
**Responses**
41+
- `200`: Returns a `Token` object
42+
```json
43+
{
44+
"access_token": "jwt.token.here",
45+
"token_type": "bearer"
46+
}
47+
```
48+
- `401`: Incorrect username or password
49+
"""
1550
user = await authenticate_user(db, form_data.username, form_data.password)
1651
if not user:
1752
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Incorrect username or password")
1853
authd_user = UserOut.model_validate(user)
19-
token = create_access_token(data={"sub": authd_user.username})
54+
token = create_access_token(data={"sub": str(authd_user.id)})
2055
return {"access_token": token, "token_type": "bearer"}

0 commit comments

Comments
 (0)