From ce839e3ce10d8dc6c5d1a7fe1f418b210310dab4 Mon Sep 17 00:00:00 2001 From: Paul Huliganga Date: Tue, 24 Mar 2026 18:06:35 -0400 Subject: [PATCH] docs(api): add initial API documentation for all endpoints (MVP) --- TODO.md | 2 +- docs/api.md | 142 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 143 insertions(+), 1 deletion(-) create mode 100644 docs/api.md diff --git a/TODO.md b/TODO.md index f15cb0d..ea2428c 100644 --- a/TODO.md +++ b/TODO.md @@ -11,7 +11,7 @@ - [ ] Test local deployment *(Unable to run `docker compose up` in environment: docker is unavailable. Manual test required on host.)* ### Documentation -- [ ] Write API documentation (docs/api.md) +- [x] Write API documentation (docs/api.md) - [ ] Create user guide (docs/user-guide.md) - [ ] Add setup instructions to README - [ ] Document first architecture decisions (ADRs) diff --git a/docs/api.md b/docs/api.md new file mode 100644 index 0000000..b222d90 --- /dev/null +++ b/docs/api.md @@ -0,0 +1,142 @@ +# API Documentation — Recipe Manager + +**Base URL:** `/api` + +--- + +## Authentication + +No authentication required for MVP (local/private use). Consider adding in v1.0. + +--- + +## Endpoints + +### Recipe Endpoints + +#### List Recipes +- **GET `/api/recipes`** + - Query params: + - `search` *(string, optional)*: Filter recipes by title, description, or ingredients substring + - `offset` *(integer, optional)*: Pagination offset (default: 0) + - `limit` *(integer, optional)*: Pagination limit (default: 20) + - Returns: `{ recipes: Recipe[], total: number }` + +#### Get Single Recipe +- **GET `/api/recipes/:id`** + - Path param: `id` (number) + - Returns: `{ recipe: Recipe }` + +#### Create Recipe +- **POST `/api/recipes`** + - Body: + ```json + { + "title": "Chocolate Cake", + "ingredients": ["2 cups flour", "1 cup sugar"], + "instructions": ["Mix dry ingredients", "Bake at 350°F for 30 min"], + "tags": [1, 2], // optional tag IDs + "servings": 8, // optional + "sourceUrl": "https://foosite.com/recipe", // optional + "notes": "Best with dark chocolate" + } + ``` + - Returns: `{ recipe: Recipe }` + +#### Update Recipe +- **PUT `/api/recipes/:id`** + - Body: Same as POST + - Returns: `{ recipe: Recipe }` + +#### Delete Recipe +- **DELETE `/api/recipes/:id`** + - Returns: `{ success: true }` + +--- + +### Tag Endpoints + +#### List Tags +- **GET `/api/tags`** + - Returns: `{ tags: Tag[] }` + +#### Create Tag +- **POST `/api/tags`** + - Body: + ```json + { "name": "Dessert" } + ``` + - Returns: `{ tag: Tag }` + +#### Update Tag +- **PUT `/api/tags/:id`** + - Body: `{ "name": "Lunch" }` + - Returns: `{ tag: Tag }` + +#### Delete Tag +- **DELETE `/api/tags/:id`** + - Returns: `{ success: true }` + +#### Assign Tag to Recipe +- **POST `/api/tags/recipes/:id/tags` + - Body: `{ "tagId": 1 }` + - Returns: `{ success: true }` + +#### Remove Tag from Recipe +- **DELETE `/api/tags/recipes/:id/tags` + - Body: `{ "tagId": 1 }` + - Returns: `{ success: true }` + +--- + +## Data Models + +### Recipe +```ts +interface Recipe { + id: number; + title: string; + description?: string; + ingredients: string[]; + instructions: string[]; + servings?: number; + tags?: Tag[]; + sourceUrl?: string; + notes?: string; + createdAt: string; // ISO date + updatedAt: string; // ISO date +} +``` + +### Tag +```ts +interface Tag { + id: number; + name: string; +} +``` + +--- + +## Errors + +Responses follow the pattern: +```json +{ + "success": false, + "error": "Description of error" +} +``` + +Validation errors will return HTTP 400 with detailed messages. + +--- + +## Versioning + +Current version: MVP v0.1 (2026-03-24) +Future versions may introduce breaking API changes (see ROADMAP.md). + +--- + +_Last updated: 2026-03-24_ \ No newline at end of file