diff --git a/capsite-checklist.md b/capsite-checklist.md index 943b450..75de868 100644 --- a/capsite-checklist.md +++ b/capsite-checklist.md @@ -7,9 +7,10 @@ items, when it has passed verification itself). Working notes live under each goal; [the capsite notes](capsite-notes.md) carry the background narrative. -- [ ] **EmDash site (madmode) collects diigo.com bookmarks; credentials - held by the host, never inside the plugin** (background: - [the capsite notes](capsite-notes.md); after step 2, expands to +- [ ] **madmode publishes a weekly roundup of diigo bookmarks** + ([#23](https://github.com/dckc/madmode-blog/issues/23)); the diigo + session stays inside webapp, so madmode holds no credential at all + (background: [the capsite notes](capsite-notes.md); after that, [bib sync #195](https://github.com/dckc/madmode-blog/issues/195)) - [x] Credential discipline: no worker secrets; the cookie lives only @@ -53,30 +54,54 @@ narrative. `startFill`/`fillStatus`/`stopFill` in `src/cache.ts`; `tests/fill.test.ts`). - - [ ] **2. madmode collects real bookmarks via the webapp cookie path** - (the API-key path is dead: [evidence in the notes](capsite-notes.md#where-the-diigo-credentials-go)) - - [ ] 2-i. Plugin rides the cache: plugin's sync calls - diigo-cache's DiigoBridge (cache id by wiring, not - secret); cookie + host gate stay host-side. - - [ ] 2-ii. Plugin "Sync now" succeeds: status 200, bookmarks - stored (admin at /_emdash/admin → Diigo Sync). - - [ ] 2-iii. Cookie-expiry story for cron: rotation is manual - (re-create via the home page form; the cache id rotates - with it) unless we automate it later. - - [ ] **3. `/bookmarks` renders real data** after a sync — titles/tags at - http://localhost:4321/bookmarks. - - [ ] **4. Cron sync** works locally without errors (`0 */6 * * *` in - `_emdash_cron_tasks`). - - [ ] **5. Deployed end-to-end** (order matters; webapp first): + - [ ] **1f. Cached pages go stale: the head must refresh.** A page hit + never expires, and diigo pages are updated-desc, so every new or + edited bookmark shifts the page boundaries: this week's bookmarks + sit on page 1, cached last week. Proposal: refetch the head + (pages from 1 until a fetched page's items are all already stored + with the same `updated`), upserting into `items` (already keyed by + `item_id`); the window/search reads of 1d run over `items`, not + over cached page numbers. A fill or a cron alarm (`ctx.storage` + alarm in the cache DO, not in madmode) can drive it. + **Durable state**: additive only if `pages`/`page_members` keep + their meaning; say so before changing them (capsite AGENTS.md). + Needs a test: an item added to the fake webapp shows up after a + refresh. + + - [ ] **2. madmode reads the public cache**: public data, so no + capability, no cookie, no plugin sync job, no cron on madmode's + side. madmode fetches `GET /public/dckc-madmode` with + `Accept: application/json` (plus 1d's `in=`/`days=`/`q=`). + - [ ] 2-i. Transport: a service binding to diigo-cache when both + are deployed (no public hop, so no rate-limit exposure); + in dev, a base URL (`http://localhost:8787`). + - [ ] 2-ii. The JSON shape of the public page is a contract + between two workers: pin it in a diigo-cache test (and + madmode's reader tests against the same fixture). + - [ ] **3. `/bookmarks` renders real data** — titles, tags, dates at + http://localhost:4321/bookmarks, newest first. + - [ ] **4. The weekly page**: `/bookmarks/2026-W41` → the cache's + `in=2026-W41` (needs 1d and 1f). Decide (user's call): a raw + week list, or a draft post the user edits before publishing + (the PESOS practice is editorial; a tag like `#weekly` in `q` + is one cheap form of discretion). + - [ ] **5. Deployed end-to-end** (order matters): - [ ] 5-i. webapp: `cd webapp && npx wrangler deploy` - - [ ] 5-ii. diigo-cache: deploy + first create against prod - (ids → password manager; no worker secret put needed); - rate-limit the public routes first (diigo-cache README, - "Deployment concern"). - - [ ] 5-iii. madmode: `pnpm wrangler deploy`, secrets via - `wrangler secret put`; plugin "Sync now" against prod - - [ ] **6. bib sync #195**: repeat the pattern for the next - read-access need. + - [ ] 5-ii. diigo-cache: rate-limit `/public/*` and `/api` first + (diigo-cache README, "Deployment concern"); deploy; create + against prod (ids → password manager; no worker secret); + run the fill job. + - [ ] 5-iii. madmode: deploy with the service binding; the + weekly page renders against prod. + - [ ] **6. Cookie expiry**: when diigo's session ends, head refreshes + fail; the public page keeps serving what's stored (say so on the + page, don't fail silently). Rotation is manual: re-mint via + `/_connect`. Open question: can an existing cache be re-wired to + a new webapp id (keeping its cache id and public username), or + does re-mint mean a new cache? Prefer re-wire — durable ids. + - [ ] **7. bib sync #195**: repeat the pattern for the next + read-access need (webapp mints for any origin; the cache's + item shape is diigo-specific). - [ ] **webapp graduates from prototype** (optional; only if it earns it) - [ ] TODO(webapp): one canonical mint form — proxy-page (current) vs running webapp as the primary worker so its own port serves the