voxblog/BACKEND_UPDATES.md

111 lines
3.3 KiB
Markdown

# 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.