api-development

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

API Development Skill

API开发技能指南

Purpose

目的

Guide API development workflow for the career_ios_backend FastAPI project, ensuring all console.html APIs are properly tested and functional.
为career_ios_backend FastAPI项目指导API开发工作流,确保所有console.html相关API均经过充分测试且功能正常。

Automatic Activation

自动触发条件

This skill is AUTOMATICALLY activated when user mentions:
  • ✅ "develop API" / "API 開發"
  • ✅ "create endpoint" / "創建端點"
  • ✅ "test API" / "測試 API"
  • ✅ "console.html"
  • ✅ "Swagger UI"
  • ✅ "FastAPI route"

当用户提及以下内容时,本技能将自动触发:
  • ✅ "开发API" / "API开发"
  • ✅ "创建端点" / "创建端点"
  • ✅ "测试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
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.

  • 开发:70%的时间
  • 测试:20%的时间
  • 修复/重构:10%的时间
核心理念:原型阶段优先考虑速度而非完美,功能验证先于质量优化。

Testing Requirements

测试要求

Integration Tests (Mandatory)

集成测试(强制要求)

CRITICAL: All
console.html
APIs MUST have integration tests.
bash
undefined
关键要求:所有
console.html
相关API必须配备集成测试。
bash
undefined

Daily development: Run integration tests only

Daily development: Run integration tests only

poetry run pytest tests/integration/ -v
poetry run pytest tests/integration/ -v

Full test suite (optional during development)

Full test suite (optional during development)

poetry run pytest tests/ -v
poetry run pytest tests/ -v

Test specific API

Test specific API

poetry run pytest tests/integration/test_auth_api.py -v
undefined
poetry run pytest tests/integration/test_auth_api.py -v
undefined

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
      )
状态(2025-12-25)
  • 106+个集成测试用例,覆盖35+个端点
  • ✅ 所有核心功能均已测试:
    • 认证API(
      test_auth_api.py
    • 客户管理(
      test_clients_api.py
    • 会话/咨询(
      test_sessions_api.py
    • 案例管理(
      test_cases_api.py
    • 报告生成(
      test_reports_api.py
    • RAG功能(
      test_rag_*.py

Requirements by Endpoint

端点测试要求

Every API endpoint needs:
  1. At least 1 happy path test
    • Test successful request/response
    • Verify expected data structure
    • Check status codes
  2. Authentication test (if protected)
    • Use
      auth_headers
      fixture
    • Verify 401 for unauthenticated requests
  3. Console integration (if used in console.html)
    • Verify endpoint works from console
    • Test actual user workflows

每个API端点需满足:
  1. 至少1条正常路径测试
    • 测试成功的请求/响应
    • 验证预期的数据结构
    • 检查状态码
  2. 认证测试(若端点受保护)
    • 使用
      auth_headers
      测试夹具
    • 验证未认证请求返回401状态码
  3. 控制台集成测试(若该API用于console.html)
    • 验证端点可在控制台正常工作
    • 测试真实用户工作流

Console API Verification

控制台API验证

All Console.html APIs Must Be Tested

所有Console.html相关API必须经过测试

Checklist:
bash
undefined
检查清单
bash
undefined

Verify test coverage

Verify test coverage

poetry run pytest tests/integration/ -v | grep -E "(test_.*_api.py|PASSED|FAILED)"
poetry run pytest tests/integration/ -v | grep -E "(test_.*_api.py|PASSED|FAILED)"

Current coverage (106+ tests):

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)
undefined
✅ 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)
undefined

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的TDD流程
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
重要提示:在集成到控制台之前先进行测试,以便尽早发现问题。

API Structure (FastAPI)

API结构(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
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

添加新API端点

Step-by-Step:
  1. Create route file (if new feature)
    python
    # 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": []}
  2. Define schemas (Pydantic)
    python
    # app/schemas/my_feature.py
    from pydantic import BaseModel
    
    class ItemCreate(BaseModel):
        name: str
        description: str
    
    class ItemResponse(BaseModel):
        id: int
        name: str
  3. Register router in
    main.py
    python
    from app.api import my_feature
    
    app.include_router(my_feature.router)
  4. Write integration test FIRST (TDD)
    python
    # 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

步骤说明
  1. 创建路由文件(若为新功能)
python
undefined

Manual Testing Tools

app/api/my_feature.py

Swagger UI (OpenAPI Docs)

bash
undefined
from fastapi import APIRouter, Depends
router = APIRouter(prefix="/api/v1/my-feature", tags=["my-feature"])
@router.get("/") async def list_items(): return {"items": []}

2. **定义数据模型**(Pydantic)
```python

Start development server

app/schemas/my_feature.py

poetry run uvicorn app.main:app --reload
from pydantic import BaseModel
class ItemCreate(BaseModel): name: str description: str
class ItemResponse(BaseModel): id: int name: str

3. **在main.py中注册路由**
```python
from app.api import my_feature

app.include_router(my_feature.router)
  1. 先编写集成测试(TDD模式)
python
undefined

Open Swagger UI

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

---

Features:

手动测试工具

Swagger UI(OpenAPI文档)

  • Interactive API testing
  • Auto-generated from FastAPI
  • Try out endpoints directly
  • See request/response schemas
undefined
bash
undefined

Console.html Testing

Start development server

bash
undefined
poetry run uvicorn app.main:app --reload

1. Start backend

Open Swagger UI

poetry run uvicorn app.main:app --reload

2. Open console.html in browser

Features:

open console.html
  • Interactive API testing
  • Auto-generated from FastAPI
  • Try out endpoints directly
  • See request/response schemas
undefined

3. Test workflows:

Console.html测试

  • Login
  • Create client
  • Add session
  • Generate report
  • etc.
undefined
bash
undefined

httpx Manual Testing

1. Start backend

python
undefined
poetry run uvicorn app.main:app --reload

Quick test script (for complex scenarios)

2. Open console.html in browser

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())

---
open console.html

Authentication Patterns

3. Test workflows:

Protected Endpoints

Most endpoints require authentication:
python
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}
  • Login
  • Create client
  • Add session
  • Generate report
  • etc.
undefined

Testing Authenticated Endpoints

httpx手动测试

Use
auth_headers
fixture:
python
@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
python
undefined

Authentication Test Pattern

Quick test script (for complex scenarios)

python
undefined
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())

---

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

---
大多数端点需要认证:
python
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}

Database Considerations

测试受保护端点

Test Database

  • Integration tests use in-memory SQLite
  • Fixtures handle setup/teardown automatically
  • See
    tests/conftest.py
    for database fixtures
使用
auth_headers
测试夹具:
python
@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

Database Patterns

认证测试模式

python
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

python
undefined

Quality Standards (Prototype Phase)

Test unauthenticated access (should fail)

Must Do ✅

  1. Integration tests for all console.html APIs
  2. Follow existing API patterns (check similar endpoints)
  3. Use Pydantic schemas for request/response validation
  4. Proper HTTP status codes:
    • 200: Success
    • 201: Created
    • 400: Bad Request
    • 401: Unauthorized
    • 404: Not Found
    • 500: Server Error
@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

---

Nice-to-Have (Optional) ⚠️

数据库注意事项

测试数据库

  • Complete type hints
  • Edge case tests
  • Performance optimization
  • Comprehensive error messages
  • 集成测试使用内存SQLite
  • 测试夹具自动处理数据库的创建与清理
  • 数据库相关夹具请查看
    tests/conftest.py

Don't Do ❌

数据库操作模式

  • 100% test coverage (overkill for prototype)
  • Excessive mocking
  • Over-engineering
Remember: Prototype phase prioritizes functional validation over perfection.

python
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

Testing Commands Reference

质量标准(原型阶段)

必须遵守 ✅

bash
undefined
  1. 所有console.html相关API都需编写集成测试
  2. 遵循现有API模式(参考类似端点的实现)
  3. 使用Pydantic模型进行请求/响应数据验证
  4. 使用正确的HTTP状态码
    • 200:成功
    • 201:已创建
    • 400:请求错误
    • 401:未授权
    • 404:资源未找到
    • 500:服务器错误

Run all integration tests

建议遵守(可选)⚠️

poetry run pytest tests/integration/ -v
  • 完整的类型提示
  • 边界场景测试
  • 性能优化
  • 全面的错误提示信息

Run specific test file

禁止操作 ❌

poetry run pytest tests/integration/test_clients_api.py -v
  • 追求100%测试覆盖率(原型阶段过度冗余)
  • 过度Mock
  • 过度工程化
记住:原型阶段优先考虑功能验证而非完美。

Run specific test

测试命令参考

poetry run pytest tests/integration/test_clients_api.py::test_create_client -v
bash
undefined

Run tests with coverage report (optional)

Run all integration tests

poetry run pytest tests/integration/ --cov=app --cov-report=html
poetry run pytest tests/integration/ -v

Run tests matching pattern

Run specific test file

poetry run pytest -k "client" -v

---
poetry run pytest tests/integration/test_clients_api.py -v

Common Patterns

Run specific test

CRUD Operations

python
undefined
poetry run pytest tests/integration/test_clients_api.py::test_create_client -v

CREATE

Run tests with coverage report (optional)

@router.post("/", response_model=ItemResponse, status_code=201) async def create_item(item: ItemCreate, db: Session = Depends(get_db)): ...
poetry run pytest tests/integration/ --cov=app --cov-report=html

READ (list)

Run tests matching pattern

@router.get("/", response_model=List[ItemResponse]) async def list_items(db: Session = Depends(get_db)): ...
poetry run pytest -k "client" -v

---

READ (single)

常见模式

CRUD操作

@router.get("/{item_id}", response_model=ItemResponse) async def get_item(item_id: int, db: Session = Depends(get_db)): ...
python
undefined

UPDATE

CREATE

@router.put("/{item_id}", response_model=ItemResponse) async def update_item(item_id: int, item: ItemUpdate, db: Session = Depends(get_db)): ...
@router.post("/", response_model=ItemResponse, status_code=201) async def create_item(item: ItemCreate, db: Session = Depends(get_db)): ...

DELETE

READ (list)

@router.delete("/{item_id}", status_code=204) async def delete_item(item_id: int, db: Session = Depends(get_db)): ...
undefined
@router.get("/", response_model=List[ItemResponse]) async def list_items(db: Session = Depends(get_db)): ...

Error Handling

READ (single)

python
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

@router.get("/{item_id}", response_model=ItemResponse) async def get_item(item_id: int, db: Session = Depends(get_db)): ...

Integration with TDD Workflow

UPDATE

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.

@router.put("/{item_id}", response_model=ItemResponse) async def update_item(item_id: int, item: ItemUpdate, db: Session = Depends(get_db)): ...

Troubleshooting

DELETE

"Test database not initialized"

bash
undefined
@router.delete("/{item_id}", status_code=204) async def delete_item(item_id: int, db: Session = Depends(get_db)): ...
undefined

Check conftest.py has database fixtures

错误处理

Ensure test uses proper fixtures

@pytest.mark.asyncio async def test_endpoint(db_session): # Use db fixture ...
undefined
python
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

"Import errors in tests"

与TDD工作流集成

bash
undefined
API开发针对核心功能遵循TDD流程:
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
参考:详细TDD流程请查看
tdd-workflow
技能文档。

Ensure PYTHONPATH includes project root

故障排查

Run from project root directory

"Test database not initialized"

cd /path/to/career_ios_backend poetry run pytest tests/integration/ -v
undefined
bash
undefined

"API endpoint not found (404)"

Check conftest.py has database fixtures

Ensure test uses proper fixtures

bash
undefined
@pytest.mark.asyncio async def test_endpoint(db_session): # Use db fixture ...
undefined

Verify router is registered in main.py

"Import errors in tests"

Check route prefix and path

Start server and check Swagger UI: /docs


---
bash
undefined

Related Skills

Ensure PYTHONPATH includes project root

Run from project root directory

  • 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)
cd /path/to/career_ios_backend poetry run pytest tests/integration/ -v
undefined

"API endpoint not found (404)"

bash
undefined

Verify router is registered in main.py

Check route prefix and path

Start server and check Swagger UI: /docs


---

相关技能

  • tdd-workflow - 测试先行的开发流程
  • quality-standards - 代码质量要求
  • git-workflow - Git提交与推送工作流

技能版本:v1.0 最后更新:2025-12-25 项目:career_ios_backend(原型阶段)