Why x70 Has Two Portals
The x70 client portal and staff Admin share one business lifecycle, but separating their interfaces and authority made the agency system simpler and safer to operate.
x70 now has two operational portals.
The client-facing App is where an organization claims a prepared website, publishes its Business Profile, reviews a Proposal Preview, chooses a Service Plan, completes checkout, and later manages the website and requests.
The internal Admin is where staff handle Leads, prepare Unclaimed Organizations, inspect preview evidence, issue Proposals, reconcile service states, and respond to client work.
They participate in the same lifecycle, but combining them into one dashboard would make the product harder to understand.
The user is different, so the verbs are different
A client should not need to understand an outreach pipeline. Staff should not pretend to be a client in order to prepare or repair a workspace.
That led to a simple split.
The client portal is organized around the organization’s owned state: Overview, Business Profile, Website, Requests, Team, and Billing. The Admin is organized around operational work: Overview, Leads, Organizations, Requests, Catalog, and Staff & access.
The nouns overlap where the underlying object is genuinely shared. The verbs do not.
A client publishes a profile change. An operator inspects preparation readiness. A client accepts commercial terms. A principal updates catalog presentation and provider references. A client asks for a human change. Staff triage and fulfill that request.
Putting all of those controls on one surface would not be “powerful.” It would be an authorization model disguised as a menu.
One source of truth, two application boundaries
The separation is in the frontends and their authority, not in duplicated business data.
Client Organizations, Website outreach records, Business Profiles, Proposals, service state, and membership remain canonical in the client portal’s Convex deployment. Admin authenticates staff through the shared portal identity and calls typed staff application-service boundaries.
Admin keeps its separate operational records for areas it already owns, such as portfolio publishing and internal tools. It does not copy the client business lifecycle into a second database just to make the dashboard convenient.
This avoids a synchronization problem that would otherwise appear immediately: which copy of an Organization is correct after a Proposal Claim, a Profile publish, or a payment reconciliation?
The answer is intentionally boring. There is one canonical record, and the staff surface receives only the commands and projections it needs.
Staff access is not an Organization role
Client roles are Owner, Admin, and Member inside an Organization. Internal roles are Operator and Principal.
Those are different trust systems. An Organization Admin manages the client workspace. An x70 Principal manages staff access and consequential operational settings. Reusing one role vocabulary for both would create accidental authority and confusing audit trails.
Staff access therefore requires verified identity and the staff security gates, while application commands enforce those claims at the backend boundary. A sidebar redirect is useful navigation, not authorization.
The UI follows the same rule. If a control is not available to an Operator, the server must reject that command even if someone constructs the request outside the page.
Proposal Claim is not activation
Separating the portals also forced cleaner lifecycle language.
An x70-created Unclaimed Organization already exists before the client arrives. The Proposal ID lets the first eligible Owner claim it under an Open or Email-bound Claim policy. Claiming creates ownership and consumes the credential.
It does not prove payment.
Checkout records the accepted terms and opens Stripe. Service Activation happens only after server-side reconciliation proves the initial invoice is paid and the subscription is active. Website Launch is another later transition with its own profile, legal, domain, build, and QA evidence.
If those steps were collapsed into “onboarding complete,” both portals would show misleading actions when a browser closes during checkout or a webhook needs reconciliation.
Simpler interfaces came from stricter architecture
The visual goal for both portals is restraint. Clients need the next meaningful decision. Staff need the work that requires attention. Neither needs a wall of generic metric cards.
The architecture makes that simplicity possible. When every command has one owner and every lifecycle state has a precise meaning, the interface can say:
- this Lead needs a follow-up;
- this Organization is missing preview evidence;
- this Proposal is waiting on the client;
- this service needs reconciliation;
- this request is ready for review.
Without those boundaries, a cleaner dashboard would only hide ambiguity.
The two-portal decision adds deployment and integration work, but it removes a larger category of product confusion. For a small agency system, that is the trade I would make again.