Documentation
Start

Project Overview

What FPM Client Hub / FPM Client Portal is, who uses it, and what problem it solves.

A quick note on naming

Internally the codebase is called FPM Client Hub. Externally — what the client sees, what we link to in proposals — it is called the FPM Client Portal (Flooring Pros Marketing). Same product, two names. Treat the two as interchangeable when reading these docs.

Mission

The FPM Client Portal is a white-label, per-client web application that serves as the single source of truth for every active client relationship. It replaces spreadsheets, email threads, Slack DMs, WhatsApp messages, and disconnected reporting tools with one branded, bookmarkable URL that the client uses throughout their entire program — from onboarding through growth and scale.

What problem does this solve?

  • Clients don't know what we're working on without a weekly call.
  • Approvals happen over email, Slack, WhatsApp and calls — never in one place.
  • Reporting is scattered across Looker Studio, GHL, SE Ranking and Local Dominator.
  • There's no structured way to onboard clients into the program and set expectations.
  • Action items from calls get lost — no permanent record of what was agreed.
  • Clients can't easily see the wins and proof of work accumulating over time.

Who uses it?

UserRole in the portal
Client (owner / stakeholder)Reads updates, approves deliverables, submits requests, books calls, views KPIs.
Chesney — Account ManagerAdds meeting notes, manages deliverables, responds to requests, sends weekly recap.
Kenan — Head of FulfillmentManages deliverable pipeline, marks items ready for review, closes requests.
Client Revenue Strategist (CRS)Currently hiring. Adds game plan updates, scorecard scores, wins, meeting summaries.
Dan — CMO / Co-founderFull admin access. Oversees all portals, adds strategy content, owns the roadmap.
Aniello — Engineering / DataOwns the codebase, the deployment, and the data integrations. The repo lives in Aniello's GitHub account.

Access model

  • Each client gets a unique URL: clients.flooringpros-marketing.com/[client-slug].
  • Client login is required — the URL is the access control. Visiting the URL without a session redirects to /login.
  • The FPM team accesses an admin overlay on the same URL — same screen the client sees, plus internal fields and edit controls.
  • The admin overlay shows internal fields, editing pencils, raw integration data, and detail tabs (Paid Marketing, Social, Website, SEO, Local SEO, Email/SMS, Calculated KPIs) that the client never sees.
Why URL = access
Each client portal is bound to a profiles.client_id. The middleware checks the logged-in user's profile and forces the URL to that client. Sharing your URL with another client's user does not leak data — they will be redirected to their own portal.

Three hubs in the per-client portal

Inside /dashboard/clients/[id] the layout is a sticky black HubNav at top with three switchable hubs. State is in the URL via ?hub=client&tab=home so admins can deep-link to any view.

HubAudiencePurpose
Client HubAdmin + ClientRelationship, strategy, accountability. Sub-tabs: Home, Onboarding, Scorecard, Game Plan, Deliverables, Wins & Progress, Content & Authority, Meeting Notes, Resources & Docs, Billing & Package.
ReportingAdmin only (today)Performance data. Sub-tabs: Reporting Home, Pipeline Overview, Website Performance, SEO & AEO Performance, Paid Ads, Social Media, Email & Automation. The previous top-level admin tabs all live here.
Client InfoAdmin + ClientSingle-page bento grid of company metadata — primary contact, address, domain & hosting expirations, brand assets, social, billing, notes. Admin pencils to edit; client read-only.

Surface area (technical)

  • /login — Supabase email/password.
  • /dashboard — admin home (client list).
  • /dashboard/clients/[id] — the FPM Client Portal for one client. Three hubs as above. This is where 95% of usage happens.
  • /dashboard/clients/[id]/edit — admin-only client config form (integrations, branding, logo upload).
  • /settings — user profile and global integration toggles.
  • /documentation — this internal documentation site.
  • Admin everywhere — dark #202020 sidebar stays visible on every /dashboard/* route, including the per-client portal, so admins can hop between clients without leaving the view. Each client row has a pencil icon (visible on hover) that jumps directly to the edit page.
  • Client on the per-client portal — sidebar hidden, full-bleed layout. They only ever see their own portal.
  • Stripped admin nav — Overview / Dashboard / Analytics / Reports / Settings rows are gone. The sidebar is now just the Web Clients list + user profile (with Settings inside the profile menu).

Data flow summary

At a high level: the browser renders a client portal component. That component fires a parallel set of fetch() calls to /api/metrics/* endpoints. Each endpoint reads the connected integration from Supabase, calls the upstream API with the appropriate OAuth token, normalises the response and returns a JSON payload. The component renders the data into MetricCard rows.

For external sources we cannot OAuth into directly (n8n, DataForSEO when budget is tight), data is pushed to /api/metrics/external via a webhook and cached in Supabase. The frontend reads from the cache the same way as a live source.

See: Data Flow
The full diagram, including which integrations are pull vs push, is in the Data Flow page.

Where we are right now

As of the last review (May 2026):

  • live Google Analytics 4, Search Console, Google Business Profile (Performance API), Google Business Profile reviews (Places API), YouTube Data API, PageSpeed Insights, GoHighLevel.
  • partial Google Ads (scope added, requires per-client re-auth), Meta Ads (account ID flow exists), DataForSEO (only via n8n proxy).
  • pending Microsoft Clarity, Windsor.ai connectors, n8n outbound metrics for email/SMS.
  • planned SE Ranking replacement, Local Dominator integration.

The canonical reference for status is the Where We Are page.

Vocabulary

TermMeaning
FPM Client HubInternal name for this codebase.
FPM Client PortalExternal / product name. Same thing.
ClientA row in the clients table — represents one of our customers.
IntegrationA row in the integrations table connecting a client to an external API. We have agency-level Google integrations (one OAuth token serves every client) and per-client integrations (GHL, Meta).
SourceThe 3-letter tag shown on each metric row indicating where the data came from (GA4, GSC, GBP, GHL, n8n, etc.).
MetricCardThe React component that renders a card with a title and a list of metric rows. Auto-hides rows with no data and the entire card if all rows are hidden.
PipelineThe GHL CRM pipeline. Leads → Appointments Booked → Showed → Quoted → Won.
ext()Helper inside ClientDashboard that reads a key from the externalData webhook cache.
n8nWorkflow automation tool we use to push aggregated metrics into the dashboard from sources we cannot pull directly.
Admin overlayThe same per-client URL viewed by an FPM team member with admin role — adds edit controls and internal-only tabs.