Static Astro pages that call the agency-api Cloudflare Worker (D1-backed) to track 256 Shopify service-agency partners through the cold-intro → win lifecycle.
/studio/ — 256 rows, filter by status / tier / q, status
change auto-saves + logs activity. Click “open” to edit contact name, email,
notes. Side-drawer shows activity log + commission rows per agency./studio/templates — 3-step email sequence (cold intro →
+3d bump → +7d breakup) and 7 reply chips. Each chip is copy-to-clipboard.
Vietnamese hint for memory only; English snippet is what to paste into
Gmail./studio/demo — embedded Loom walkthrough. Same link goes into
every cold intro email. The recording checklist is on the same page./studio/commission — payout log (per agency × client
store × months counted × %). Add new entries; mark paid. Total paid /
pending appear at the top.npm install # one-time
npm run dev # http://localhost:4321
# Build static output (uses AOT compiler; not blocked by Windows AppLocker
# in our case since we're running under PowerShell 7+).
npm run build # static output in ./dist
Note: On this machine, the bundled
@astrojs/compiler-bindingnative module fails to load undernpm run build(Windows AppLocker blocks the.nodebinary). Workaround: build on the Vultr box (deploy.shalready runs there) — the AppLocker policy doesn’t apply on Linux.
src/data/studio-config.json:
{
"apiBase": "https://agency-api.ksentri.workers.dev",
"loomUrl": "https://www.loom.com/embed/<LOOM_ID>",
"senderEmail": "sam@ksentri.cloud",
"senderName": "Sam",
"company": "Packmate",
"companySite": "https://packmate.ksentri.cloud",
"gatePassword": "studio-letmein-2026",
"gateEnabled": true
}
Edit this file before npm run build to roll a new Loom recording or change
the Worker URL. The dashboard rehydrates against these values at build time.
bash deploy.sh
(deploy.sh is unchanged — it ships ./dist to /opt/ksentri/dist on the
Vultr box, where Caddy serves it at https://ksentri.com.)
MVP uses a ?key= query-password with sessionStorage to avoid re-asking
within the same tab. That covers accidental discovery; replace with Cloudflare
Access on a studio.ksentri.com subdomain before publicizing the URL.
See ../workers/agency-api/migrations/0001_init.sql. The pipeline tracks
state per agency; the commission log is keyed on agency_slug. PATCH
status and the activity row auto-logs status changes. POST
/api/agencies/:slug/activity timestamps first_contact_at,
last_action_at, and reply_at based on action class.
D:\bundle-master\private\outreach-agencies-next-steps.md lists the
prerequisites that must be wired before the first agency email can be sent
(Email Routing for sam-agencies@, reply-attribution in the existing
outreach engine, install-attribution so ROI can be measured).