Three independent feature specs covering: - API endpoint for fetching images from URLs with local storage - Public-read/authenticated-write auth with sessions and API keys - Built-in MCP server for Claude Code/Desktop integration Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2.2 KiB
2.2 KiB
Image URL Fetching — Design Spec
Overview
Add the ability to fetch images from external URLs via the API, download them to local storage, and preserve the original source URL as metadata. API-only feature — no frontend changes.
New Endpoint
POST /api/images/from-url
Request:
{ "url": "https://example.com/photo.jpg" }
Validation (Zod):
url— valid URL string, required
Server-side behavior:
- Fetch the URL with a 10-second timeout
- Check response
Content-Typeis one of:image/jpeg,image/png,image/webp - Check
Content-Lengthdoes not exceed 5MB (match existing upload limit) - Stream response body to
uploads/directory using existing naming:${Date.now()}-${randomUUID()}.${ext} - If any check fails, return 400 with descriptive error
Response:
{ "filename": "1712160000000-abc123.jpg", "sourceUrl": "https://example.com/photo.jpg" }
Callers can use filename for imageFilename and sourceUrl for imageSourceUrl when creating/updating items or candidates.
Error responses:
400— invalid URL, unsupported content type, file too large, fetch failed500— server error during download/save
Schema Changes
items table
Add column:
imageSourceUrl: text("image_source_url") // nullable
threadCandidates table
Add column:
imageSourceUrl: text("image_source_url") // nullable
Zod schemas
Add imageSourceUrl: z.string().url().optional() to:
createItemSchemaupdateItemSchemacreateCandidateSchemaupdateCandidateSchema
Types
Types are inferred from Zod schemas and Drizzle tables — no manual updates needed.
Existing Behavior Unchanged
POST /api/images(file upload) remains as-is- All existing image display, cleanup, and serving logic unchanged
imageFilenamecontinues to work identically
Test Helper Updates
Add image_source_url TEXT column to the items and thread_candidates CREATE TABLE statements in tests/helpers/db.ts.
Testing
- Service test: fetch from a valid URL, verify file saved and filename returned
- Route test: POST to
/api/images/from-urlwith valid/invalid URLs - Validation tests: wrong content type, oversized image, invalid URL format, timeout