Skip to content

A partner landing page, a staff CRM, and a clinic portal — one catalog, three hostnames. The system the business had outgrown is gone; this is the desk that prices a live pharmacy formulary and routes the Rx.

HIPAA compliant

Marketing site, staff CRM, and clinic portal — live.

Screens
Total Script Solutions
Partner landingStaff sign-inClinic portal sign-inPharmacy catalog
Partner landing
What it is

The brief started as a wholesale CRM — clinics and med-spas, per-customer price lists, quotes that become orders. The previous tool couldn't hold that shape. What shipped is the other half of the business: clinics don't just buy SKUs, they send prescriptions to a pharmacy.

So the product grew three ways. A public site that explains the desk. A staff app that holds the live formulary, prices it per clinic, and routes the Rx. A portal where the clinic browses only what they're allowed to see. The catalog is shared; the logins are not.

Three surfaces

Partner landing

totalscriptsolutions.com

The public site. Weight-loss positioning, how the desk works, a partner form. Staff and clinic logins live in the footer — the marketing page is not the app.

Staff CRM

crm.totalscriptsolutions.com

The desk. Call list, leads, clinics, a live pharmacy catalog, prescription orders, billing, commissions, reports. Fifteen rail items for admin; none of them dead.

Clinic portal

portal.totalscriptsolutions.com

A separate login. Browse the assigned formulary, keep patients, write the order, see invoices. Onboarding blocks the rest until practice, prescribers, and the agreement are done.

Staff CRM

The rail was condensed so a rep's Monday is one screen, not twenty-four tabs. Sales, pharmacy, money, and admin — each job has a place, and the P&L reads the same numbers the staff already entered.

Sales floor

A Monday call list by reorder rhythm, leads with a qualification script, clinics and physicians on one record, a Google Calendar per rep.

Pharmacy catalog

Two vendors, one browse. Categories and routing rules, per-clinic assignment, a pricing-review queue so a below-floor price never reaches an order.

Orders & billing

Prescription orders are the book. Invoices, payments, and pharmacy payables share one Billing page. Clinics pay on account; the pharmacy bills the brand separately.

Commissions & reports

Earned → payable → paid, with a P&L waterfall — revenue, COGS, commissions, fees, net. Money Owed is cash position, not a spreadsheet.

Clinic portal

The second product. A clinic browses what they're allowed to see, at their price, and the order that leaves is a real prescription — validated with the pharmacy before anyone is charged.

Onboarding, then the catalog

Practice → prescribers → agreement. Until that's done the rest of the portal is closed. After, they browse only what they were assigned, at their price.

Patients and orders

Clinic-scoped patients — create or CSV import — then a cart. Validate with the pharmacy before anyone is charged. Status comes back inbound.

Invoices and resources

The same invoices the staff raised. A document library staff publish on purpose — downloads stream through the API, not a signed URL.

Book a specialist

Availability from a connected Google Calendar. Video or phone. Staff can sit in a clinic's session; the order is still attributed to them.

Architecture

One Next app, three hosts

Middleware splits marketing, staff, and portal by hostname. Cookies are host-only. A same-origin proxy turns the session into a bearer; the API is private Cloud Run, reached with a Google identity token in a header the platform won't strip.

Two pharmacies, one catalog

Pharmetika (Saint Luke) and Kaduceus are separate vendors with different contracts — one formulary has no prices, the other seeds cost floors. Products key on vendor + pharmacy. Routing rules put rows on shelves.

Postgres, not a document store

Cloud SQL with CHECKs derived from one status vocabulary, append-only activity, and money totals that come from the whole table — never from a page of rows.

Snapshots over joins

Price, cost, patient, and prescriber are snapshotted onto the order. Editing the catalog later doesn't rewrite history, and a rate change doesn't re-attribute last month's commission.

Built with
Next.js 16HonoPostgreSQLDrizzle ORMGoogle Cloud