NFTY™ Universal CE Compliance · Technical Handoff

The NBos Systemwhat stays native, what must move.

An evaluation of the existing CE compliance automation system — identifying which pieces can live entirely inside your agency account, and which pieces need a standalone web app to replace the external webhooks, Make Data Stores, and Google Apps Scripts.

5

components stay native

4

move to the NBos web app

4

hybrid — GHL + web app

Scroll for the full system map, plain-language explainer, and migration plan.Open the provider console+ Onboard new providerAgency dashboardSee the live demo courseTry the certificate request

For a ten-year-old

What the NBos System actually is.

No jargon. Just what it does, why it exists, and how the two halves fit together.

What is the NBos System?

+

NBos is a website (a web app) It sits next to your GHL account and does the jobs that GHL can't do by itself — like remembering which nurse started which course on which date, storing each course's learning goals, and creating reports.

Why can't GHL do all of this alone?

+

GHL is great at selling courses, taking payments, and sending emails. But it has two blind spots: (1) it can't put a password on a custom page, so anyone could see a nurse's private evaluation; and (2) it only has one 'slot' per contact for a start-date, so if a nurse takes two courses the second course erases the first course's date. We needed Make and Google Apps Script to work around those two blind spots.

What does the NBos web app replace?

+

It replaces four external tools: the Google Apps Script that looked up provider info, the Google Apps Script that built rosters in Google Sheets, the Make Data Store that held course goals, and the Google Apps Script that wrote monthly reports. GHL keeps doing what it's good at — courses, offers, payments, emails, and issuing the final certificate PDF.

Can a course issue a certificate with someone else's logo on it?

+

Yes. The 'one Master CE Certificate' was a setup choice, not a limit. The web app adds a certificate-templates registry — one row per design, including a background image that carries the logo and any pre-printed issuer info. Each course picks which template it issues, so a provider can run many co-branded designs side by side. The dynamic fields (learner name, course, credits, date, certificate number) overlay on top. One rule: the accredited provider's name and provider number still have to appear on the certificate for the nursing CE credit to be valid — the co-brand sits alongside them, not instead of them.

What stays inside GHL?

+

The provider sign-up form, the snapshot template, course products and offers, the access trigger, the field-clearing workflow, and the actual certificate PDF printing. These all work fine inside GHL and don't need outside help.

How do the two halves talk to each other?

+

When a learner starts a course in GHL, a GHL workflow pings the NBos web app with the learner's ID, the course ID, and the date. NBos saves it. When the learner finishes, GHL pings NBos again. NBos updates its records and can send the data back as a report or a Google Sheet whenever the provider asks.

Component-by-component

The system, mapped piece by piece.

Every form, workflow, webhook, and script from the handoff — with a verdict on where it should live in the NBos architecture.

01

Step 1 — Register provider

New CE Client Setup Form

A form completed once per new CE provider. Collects business name, GHL Location ID, CE provider number, Google Drive folder ID, and the provider's Master Certificate Form URL.

Now: GHL form (CE ADMIN AUTOMATIONS)

The form itself is native GHL. It can stay. Only the downstream storage target changes — provider config should write to GHL custom values on the subaccount instead of an external Apps Script lookup.

GHL native

Form stays in GHL → writes to Location custom values

Stays native
02

Step 1 — Register provider

New CE Client Setup Workflow

GHL workflow triggered by the setup form. Currently sends submission data to the external CE Client Setup Automation (Google Apps Script).

Now: GHL workflow

The workflow trigger stays native. Modify its action: instead of calling the external Apps Script endpoint, write the three provider fields (ghl_location_id, ceprovider_number, ce_report_folder_id) directly to the subaccount's custom values.

GHL native

Workflow stays → action rewritten to write custom values

Stays native
03

Step 1 — Register provider

CE Client Setup Automation (Apps Script)

Google Apps Script that receives provider registration and stores it as a lookup endpoint (CLIENT_SETUP_LOOKUP_URL) referenced by every downstream script.

Now: Google Apps Script (external)External: Google Apps Script

Eliminated. GHL subaccount custom values now hold ghl_location_id, ceprovider_number, and ce_report_folder_id. Downstream automations read these from the subaccount directly — no external lookup service needed.

NBos web app

Not needed — data lives in GHL custom values

Replaced
04

Step 2 — Deploy snapshot

New CE Compliance Snapshot

A master GHL subaccount used as a template. Contains universal workflows, forms, custom fields, the evaluation page, certificate config, and reporting setup — applied to every new provider.

Now: GHL subaccount (snapshot)

Snapshots are native GHL. Keep as-is. The snapshot must be cleaned of source-account-specific values (provider numbers, folder IDs, certificate URLs) so it carries only structure, not data.

GHL native

Snapshot stays native — strip client-specific values before deploy

Stays native
05

Step 3 — Create course

Course Product + Offer

Provider creates a GHL course Product with lessons/materials and an Offer that grants learner access (free or paid).

Now: GHL courses / offers

Fully native GHL. No change. The universal Product Access Granted trigger (already verified) handles access without per-course workflow duplication.

GHL native

Stays native — no change

Stays native
06

Step 5 — Course access date

Universal Course Access Workflow

Records the date a learner starts a course. Currently updates a single contact field 'Date Course Access Granted'.

Now: GHL workflow (Product Access Granted / Product Started)

STRUCTURAL PROBLEM: one contact-level date field cannot hold per-course dates for a learner taking multiple courses. A learner starting Course B would overwrite Course A's start date. This requires a real enrollment table (one row per learner × course) — which is exactly what the NBos web app's database provides.

NBos web app

NBos enrollments table (learner_id, course_id, started_at, completed_at, cert_status)

Move to web app
07

Step 4 — Create roster

Course Roster Setup Form + Workflow

Form collects course info and triggers roster creation. Currently sends to a webhook → Google Apps Script → copies a master Google Sheet template into the provider's Drive folder.

Now: GHL form + workflow + webhookExternal: Google Apps Script, Google Sheets

The form and its GHL trigger stay native (providers already use it). The roster storage moves to the NBos web app database — one roster row per learner per course. The web app can export to Google Sheets on demand for providers who still want the spreadsheet.

GHL native

Form + trigger stay native

NBos web app

Roster lives in NBos DB → optional Sheets export

Hybrid
08

Step 4 — Create roster

CE Course Roster Automation (Apps Script)

Receives course info via webhook, resolves provider via GHL Location ID, finds the Course Rosters folder, copies the master template, populates course header, saves the new roster sheet.

Now: Google Apps Script (external)External: Google Apps Script, Google Sheets, Google Drive

Replaced by the NBos web app. On roster-form submission, the web app creates a roster record in its database keyed by course_tracking_number. A scheduled job can sync to the provider's Google Sheet if the provider wants a spreadsheet copy.

NBos web app

NBos roster endpoint + optional Sheets sync job

Replaced
09

Step 6 — Register course

CE Course Automation Setup Form + Workflow

Form collects course tracking number, provider association, and 1–20 learning objectives. Workflow sends to Make Data Store 'CE Course Registry'.

Now: GHL form + workflow → MakeExternal: Make Data Store

The form and trigger can stay native. The course registry storage moves to the NBos web app database (a 'courses' table with objective1–objective20 columns). The universal evaluation page reads objectives from the web app API instead of Make.

GHL native

Form + trigger stay native

NBos web app

NBos courses table (course_tracking_number, objectives[1..20])

Hybrid
10

Step 8 — Evaluation

Universal CE Program Evaluation Page

A single page that serves every course. JavaScript fetches the course tracking number, calls Make to retrieve objectives, populates the evaluation, and captures the learner's responses through a GHL form.

Now: GHL page with JavaScript → MakeExternal: Make Data Store, GHL custom page JS

This was external because GHL custom pages didn't allow authentication, so Make was used as a public lookup. The NBos web app hosts the evaluation page with its own auth and reads objectives from its own database — eliminating both the Make dependency and the auth workaround.

NBos web app

NBos /evaluate/:courseTrackingNumber route + objectives API

Move to web app
11

Step 8 — Evaluation

Evaluation Clear-Fields Workflow

GHL workflow that clears evaluation-related contact fields so data from one course doesn't bleed into the next.

Now: GHL workflow

Stays native. It only touches contact fields within GHL. No external dependency. Keep as-is.

GHL native

Stays native — no change

Stays native
12

Step 9 — Certificate

Certificate Request + Issuance

Learner requests a certificate. Provider-specific routing currently uses the external lookup to find the right certificate template. GHL issues the certificate. Today only one Master CE Certificate exists per provider — so a co-branded certificate (with another person's logo and info baked into the background) is not possible without a separate template per design.

Now: GHL certificate + Apps Script routingExternal: Google Apps Script (certificate routing)

GHL's native certificate feature can issue the PDF. But the request page was sometimes blank/unpublished after snapshot deploy — a known reliability issue. The NBos web app hosts a stable certificate-request page and does the provider routing using its database, then hands off to GHL's certificate issuer. Multi-certificate routing adds a certificate_templates table (one row per design: background_image_url, issuer_name, signature, provider_number) and a certificate_template_id column on courses. A provider can create as many designs as they want — including co-branded backgrounds that carry a partner's logo alongside the required accreditation fields — and assign the right template per course.

GHL native

GHL certificate issuance stays native

NBos web app

NBos /certificate/:courseTrackingNumber request page + multi-template routing

Hybrid
12b

Step 9 — Certificate

Multi-Certificate Template Registry

A certificate_templates table in the NBos database. Each row is one certificate design: template_id, provider_id, background_image_url (PNG with logo/issuer info baked in), issuer_name, issuer_credentials, signature, provider_number. The courses table gets a certificate_template_id column so each course picks which design it issues. A provider can have many designs — including co-branded certificates carrying a partner's logo alongside the required accreditation fields.

Now: Does not exist (single Master CE Certificate today)

The 'one Master CE Certificate' is a configuration choice, not a platform limit. Supporting multiple branded certificates per provider is the same routing pattern one level deeper: select a template per course instead of per provider. The co-presenter's logo/info lives in the background PNG; the dynamic fields (learner name, course title, credit hours, date, certificate number) overlay on top. The accredited provider's name and provider number must still appear on the certificate for the CE credit to be valid — the co-brand is in addition, not instead.

NBos web app

NBos certificate_templates table + certificate_template_id on courses

Move to web app
13

Step 10 — Reporting

Completion Reporting (Florida + general)

Apps Script adds Florida-licensed nurses to the provider's monthly reporting Google Sheet and records general completions.

Now: Google Apps Script → Google SheetsExternal: Google Apps Script, Google Sheets

Reporting is a read of the enrollments table filtered by state and month. The NBos web app generates the report from its database and exports to Google Sheets (or CSV) on demand. No Apps Script needed.

NBos web app

NBos /reports/fl-monthly + /reports/completions export

Move to web app

Interactive

Current vs. proposed architecture.

Drag any node to rearrange. The left column is today's flow — notice the three external Apps Script hops and the Make Data Store. The right column is the NBos target: external tools collapse into one web app with its own database and auth.

GHL native NBos web app Removed drag to rearrange

Current — external webhooks

Proposed — NBos web app

GHL Setup Form

provider onboarding

GHL Workflow

trigger → action

Apps Script

provider lookup

Google Drive

provider folder

GHL Course + Offer

learner access

Access Trigger

Product Started

Make Data Store

course objectives

Apps Script

roster creation

Google Sheets

rosters + reports

Apps Script

FL monthly report

GHL Setup Form

provider onboarding

GHL Workflow

writes custom values

GHL Course + Offer

learner access

Access Trigger

webhook → NBos

NBos API

new

enrollments endpoint

NBos Database

new

courses + enrollments

Evaluation Page

new

/evaluate/:track

Cert Templates

new

co-brand designs

GHL Certificate

PDF issuance

NBos Reports

new

FL monthly + CSV

collapse

3 Apps Scripts removed

provider lookup, roster creation, monthly report

Make Data Store removed

course objectives now in NBos DB

1 NBos API added

receives GHL webhooks, writes to DB

The verdict

What works, what doesn't.

5

Stays native in GHL

Forms, the snapshot, course products/offers, the access trigger, and the field-clearing workflow. These work fine inside GHL and need no outside help.

  • New CE Client Setup Form
  • New CE Compliance Snapshot
  • Course Product + Offer
  • Evaluation Clear-Fields Workflow
  • New CE Client Setup Workflow (action rewritten)
4

Hybrid — GHL + NBos web app

The GHL form and trigger stay native; only the storage target moves to the NBos database. Providers keep their familiar workflow.

  • Course Roster Setup Form + Workflow
  • CE Course Automation Setup Form + Workflow
  • Certificate Request + Issuance
  • Completion Reporting (Florida + general)
5

Moves to the NBos web app

These existed only because GHL couldn't authenticate custom pages or hold per-course data. The web app's database + auth removes both limits.

  • Universal CE Program Evaluation Page
  • Universal Course Access Workflow (per-course dates)
  • CE Course Roster Automation (Apps Script)
  • CE Client Setup Automation (Apps Script lookup)

Step-by-step · do it now

How we change everything — without breaking what works.

The rule that governs this whole plan: the current production system stays exactly as it is until the NBos web app is built and a test subaccount runs clean end-to-end. Nothing in your live GHL agency account changes until Phase 4, and no live provider moves until Phase 5.

13 of 19 steps done68%

The current system is not touched until the web app is complete and all automations are ready for a test.

Phases 1–3 are pure new build in a separate environment. Phase 4 uses a brand-new test subaccount. Phase 5 migrates live providers one at a time. The old Apps Scripts and Make scenarios stay running until the very last step so unmigrated providers keep working.

Still no changes to GHL. You're building the NBos pages that will eventually replace the GHL custom pages and the single Master CE Certificate. The co-branded certificate your client asked about becomes possible here.

  1. Build /ce/evaluation?course=:trackingNumber

    Done

    A hosted, authenticated page that reads the course's objectives from the courses table and renders the evaluation. This replaces the GHL custom page + its JavaScript that called Make. It is not live yet — the GHL course lesson still links to the old page.

  2. Build the certificate_templates table

    Done

    One row per certificate design: template_id, provider_id, background_image_url (a PNG with the logo and any pre-printed issuer info baked in), issuer_name, issuer_credentials, signature, provider_number. Add a certificate_template_id column to courses so each course picks which design it issues.

  3. Create the co-branded template your client wants

    Done

    Upload the partner's background PNG (logo + their info in the artwork). The dynamic fields — learner name, course title, credit hours, date, certificate number — overlay on top. Keep the accredited provider's name and provider number on the certificate too; the co-brand sits alongside them, not instead of them, so the CE credit stays valid.

  4. Build /certificate/:trackingNumber

    Done

    A stable, authenticated request page that looks up the course → its assigned template → routes to the correct certificate config, then hands off to GHL's native PDF issuer. This fixes the 'blank/unpublished after snapshot deploy' problem because the page now lives in NBos, not in a snapshot.

The one rule to hold to: never decommission an Apps Script, a Make scenario, or the central lookup until every provider that depended on it has been cut over and verified. Both systems run in parallel through Phase 4 and most of Phase 5. The old tools are removed last, not first.

The replacement

What the NBos web app looks like.

A standalone web app that sits next to your GHL agency account and handles the four jobs GHL can't do alone. Here's the shape of it.

Database

Course Registry

One row per course. Holds the tracking number, provider, and up to 20 learning objectives. The evaluation page reads from here — no Make Data Store.

Enrollments

Per-Course Learner Records

One row per learner × course. Each course keeps its own start date, completion date, and certificate status — solving the overwrite problem.

Page

Universal Evaluation

A hosted page at /evaluate/:trackingNumber. Authenticated, reads objectives from the database, renders the right questions for that course.

Page

Certificate Request

A stable /certificate/:trackingNumber page that routes to the correct provider's certificate config, then hands off to GHL's PDF issuer.

Registry

Certificate Templates

One row per design — a background PNG carrying a logo and co-brand, plus the issuer name, credentials, signature, and provider number. Each course picks which template it issues, so a provider can run many co-branded designs side by side.

Reporting

Florida + General Reports

Generated from the enrollments table, filtered by state and month. Exports to Google Sheets or CSV on demand — no Apps Script.

Auth

Authenticated Access

The reason this layer existed externally. The web app puts real auth on every page, so learner data is no longer exposed on public GHL pages.

How the two halves connect

GHL

course, offer, payment, email, certificate PDF

↓webhook ping

NBos web app

registry, enrollments, evaluation, reports

↓report / sheet export

Provider

Google Sheets, monthly reports

GHL keeps doing what it's good at. When a learner starts or finishes a course, a GHL workflow pings the NBos web app with the learner ID, course ID, and date. NBos stores it and can send the data back as a report or Google Sheet whenever the provider asks.

Getting there

A five-week migration plan.

Build the web app first, move evaluation and certificates, then roster and reporting — and only decommission the external tools after one real provider runs end-to-end.

01

Phase 1 — Foundation

Week 1–2

Stand up the NBos web app with auth, database, and the enrollment + course registry + certificate-templates tables.

  • Create the NBos web app project (this environment) with Cloud enabled for database + auth.
  • Design the database schema: enrollments, courses, providers, rosters, certificate_templates.
  • Build the API: POST /enrollments, GET /courses/:trackingNumber, POST /completions, GET /certificate-templates.
  • Seed one demo provider + one demo course so the preview shows real data.
02

Phase 2 — Evaluation + Certificate

Week 3

Move the universal evaluation page, certificate request page, and multi-certificate template registry to NBos.

  • Build /evaluate/:trackingNumber route that fetches objectives from the courses table and renders the evaluation form.
  • Build /certificate/:trackingNumber route that routes to the correct provider's certificate config and hands off to GHL's issuer.
  • Create the certificate_templates table (template_id, provider_id, background_image_url, issuer_name, issuer_credentials, signature, provider_number) and add certificate_template_id to courses.
  • Build a template-picker so providers can create co-branded designs (partner logo in the background PNG) and assign one per course.
  • Replace the GHL custom-page JavaScript to redirect to the NBos evaluation URL.
03

Phase 3 — Roster + Reporting

Week 4

Move roster creation and completion reporting to NBos.

  • Build the roster endpoint that the GHL roster form webhook calls.
  • Build the Florida monthly report generator (reads enrollments filtered by state + month).
  • Add a 'Sync to Google Sheet' button for providers who want spreadsheet copies.
  • Update GHL workflows to call NBos endpoints instead of Apps Script / Make.
04

Phase 4 — Decommission

Week 5

Remove the external tools and verify end-to-end with a live provider.

  • Run one real provider end-to-end: register → snapshot → create course → learner enrolls → evaluates → gets certificate → appears on report.
  • Turn off the Make scenarios and Apps Script webhooks.
  • Remove the CLIENT_SETUP_LOOKUP_URL reference from remaining scripts.

Important: do not remove the existing registration workflow, the Apps Script lookup, or the Make scenarios until every dependent automation has been cut over to the NBos web app. The plan keeps both systems running in parallel through Phase 3 and only decommissions external tools in Phase 4 after a live provider verifies end-to-end.