import { jsonResponse, errorResponse } from "../../../lib/respond.js"; import { logActivity } from "../../../lib/activityLog.js"; // GET /api/photos?task_id= - list photo metadata for a task (image bytes are // fetched separately per-photo via GET /api/photos/:id so lists stay light). export async function onRequestGet(context) { const { env, request } = context; const url = new URL(request.url); const taskId = url.searchParams.get("task_id"); if (!taskId) return errorResponse("task_id query param is required"); const { results } = await env.DB.prepare( "SELECT id, task_id, caption, uploaded_by, created_at, (thumb_r2_key IS NOT NULL) as has_thumb FROM photos WHERE task_id = ? ORDER BY created_at DESC" ) .bind(taskId) .all(); return jsonResponse({ photos: results }); } // POST /api/photos - multipart/form-data: task_id, image (File), thumb (File, optional), caption // The browser compresses before upload (see public/js/compress.js) - this // handler just stores whatever it's given. export async function onRequestPost(context) { const { env, request, data } = context; const form = await request.formData().catch(() => null); if (!form) return errorResponse("Expected multipart/form-data"); const taskId = form.get("task_id"); const image = form.get("image"); const thumb = form.get("thumb"); const caption = form.get("caption"); if (!taskId || !(image instanceof File)) { return errorResponse("task_id and image are required"); } const task = await env.DB.prepare("SELECT id FROM tasks WHERE id = ?").bind(taskId).first(); if (!task) return errorResponse("Unknown task_id", 404); const stamp = Date.now(); const rand = Math.random().toString(36).slice(2, 8); const key = `photos/${taskId}/${stamp}-${rand}.jpg`; const thumbKey = thumb instanceof File ? `thumbs/${taskId}/${stamp}-${rand}.jpg` : null; await env.PHOTOS.put(key, await image.arrayBuffer(), { httpMetadata: { contentType: "image/jpeg" }, }); if (thumbKey) { await env.PHOTOS.put(thumbKey, await thumb.arrayBuffer(), { httpMetadata: { contentType: "image/jpeg" }, }); } const result = await env.DB.prepare( `INSERT INTO photos (task_id, r2_key, thumb_r2_key, caption, uploaded_by) VALUES (?, ?, ?, ?, ?)` ) .bind(taskId, key, thumbKey, caption || null, data.userEmail) .run(); const photoId = result.meta.last_row_id; await logActivity(env.DB, data.userEmail, "photo_uploaded", caption || null, Number(taskId)); const photo = await env.DB.prepare("SELECT * FROM photos WHERE id = ?").bind(photoId).first(); return jsonResponse({ photo }, { status: 201 }); }