Files
job-forge/docs/api_specification.md
2025-08-01 09:31:37 -04:00

597 lines
14 KiB
Markdown

# JobForge MVP - API Specification
**Version:** 1.0.0 MVP
**Base URL:** `http://localhost:8000`
**Target Audience:** Backend Developers
**Last Updated:** July 2025
---
## 🔐 Authentication
### Overview
- **Method:** JWT Bearer tokens
- **Token Expiry:** 24 hours
- **Refresh:** Not implemented in MVP (re-login required)
- **Header Format:** `Authorization: Bearer <jwt_token>`
### Authentication Endpoints
#### POST /api/v1/auth/register
Register new user account.
**Request:**
```json
{
"email": "user@example.com",
"password": "SecurePass123!",
"full_name": "John Doe"
}
```
**Response (201):**
```json
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"email": "user@example.com",
"full_name": "John Doe",
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "bearer"
}
```
**Errors:**
- `400` - Invalid email format or weak password
- `409` - Email already registered
#### POST /api/v1/auth/login
Authenticate user and return JWT token.
**Request:**
```json
{
"email": "user@example.com",
"password": "SecurePass123!"
}
```
**Response (200):**
```json
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"email": "user@example.com",
"full_name": "John Doe",
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "bearer"
}
```
**Errors:**
- `401` - Invalid credentials
- `400` - Missing email or password
#### GET /api/v1/auth/me
Get current user profile (requires authentication).
**Headers:** `Authorization: Bearer <token>`
**Response (200):**
```json
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"email": "user@example.com",
"full_name": "John Doe",
"created_at": "2025-07-01T10:00:00Z"
}
```
**Errors:**
- `401` - Invalid or expired token
---
## 📋 Applications API
### Application Model
```json
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "google_senior_developer_2025_07_01",
"company_name": "Google",
"role_title": "Senior Developer",
"job_url": "https://careers.google.com/jobs/123",
"job_description": "We are looking for...",
"location": "Toronto, ON",
"priority_level": "high",
"status": "draft",
"research_completed": false,
"resume_optimized": false,
"cover_letter_generated": false,
"created_at": "2025-07-01T10:00:00Z",
"updated_at": "2025-07-01T10:00:00Z"
}
```
### Application Endpoints
#### POST /api/v1/applications
Create new job application.
**Headers:** `Authorization: Bearer <token>`
**Request:**
```json
{
"company_name": "Google",
"role_title": "Senior Developer",
"job_description": "We are looking for an experienced developer...",
"job_url": "https://careers.google.com/jobs/123",
"location": "Toronto, ON",
"priority_level": "high",
"additional_context": "Found through LinkedIn, know someone there"
}
```
**Response (201):**
```json
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "google_senior_developer_2025_07_01",
"company_name": "Google",
"role_title": "Senior Developer",
"job_url": "https://careers.google.com/jobs/123",
"job_description": "We are looking for an experienced developer...",
"location": "Toronto, ON",
"priority_level": "high",
"status": "draft",
"research_completed": false,
"resume_optimized": false,
"cover_letter_generated": false,
"created_at": "2025-07-01T10:00:00Z",
"updated_at": "2025-07-01T10:00:00Z"
}
```
**Validation Rules:**
- `company_name`: Required, 1-255 characters
- `role_title`: Required, 1-255 characters
- `job_description`: Required, minimum 50 characters
- `job_url`: Optional, valid URL format
- `priority_level`: Optional, enum: `low|medium|high`
**Errors:**
- `400` - Validation errors
- `401` - Unauthorized
#### GET /api/v1/applications
List user's applications.
**Headers:** `Authorization: Bearer <token>`
**Query Parameters:**
- `status`: Filter by status (optional)
- `priority`: Filter by priority level (optional)
- `limit`: Number of results (default: 50, max: 100)
- `offset`: Pagination offset (default: 0)
**Response (200):**
```json
{
"applications": [
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "google_senior_developer_2025_07_01",
"company_name": "Google",
"role_title": "Senior Developer",
"status": "research_complete",
"priority_level": "high",
"research_completed": true,
"resume_optimized": false,
"cover_letter_generated": false,
"created_at": "2025-07-01T10:00:00Z",
"updated_at": "2025-07-01T11:30:00Z"
}
],
"total": 1,
"limit": 50,
"offset": 0
}
```
#### GET /api/v1/applications/{application_id}
Get specific application details.
**Headers:** `Authorization: Bearer <token>`
**Response (200):** Full application object (see Application Model above)
**Errors:**
- `404` - Application not found or not owned by user
- `401` - Unauthorized
#### PUT /api/v1/applications/{application_id}
Update application details.
**Headers:** `Authorization: Bearer <token>`
**Request:**
```json
{
"company_name": "Google Inc.",
"location": "Toronto, ON, Canada",
"priority_level": "medium"
}
```
**Response (200):** Updated application object
**Errors:**
- `404` - Application not found
- `400` - Validation errors
- `401` - Unauthorized
#### DELETE /api/v1/applications/{application_id}
Delete application and all associated documents.
**Headers:** `Authorization: Bearer <token>`
**Response (204):** No content
**Errors:**
- `404` - Application not found
- `401` - Unauthorized
---
## 📄 Documents API
### Document Model
```json
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"application_id": "456e7890-e89b-12d3-a456-426614174000",
"document_type": "research_report",
"content": "# Research Report\n\n## Job Analysis\n...",
"created_at": "2025-07-01T10:30:00Z",
"updated_at": "2025-07-01T10:30:00Z"
}
```
### Document Endpoints
#### GET /api/v1/applications/{application_id}/documents
Get all documents for an application.
**Headers:** `Authorization: Bearer <token>`
**Response (200):**
```json
{
"research_report": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"content": "# Research Report\n\n## Job Analysis\n...",
"created_at": "2025-07-01T10:30:00Z",
"updated_at": "2025-07-01T10:30:00Z"
},
"optimized_resume": {
"id": "234e5678-e89b-12d3-a456-426614174000",
"content": "# John Doe\n\n## Experience\n...",
"created_at": "2025-07-01T11:00:00Z",
"updated_at": "2025-07-01T11:00:00Z"
},
"cover_letter": null
}
```
#### GET /api/v1/applications/{application_id}/documents/{document_type}
Get specific document.
**Headers:** `Authorization: Bearer <token>`
**URL Parameters:**
- `document_type`: enum: `research_report|optimized_resume|cover_letter`
**Response (200):**
```json
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"application_id": "456e7890-e89b-12d3-a456-426614174000",
"document_type": "research_report",
"content": "# Research Report\n\n## Job Analysis\n...",
"created_at": "2025-07-01T10:30:00Z",
"updated_at": "2025-07-01T10:30:00Z"
}
```
**Errors:**
- `404` - Document not found or application not owned by user
#### PUT /api/v1/applications/{application_id}/documents/{document_type}
Update document content (user editing).
**Headers:** `Authorization: Bearer <token>`
**Request:**
```json
{
"content": "# Updated Research Report\n\n## Job Analysis\nUpdated content..."
}
```
**Response (200):** Updated document object
**Validation:**
- `content`: Required, minimum 10 characters
**Errors:**
- `404` - Document or application not found
- `400` - Validation errors
---
## 🤖 AI Processing API
### Processing Status Model
```json
{
"application_id": "123e4567-e89b-12d3-a456-426614174000",
"current_phase": "research",
"status": "processing",
"progress": 0.6,
"estimated_completion": "2025-07-01T10:35:00Z",
"error_message": null
}
```
### Processing Endpoints
#### POST /api/v1/processing/applications/{application_id}/research
Start research phase processing.
**Headers:** `Authorization: Bearer <token>`
**Response (202):**
```json
{
"message": "Research phase started",
"application_id": "123e4567-e89b-12d3-a456-426614174000",
"estimated_completion": "2025-07-01T10:35:00Z"
}
```
**Errors:**
- `404` - Application not found
- `409` - Research already completed
- `400` - Application not in correct state
#### POST /api/v1/processing/applications/{application_id}/resume
Start resume optimization phase.
**Headers:** `Authorization: Bearer <token>`
**Requirements:** Research phase must be completed
**Response (202):**
```json
{
"message": "Resume optimization started",
"application_id": "123e4567-e89b-12d3-a456-426614174000",
"estimated_completion": "2025-07-01T11:05:00Z"
}
```
**Errors:**
- `404` - Application not found
- `409` - Resume already optimized
- `412` - Research phase not completed
#### POST /api/v1/processing/applications/{application_id}/cover-letter
Start cover letter generation phase.
**Headers:** `Authorization: Bearer <token>`
**Request:**
```json
{
"additional_context": "I'm particularly interested in their AI/ML projects. I have experience with TensorFlow and PyTorch."
}
```
**Requirements:** Resume optimization must be completed
**Response (202):**
```json
{
"message": "Cover letter generation started",
"application_id": "123e4567-e89b-12d3-a456-426614174000",
"estimated_completion": "2025-07-01T11:15:00Z"
}
```
**Errors:**
- `404` - Application not found
- `409` - Cover letter already generated
- `412` - Resume optimization not completed
#### GET /api/v1/processing/applications/{application_id}/status
Get current processing status.
**Headers:** `Authorization: Bearer <token>`
**Response (200):**
```json
{
"application_id": "123e4567-e89b-12d3-a456-426614174000",
"current_phase": "resume",
"status": "completed",
"progress": 1.0,
"completed_at": "2025-07-01T11:05:00Z",
"error_message": null
}
```
**Status Values:**
- `idle` - No processing active
- `processing` - AI generation in progress
- `completed` - Phase completed successfully
- `failed` - Processing failed with error
---
## 👤 User Resumes API
### Resume Model
```json
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "Technical Resume",
"content": "# John Doe\n\n## Technical Skills\n...",
"focus_area": "software_development",
"is_primary": true,
"created_at": "2025-07-01T09:00:00Z",
"updated_at": "2025-07-01T09:00:00Z"
}
```
### Resume Endpoints
#### GET /api/v1/resumes
Get user's resume library.
**Headers:** `Authorization: Bearer <token>`
**Response (200):**
```json
{
"resumes": [
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "Technical Resume",
"focus_area": "software_development",
"is_primary": true,
"created_at": "2025-07-01T09:00:00Z",
"updated_at": "2025-07-01T09:00:00Z"
}
]
}
```
#### POST /api/v1/resumes
Upload new resume to library.
**Headers:** `Authorization: Bearer <token>`
**Request:**
```json
{
"name": "Management Resume",
"content": "# John Doe\n\n## Leadership Experience\n...",
"focus_area": "management",
"is_primary": false
}
```
**Response (201):** Created resume object
**Validation:**
- `name`: Required, 1-255 characters
- `content`: Required, minimum 100 characters
- `focus_area`: Optional, enum: `software_development|management|data_science|consulting|other`
#### GET /api/v1/resumes/{resume_id}
Get specific resume details.
**Headers:** `Authorization: Bearer <token>`
**Response (200):** Full resume object
#### PUT /api/v1/resumes/{resume_id}
Update resume content.
**Headers:** `Authorization: Bearer <token>`
**Request:** Same as POST
**Response (200):** Updated resume object
#### DELETE /api/v1/resumes/{resume_id}
Delete resume from library.
**Headers:** `Authorization: Bearer <token>`
**Response (204):** No content
**Errors:**
- `409` - Cannot delete primary resume if it's the only one
---
## 🚨 Error Handling
### Standard Error Response
```json
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid input data",
"details": {
"company_name": ["This field is required"],
"job_description": ["Must be at least 50 characters"]
}
},
"timestamp": "2025-07-01T10:00:00Z",
"path": "/api/v1/applications"
}
```
### HTTP Status Codes
- `200` - Success
- `201` - Created successfully
- `202` - Accepted (async processing started)
- `204` - No content (successful deletion)
- `400` - Bad request (validation errors)
- `401` - Unauthorized (invalid/missing token)
- `403` - Forbidden (valid token, insufficient permissions)
- `404` - Not found
- `409` - Conflict (duplicate email, invalid state transition)
- `412` - Precondition failed (phase not completed)
- `422` - Unprocessable entity (semantic errors)
- `500` - Internal server error
### Error Codes
- `VALIDATION_ERROR` - Input validation failed
- `AUTHENTICATION_ERROR` - Invalid credentials
- `AUTHORIZATION_ERROR` - Insufficient permissions
- `NOT_FOUND` - Resource not found
- `DUPLICATE_RESOURCE` - Resource already exists
- `INVALID_STATE` - Operation not valid for current state
- `EXTERNAL_API_ERROR` - Claude/OpenAI API error
- `PROCESSING_ERROR` - AI processing failed
---
## 🔧 Development Notes
### Rate Limiting (Future)
- Not implemented in MVP
- Will be added in Phase 2 for SaaS
### Pagination
- Default limit: 50
- Maximum limit: 100
- Use `offset` for pagination
### Content Validation
- Job description: 50-10000 characters
- Resume content: 100-50000 characters
- Names: 1-255 characters
- URLs: Valid HTTP/HTTPS format
### Background Processing
- AI operations run asynchronously
- Use `/processing/applications/{id}/status` to check progress
- Frontend should poll every 2-3 seconds during processing
---
*This API specification covers all endpoints required for MVP implementation. Use the OpenAPI documentation at `/docs` for interactive testing during development.*