///Internal proposal · July 2026

Streamlink is a promise our portal can't keep. Here's the build that keeps it.

Our new marketing site sells "every site, every service order — one pane of glass." The Salesforce portal behind it can't deliver that, and customers have noticed by leaving. This proposal replaces it with a real product on AWS — researched against our live org, designed, and planned down to individual commits.

See the portal mockup Read the case
105
successful customer logins to Streamlink — entire last quarter
///
38,887
order line items we delivered in the same quarter that customers couldn't see

The data customers want already exists in Salesforce. The portal in front of it is the problem — 40% of login attempts fail, and 86 of 225 provisioned users have never logged in once.

///The situation

Today's portal vs. what we're proposing

Today — Salesforce Experience Cloud

A licensed door almost nobody walks through

  • License wall: Customer Community Plus is at 180/180 — we literally cannot add another portal user today.
  • 19 genuinely active customer users in the last 6 months; most accounts log in once on the day they're provisioned, then never again.
  • 40% of all login attempts fail (forgotten passwords, "no community access" errors).
  • Salesforce page loads, Salesforce UX, Salesforce license cost per seat.
  • Seventh attempt at this problem — six earlier portal shells sit abandoned in the org.
Proposed — Streamlink v2 on AWS

A real product on our own infrastructure

  • No licenses, no provisioning: passwordless magic-link sign-in. All 23,191 contacts on recently-active accounts can self-serve access on day one.
  • Own database synced from Salesforce every 2 minutes — fast dashboards, zero load on the org.
  • Orders, sites, billing, and support tickets in one view; service requests flow back into Salesforce as cases.
  • Same stack and AWS platform as our checkout site — patterns we already run in production.
  • Vendor portal follows on the same backbone (that's where 156 of the 180 licenses go).
23,191
customer contacts who could sign in on day one
180/180
community licenses consumed today — hard blocked
2 min
data freshness via incremental Salesforce sync
1,937
orders/yr from our largest account alone (Target)
///Architecture

Salesforce stays the system of record. AWS serves the customers.

A sync worker copies only an allowlisted set of fields into the portal's own database — vendor rates, margins, and card data physically never leave Salesforce. Customers get fast pages from our database; their service requests write back through the same proven pipeline our checkout site uses.

SALESFORCE (system of record)              AWS (customer experience)
┌───────────────────┐   poll changes      ┌──────────────────┐
│ Orders            │   every 2 min       │  Sync worker     │
│ Line items        │────(allowlisted ───▶│  (Lambda)        │
│ Cases / tickets   │     fields only)    └────────┬─────────┘
│ Invoices          │                              ▼
│ Payments          │                     ┌──────────────────┐
│ Accounts/Contacts │                     │ Portal database  │
└─────────▲─────────┘                     │ (RDS Postgres)   │
          │                               └────────┬─────────┘
          │   service requests                     │
          └── written back as Cases ──── ┌─────────┴────────┐
              (idempotent, retried)      │ streamlink.      │
                                         │ ldrsiteservices  │
                                         │ .com  (Next.js)  │
                                         └──────────────────┘

Vendor costs and margins live on the same Salesforce records as customer data — roughly a third of the 468 fields on a line item. The sync allowlist is enforced in code with an automated leak test, so exposing a vendor field would require deliberately editing two lists in one reviewed change.

///Scope

Version 1: see everything, ask for anything

Deliberately scoped: full visibility plus exactly one write path — a service request that lands in Salesforce as a case. No payments, no self-service ordering in v1; those layer on after the foundation earns trust.

/// Dashboard

Active units, open balance, recent activity

One glance answers "what's on my sites right now and what do I owe."

/// Sites & orders

Every location, grouped the way national accounts think

Orders grouped by store name and number — a Target facilities manager sees #1142 Dallas, not a flat list of 1,900 orders. Each unit shows an honest delivery lifecycle: scheduled → delivered → removal requested → completed.

/// Billing

Payment history, open invoices, cards on file

Built on the live NetSuite-synced records. Balances per order, last-4 card display only.

/// Support

Real tickets plus new service requests

Customers see their account's cases (with internal noise filtered out) and submit swaps, removals, and issues — each one becomes a Salesforce case marked "Customer Portal," confirmed by email, tracked in the portal. A request is never lost: it persists on our side first and retries until Salesforce accepts it.

///Delivery

Researched, designed, planned — ready to build

This isn't a slide-deck idea. We mapped the live Salesforce org (row counts, field usage, what's dead and what's load-bearing), wrote the design spec, and produced an 18-task implementation plan with test-first steps — then ran an adversarial review that caught and fixed 15 defects in the plan before a line of product code gets written.

Found during research — needs action regardless of this project

The org is storing card security codes (CVVs) in plain text on Credit_Card__c.Security_Code__c — 77,945 rows, still being written today. Storing CVV after authorization is prohibited under PCI DSS in any form. A legacy portal object also holds plaintext passwords. Both need an owner and a purge plan this quarter, independent of Streamlink v2.

///Rollout

Pilot small, migrate honestly, then go after the vendor side

Phase 1

Build & internal dogfood

Stand up sync + portal against the UAT org, backfill production history, LDR staff verify against real accounts.

Phase 2

Pilot

The ~19 active portal users plus one or two national accounts, personally invited. Existing portal stays live until parity confidence.

Phase 3

Cutover

Redirect the old portal, free the customer licenses, retire the seventh portal attempt for good.

Phase 4

Vendor surface

Same backbone, separate project — this is where 156 of 180 licenses and the deep ops workflows live, and where the larger savings are.