packages/server/src/routes/admin.ts 1.7 K raw
1
import { Hono } from "hono";
2
import type { Bindings } from "../types";
3
4
const admin = new Hono<{ Bindings: Bindings }>();
5
6
// Queue all documents for re-processing
7
admin.post("/resolve-all", async (c) => {
8
	try {
9
		const db = c.env.DB;
10
		const queue = c.env.RESOLUTION_QUEUE;
11
12
		// Get limit from query params (default to 100 for safety)
13
		const limitParam = c.req.query("limit");
14
		const limit = limitParam ? parseInt(limitParam, 10) : 100;
15
16
		// Get records from repo_records
17
		const query =
18
			limit > 0
19
				? `SELECT did, rkey FROM repo_records
20
         WHERE collection = 'site.standard.document'
21
         ORDER BY synced_at DESC
22
         LIMIT ?`
23
				: `SELECT did, rkey FROM repo_records
24
         WHERE collection = 'site.standard.document'`;
25
26
		const { results } =
27
			limit > 0
28
				? await db
29
						.prepare(query)
30
						.bind(limit)
31
						.all<{ did: string; rkey: string }>()
32
				: await db.prepare(query).all<{ did: string; rkey: string }>();
33
34
		if (!results || results.length === 0) {
35
			return c.json({ message: "No documents to process", queued: 0 });
36
		}
37
38
		// Queue in batches of 100 (Cloudflare Queue limit)
39
		const batchSize = 100;
40
		let queued = 0;
41
42
		for (let i = 0; i < results.length; i += batchSize) {
43
			const batch = results.slice(i, i + batchSize);
44
			const messages = batch.map((row) => ({
45
				body: {
46
					did: row.did,
47
					collection: "site.standard.document",
48
					rkey: row.rkey,
49
				},
50
			}));
51
52
			await queue.sendBatch(messages);
53
			queued += messages.length;
54
		}
55
56
		return c.json({
57
			message: "Documents queued for re-processing",
58
			queued,
59
		});
60
	} catch (error) {
61
		return c.json(
62
			{ error: "Failed to queue documents", details: String(error) },
63
			500,
64
		);
65
	}
66
});
67
68
export default admin;