# Backend Updates Summary ## Database Schema Changes ### Posts Table - New Fields Added 1. **`ghost_slug`** (VARCHAR(255), nullable) - Stores the Ghost post slug for association - Used to link VoxBlog posts with their Ghost counterparts 2. **`ghost_published_at`** (DATETIME(3), nullable) - Timestamp when the post was published to Ghost - Helps track publication history 3. **`selected_image_keys`** (TEXT, nullable) - JSON array of selected image keys for the post - Persists user's image selection for the Generate step - Stored as JSON string, parsed on retrieval ### Migration File - **Location**: `apps/api/drizzle/0001_jittery_revanche.sql` - **Status**: ✅ Migration has been generated and applied ```sql ALTER TABLE `posts` ADD `ghost_slug` varchar(255); ALTER TABLE `posts` ADD `ghost_published_at` datetime(3); ALTER TABLE `posts` ADD `selected_image_keys` text; ``` **To apply this migration** (if needed on other environments): ```bash cd apps/api pnpm drizzle:migrate ``` ## API Endpoint Changes ### 1. GET `/api/posts/:id` **Added Response Fields:** - `ghostPostId`: string | null - `ghostSlug`: string | null - `ghostPublishedAt`: Date | null - `ghostUrl`: string | null - `selectedImageKeys`: string[] (parsed from JSON) ### 2. POST `/api/posts` **Added Request Body Fields:** - `selectedImageKeys`: string[] (optional) - `ghostPostId`: string (optional) - `ghostSlug`: string (optional) - `ghostPublishedAt`: string (optional, ISO date string) - `ghostUrl`: string (optional) **Behavior:** - `selectedImageKeys` is serialized to JSON before storage - Ghost fields are only updated if provided in the request - All fields are nullable and optional ### 3. GET `/api/media/list` **Added Query Parameters:** - `page`: number (default: 1, min: 1) - `pageSize`: number (default: 50, min: 1, max: 200) **Updated Response:** ```json { "items": [...], "total": number, "page": number, "pageSize": number } ``` **Note:** Due to S3 limitations, pagination fetches `page * pageSize` items and slices them. For large datasets, consider implementing cursor-based pagination or caching. ## Files Modified 1. **`apps/api/src/db/schema.ts`** - Added new fields to posts table definition 2. **`apps/api/src/posts.ts`** - Updated GET endpoint to return new fields - Updated POST endpoint to accept and store new fields - Added JSON serialization/deserialization for `selectedImageKeys` 3. **`apps/api/src/media.ts`** - Added pagination support to `/list` endpoint - Implemented page and pageSize query parameters ## Testing Checklist - [x] Run database migration ✅ - [ ] Test POST `/api/posts` with `selectedImageKeys` array - [ ] Test GET `/api/posts/:id` returns `selectedImageKeys` as array - [ ] Test POST `/api/posts` with Ghost fields - [ ] Test GET `/api/media/list?page=1&pageSize=50` - [ ] Test GET `/api/media/list?page=2&pageSize=50` - [ ] Verify `selectedImageKeys` persists across save/load cycles - [ ] Verify Ghost fields update correctly on publish ## Frontend Integration The frontend has been updated to: 1. Send `selectedImageKeys` when saving posts 2. Load `selectedImageKeys` when opening posts 3. Use pagination for media library 4. Update post status after Ghost publish 5. Auto-upload audio recordings All frontend changes are complete and ready to work with these backend updates.