···11+MIT License
22+33+Copyright (c) 2026 Steve Simkins
44+55+Permission is hereby granted, free of charge, to any person obtaining a copy
66+of this software and associated documentation files (the "Software"), to deal
77+in the Software without restriction, including without limitation the rights
88+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
99+copies of the Software, and to permit persons to whom the Software is
1010+furnished to do so, subject to the following conditions:
1111+1212+The above copyright notice and this permission notice shall be included in all
1313+copies or substantial portions of the Software.
1414+1515+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1616+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1717+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1818+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1919+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2020+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2121+SOFTWARE.
+5-112
README.md
···6677```
88┌─────────────────────────────────────────────────────────────┐
99-│ Cloudflare │
99+│ Cloudflare │
1010├─────────────────────────────────────────────────────────────┤
1111-│ │
1111+│ │
1212│ ┌──────────────┐ ┌──────────────┐ ┌─────────────┐ │
1313│ │ Pages │────▶│ Worker │────▶│ D1 │ │
1414│ │ (Client) │ │ (API) │ │ (Database) │ │
1515│ └──────────────┘ └──────────────┘ └─────────────┘ │
1616-│ ▲ ▲ │
1717-│ │ │ │
1616+│ ▲ ▲ │
1717+│ │ │ │
1818│ ┌──────┴───────┐ ┌──────┴───────┐ │
1919│ │ Queue │ │ Cron │ │
2020│ │ (Resolver) │ │ (Refresh) │ │
···2424 │ POST /webhook/tap
2525 ┌──────────┴───────────┐
2626 │ Tap Instance │
2727- │ (External VPS) │
2727+ │ (External) │
2828 └──────────────────────┘
2929```
3030···34342. **Server** (`packages/server`) - Cloudflare Worker with Hono API, D1 database, and Queue consumer
35353. **Client** (`packages/client`) - Vite + React app deployed to Cloudflare Pages
36363737-## Quick Start
3838-3939-### Prerequisites
4040-4141-- [Bun](https://bun.sh) installed
4242-- [Wrangler CLI](https://developers.cloudflare.com/workers/wrangler/) installed and authenticated
4343-- A tap instance running somewhere (VPS, Fly.io, etc.)
4444-4545-### Setup
4646-4747-1. Install dependencies:
4848-4949-```bash
5050-bun install
5151-```
5252-5353-2. Create the D1 database:
5454-5555-```bash
5656-bun run db:create
5757-```
5858-5959-Copy the database ID and update `packages/server/wrangler.toml`.
6060-6161-3. Create the queue:
6262-6363-```bash
6464-wrangler queues create document-resolution
6565-```
6666-6767-4. Run database migrations:
6868-6969-```bash
7070-# Local development
7171-bun run db:migrate
7272-7373-# Production
7474-bun run db:migrate:prod
7575-```
7676-7777-5. (Optional) Set webhook secret:
7878-7979-```bash
8080-bun run secret:set
8181-```
8282-8383-6. Deploy the worker:
8484-8585-```bash
8686-bun run deploy
8787-```
8888-8989-7. Configure your tap instance:
9090-9191-```bash
9292-TAP_WEBHOOK_URL=https://your-worker.workers.dev/webhook/tap
9393-TAP_SIGNAL_COLLECTION=site.standard.document
9494-TAP_COLLECTION_FILTERS=site.standard.document
9595-```
9696-9797-8. Trigger initial resolution of existing records:
9898-9999-```bash
100100-curl -X POST https://your-worker.workers.dev/admin/resolve-all
101101-```
102102-10337## Local Development
10438105391. Start the worker locally:
···155893. **Queue consumer** resolves each document (PDS lookup → record fetch → publication URL) and stores in `resolved_documents`
156904. **Cron job** (every 15 min) refreshes stale documents and processes any missed records
157915. **`/feed` endpoint** reads directly from `resolved_documents` for instant responses
158158-159159-## Project Structure
160160-161161-```
162162-.
163163-├── package.json # Root workspace config
164164-└── packages/
165165- ├── server/ # Cloudflare Worker
166166- │ ├── wrangler.toml # Worker configuration
167167- │ ├── schema.sql # D1 database schema
168168- │ ├── package.json
169169- │ └── src/
170170- │ └── index.ts # API + Queue consumer + Cron handler
171171- └── client/ # Vite + React app
172172- ├── package.json
173173- ├── vite.config.ts
174174- └── src/
175175- ├── main.tsx
176176- └── App.tsx
177177-```
178178-179179-## Scripts
180180-181181-```bash
182182-# Development
183183-bun run dev # Run all packages in dev mode
184184-bun run dev:server # Run worker locally
185185-bun run dev:client # Run client locally
186186-187187-# Deployment
188188-bun run deploy # Deploy worker to Cloudflare
189189-bun run deploy:client # Deploy client to Cloudflare Pages
190190-191191-# Database
192192-bun run db:create # Create D1 database
193193-bun run db:migrate # Run migrations (local)
194194-bun run db:migrate:prod # Run migrations (production)
195195-196196-# Secrets
197197-bun run secret:set # Set TAP_WEBHOOK_SECRET
198198-```
1999220093## Resources
20194