Deploy — Distribution-Vault auf Cloudflare-Pages
Push-and-forget. Du editierst Distribution/, pushst zu GitHub, Cloudflare baut + deployed automatisch. ~15min One-Time-Setup.
Was du dazu brauchst
| Was | Free? | Account-Link | |
|---|---|---|---|
| 1 | GitHub Account | ✓ | https://github.com/signup |
| 2 | Cloudflare Account | ✓ | https://dash.cloudflare.com/sign-up |
| 3 | Node 22+ lokal | ✓ | (haben wir schon — 23.3.0 läuft) |
Optional: eigene Domain (z.B. distribution.a-friend.ai) — geht später, nicht nötig für Launch.
Step 1 — GitHub Private Repo (one-time)
afriend-business hat noch kein Remote. Push als private Repo:
# in afriend-business root
gh repo create afriend-business --private --source=. --remote=origin --pushoder via Web-UI:
- https://github.com/new → name
afriend-business, Private, kein README/.gitignore (haben wir schon) - Locally:
git remote add origin git@github.com:<your-handle>/afriend-business.git git push -u origin main
Wichtig: Repo MUSS private bleiben — afriend-business enthält AD-Strategy + Marco-Notes + sensitive Biz-Daten. Cloudflare-Pages funktioniert trotzdem (es liest privat via OAuth-Connect).
Step 2 — Cloudflare-Pages Project (one-time)
- https://dash.cloudflare.com → Workers & Pages → Create application → Pages → Connect to Git
- Authorize Cloudflare GitHub-App → select
afriend-businessrepo - Build configuration:
- Project name:
a-friend-distribution→ wird zuhttps://a-friend-distribution.pages.dev - Production branch:
main - Build command:
cd Distribution && npm --prefix _quartz install --no-engine-strict && node _scripts/build.mjs - Build output directory:
Distribution/_quartz/public - Root directory (advanced): leave empty (Cloudflare runs from repo root)
- Project name:
- Environment variables (Production + Preview):
SITE_BASE=https://a-friend-distribution.pages.dev(used byemit-ics.mjsfor VEVENT URL field)NODE_VERSION=22
- Save and Deploy → first build runs (~3-5min)
Step 3 — Apple-Calendar subscribe (per device, one-time)
Mac:
- Calendar.app → File → New Calendar Subscription
- URL:
https://a-friend-distribution.pages.dev/calendar.ics - Auto-refresh: Every 15 minutes
- Color: brown/warm
- Subscribe
iPhone:
- Settings → Calendar → Accounts → Add Account → Other → Add Subscribed Calendar
- Server:
https://a-friend-distribution.pages.dev/calendar.ics - Save — events appear in Calendar.app
Step 4 — Share with Daniel (one-time)
Send him two links:
Backlog + Strategy + Doctrine:
https://a-friend-distribution.pages.dev/
Calendar subscribe (iPhone — paste in Safari, hit subscribe):
webcal://a-friend-distribution.pages.dev/calendar.ics
Daniel-Setup:
- Bookmark first URL on phone Home-Screen
- Tap second URL in Safari → Apple Calendar opens → confirm subscription
- Events show in his Calendar — each event has URL → tap opens backlog-entry page
Working day-to-day
# add a Backlog entry (Obsidian or any editor)
vim Distribution/Backlog/2026-06-03-b1-hardware-deep-dive.md
# locally verify ics is right
node Distribution/_scripts/prebuild.mjs
# push → Cloudflare auto-rebuilds in ~60s
git add Distribution/ && git commit -m "BACKLOG +b1 hardware deep dive" && git pushDaniel sees the new event in Apple-Calendar within 15min (refresh interval).
Custom Domain (optional, anytime later)
CF-Pages → Project → Custom Domains → Add distribution.a-friend.ai → CF auto-creates DNS-CNAME. URL flips to https://distribution.a-friend.ai/.
Update SITE_BASE env var → re-push → ICS now points at custom domain.
Troubleshooting
Build fails on “npm error EBADENGINE”:
Check Build-Cmd uses --no-engine-strict (Quartz requires npm 10.9.2+, CF runs older sometimes).
calendar.ics 404 in CF deploy:
Check Distribution/_quartz/public/calendar.ics exists post-build. Run node _scripts/build.mjs locally and verify.
Apple-Cal doesn’t refresh: Setting → Mail → Accounts → Subscribed Calendar → set “Fetch New Data” to 15min. Default may be “Manually”.
Daniel sees old event:
Cache. Apple-Cal honors Cache-Control: max-age=300 set in _headers. After 5min he sees updated.
Roll-back
Want to undo a deploy? CF-Pages dashboard → Deployments → pick prior → Rollback to this deployment. Instant.
File map
Distribution/
├─ _scripts/
│ ├─ build.mjs ← entry-point (prebuild + quartz + post-copy + headers)
│ ├─ prebuild.mjs ← sync-doctrine + sync-scripts + emit-ics
│ ├─ sync-doctrine.mjs ← afriend-script-pool + content-extraction → Doctrine/
│ ├─ sync-scripts.mjs ← onari content-pool/scripts → Scripts/
│ └─ emit-ics.mjs ← Backlog/ frontmatter → calendar.ics
├─ _quartz/ ← gitignored node_modules; tracked: config, plugins
│ ├─ quartz.config.ts ← A Friend palette + content-symlink + ignore-patterns
│ ├─ quartz.layout.ts ← (Quartz-default)
│ └─ public/ ← gitignored build output
└─ (vault content folders)