-
Notifications
You must be signed in to change notification settings - Fork 0
Mini Project Idea
A guided full-stack mini-project for interns to complete during or immediately after the induction program. It is intentionally scoped to be completable in 3–5 days while covering every skill in the program.
Build a Task Management API with a minimal frontend. The system must be designed, built, tested, and documented using all the practices from the induction program.
This is not a tutorial. There is no step-by-step guide. You will use the induction program, your own judgment, and AI tools (with proper documentation) to produce a working, tested, reviewable system.
A small engineering team needs a simple tool to track tasks. A task has a title, a status, and an optional due date. Team members need to create tasks, update their status, and retrieve a list of open tasks. The system must be reliable enough that the team trusts it — meaning it rejects bad input clearly and does not crash on edge cases.
- Create a task (title required, status defaults to
pending, due date optional) - Update a task's status (
pending→in_progress→completedonly — no backward transitions) - Retrieve all tasks (filter by status, optional)
- Retrieve a single task by ID
- Delete a task
- All API endpoints return structured JSON (including errors)
- All inputs validated with clear error messages
- All error responses include an
errorcode anddetailmessage - No hardcoded configuration — all environment values via env vars
- All tests pass before any PR is opened
Use the Full-Stack GitHub Template from the induction page. Every item below must be present in your submission.
| # | Deliverable | Where |
|---|---|---|
| 1 | Problem Statement | docs/problem-statement.md |
| 2 | System Design | docs/system-design.md |
| 3 | API Contracts (all 5 endpoints) | docs/api-contracts.md |
| 4 | Data Model | docs/data-models.md |
| 5 | Test Strategy | docs/test-strategy.md |
| 6 | AI Usage Log | docs/ai-usage-log.md |
| 7 | Backend implementation | backend/ |
| 8 | Frontend (minimal UI) | frontend/ |
| 9 | Test suite | tests/ |
| 10 | PR using the PR template | GitHub PR |
These constraints are not suggestions — they are requirements:
- ✅ Tests written before implementation — your git history must show test commits preceding implementation commits
- ✅ API contract documented before coding —
docs/api-contracts.mdmust exist before any backend code - ✅ No AI output accepted without verification — every AI interaction logged in
ai-usage-log.md - ✅ Status transitions enforced in business logic —
pending → completedin one step is invalid - ✅ All endpoints return consistent error format — same shape as the induction API contract example
You may use any stack, but these are recommended for consistency with the induction examples:
| Layer | Recommendation | Alternative |
|---|---|---|
| Backend | Python + Flask or FastAPI | Go + net/http |
| Database | SQLite (via SQLAlchemy) | PostgreSQL |
| Frontend | Plain HTML + fetch API | React |
| Testing | pytest + pytest-coverage | Go testing package |
| CI | GitHub Actions (already in repo) | — |
The project is structured in levels matching the Graded Debugging Challenge rubric. Complete levels in order.
- All inputs validated; API does not crash on bad input
- Missing title → 400 with structured error
- Invalid status → 400 with list of valid values
- Nonexistent task ID → 404
Acceptance test: Send {} to POST /tasks. Receive 400 {"error": "INVALID_INPUT", "field": "title", "detail": "title is required"}.
- All endpoints return consistent response shapes
- Correct HTTP status codes on all paths
- Error format consistent across all endpoints
-
GET /taskssupports?status=pendingfilter
Acceptance test: Every endpoint documented in api-contracts.md matches the actual implementation exactly.
- Status transitions enforced: only
pending→in_progressandin_progress→completedare valid - Attempting an invalid transition returns 422 with a clear error
- Due dates must be in the future at creation time
- Completed tasks cannot be deleted (return 409)
Acceptance test: PATCH /tasks/{id}/status with {"status": "pending"} on an in_progress task returns 422.
- No function longer than 20 lines
- No hardcoded strings (status values, error codes defined as constants)
- Validation logic separated from route handlers
- Database access separated from business logic
Acceptance test: A reviewer can identify the validation layer, service layer, and data layer without asking you to explain it.
- Unit tests for all business logic functions
- Integration tests for all API endpoints
- Minimum one negative test per endpoint
- Coverage report shows ≥ 80% on backend
Acceptance test: pytest --cov=backend tests/ passes with ≥ 80% coverage, zero skipped tests.
- AI Usage Log documents: tool used, prompt, what was accepted, what was rejected, and why
- At least one example where you rejected or modified AI output
- Reflection: one thing AI helped you do faster; one thing AI got wrong
| Category | Points | What reviewers look for |
|---|---|---|
| Validation & Stability | 20 | No crashes, all edge cases handled |
| API Contract | 20 | Consistency, correct status codes |
| Business Logic | 20 | Correct transition enforcement |
| Code Quality | 20 | Readability, separation of concerns |
| Testing | 20 | Coverage, meaningful assertions |
| AI Usage (Bonus) | 10 | Honest, reflective documentation |
| Total | 110 |
- Push your completed work to a GitHub repository (can be a fork of this one or a new repo using the template)
- Open a PR using the PR template from the induction page
- Raise a feedback issue sharing your experience
Hint 1 — Status transitions
Define valid transitions as a dictionary before writing any logic:
VALID_TRANSITIONS = {
"pending": ["in_progress"],
"in_progress": ["completed"],
"completed": []
}Your validation function then checks new_status in VALID_TRANSITIONS[current_status].
Hint 2 — Consistent error format
Define an error helper at the top of your API layer and use it everywhere:
def error_response(code, detail, field=None, status=400):
body = {"error": code, "detail": detail}
if field:
body["field"] = field
return body, statusThis ensures every error in the system has the same shape.
Hint 3 — Writing tests before code
Write the test file first, import the function you haven't written yet, and run pytest. It will fail with ImportError or ModuleNotFoundError. That is your red state. Now create the module and function stub (returning None). Tests fail with assertion errors. Now implement.