| File | Purpose |
|---|---|
review.html |
The gated review page. Runs standalone in mock mode right now — open it and try the full loop (sign in as reviewer, suggest an edit, sign in as owner, approve it). |
framework.json |
Your framework as structured data: 13 disciplines, 164 cells extracted directly from the live site's data-id/data-tip attributes — real tooltips, the site's own stable cell IDs, correct tactical/strategic zones, plus links (predecessor/successor) and how fields reserved for the future dimension. |
extracted.json |
Raw extraction from the live DOM (kept as a reference snapshot). |
Before going live: the predecessor/successor relations aren't in framework.json yet — they live in your page's JS, not in cell attributes. Send me the page source (or the relation map) and I'll merge them into links.
Public page (static) Review page (gated) n8n
rightbrained.cloud ←reads─ review.rightbrained.cloud ─POST→ webhooks
↑ │
framework.json ←──────── publish on approve ──────────────────┤
│
DB (Supabase/NocoDB/Airtable)
suggestions + allowlist + sessions
The public page and review page both render from the same framework.json. Reviewers never edit the page — they submit suggestions; approval merges into the JSON and republishes.
- Redirect to LinkedIn OIDC (
https://www.linkedin.com/oauth/v2/authorization) with scopesopenid profile email. Create the app at developer.linkedin.com and enable the "Sign In with LinkedIn using OpenID Connect" product — it's self-serve, no partner review. - Callback node exchanges the code, calls
https://api.linkedin.com/v2/userinfo→{name, email, picture}. - Allowlist check (the actual gate): look up the email in your
inviteestable. Miss → friendly "request access" page that notifies you. Hit → issue a session: signed JWT in an HttpOnly cookie (or a random token stored in asessionstable), then redirect toreview.html. review.htmlchange for live mode: setCONFIG.mockMode = false; the Sign in button then redirects to this webhook.
Validate session → insert row into suggestions (cellId, type, proposedLabel, proposedTooltip, comment, user, ts, status=pending) → notify you (email or Slack) with the diff and one-click approve/reject links (n8n Wait-for-Webhook or links to workflow 4).
Validate session → return suggestions (reviewers see their own + statuses; you see all).
Owner-only. Set status → if approved and type=edit, merge into the canonical framework.json → push to your static host (commit to the repo, or upload to the bucket/Netlify via API). Tip: stage approvals and publish in batches as versioned releases (v3.3, v3.4) instead of live-publishing every click — keeps the public page stable and gives you release notes to post on LinkedIn.
Full schema in schema.sql — run it once in the Supabase SQL Editor. Setup:
- Create a project at supabase.com (free tier is plenty).
- SQL Editor → paste
schema.sql→ Run. This createsinvitees(the allowlist — you're seeded as owner),sessions,suggestions,framework_versions, pluspending_queueandcontributorsviews, with RLS locked so only the service key can read/write. - Project Settings → API → copy the service_role key and URL into an n8n Postgres/Supabase credential. Never put this key in the browser — review.html only ever talks to n8n.
- Each workflow's exact SQL is commented at the bottom of
schema.sql, including the rate-limit check.
Manage invites by inserting rows into invitees (Supabase Table Editor works fine as the UI for this).
- Gate = allowlist, not OAuth. LinkedIn only proves identity; the allowlist grants access.
- Sanitize all submitted text server-side too (the page already renders user text as plain text, never HTML).
- Rate-limit the submit webhook (n8n: simple count-per-session check) to stop spam.
- Webhook URLs are guessable — every endpoint must validate the session, not just the UI.
- Serve
review.htmlfrom a separate path/subdomain that isn't linked from the public page.
Already modeled. Each cell carries:
"how": { "processGuide": null, "useCases": [] }When ready: the review panel gets a third tab ("Suggest a process guide"), the public page gets a click-to-expand view per cell, and the same suggest→approve pipeline handles it with zero backend changes — it's just two more fields in the diff. This is the payoff of moving content into structured data: new dimensions are fields, not pages.
- Verify/correct
framework.jsonagainst your source (or send me the page source for exact extraction, tooltips included). - Refactor the public page to render from
framework.json(small JS change; markup stays identical). - Stand up the 4 n8n workflows; flip
CONFIG.mockModeto false. - Add a visible "Reviewed by" credits strip with LinkedIn profile links — it's the incentive for contributors and feeds traffic back from LinkedIn.