import { acceptSuggestion, listSuggestions, rejectSuggestion, resolveVisibleWork } from "@sttracker/core/entries"; import { NotFoundError } from "@sttracker/core/errors"; import { getWork, searchWorks } from "@sttracker/core/works"; import { z } from "zod"; import { noContent, route } from "../http.ts"; import { mediaType, qInt } from "./schemas.ts"; export const workRoutes = [ route({ method: "GET", path: "works/search", summary: "Search works visible to you by title.", auth: "any:read", query: z.object({ q: z.string().min(1).max(500), mediaType: mediaType.optional(), limit: qInt.optional() }), handler: async ({ deps, user, query }) => searchWorks(deps.db, user.id, query.q, { mediaType: query.mediaType, limit: query.limit }), }), route({ method: "GET", path: "works/:id", summary: "One work (follows merges and your aliases).", auth: "any:read", handler: async ({ deps, user, params }) => { const visible = await resolveVisibleWork(deps.db.k, user.id, params.id!); const work = await getWork(deps.db, visible.id); if (!work) throw new NotFoundError("work"); return work; }, }), route({ method: "GET", path: "works/:id/suggestions", summary: "Pending match suggestions for a work.", auth: "any:read", handler: async ({ deps, user, params }) => listSuggestions(deps.db, user.id, params.id!), }), route({ method: "POST", path: "suggestions/:id/accept", summary: "Accept a match suggestion (moves your entry to the candidate work).", auth: "any:write", handler: async ({ deps, user, params }) => { await acceptSuggestion(deps.db, user.id, params.id!); return noContent(); }, }), route({ method: "POST", path: "suggestions/:id/reject", summary: "Reject a match suggestion.", auth: "any:write", handler: async ({ deps, user, params }) => { await rejectSuggestion(deps.db, user.id, params.id!); return noContent(); }, }), ];