No description
- Python 100%
| app | ||
| tests | ||
| .gitignore | ||
| pyproject.toml | ||
| README.md | ||
| sms_auth_api.py | ||
| stage1-design.md | ||
| stage1-student-task-book.md | ||
| stage2-student-task-book.md | ||
| uniform_login_des.py | ||
| uv.lock | ||
2026 Core Backend Test
FastAPI + SQLModel + SQLite implementation for:
- Stage 1 design scope (student/admin/handler core APIs)
- Stage 2 assignment API rules
- Unified CAS SMS login integration based on
sms_auth_api.py
Tech Stack
- FastAPI
- SQLModel
- SQLite
- uv (environment and dependency management)
- pytest
Project Structure
app/main.py: FastAPI app entrypointapp/config.py: Settingsapp/db.py: DB engine/session dependenciesapp/models.py: SQLModel tables and enumsapp/schemas.py: Request/response schemasapp/auth/router.py:/authendpoints and JWT issuingapp/auth/deps.py: current user and role guardsapp/api/student.py: student APIsapp/api/admin.py: admin APIs (includes assignment)app/api/handler.py: handler APIssms_auth_api.py: CAS SMS auth upstream flow sourcetests/: test suite
Quick Start (uv)
- Install dependencies:
uv sync --dev
- Run server:
uv run uvicorn app.main:app --reload
- Run tests:
uv run pytest -q
Authentication
CAS SMS flow
POST /auth/code: get image captchaPOST /auth/sms: request SMS codePOST /auth/login: CAS SMS login and issue JWT
/auth/login behavior:
- Reuses
sms_auth_api.pylogin logic to fetch SDU user info - Upserts local
Userbysduid - Issues JWT for business APIs
Use header for protected APIs:
Authorization: Bearer <access_token>
Role Scope
student: create/list/view own tickets, append notesadmin: list/manage tickets, assign/reassign tickets, update user rolehandler: list own assigned tickets, start processing, close tickets
Implemented APIs
Student
POST /ticketsGET /ticketsGET /tickets/{ticket_id}POST /tickets/{ticket_id}/notes
Admin
GET /admin/ticketsGET /admin/tickets/{ticket_id}POST /admin/tickets/{ticket_id}/assignmentsPUT /admin/users/{user_id}/role
Handler
GET /handler/ticketsGET /handler/tickets/{ticket_id}POST /handler/tickets/{ticket_id}/startPOST /handler/tickets/{ticket_id}/close
Stage 2 Assignment Rules Implemented
The endpoint POST /admin/tickets/{ticket_id}/assignments enforces:
- Only admin can assign.
- Ticket must exist.
- Target handler must exist.
- Target user must have
handlerrole. - Supports first assignment and reassignment.
- Allowed source states:
pending,assigned,in_progress. closedcannot be assigned.- Always updates
current_handler_id. - Always appends
TicketAssignmentHistory.
State transitions:
pending -> assignedassigned -> assignedin_progress -> assigned
Notes
- SQLite DB file defaults to
./app.db. - CAS upstream depends on external SDU services; tests do not require live CAS calls.