Skip to content

[recipes] Daily digest — implement the Supabase Edge Function approach - #445

Open
kaizengrowth wants to merge 1 commit into
NateBJones-Projects:mainfrom
kaizengrowth:contrib/kaizengrowth/daily-digest-edge-function
Open

[recipes] Daily digest — implement the Supabase Edge Function approach#445
kaizengrowth wants to merge 1 commit into
NateBJones-Projects:mainfrom
kaizengrowth:contrib/kaizengrowth/daily-digest-edge-function

Conversation

@kaizengrowth

@kaizengrowth kaizengrowth commented Jul 13, 2026

Copy link
Copy Markdown

Fixes #14

Contribution Type

  • Recipe (/recipes)
  • Schema (/schemas)
  • Dashboard (/dashboards)
  • Integration (/integrations)
  • Skill (/skills)
  • Repo improvement (docs, CI, templates)

What does this do?

Completes the daily-digest recipe. The stub already had a working Approach A (Claude Code scheduled task → Gmail draft); the Supabase Edge Function path was marked "Planned — contributions welcome." This PR implements it:

  • edge-function/index.ts — a self-contained Deno Edge Function that queries thoughts from the last N hours (default 24, max 168) via PostgREST, groups them by type with a summary header (total count, per-type breakdown, top topics), and sends the digest through Resend as both text and HTML. Thoughts with sensitivity_tier of personal/restricted (enhanced-thoughts schema) are excluded by default; rows without that column are unaffected. Supports { dry_run: true } (returns the digest as JSON without sending — used for testing), hours, and include_personal body params.
  • schedule.sql — pg_cron + pg_net job firing daily at 07:00 UTC, with verify/run-history/manual-test/unschedule snippets. Modeled on the editorial-policy recipe's schedule.sql.
  • Security — deployed with --no-verify-jwt (pg_cron can't send a user JWT) and gated by a DIGEST_ACCESS_KEY query secret instead, the same pattern as the editorial-policy auditor.
  • README — Approach B rewritten from "planned" to full step-by-step setup (Resend key → deploy → secrets → dry-run test → schedule), expected outcome, and a troubleshooting section covering the five failure modes I could produce (bad access key, Resend sender restrictions, wrong project link, empty-window confusion, pg_net not enabled).
  • metadata.json — bumped to 1.1.0, description/services/tools/tags updated to cover both approaches. Original author credit unchanged.

One deliberate simplification: the digest is formatted with plain template code rather than the OpenRouter LLM call the original stub sketched. It keeps the recipe at "beginner" difficulty and zero marginal cost, and matches what the issue asked for (grouped, readable, with summaries). An LLM-synthesized variant already exists in the weekly-digest recipe for those who want prose synthesis.

Tested: deno check passes, and the function was driven end-to-end under Deno against a mock PostgREST endpoint: auth gate rejects a bad key, dry_run returns the digest without sending, personal/restricted rows are excluded (and included with include_personal), grouping/summary/topic counts/truncation come out as described, and the PostgREST query carries the expected window, ordering, and limit. Not yet run against a live Supabase project — the dry_run curl in the README is the first thing to try on a real instance.

Requirements

  • Supabase CLI (deploy) and the pg_cron + pg_net extensions (schedule)
  • Resend account (free tier) with its API key set as a function secret
  • No LLM key, no new schema — works against the core thoughts table

Checklist

  • I've read CONTRIBUTING.md
  • My contribution has a README.md with prerequisites, step-by-step instructions, and expected outcome
  • My metadata.json has all required fields
  • If my contribution depends on a skill or primitive, I declared it in metadata.json and linked it in the README — N/A
  • I tested this on my own Open Brain instance — validated via typecheck + end-to-end mock-PostgREST run (details above); happy to post live dry-run output if wanted before merge
  • No credentials, API keys, or secrets are included

Completes the planned Supabase Edge Function path for the daily-digest
recipe (issue NateBJones-Projects#14): a self-contained function that queries thoughts
from the last N hours (default 24) via PostgREST, filters out
personal/restricted sensitivity tiers by default, groups by type with
a summary header (counts, top topics), and emails the digest through
Resend. Supports dry_run (returns JSON instead of sending), hours
(1-168), and include_personal body params. Access is gated by a
DIGEST_ACCESS_KEY query secret, matching the editorial-policy auditor
pattern.

Formatting is pure template code — no LLM key required, unlike the
originally sketched OpenRouter approach.

Adds schedule.sql (pg_cron + pg_net, daily 07:00 UTC, with verify and
manual-test snippets), rewrites the README's Approach B section from
"planned" to full setup steps with expected outcome and
troubleshooting, and bumps metadata to 1.1.0.
@github-actions github-actions Bot added the recipe Contribution: step-by-step recipe label Jul 13, 2026
@github-actions

Copy link
Copy Markdown

OB1 PR Gate

Folder structure — All files are in allowed directories
Required files — README.md and metadata.json found in all contribution folders
Metadata valid — All metadata.json files passed JSON Schema validation
No credentials — No API keys, tokens, or secrets detected
SQL safety — No destructive SQL or core table modifications
Category artifacts — Required file types present for each category
PR format — Title follows [category] Description format
No binary blobs — No oversized or binary files
README completeness — All READMEs include Prerequisites, Steps, and Expected Outcome
Contribution dependencies — All declared skill and primitive dependencies exist and are linked in README
LLM clarity review — Covered by Claude PR Review workflow
Remote MCP pattern — No local MCP server patterns detected — uses remote MCP correctly
Tool audit link — Extensions/integrations link to the MCP Tool Audit guide
Scope check — All changes are within the contribution folder(s)
Internal links — All relative links in READMEs resolve to existing files

Result: All 15 checks passed! Ready for human review.


Post-Merge Tasks

These don't block merge — they're reminders for admins after this PR lands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

recipe Contribution: step-by-step recipe

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Recipe: Daily digest email from recent thoughts

1 participant