A fullstack app for indexing standard.site documents
1import { Hono } from "hono";
2import type { Bindings } from "../types";
3
4const admin = new Hono<{ Bindings: Bindings }>();
5
6// Queue all documents for re-processing
7admin.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
68export default admin;