feat(server): REST API, auth, sources, changes, export
createApp() serves /api/v1 from a typed route table (zod bodies and queries), with session-cookie and Bearer app-token auth, a CSRF header for cookie writes, login/register rate limiting, body caps, JSON error mapping, OpenAPI generation and a 404 /ingest mount. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
7b0a6738dd
commit
6963e297b0
@@ -0,0 +1,31 @@
|
||||
import { listChanges, resolveChange } from "@sttracker/core/sync/changes";
|
||||
import { z } from "zod";
|
||||
import { noContent, route } from "../http.ts";
|
||||
import { qInt } from "./schemas.ts";
|
||||
|
||||
export const changeRoutes = [
|
||||
route({
|
||||
method: "GET",
|
||||
path: "changes",
|
||||
summary: "The Changes inbox (pending by default; status=all for everything).",
|
||||
auth: "any:read",
|
||||
query: z.object({
|
||||
status: z.enum(["pending", "all"]).optional(),
|
||||
connectionId: z.string().optional(),
|
||||
limit: qInt.optional(),
|
||||
cursor: z.string().optional(),
|
||||
}),
|
||||
handler: async ({ deps, user, query }) => listChanges(deps.db, user.id, query),
|
||||
}),
|
||||
route({
|
||||
method: "POST",
|
||||
path: "changes/:id/resolve",
|
||||
summary: "Resolve a pending change: accept, ignore or keep_mine.",
|
||||
auth: "any:write",
|
||||
body: z.object({ action: z.enum(["accept", "ignore", "keep_mine"]) }).strict(),
|
||||
handler: async ({ deps, user, params, body }) => {
|
||||
await resolveChange(deps.db, user.id, params.id!, body.action);
|
||||
return noContent();
|
||||
},
|
||||
}),
|
||||
];
|
||||
Reference in New Issue
Block a user