api-development
npx skills add https://github.com/youngger9765/career_ios_backend --skill api-development
Agent 安装分布
Skill 文档
API Development Skill
Purpose
Guide API development workflow for the career_ios_backend FastAPI project, ensuring all console.html APIs are properly tested and functional.
Automatic Activation
This skill is AUTOMATICALLY activated when user mentions:
- â “develop API” / “API éç¼”
- â “create endpoint” / “åµå»ºç«¯é»”
- â “test API” / “測試 API”
- â “console.html”
- â “Swagger UI”
- â “FastAPI route”
Development Flow (Prototype Speed-First)
Standard Workflow
1. Write Feature Code (AI-Assisted)
â 70% time
2. Manual Test API (Swagger UI or Console)
â Quick verification
3. Write Integration Test (Verify API works)
â 20% time
4. ruff check --fix (Auto-fix formatting)
â Auto
5. Commit (Pre-commit hooks)
â ~5s
6. Push â CI runs Integration Tests
â ~2 min
Time Allocation
- Development: 70% of time
- Testing: 20% of time
- Fixing/Refactoring: 10% of time
Philosophy: Prototype phase prioritizes speed over perfection. Functional validation comes before quality optimization.
Testing Requirements
Integration Tests (Mandatory)
CRITICAL: All console.html APIs MUST have integration tests.
# Daily development: Run integration tests only
poetry run pytest tests/integration/ -v
# Full test suite (optional during development)
poetry run pytest tests/ -v
# Test specific API
poetry run pytest tests/integration/test_auth_api.py -v
Current Test Coverage
Status (2025-12-25):
- â 106+ integration tests covering 35+ endpoints
- â
All major features tested:
- Authentication API (
test_auth_api.py) - Client Management (
test_clients_api.py) - Sessions/Consultations (
test_sessions_api.py) - Case Management (
test_cases_api.py) - Report Generation (
test_reports_api.py) - RAG Features (
test_rag_*.py)
- Authentication API (
Requirements by Endpoint
Every API endpoint needs:
-
At least 1 happy path test
- Test successful request/response
- Verify expected data structure
- Check status codes
-
Authentication test (if protected)
- Use
auth_headersfixture - Verify 401 for unauthenticated requests
- Use
-
Console integration (if used in console.html)
- Verify endpoint works from console
- Test actual user workflows
Console API Verification
All Console.html APIs Must Be Tested
Checklist:
# Verify test coverage
poetry run pytest tests/integration/ -v | grep -E "(test_.*_api\.py|PASSED|FAILED)"
# Current coverage (106+ tests):
â
Authentication (login, token refresh)
â
Client Management (CRUD, search, code generation)
â
Session Management (CRUD, transcripts, reflections)
â
Case Management (CRUD, timeline)
â
Report Generation (consultation reports)
â
RAG Features (upload, embed, search, evaluate)
When Adding New Console Feature
TDD Flow for Console APIs:
1. Design API behavior
â
2. Write integration test FIRST
â (test in tests/integration/)
3. Run test â RED (fails)
â
4. Implement API endpoint
â
5. Run test â GREEN (passes)
â
6. Update console.html to use API
â
7. Manual test in browser console
IMPORTANT: Test before console integration to catch bugs early.
API Structure (FastAPI)
Project Layout
app/
âââ api/
â âââ auth.py # Authentication endpoints
â âââ clients.py # Client management
â âââ sessions.py # Session/consultation
â âââ cases.py # Case management
â âââ <feature>.py # New feature routes
âââ models/
â âââ user.py # SQLAlchemy models
â âââ client.py
â âââ <feature>.py # New feature models
âââ schemas/
â âââ client.py # Pydantic schemas (request/response)
â âââ <feature>.py
âââ services/ # Business logic (optional)
â âââ <feature>_service.py
âââ main.py # App initialization, router registration
Adding New API Endpoint
Step-by-Step:
-
Create route file (if new feature)
# app/api/my_feature.py from fastapi import APIRouter, Depends router = APIRouter(prefix="/api/v1/my-feature", tags=["my-feature"]) @router.get("/") async def list_items(): return {"items": []} -
Define schemas (Pydantic)
# app/schemas/my_feature.py from pydantic import BaseModel class ItemCreate(BaseModel): name: str description: str class ItemResponse(BaseModel): id: int name: str -
Register router in
main.pyfrom app.api import my_feature app.include_router(my_feature.router) -
Write integration test FIRST (TDD)
# tests/integration/test_my_feature_api.py @pytest.mark.asyncio async def test_list_items(auth_headers): async with AsyncClient(app=app, base_url="http://test") as client: response = await client.get( "/api/v1/my-feature/", headers=auth_headers ) assert response.status_code == 200
Manual Testing Tools
Swagger UI (OpenAPI Docs)
# Start development server
poetry run uvicorn app.main:app --reload
# Open Swagger UI
http://localhost:8000/docs
# Features:
- Interactive API testing
- Auto-generated from FastAPI
- Try out endpoints directly
- See request/response schemas
Console.html Testing
# 1. Start backend
poetry run uvicorn app.main:app --reload
# 2. Open console.html in browser
open console.html
# 3. Test workflows:
- Login
- Create client
- Add session
- Generate report
- etc.
httpx Manual Testing
# Quick test script (for complex scenarios)
import httpx
import asyncio
async def test_api():
async with httpx.AsyncClient(base_url="http://localhost:8000") as client:
# Login
response = await client.post("/api/v1/auth/login", json={
"username": "testuser",
"password": "testpass"
})
token = response.json()["access_token"]
# Test endpoint
response = await client.get(
"/api/v1/clients/",
headers={"Authorization": f"Bearer {token}"}
)
print(response.json())
asyncio.run(test_api())
Authentication Patterns
Protected Endpoints
Most endpoints require authentication:
from app.core.security import get_current_user
@router.get("/protected")
async def protected_route(current_user = Depends(get_current_user)):
return {"user": current_user.username}
Testing Authenticated Endpoints
Use auth_headers fixture:
@pytest.mark.asyncio
async def test_protected_endpoint(auth_headers):
async with AsyncClient(app=app, base_url="http://test") as client:
response = await client.get(
"/api/v1/protected",
headers=auth_headers # Provides valid JWT token
)
assert response.status_code == 200
Authentication Test Pattern
# Test unauthenticated access (should fail)
@pytest.mark.asyncio
async def test_endpoint_requires_auth():
async with AsyncClient(app=app, base_url="http://test") as client:
response = await client.get("/api/v1/protected")
assert response.status_code == 401 # Unauthorized
Database Considerations
Test Database
- Integration tests use in-memory SQLite
- Fixtures handle setup/teardown automatically
- See
tests/conftest.pyfor database fixtures
Database Patterns
from app.db.session import get_db
from sqlalchemy.orm import Session
@router.post("/clients")
async def create_client(
client_data: ClientCreate,
db: Session = Depends(get_db)
):
# Use db session for database operations
new_client = Client(**client_data.dict())
db.add(new_client)
db.commit()
db.refresh(new_client)
return new_client
Quality Standards (Prototype Phase)
Must Do â
- Integration tests for all console.html APIs
- Follow existing API patterns (check similar endpoints)
- Use Pydantic schemas for request/response validation
- Proper HTTP status codes:
- 200: Success
- 201: Created
- 400: Bad Request
- 401: Unauthorized
- 404: Not Found
- 500: Server Error
Nice-to-Have (Optional) â ï¸
- Complete type hints
- Edge case tests
- Performance optimization
- Comprehensive error messages
Don’t Do â
- 100% test coverage (overkill for prototype)
- Excessive mocking
- Over-engineering
Remember: Prototype phase prioritizes functional validation over perfection.
Testing Commands Reference
# Run all integration tests
poetry run pytest tests/integration/ -v
# Run specific test file
poetry run pytest tests/integration/test_clients_api.py -v
# Run specific test
poetry run pytest tests/integration/test_clients_api.py::test_create_client -v
# Run tests with coverage report (optional)
poetry run pytest tests/integration/ --cov=app --cov-report=html
# Run tests matching pattern
poetry run pytest -k "client" -v
Common Patterns
CRUD Operations
# CREATE
@router.post("/", response_model=ItemResponse, status_code=201)
async def create_item(item: ItemCreate, db: Session = Depends(get_db)):
...
# READ (list)
@router.get("/", response_model=List[ItemResponse])
async def list_items(db: Session = Depends(get_db)):
...
# READ (single)
@router.get("/{item_id}", response_model=ItemResponse)
async def get_item(item_id: int, db: Session = Depends(get_db)):
...
# UPDATE
@router.put("/{item_id}", response_model=ItemResponse)
async def update_item(item_id: int, item: ItemUpdate, db: Session = Depends(get_db)):
...
# DELETE
@router.delete("/{item_id}", status_code=204)
async def delete_item(item_id: int, db: Session = Depends(get_db)):
...
Error Handling
from fastapi import HTTPException
@router.get("/{item_id}")
async def get_item(item_id: int, db: Session = Depends(get_db)):
item = db.query(Item).filter(Item.id == item_id).first()
if not item:
raise HTTPException(status_code=404, detail="Item not found")
return item
Integration with TDD Workflow
API development follows TDD for critical features:
tdd-workflow skill activates:
â
1. RED: Write integration test (fails)
â tests/integration/test_<feature>_api.py
â
2. GREEN: Implement API endpoint (passes)
â app/api/<feature>.py
â
3. REFACTOR: Code review and quality check
â
4. git-workflow skill: Commit and push
Reference: See tdd-workflow skill for detailed TDD process.
Troubleshooting
“Test database not initialized”
# Check conftest.py has database fixtures
# Ensure test uses proper fixtures
@pytest.mark.asyncio
async def test_endpoint(db_session): # Use db fixture
...
“Import errors in tests”
# Ensure PYTHONPATH includes project root
# Run from project root directory
cd /path/to/career_ios_backend
poetry run pytest tests/integration/ -v
“API endpoint not found (404)”
# Verify router is registered in main.py
# Check route prefix and path
# Start server and check Swagger UI: /docs
Related Skills
- tdd-workflow – Test-first development process
- quality-standards – Code quality requirements
- git-workflow – Git commit and push workflow
Skill Version: v1.0 Last Updated: 2025-12-25 Project: career_ios_backend (Prototype Phase)