SmartPRO Docs ยท Internal ๐Ÿ”’ โ† Back to SmartPRO

Concept

Every company on SmartPRO has exactly one workspace. All data is scoped to a workspace โ€” employees, contracts, payroll, attendance, and settings are never shared across companies.

Key tables

Table Purpose
companies One row per tenant โ€” the company is the workspace; holds subscription_status (legacy sync column)
company_members Maps users to companies with a role
company_subscriptions Source of truth for subscription state

There is no separate workspaces table โ€” the tenant/workspace boundary is the companies row, and all data is scoped by company_id.

Subscription status

companies.subscription_status (legacy) and company_subscriptions must stay in sync. The banner and enforcement logic read the legacy column; a sync trigger and backfill migration (0161) keep them aligned.

If they diverge: 1. Run the backfill: UPDATE companies c JOIN company_subscriptions cs ON cs.company_id = c.id SET c.subscription_status = cs.status 2. Verify the sync trigger is active

Session scoping

Every tRPC request carries a session with companyId. Procedures call requireWorkspaceMembership(ctx) to assert the user belongs to the workspace, then scope all queries with WHERE company_id = ctx.companyId.

Never query cross-company without an explicit platform_admin check.

Pre-company state

New users who haven't joined or created a company land on the PreCompanyDashboard โ€” they can create a workspace or accept an invite. The AcceptInvitePage handles invite tokens.