Business Owner Access & Reporting

End-to-end workflow for the EP043 business owner access level. An admin creates a per-client owner token; the owner authenticates with it on their site, gains access to the chat widget, widget reporting, and a new aggregated website tracking dashboard.

Backend at shared-website-assistant-api. Deployed lineage has since moved well past cc6fd5d2 — production was found (2026-08-11 forensics) actually running 113ba608, and master has since been reconciled to aa50542d (pending the service's next redeploy cycle; see EP043_thetechprinciple_widget_rollout_and_lead_capture_workflow.html for the full account). Admin routes at /api/admin/owners; owner routes at /api/owner/reporting and /api/owner/reporting/tracking.

Click any node for its detailed plan — steps, completion test, evidence and dependency.

Lane 1 — Admin: create site + business owner

Actor: admin · runs once per generated site

Lane 2 — Owner: site access and dashboard

Actor: business owner · authenticated via Bearer token

Lane 3 — Aggregated website tracking report

Actor: tracking system · captures and aggregates per-session data

Lane 4 — Subscription model

Actor: admin + system · business owner access tier gating

Lane 5 — Promotion response (sub-process)

Actor: business owner · responds to popular services with time-limited offers

API contract — business_owner endpoints

All endpoints deployed on shared-website-assistant-api. Deployed lineage has since advanced well past cc6fd5d2 — see the header note above for the 2026-08-11 master reconciliation.

POST /api/admin/owners
  Auth: ADMIN_TOKEN
  Body: { "clientId": "client_key" }
  Response: { clientId, ownerToken, businessName, message }
  Note: Token shown once — must be saved to Render env var

GET /api/admin/owners
  Auth: ADMIN_TOKEN
  Response: { owners: [{ clientId, tokenPresent, businessName }] }

GET /api/owner/reporting?tenant=<id>
  Auth: Bearer <owner_token> (or legacy console token)
  Response: { clientId, businessName, pageAnalytics, summary, performance }

PUT /api/owner/reporting/tracking?tenant=<id>
  Auth: Bearer <owner_token> (or legacy console token)
  Body: { "analyticsEnabled": true|false }
  Response: { clientId, analyticsEnabled, message }

Sub-process: Promotion Response Workflow →

Aggregated tracking report structure

The tracking report provides the following data to the business owner:

  • Pages accessed — List of pages visited, with visit count per page and timestamp of first/last visit.
  • Functions accessed / buttons clicked — Per-page breakdown of which features were interacted with (chat widget opened, CTA buttons clicked, form submitted) with timestamps.
  • Services accessed — Which services were viewed, booking links clicked, or callbacks requested, with timestamps.
  • Timestamp of each event — Every recorded event carries its creation timestamp. The report presents them in chronological order per category.

Tracking report — pageAnalytics shape

{
  "uniqueVisits": 42,
  "pageViews": 156,
  "engagedPct": 64,
  "ctaClicks": 28,
  "mostVisitedPages": [
    { "url": "index.html", "views": 48, "lastVisit": "2026-08-08T10:22:00Z" },
    { "url": "services.html", "views": 37, "lastVisit": "2026-08-08T10:15:00Z" }
  ],
  "buttonClicks": {
    "cta_book_now": 12,
    "chat_widget_open": 8,
    "callback_request": 5,
    "service_view": 15
  },
  "serviceRequests": {
    "Boiler servicing": 6,
    "Emergency repairs": 4,
    "Annual inspection": 3
  },
  "eventsTimeline": [
    { "type": "page_view", "url": "services.html", "timestamp": "2026-08-08T10:10:00Z" },
    { "type": "button_click", "target": "cta_book_now", "timestamp": "2026-08-08T10:11:00Z" },
    { "type": "service_request", "service": "Boiler servicing", "timestamp": "2026-08-08T10:12:00Z" }
  ]
}
Data is aggregated, not per-visitor. The owner sees counts and rates only, never raw per-visitor rows. This matches the same anonymity contract as the analytics ingestion system — the business owner learns what their visitors did as a population, but cannot identify individuals.
Tracking is opt-in per-client. If analyticsEnabled is false for a client, the reporting endpoint returns {"status": "tracking_disabled"} instead of analytics data. The owner can toggle this on/off via PUT /api/owner/reporting/tracking.

Auth model — two-tier owner verification

  • Admin — full platform access via ADMIN_TOKEN env var. Can create clients, list all data, create owner tokens.
  • Business owner — per-client access via token stored in BUSINESS_OWNER_TOKENS_JSON env var. Can only access their own tenant's reporting and tracking. Created by admin only.
  • Legacy owner console — backward compatible via OWNER_CONSOLE_TOKENS_JSON and OWNER_CONSOLE_TOKENS_JSON_BATCH_01. Both new and legacy tokens work via anyOwnerAuthorized().
Token distribution model. The admin generates a token via POST /api/admin/owners and receives it once. The token must be saved into the BUSINESS_OWNER_TOKENS_JSON Render env var and the service redeployed. After that, the business owner uses their token to call the owner API endpoints. The token is never stored in the application database — only in the Render env var, making token revocation a deploy-level action.