Bonus ā Team Collaboration: API-First Design, OpenAPI Contracts & PR Workflow
Ship PharmaBot as a team: write the OpenAPI contract before writing code, keep a structured PR workflow, and use contract-driven development to eliminate integration surprises.
Why API-First Matters on a Team
When a frontend developer and a backend developer work simultaneously, they need a contract. Without one, the backend ships session_id and the frontend expects sessionId. You discover this at integration time ā usually at 11pm before a demo.
API-first means you write the OpenAPI specification before writing a single line of implementation. Both sides code against the contract. Integration becomes a formality.
The PharmaBot OpenAPI Contract
FastAPI generates OpenAPI automatically from your Pydantic models and route decorators. Lock this contract in early:
# pharmabot/main.py
from fastapi import FastAPI
app = FastAPI(
title="PharmaBot API",
description="AI-powered pharmaceutical information assistant",
version="1.0.0",
contact={"name": "PharmaBot Team", "email": "team@pharmabot.dev"},
license_info={"name": "MIT"},
)And annotate every route with response models:
# pharmabot/api/chat.py
from pharmabot.schemas.chat import ChatRequest, StreamChunk
@router.post(
"/chat",
summary="Send a chat message",
description="Send a message and receive a streamed SSE response.",
response_description="Server-Sent Events stream of text tokens",
responses={
200: {"description": "Stream of SSE tokens"},
400: {"description": "Invalid input or injection detected"},
429: {"description": "Rate limit exceeded"},
503: {"description": "LLM service temporarily unavailable"},
},
tags=["Chat"],
)
async def chat(request: ChatRequest, _=Depends(check_rate_limit)):
...Visit http://localhost:8000/docs ā your team has an interactive API explorer.
Exporting and Committing the Contract
# Export the OpenAPI schema as a file ā commit it to the repo
curl http://localhost:8000/openapi.json > openapi.json
git add openapi.json
git commit -m "docs: export OpenAPI schema v1.0"Now the contract is version-controlled. When you change an endpoint, the diff is visible in the PR:
- "required": ["message", "session_id"]
+ "required": ["message", "session_id", "user_locale"]A reviewer can immediately see the breaking change. A frontend developer can update their client before the backend ships.
Frontend Type Generation from the Schema
Instead of maintaining frontend types by hand, generate them from the OpenAPI schema:
# Install openapi-typescript
npm install -D openapi-typescript
# Generate types from the running API
npx openapi-typescript http://localhost:8000/openapi.json -o src/types/pharmabot-api.tsThe generated file:
// src/types/pharmabot-api.ts (auto-generated ā do not edit)
export interface paths {
"/api/chat": {
post: {
requestBody: {
content: {
"application/json": components["schemas"]["ChatRequest"];
};
};
responses: {
200: { description: "Stream of SSE tokens" };
400: { description: "Invalid input or injection detected" };
429: { description: "Rate limit exceeded" };
};
};
};
}
export interface components {
schemas: {
ChatRequest: {
message: string; // max 500 chars
session_id: string; // UUID
};
HealthResponse: {
status: "healthy" | "degraded";
database: "ok" | "error";
redis: "ok" | "error";
azure_openai: "ok" | "error";
};
};
}Every time the backend changes the contract, re-run the generator. TypeScript compilation catches mismatches before they reach production.
PR Workflow for the Team
Branch naming
feature/skill-06-ai-agents
fix/rate-limiter-edge-case
docs/update-openapi-schema
chore/bump-openai-sdkPR checklist (add as PULL_REQUEST_TEMPLATE.md)
## What does this PR do?
<!-- One sentence -->
## How to test
<!-- Steps the reviewer should follow -->
## Checklist
- [ ] Tests pass locally (`pytest tests/ -v`)
- [ ] OpenAPI schema exported and committed if routes changed
- [ ] No secrets in code (use Key Vault references)
- [ ] Structured logging added for new operations
- [ ] CHANGELOG.md updated if this is a user-visible changeReview process
1. Author opens PR ā CI runs automatically (tests + linting)
2. One reviewer approves ā auto-merge enabled if CI passes
3. Merge to main ā GitHub Actions deploys to staging
4. Staging smoke test passes ā promote to production (manual approval gate)Keeping the Team in Sync: CHANGELOG.md
# Changelog
## [Unreleased]
### Added
- Interaction Checker Agent with severity scoring (JSON output)
- Redis response caching for repeated queries
### Fixed
- Rate limiter now correctly handles clock skew on multi-replica deployments
## [1.0.0] ā 2026-05-15
### Added
- Initial PharmaBot release
- Drug info and interaction check via Azure OpenAI
- Redis token bucket rate limiting
- Azure Container Apps deploymentUse Keep a Changelog format. Every PR that touches user-visible behavior gets a CHANGELOG entry.
Communication Protocol for Async Teams
| Situation | How to handle |
|---|---|
| Changing a request schema | Add a migration period ā accept both old and new field names for 1 sprint |
| Adding a new endpoint | Announce in team channel, update openapi.json, bump minor version |
| Breaking a response field | Bump major version, communicate 2 sprints in advance |
| Bug fix | Fix + test + PR ā no announcement needed |
| Performance regression | File issue tagged perf, add it to the next sprint board |
Checkpoint
Add the PR template and export the schema:
# Create PR template
mkdir -p .github
cat > .github/PULL_REQUEST_TEMPLATE.md << 'EOF'
## What does this PR do?
## How to test
## Checklist
- [ ] Tests pass (`pytest tests/ -v`)
- [ ] OpenAPI schema updated if routes changed
- [ ] No secrets in code
EOF
# Export current schema
curl http://localhost:8000/openapi.json | python3 -m json.tool > openapi.json
# Commit both
git add .github/PULL_REQUEST_TEMPLATE.md openapi.json
git commit -m "docs: add PR template and export OpenAPI schema"
git push origin mainOpen a PR against your own repo ā you should see the template auto-populate. From now on, every PR follows the same structure.
API Design Principles Knowledge Check
5 questions Ā· Test what you just learned Ā· Instant explanations
Found this helpful?
Leave a comment
Have a question, correction, or just found this helpful? Leave a note below.