A fullstack app for indexing standard.site documents
8
fork

Configure Feed

Select the types of activity you want to include in your feed.

chore: cleaned up old routes

Steve d0aec2c8 f73ffb88

+89 -162
-24
packages/server/src/index.ts
··· 17 17 app.route("/records", records); 18 18 app.route("/admin", admin); 19 19 20 - // Legacy alias: /feed-raw -> /feed/raw 21 - app.get("/feed-raw", async (c) => { 22 - const db = c.env.DB; 23 - const limit = Math.min(Number(c.req.query("limit")) || 15, 15); 24 - const offset = Number(c.req.query("offset")) || 0; 25 - 26 - const { results } = await db 27 - .prepare( 28 - `SELECT did, rkey FROM repo_records 29 - WHERE collection = 'site.standard.document' 30 - ORDER BY rkey DESC 31 - LIMIT ? OFFSET ?`, 32 - ) 33 - .bind(limit, offset) 34 - .all<{ did: string; rkey: string }>(); 35 - 36 - return c.json({ 37 - count: results?.length || 0, 38 - limit, 39 - offset, 40 - records: results || [], 41 - }); 42 - }); 43 - 44 20 // 404 handler 45 21 app.notFound((c) => { 46 22 return c.json({ error: "Not found" }, 404);
-23
packages/server/src/routes/admin.ts
··· 51 51 } 52 52 }); 53 53 54 - // Mark all documents as stale (alternative - lets cron handle it) 55 - admin.post("/mark-stale", async (c) => { 56 - try { 57 - const db = c.env.DB; 58 - 59 - const result = await db 60 - .prepare( 61 - `UPDATE resolved_documents SET stale_at = datetime('now', '-1 hour')`, 62 - ) 63 - .run(); 64 - 65 - return c.json({ 66 - message: "All documents marked as stale", 67 - affected: result.meta.changes, 68 - }); 69 - } catch (error) { 70 - return c.json( 71 - { error: "Failed to mark documents as stale", details: String(error) }, 72 - 500, 73 - ); 74 - } 75 - }); 76 - 77 54 export default admin;
+89 -115
packages/server/src/routes/feed.ts
··· 1 1 import { Hono } from "hono"; 2 - import type { Bindings, ResolvedDocumentRow, Document, Publication, BskyPostRef } from "../types"; 2 + import type { 3 + Bindings, 4 + ResolvedDocumentRow, 5 + Document, 6 + Publication, 7 + BskyPostRef, 8 + } from "../types"; 3 9 4 10 const feed = new Hono<{ Bindings: Bindings }>(); 5 11 ··· 7 13 * Transforms a database row into a Document object for the API response. 8 14 */ 9 15 function rowToDocument(row: ResolvedDocumentRow): Document { 10 - // Build publication object if we have publication data 11 - let publication: Publication | undefined; 12 - if (row.pub_url && row.pub_name) { 13 - publication = { 14 - url: row.pub_url, 15 - name: row.pub_name, 16 - description: row.pub_description || undefined, 17 - iconCid: row.pub_icon_cid || undefined, 18 - iconUrl: row.pub_icon_url || undefined, 19 - }; 20 - } 16 + // Build publication object if we have publication data 17 + let publication: Publication | undefined; 18 + if (row.pub_url && row.pub_name) { 19 + publication = { 20 + url: row.pub_url, 21 + name: row.pub_name, 22 + description: row.pub_description || undefined, 23 + iconCid: row.pub_icon_cid || undefined, 24 + iconUrl: row.pub_icon_url || undefined, 25 + }; 26 + } 21 27 22 - // Parse bskyPostRef if present 23 - let bskyPostRef: BskyPostRef | undefined; 24 - if (row.bsky_post_ref) { 25 - try { 26 - bskyPostRef = JSON.parse(row.bsky_post_ref); 27 - } catch { 28 - // Ignore parse errors 29 - } 30 - } 28 + // Parse bskyPostRef if present 29 + let bskyPostRef: BskyPostRef | undefined; 30 + if (row.bsky_post_ref) { 31 + try { 32 + bskyPostRef = JSON.parse(row.bsky_post_ref); 33 + } catch { 34 + // Ignore parse errors 35 + } 36 + } 31 37 32 - // Parse tags if present 33 - let tags: string[] | undefined; 34 - if (row.tags) { 35 - try { 36 - tags = JSON.parse(row.tags); 37 - } catch { 38 - // Ignore parse errors 39 - } 40 - } 38 + // Parse tags if present 39 + let tags: string[] | undefined; 40 + if (row.tags) { 41 + try { 42 + tags = JSON.parse(row.tags); 43 + } catch { 44 + // Ignore parse errors 45 + } 46 + } 41 47 42 - // Parse content if present 43 - let content: unknown | undefined; 44 - if (row.content) { 45 - try { 46 - content = JSON.parse(row.content); 47 - } catch { 48 - // Ignore parse errors 49 - } 50 - } 48 + // Parse content if present 49 + let content: unknown | undefined; 50 + if (row.content) { 51 + try { 52 + content = JSON.parse(row.content); 53 + } catch { 54 + // Ignore parse errors 55 + } 56 + } 51 57 52 - return { 53 - uri: row.uri, 54 - did: row.did, 55 - rkey: row.rkey, 56 - title: row.title || "Untitled", 57 - description: row.description || undefined, 58 - path: row.path || undefined, 59 - site: row.site || undefined, 60 - content, 61 - textContent: row.text_content || undefined, 62 - coverImageCid: row.cover_image_cid || undefined, 63 - coverImageUrl: row.cover_image_url || undefined, 64 - bskyPostRef, 65 - tags, 66 - publishedAt: row.published_at || undefined, 67 - updatedAt: row.updated_at || undefined, 68 - publication, 69 - viewUrl: row.view_url || undefined, 70 - pdsEndpoint: row.pds_endpoint || undefined, 71 - }; 58 + return { 59 + uri: row.uri, 60 + did: row.did, 61 + rkey: row.rkey, 62 + title: row.title || "Untitled", 63 + description: row.description || undefined, 64 + path: row.path || undefined, 65 + site: row.site || undefined, 66 + content, 67 + textContent: row.text_content || undefined, 68 + coverImageCid: row.cover_image_cid || undefined, 69 + coverImageUrl: row.cover_image_url || undefined, 70 + bskyPostRef, 71 + tags, 72 + publishedAt: row.published_at || undefined, 73 + updatedAt: row.updated_at || undefined, 74 + publication, 75 + viewUrl: row.view_url || undefined, 76 + pdsEndpoint: row.pds_endpoint || undefined, 77 + }; 72 78 } 73 79 74 - // Get raw feed data (for client-side fetching) 75 - // Accessible at both /feed/raw and /feed-raw (via alias in index.ts) 76 - feed.get("/raw", async (c) => { 77 - try { 78 - const db = c.env.DB; 79 - const limit = Math.min(Number(c.req.query("limit")) || 15, 15); 80 - const offset = Number(c.req.query("offset")) || 0; 81 - 82 - const { results } = await db 83 - .prepare( 84 - `SELECT did, rkey FROM repo_records 85 - WHERE collection = 'site.standard.document' 86 - ORDER BY published_at DESC 87 - LIMIT ? OFFSET ?` 88 - ) 89 - .bind(limit, offset) 90 - .all<{ did: string; rkey: string }>(); 91 - 92 - return c.json({ 93 - count: results?.length || 0, 94 - limit, 95 - offset, 96 - records: results || [], 97 - }); 98 - } catch (error) { 99 - return c.json( 100 - { error: "Failed to fetch feed", details: String(error) }, 101 - 500 102 - ); 103 - } 104 - }); 105 - 106 80 // Get feed of documents with resolved URLs (server-side resolution) 107 81 feed.get("/", async (c) => { 108 - try { 109 - const db = c.env.DB; 110 - const limit = Number(c.req.query("limit")) || 50; 111 - const offset = Number(c.req.query("offset")) || 0; 82 + try { 83 + const db = c.env.DB; 84 + const limit = Number(c.req.query("limit")) || 50; 85 + const offset = Number(c.req.query("offset")) || 0; 112 86 113 - const { results } = await db 114 - .prepare( 115 - `SELECT uri, did, rkey, title, description, path, site, content, text_content, 87 + const { results } = await db 88 + .prepare( 89 + `SELECT uri, did, rkey, title, description, path, site, content, text_content, 116 90 cover_image_cid, cover_image_url, bsky_post_ref, tags, 117 91 published_at, updated_at, pub_url, pub_name, pub_description, 118 92 pub_icon_cid, pub_icon_url, view_url, pds_endpoint, ··· 120 94 FROM resolved_documents 121 95 WHERE verified = 1 122 96 ORDER BY published_at DESC 123 - LIMIT ? OFFSET ?` 124 - ) 125 - .bind(limit, offset) 126 - .all<ResolvedDocumentRow>(); 97 + LIMIT ? OFFSET ?`, 98 + ) 99 + .bind(limit, offset) 100 + .all<ResolvedDocumentRow>(); 127 101 128 - const documents = (results || []).map(rowToDocument); 102 + const documents = (results || []).map(rowToDocument); 129 103 130 - return c.json({ 131 - count: documents.length, 132 - limit, 133 - offset, 134 - documents, 135 - }); 136 - } catch (error) { 137 - return c.json( 138 - { error: "Failed to fetch feed", details: String(error) }, 139 - 500 140 - ); 141 - } 104 + return c.json({ 105 + count: documents.length, 106 + limit, 107 + offset, 108 + documents, 109 + }); 110 + } catch (error) { 111 + return c.json( 112 + { error: "Failed to fetch feed", details: String(error) }, 113 + 500, 114 + ); 115 + } 142 116 }); 143 117 144 118 export default feed;