Skip to content

Repo Layout & Deploy Targets

Where the code physically lives, where each piece is deployed, and which accounts own what.

The platform spans two GitHub repos and four deploy surfaces, and the source repo is not always the same as the account that hosts the deploy. This page maps it out so the question “where do I edit X and what does deploying it actually touch?” has a single answer.


Roam (ai-advisor, hosted by Roam HQ Inc.)
│ webhook
┌─── fcr-dashboard ── worker ──► fcr-dashboard-api.fcrmedia.workers.dev
│ (FCR4IE/DASHBOARD) (FCR Cloudflare)
│ │
│ ├── docs/ + docs-starlight/ ──► docs.fcrinsights.ie
│ │ (FCR Cloudflare Pages, project fcr-dashboard-docs)
│ │
│ └── services/image-normalizer/ ──► …--fcr-image-normalizer-fastapi-app.modal.run
│ (cathaldempsey Modal workspace)
└─── workflowlogo-repo ── studio/ ──► creator-studio-738.pages.dev
(DCathal/workflowlogo) (FCR Cloudflare)
└── workflows/imagegen.json ──► Creator — Image Gen
(source-of-truth) (fcrmedia n8n)

Two repos. Source in either FCR-owned or personal GitHub. Deploys hit FCR Cloudflare, fcrmedia n8n, and a personal Modal workspace.


  • Remote: github.com/FCR4IE/DASHBOARD
  • Local clone: ~/fcr-dashboard/
  • Owner: FCR org
SubtreeDeploys toDeploy command
worker/api.fcrinsights.ie (custom domain) + fcr-dashboard-api.fcrmedia.workers.dev + .cathaldempsey.workers.dev (dev mirror)scripts/ship.sh (auto) or scripts/deploy-worker.sh
docs/ + docs-starlight/ (Astro Starlight site; docs-starlight/nav.mjs is the single source of truth for what publishes)docs.fcrinsights.ie (FCR CF Pages project fcr-dashboard-docs)scripts/ship.sh (auto-detects docs changes) or scripts/deploy-docs-starlight.sh. Legacy deploy-docs.sh is retired — gated behind FCR_DOCS_LEGACY_ROLLBACK=1
services/image-normalizer/normalize.pyModal app fcr-image-normalizer (workspace cathaldempsey)modal deploy services/image-normalizer/normalize.py
.claude/skills/the slash-command catalogue (rendered into the docs site’s Skills page at build time)— (consumed by docs-starlight/scripts/sync-content.mjs)
scripts/ship.shthe canonical deploy orchestrator — routes worker + docs + reindex by what’s changed since the last tag
scripts/<pipeline>/local data pipelines, run by hand or by background drivers — prospect-resolve/ (Pleper/SerpAPI/crawl enrichment), opportunity-tier/ (20-Minute Market build), segment/, cro-match/, crawl-tail/, google-ads/, sitepro-websites/, snapsync-saymore/— (not deployed; they write to BQ)
dashboard.html + assets/fcrinsights.ie (apex) + fcr-dashboard-ui.pages.dev (FCR CF Pages project fcr-dashboard-ui, manual deploy — NOT GitHub-connected)npm run deploy (build + wrangler pages deploy dist --project-name=fcr-dashboard-ui --branch=production)

Anything that calls out to BQ / HubSpot / Teamwork / Ahrefs / SerpAPI / GBP / GA4 / Search Console / iovox / GMC lives in worker/src/handlers/. The advisor is worker/src/handlers/ai-advisor.js.

workflowlogo-repo — Studio + Creator n8n workflows

Section titled “workflowlogo-repo — Studio + Creator n8n workflows”
  • Remote: github.com/DCathal/workflowlogo
  • Local clone: ~/workflowlogo-repo/
  • Owner: personal GitHub (Cathal). Not under FCR4IE. See Ownership gaps worth closing.
FileDeploys toDeploy command
studio/index.htmlcreator-studio-738.pages.dev (FCR CF Pages project creator-studio)wrangler pages deploy studio --project-name creator-studio with CF_API_TOKEN_FCR
workflows/imagegen.jsonn8n workflow Creator — Image Gen (id K5OJSy8uI31UwTKl) on fcrmedia.app.n8n.cloudn8n REST PUT /api/v1/workflows/:id with N8N_API_KEY (surgical), or paste into the n8n UI
MIGRATION_GUIDE.mdreference for moving Creator workflows between n8n instances
Agents.mdagent-context doc for Studio

creator-workflow-restructure — local working dir (not a git repo)

Section titled “creator-workflow-restructure — local working dir (not a git repo)”
  • Path: ~/creator-workflow-restructure/
  • Migration scripts, backup JSONs of the Creator router/agent/pack-resolver/delivery workflows, and TODO.md (open bugs noted during the migration sprint, e.g. /edit-/remix-/reframe from non-reply context).
  • Not version-controlled. These are scratch files; the workflow JSONs that are source-of-truth live in workflowlogo-repo/workflows/.

1. Cloudflare Worker — fcr-dashboard-api

Section titled “1. Cloudflare Worker — fcr-dashboard-api”
FCR (prod)CD (dev mirror)
URLfcr-dashboard-api.fcrmedia.workers.devfcr-dashboard-api.cathaldempsey.workers.dev
CF AccountFCR Media Ltd (0481b38f86c96053c528ec08d7d7dddc)cathaldempsey personal (1ceb8928d441467855ece30aa22f8283)
Wrangler env--env fcr--env="" (top-level block)
API tokenCF_API_TOKEN_FCR in .env.localCF_API_TOKEN_CD in .env.local
Where Roam + HubSpot card call❌ (dev mirror only — never wired to real surfaces)

Both env blocks share the same worker/ source. scripts/deploy-worker.sh deploys to both, gates on a clean worker/ git state, and writes a deploy/worker/<timestamp>-<sha> tag pushed to origin. scripts/ship.sh is the recommended entry point — it also routes docs + reindex.

2. Cloudflare Pages — three projects, all on the FCR account

Section titled “2. Cloudflare Pages — three projects, all on the FCR account”
ProjectDomainSourceDeploy
fcr-dashboard-uifcrinsights.ie (apex) + fcr-dashboard-ui.pages.devfcr-dashboard/dashboard.html + assetsmanual — NOT GitHub-connected (source: null): npm run deploy (build + wrangler pages deploy dist). A git push alone does NOT update the dashboard
fcr-dashboard-docsdocs.fcrinsights.ie + fcr-dashboard-docs.pages.devdocs-starlight/ (Astro Starlight; nav.mjs maps docs/** + skill SKILL.md sources to pages)scripts/deploy-docs-starlight.sh (or ship.sh) — builds, deploys, reindexes Vectorize, tags deploy/docs/...
creator-studiocreator-studio-738.pages.devworkflowlogo-repo/studio/index.htmlwrangler pages deploy studio --project-name creator-studio (manual; no git auto-deploy)

The CF account holds all three Pages projects, but the project sources live in different git repos.

96 workflows tenant-wide, 64 in the Dashboard project (as of 2026-06-09 — see n8n Workflows for the authoritative inventory). The ones in the Creator stack (per the Creator/Studio migration memory):

WorkflowidSource-of-truth
Creator (router)6tHvygC2CupKlVyy— (n8n is the source)
Creator — AgentV70HT8Od6meZnHEb
Creator — Pack ResolverLyhB6IKzqGpllR07
Creator — Image GenK5OJSy8uI31UwTKlworkflowlogo-repo/workflows/imagegen.json (the only one with a committed JSON source)
Creator — DeliverywTMr3YZ1YEuRd8rH
Creator — Roam LinkHs0Klsc5Dr1ULVfj
Creator — Yext Gallery9r168h632Cw0M9HL

API token (N8N_API_KEY in .env.local) authorises surgical PUT /api/v1/workflows/:id edits. See docs/n8n-workflows.md for the broader workflow inventory.

  • URL: https://cathaldempsey--fcr-image-normalizer-fastapi-app.modal.run
  • Modal workspace: cathaldempsey (personal — see Ownership gaps)
  • Source: fcr-dashboard/services/image-normalizer/normalize.py
  • Deploy: modal deploy services/image-normalizer/normalize.py (after modal token new once)
  • Endpoints: POST /normalize (called by worker hydrateUserImages/hydrateHubspotImages), POST /composite (called by the n8n Composite Images node), GET /health
  • Secrets: two Modal secrets, image-normalizer (carries FCR_NORMALIZER_TOKEN used by the worker) and image-normalizer-n8n (carries FCR_N8N_TOKEN used by n8n). Either authenticates either endpoint — the split is rotation-isolation.

roam advisor HubSpot card iframe
│ │
└─────────────► dashboard-ai-advisor (worker)
┌───────────────┼───────────────────────┐
▼ ▼ ▼
BQ / HubSpot / open_studio tool generate_image
Teamwork / etc. ─── JWT link ──► tool
creator-studio-738 │
(Studio app) ▼
│ creator-image-gen gateway (worker)
│ │
│ ▼
└───── HTTP POST ──► fcrmedia n8n
/webhook/Creator700
Creator router → Image Gen → Composite Images
Modal /composite
└── Modal /normalize ◄── worker hydrateUserImages
(HEIC/AVIF fallback)

Practical: Studio is the only piece in the personal GitHub repo. Everything else (worker, docs, Modal source, dashboard UI) is in FCR4IE/DASHBOARD. The n8n workflows are in n8n itself; only Image Gen has a JSON twin in workflowlogo-repo/workflows/.


Where the deploy lever lives for each change

Section titled “Where the deploy lever lives for each change”
You want to change…Edit in…Deploy with…
The advisor’s tools, prompt, hydrate logic, etc.fcr-dashboard/worker/src/handlers/ai-advisor.jsscripts/ship.sh
A worker route or composite endpointfcr-dashboard/worker/src/handlers/<file>.jsscripts/ship.sh
A docs page (or add a new one)fcr-dashboard/docs/<page>.md + nav entry in scripts/build-docs-site.mjsscripts/ship.sh (auto-routes to docs)
A skill’s behaviour or argsfcr-dashboard/.claude/skills/<name>/SKILL.mdgit commit + scripts/ship.sh (docs page regenerates)
The dashboard UIfcr-dashboard/dashboard.html (+ assets)git push (Pages auto-deploys)
The Studio frontendworkflowlogo-repo/studio/index.htmlwrangler pages deploy studio --project-name creator-studio (FCR CF)
The Creator — Image Gen workflowworkflowlogo-repo/workflows/imagegen.json AND live n8n (PUT or UI)n8n REST PUT or paste in UI
Modal /normalize or /compositefcr-dashboard/services/image-normalizer/normalize.pymodal deploy …/normalize.py
A Modal secret (e.g. rotate FCR_NORMALIZER_TOKEN)modal secret create image-normalizer FCR_NORMALIZER_TOKEN=… --force + corresponding wrangler secret put IMAGE_NORMALIZER_TOKEN on both worker envs

For the worker-secret rotation step: wrangler secret put --env="" doesn’t work for the CD/dev env — omit --env entirely and pass CLOUDFLARE_ACCOUNT_ID=1ceb8928… explicitly. --env fcr is normal.


A few pieces of the platform live in personal accounts, not under FCR org control. Production touches FCR Cloudflare + fcrmedia n8n in every case, but the source / Modal compute is personal. If the maintainer changes, these would need transfer to remain accessible:

  • github.com/DCathal/workflowlogo — Studio frontend + Image Gen workflow JSON. Should be transferred to FCR4IE (or mirrored into fcr-dashboard as a studio/ subtree).
  • cathaldempsey Modal workspace/normalize + /composite run on a personal Modal account. Should be moved to an FCR Modal org workspace if one is created.

Neither blocks day-to-day work; both are organisational hygiene for handover/continuity.


Studio was a personal experiment (Creator/Studio migration onto the FCR stack, 2026-05-25) that proved out and moved its deploy targets (CF Pages, n8n, R2) onto the FCR stack — but the source repo didn’t migrate with the deploys. Same for Modal: chosen for time-to-ship (scale-to-zero, single-file deploy), but the workspace is personal because that’s whose Modal account was set up.

The deploy outcome is correct (everything runs on FCR infrastructure that the team controls). The source ownership is the residual cleanup.

Ask the docsRAG over this site
Ask anything about the FCR Dashboard platform — architecture, BigQuery, the worker routes, billing rules, the LRC stack, scoring… Answers are grounded in this documentation, with source links.
How does the deal-brief refresh work? Which routes are Worker vs n8n? How is account health scored?