Building a Customer Onboarding Portal in ViibeStack
August 30, 2026

Building a Customer Onboarding Portal in ViibeStack

Why the forms-plus-email-plus-drive setup breaks down

Most companies back into customer onboarding the same way: a signup form feeds a spreadsheet, a welcome email links to a shared drive folder, and approvals happen over email or in a group chat nobody can search six months later. It works for the first ten customers. By customer fifty, someone is manually checking three systems to answer 'where is this account stuck?' and the honest answer is often 'we don't know.' Files get uploaded with the wrong name, approvals get buried in inboxes, and the customer experience is a string of 'just checking in' emails instead of a clear status they can see themselves. The fix isn't a better form or a better folder structure. It's collapsing checklist, document collection, approval, and status into one record that lives in your CRM, where sales handed off the deal in the first place. That's the core idea behind ViibeStack's CRM: onboarding isn't a separate tool bolted on after the close, it's the next stage of the same customer record.

The data structure: one Customer record, four related tables

Set this up as one core object and four related tables, not a pile of disconnected forms. 1. Customer (or Account) — the parent record, already in your CRM from the sales pipeline. Add fields for onboarding_stage (a picklist: Welcome, Docs Requested, Docs Received, Pending Approval, Approved, Live), onboarding_owner, and target_go_live_date. 2. Onboarding Tasks — a related table with one row per checklist item (e.g., 'Sign MSA,' 'Add billing contact,' 'Complete integration setup'). Fields: task_name, status (Not Started / In Progress / Done / Blocked), due_date, assigned_to, and a customer_visible boolean so you control what the client sees versus internal-only steps. 3. Documents — one row per file or form the customer needs to submit. Fields: doc_type, status (Requested / Uploaded / Rejected / Approved), file_link, uploaded_by, and reviewed_by. This is where you replace the shared drive: instead of a folder full of ambiguously-named PDFs, every document is a row tied to a status and a reviewer. 4. Approvals — a lightweight table for anything requiring sign-off: contracts, statements of work, custom pricing exceptions. Fields: approval_type, requested_from, decision (Approved / Rejected / Changes Requested), decision_date, and notes. This is your e-signature-style layer — you're not licensing DocuSign, you're capturing intent and a timestamp directly against the customer record. This structure mirrors what we recommend in migrating a spreadsheet CRM without losing history: keep one source of truth per customer, and treat everything else as a related, filtered view of that record rather than a separate system.

Setup steps, in order

1. Start from the CRM, not a blank app. If you're already tracking deals in ViibeStack, add the onboarding_stage field to the existing Customer object rather than creating a new one. This keeps sales handoff and onboarding in the same record, which is the whole point. 2. Build the Onboarding Tasks table with a template. Create one 'template' set of tasks (your standard checklist) and a simple automation that clones them onto a new related-table entry whenever a deal moves to Closed Won. This is a good first use of workflow automation — no custom code, just a trigger-and-clone rule. 3. Build the customer-facing portal view. Use ViibeStack's AI app builder to generate a simple portal page scoped to the logged-in customer: their checklist, their document upload fields, their approval status, filtered by customer_visible = true. Internal-only tasks (like 'run background check') stay hidden from that view but live in the same table. 4. Wire up document uploads to the Documents table. Each upload creates or updates a row rather than dropping a file into an unstructured folder. Set a status default of 'Requested' when a doc_type is added, and require someone to flip it to 'Approved' or 'Rejected' before the related task can be marked Done — this is the guardrail that replaces a human chasing files across a shared drive. 5. Add the Approvals table for anything contractual. For simple approvals, a status field plus a timestamp and the approver's name is enough; you don't need a full e-signature product for internal sign-offs, though for legally binding contracts you'll still want a proper e-signature integration — check Integrations for what connects natively. 6. Build the progress view last. A single dashboard, filtered per customer, showing percentage of tasks done, outstanding documents, and pending approvals. This is what replaces the 'just checking in' email — the customer (and your team) can see status without asking.

What this replaces, concretely

A typed-up welcome email becomes a live checklist tied to a record. A shared drive folder becomes a Documents table with status and reviewer fields, so nothing sits in limbo without an owner. An email approval thread becomes an Approvals row with a timestamp and a name attached. And the spreadsheet someone was maintaining to track 'who's stuck where' becomes a filtered view anyone on the team can pull up instantly. If your onboarding today already lives partly in HubSpot, Airtable, or a Google Form-to-Sheet chain, this is a smaller migration than it sounds — see how teams approach it in replacing HubSpot or replacing Airtable. The pattern is the same either way: pull the fragmented pieces into one record structure, and stop treating onboarding as a side process bolted onto the sale.

A note on scope

Don't try to build the full portal in one sitting. Start with the Onboarding Tasks table and the stage field on the Customer record — that alone kills the 'where are we stuck' problem. Add Documents once you've confirmed the checklist flow works. Add the customer-facing portal view last, after your team has used the internal version for a few onboardings and knows which fields actually matter to show a client. This staged approach is the same one we recommend in the case for building instead of buying: ship the smallest useful version first, and let real onboarding cycles tell you what's missing rather than guessing upfront.

← Back to the blog