# Cloud Setup — for Claude Code

> **What this is:** the cloud upgrade for your Operating System. You started with the dashboards saved locally; this puts them on your own cloud so they sync across every device and browser — and can be shared with your team later. Everything lives on **your** accounts: your Supabase (the data) and your Framer site (the pages). Nobody else hosts anything.
>
> **The promise:** you don't write code, copy keys, or run SQL. You connect two things once, paste this in, and Claude Code does the build.
>
> **How to use it:** open **Claude Code** in the folder with your six dashboards, make sure the **Supabase** and **Framer** connectors are on (one-time setup below), then paste everything under the line and say *"set up my cloud OS."*

---

## ONE-TIME SETUP — connect your two accounts (~5 min)
This is your system on your own infrastructure. Two connectors do the work — one for your data, one for your pages. Both accounts are free and worth having.

**1. Supabase — your data.**
- Create a free account at https://supabase.com
- Connect it to Claude Code. Easiest: add it from Claude Code's connector list and sign in to Supabase when prompted. (CLI alternative: `claude mcp add --transport http supabase https://mcp.supabase.com/mcp`, then authenticate.)
- Nothing to copy or paste by hand — once you're signed in, Claude Code can create your project and write your keys for you.

**2. Framer — your pages.**
- Use your existing Framer site, or create one at https://framer.com
- In your Framer project, install the **MCP** plugin: https://www.framer.com/community/marketplace/plugins/mcp/
- **Run the plugin** — it generates a connection link. Copy it.
- Add that link to Claude Code as a connector (Settings → Connectors → Add custom connector → paste the link; or CLI: `claude mcp add --transport sse framer <paste-the-link>`).

**Check both are on:** in Claude Code, ask *"list my Supabase projects and my Framer pages."* If it returns them, you're ready.

Once both are connected, Claude Code sets up your database, writes your keys, and builds the gated pages on your Framer site — you never touch keys or code.

---

## ROLE
You are a setup engineer with the **Supabase** and **Framer** MCP connectors available. You're turning a business owner's six local Operating System dashboards into a private, synced cloud version that lives entirely on **their own** accounts: their Supabase for data, their Framer site for the pages. You host nothing for them. The owner must never copy a key, run SQL, or edit code — you do all of it through the connectors. Confirm before any billable action; use free tiers.

## CONTEXT — the files in this folder
- Six dashboards: `seed-of-life.html`, `vision-doc-dashboard.html`, `org-chart.html`, `golden-section-dashboard.html`, `scoreboard.html`, `problems.html`.
- **The Hub:** `os-hub.html` — the branded front-door page with a visual card for each of the six systems. Its cards link out to the dashboards (placeholder relative links for now). This becomes the owner's `/os` landing page.
- `sfb-config.js` — **the only file that holds the keys.** Every dashboard loads it; you write the keys here.
- `sfb-storage.js` — the storage engine. With keys present, it signs the user in with **email + password** and syncs their data to Supabase; with no keys it's local-only. **Never modify.**
- `sfb-export.js` — export engine. **Never modify.**

Your job: stand up the owner's Supabase backend (data), wire `sfb-config.js`, and deploy the six dashboards **plus the Hub** (`os-hub.html`) as gated pages on the owner's Framer site — with the Hub as the `/os` front door that links to each dashboard. Two connectors, two halves: **Supabase = the data, Framer = the host.**

## INSTRUCTIONS

### Part A — Supabase (the data backend)

**A1. Confirm the Supabase connector** (e.g. list projects). If it's not connected, point the owner to ONE-TIME SETUP and stop.

**A2. Create or pick the project — YOU do this.** Use an existing one if it fits; otherwise create a new free-tier project (confirm cost if required; name it e.g. "My Business OS"). Wait until ready.

**A3. Set up the database — YOU do this.** Apply this migration: the documents table, row-level security (each user sees only their own rows), and an auto-confirm trigger so email+password signup works instantly with no confirmation email.

```sql
create table if not exists public.documents (
  user_id    uuid not null references auth.users(id) on delete cascade,
  doc_type   text not null,
  data       jsonb,
  updated_at timestamptz default now(),
  primary key (user_id, doc_type)
);
alter table public.documents enable row level security;
create policy "read own documents"   on public.documents for select using (auth.uid() = user_id);
create policy "insert own documents" on public.documents for insert with check (auth.uid() = user_id);
create policy "update own documents" on public.documents for update using (auth.uid() = user_id) with check (auth.uid() = user_id);
create policy "delete own documents" on public.documents for delete using (auth.uid() = user_id);

create or replace function public.sfb_auto_confirm()
returns trigger language plpgsql security definer as $$
begin
  new.email_confirmed_at = coalesce(new.email_confirmed_at, now());
  return new;
end; $$;
drop trigger if exists sfb_auto_confirm_trigger on auth.users;
create trigger sfb_auto_confirm_trigger
  before insert on auth.users for each row execute function public.sfb_auto_confirm();
```

Confirm it applied. (Fallback if the auth.users trigger is blocked: Authentication → Providers → Email → turn OFF "Confirm email." Only mention if needed.)

**A4. Write the keys — YOU do this.** Fetch the project **URL** and **publishable key** (`sb_publishable_...`). Write both into `sfb-config.js`, changing nothing else. The owner never sees them.

```js
window.SFB_SUPABASE_URL      = "<fetched automatically>";
window.SFB_SUPABASE_ANON_KEY = "<fetched automatically — the sb_publishable_ key>";
```

### Part B — Framer (the host)

**B1. Confirm the Framer connector** (list pages/components). If not connected, point to ONE-TIME SETUP and stop.

**B2. Deploy the six dashboards — YOU do this.** Create one private/gated page per dashboard on the owner's Framer site (e.g. `/os/seed-of-life`, `/os/vision`, `/os/org-chart`, `/os/golden-section`, `/os/scoreboard`, `/os/problems`) and embed each dashboard, keeping its branding and the SFB footer. Note each page's published URL — you'll wire them into the Hub next.

> **Builder note — known gotcha (do this right the first time):** a Framer embed renders the dashboard in an isolated frame where **relative `<script src="sfb-config.js">` / `sfb-storage.js` / `sfb-export.js` do NOT resolve** — they fail silently and the dashboard falls back to local-only with no sign-in. So when embedding, either (a) reference those three helper files by **absolute URLs** the frame can load, or (b) inline the config + storage so the Supabase client initialises inside the frame. Verify after embedding that the sign-in actually appears and a write reaches Supabase — don't assume.

**B3. Build the Hub front door at `/os` — YOU do this.** Stand up `os-hub.html` as the `/os` landing page (recreate it as a Framer page, or embed it the same way as the dashboards). It's the branded grid with a visual card for each of the six systems, plus the *How they interlock* section and the *Run it with Claude* block. Gate it the same way. This is the screen the owner lands on — their whole business, one page. **Every link on it (and on the dashboards) is a placeholder — you wire them all in B4.**

**B4. Wire every link — DO NOT SKIP.** All seven pages ship with **placeholder relative links** (e.g. `seed-of-life.html`). They work locally, but on Framer each page lives at its own URL, so every link must be repointed to the live Framer URL. Build this mapping once from your B2/B3 pages, then apply it everywhere:

| Placeholder in the HTML | → Framer page URL |
| --- | --- |
| `os-hub.html` | the `/os` Hub page |
| `seed-of-life.html` | `/os/seed-of-life` |
| `vision-doc-dashboard.html` | `/os/vision` |
| `org-chart.html` | `/os/org-chart` |
| `golden-section-dashboard.html` | `/os/golden-section` |
| `scoreboard.html` | `/os/scoreboard` |
| `problems.html` | `/os/problems` |

Apply the mapping in **two places**:
- **The top-left Operating System menu** — present on *every* page (Hub + all six dashboards). Replace all seven `href`s in each page's menu so the owner can jump between docs from anywhere.
- **The Hub only** — the six **card** links (same filenames) and the **Open my Claude Project** button (`href="#"`, attribute `data-claude-project`) → set to the owner's Claude Project URL (ask them; leave it off if they don't have one yet).

Do a literal find-and-replace of each filename string in each file **before/at embed time**. When done, **no `.html` filename should remain in any `href`** across the deployed pages.

**B5. Publish** the Framer site so the pages go live.

### Verify
Owner opens their Framer `/os` Hub → taps a system card → that dashboard opens → signs in with email + password (first time creates the account) → adds something → opens the same dashboard on a second device/browser, signs in with the same details → the data is there. **Link check:** open the top-left menu on at least two different pages and click through every item, and click every Hub card — each must land on the right live Framer page (no raw `.html`, no 404). Confirm the links AND sync before declaring done.

## DONE WHEN
The owner's Hub (`/os`) and six dashboards are live on their own Framer site, gated, synced through their own Supabase, signed in by email+password — the Hub links to each dashboard, and nothing was touched by them (no key, code, or SQL) and nothing is hosted by anyone else. Next is the **Operating Flow** — putting the dashboards to work each week.

## TROUBLESHOOTING
- **Claude can't see the Framer project** — the connector is off for this chat, or the plugin link expired. Re-run the Framer MCP plugin to generate a fresh link and reconnect.
- **Built it but changes aren't live** — Framer edits land in the editor first. **Publish** the site to push them live.
- **Sign-in throws an error in the embed** — almost always the relative-script gotcha in B2. Make sure the embed loads `sfb-config.js` / `sfb-storage.js` by absolute URL or inline, not a relative `<script src>`.

## GUARDRAILS
- Everything through the two connectors. The owner does not copy keys, write SQL, or edit code.
- Only `sfb-config.js` gets written to. Never modify `sfb-storage.js` or `sfb-export.js`.
- Use the **publishable** key only — never the service-role key or DB password.
- Data lives in the owner's Supabase; pages live on the owner's Framer. You host nothing.
- Confirm before any billable action; default to free tiers.
