diff --git a/docs/astro.config.mjs b/docs/astro.config.mjs index 93fb33915..441385fc1 100644 --- a/docs/astro.config.mjs +++ b/docs/astro.config.mjs @@ -171,6 +171,17 @@ export default defineConfig({ { label: "Translating EmDash", slug: "contributing/translating" }, ], }, + { + label: "Runbooks", + collapsed: true, + items: [ + { label: "Runbooks Index", slug: "runbooks" }, + { + label: "Cloudflare Post-Deploy Operations", + slug: "runbooks/deployment/cloudflare-post-deploy-operations", + }, + ], + }, { label: "Themes", diff --git a/docs/src/content/docs/deployment/cloudflare.mdx b/docs/src/content/docs/deployment/cloudflare.mdx index 63e68aa26..be4416b6b 100644 --- a/docs/src/content/docs/deployment/cloudflare.mdx +++ b/docs/src/content/docs/deployment/cloudflare.mdx @@ -78,6 +78,46 @@ wrangler deploy Your site is now live at `https://my-emdash-site..workers.dev`. +## Manage a deployed site via API + +Your deployed site exposes EmDash's API under: + +```text +https://my-emdash-site..workers.dev/_emdash/api +``` + +If you use a custom domain, replace the hostname and keep the `/_emdash/api` path. + +Recommended flow for programmatic content operations: + +1. In the admin UI, open **Settings > API tokens** (`/_emdash/admin/settings/api-tokens`). +2. Create a **Personal Access Token** with the scopes your integration needs. +3. Copy the token once (it's only shown at creation time). +4. Call EmDash endpoints with: + +```http +Authorization: Bearer +``` + +```bash +curl -H "Authorization: Bearer " \ + "https://my-emdash-site..workers.dev/_emdash/api/content/posts" + +curl -X POST \ + -H "Authorization: Bearer " \ + -H "Content-Type: application/json" \ + -d '{"slug":"hello","data":{"title":"Hello from deploy"},"status":"draft"}' \ + "https://my-emdash-site..workers.dev/_emdash/api/content/posts" +``` + +For browser-based admin workflows, cookies/sessions also work when requests are made from your site, but external scripts should use tokens. + +Infrastructure management is separate: deploy/redeploy, bindings, KV/D1/R2 resources, DNS, and env secrets are handled through Cloudflare tooling (Workers/Pages dashboard, `wrangler`, or Cloudflare API), not EmDash. + +MCP clients can also use `/_emdash/api/mcp`, and CLI operations use `emdash` with `--url` and `--token`. + +For a full post-deploy operational checklist (smoke checks, token flow, and what stays in Cloudflare tooling), see [Cloudflare Post-Deploy Operations](/runbooks/deployment/cloudflare-post-deploy-operations). + ## Read Replicas For globally distributed sites, enable D1 read replication to route read queries to nearby replicas instead of always hitting the primary database. This significantly reduces latency for visitors far from the primary region. diff --git a/docs/src/content/docs/reference/rest-api.mdx b/docs/src/content/docs/reference/rest-api.mdx index 1e38e9c00..bf751d343 100644 --- a/docs/src/content/docs/reference/rest-api.mdx +++ b/docs/src/content/docs/reference/rest-api.mdx @@ -17,6 +17,8 @@ Authorization: Bearer Generate tokens through the admin interface or programmatically. +For post-deploy operational checks that separate EmDash API usage from Cloudflare platform tasks, see [Cloudflare Post-Deploy Operations](/runbooks/deployment/cloudflare-post-deploy-operations). + ## Response format All responses follow a consistent format. A successful response wraps the result in `data`: diff --git a/docs/src/content/docs/runbooks/deployment/cloudflare-post-deploy-operations.mdx b/docs/src/content/docs/runbooks/deployment/cloudflare-post-deploy-operations.mdx new file mode 100644 index 000000000..3683845d4 --- /dev/null +++ b/docs/src/content/docs/runbooks/deployment/cloudflare-post-deploy-operations.mdx @@ -0,0 +1,146 @@ +--- +title: Cloudflare Post-Deploy Operations +description: Separate EmDash content API operations from Cloudflare infrastructure actions after deployment. +--- + +import { Steps, Aside } from "@astrojs/starlight/components"; + +## Scope + +Use this runbook after `wrangler deploy` succeeds on a Worker that serves EmDash. + +It covers: + +- API verification and token-based access patterns, +- what to do for content workflows, +- what remains an infrastructure task outside of EmDash. + +## Why this matters + +EmDash's admin/content APIs are for **application data operations** only. All deployment and platform controls (`env`, `secrets`, `routes`, DNS, D1/R2 lifecycle) are handled by Cloudflare tooling. + +## Preconditions + +- EmDash worker URL is known (for example `https://my-emdash-site..workers.dev` or custom domain). +- At least one `Role.ADMIN` account can access the admin UI to generate API tokens. +- `curl` available for API checks. +- Cloudflare deployment credentials available (`wrangler login` already run) when doing infra actions. + +## Runbook + + + +1. **Smoke check deployment surface (no auth required)** + + Confirm the Worker answers and setup API is reachable: + + ```bash + BASE_URL="https://my-emdash-site..workers.dev" + curl -i "${BASE_URL}/_emdash/api/setup/status" + ``` + + Expect `200` with an `application/json` response containing `needsSetup`. + +2. **Get baseline API auth behavior for a known content endpoint** + + Confirm unauthorized access fails for protected operations: + + ```bash + curl -i "${BASE_URL}/_emdash/api/content/posts" + ``` + + Expect `401` when route is available (missing token/cookie). If your instance has not created the `posts` collection yet, you may get `404` instead. + +3. **Create and capture a Personal Access Token in the admin UI** + + - Open **Settings > API tokens** (`/_emdash/admin/settings/api-tokens`). + - Create a token with only the scopes needed for your integration. + - Export the raw token to your shell immediately (it is shown once): + + ```bash + export EMDASH_TOKEN="" + ``` + + A good first scope set for a publishing script is: + + - `content:read` + - `content:write` + - `media:write` + +4. **Re-check API with bearer token** + + ```bash + curl -H "Authorization: Bearer ${EMDASH_TOKEN}" \ + "${BASE_URL}/_emdash/api/content/posts" + + curl -X POST \ + -H "Authorization: Bearer ${EMDASH_TOKEN}" \ + -H "Content-Type: application/json" \ + -d '{"slug":"deploy-smoke","data":{"title":"Deploy smoke"},"status":"draft"}' \ + "${BASE_URL}/_emdash/api/content/posts" + ``` + + If POST returns `403`, the token is missing scope for the route. + If POST returns `400`, verify your payload includes a valid object under `data` (for example `{"data": {...}}`). + If you get `404`, confirm the collection exists and your token endpoint URL is correct. + +5. **Use tool endpoints when needed** + + MCP clients and automation that supports JSON-RPC can connect at: + + ```text + ${BASE_URL}/_emdash/api/mcp + ``` + + CLI usage should set `--url ${BASE_URL}` and `--token ${EMDASH_TOKEN}`. + +6. **Perform platform-level actions through Cloudflare control plane** + + Use Cloudflare dashboard or Wrangler for: + + - deploy/redeploy, + - secrets and bindings, + - DNS and custom domain changes, + - D1/R2 management and migrations, + - observability and log streaming. + + Treat these as separate from EmDash runtime API usage: + + ```bash + # Example: inspect runtime logs during an issue + wrangler tail + + # Example: update secret values + wrangler secret put EMDASH_ENCRYPTION_KEY + ``` + + + +## Escalation paths + +### If protected API calls return `404` + +This can mean setup has not completed or collection names are different. Re-run setup in admin and verify collection slugs. + +### If token operations return `401` + +Recreate the token and ensure `Authorization` header is exactly `Bearer ` (no quotes). + +### If deploy succeeds but API writes still fail + +Use platform logs first before changing application code: + +```bash +wrangler tail +``` + +If the worker logs show DB errors, check D1 binding names and migration state in `wrangler.jsonc` vs `emdash` config. + + diff --git a/docs/src/content/docs/runbooks/index.mdx b/docs/src/content/docs/runbooks/index.mdx new file mode 100644 index 000000000..42d9e9f3b --- /dev/null +++ b/docs/src/content/docs/runbooks/index.mdx @@ -0,0 +1,26 @@ +--- +title: Runbooks +description: Operational runbooks for platform upkeep, validation, and incident response. +--- + +Runbooks are the practical checklists behind this repo. They are intentionally concrete and command-driven so an agent or maintainer can execute the same sequence quickly. + +## Available runbooks + +- [Cloudflare Post-Deploy Operations](./deployment/cloudflare-post-deploy-operations): verify API access, token-based ops, and infrastructure handoff after deploy. + +## Purpose and maintenance rhythm + +These runbooks are written for: + +- fast recovery after regressions in behavior-critical paths, +- release prep where repeatable validation matters, +- onboarding scripts for new automation actors (including the Master-Orchestrator). + +Each runbook includes: + +- expected prerequisites, +- exact commands, +- success criteria, +- known failure modes, +- a short note on what to do when the environment is not clean.