Architecture note
StaffySoft Core
The shared spine behind every StaffySoft product: auth, billing, feedback, and observability as one platform instead of five copies. This page explains why it exists, what it provides, and what “done” means for a product built on it.
Why Core exists
StaffySoft ships many small products rather than one big one. That model only works if the cost of launching a product stays low — and without shared infrastructure, it doesn't. Every new app would reinvent sign-up and sessions, bolt on its own Stripe integration, grow its own feedback channel, and wire up its own error reporting. Each copy would be slightly different, each would drift, and each would be a place for the same bugs to reappear.
Core is that shared spine, extracted once and owned centrally. Accounts, entitlements, payments, feedback, and observability live in one service with one data model, and products consume them through a small SDK.
The goal is leverage: launching a new product should be boring. Not effortless — the product itself is still the hard part — but the platform work should be a checklist, not a project. When the undifferentiated plumbing is a solved problem, a new idea can go from repo to revenue without re-earning any of it.
What Core provides
Single sign-on. One session across every product on .staffysoft.com. Sign in once; every app resolves the same identity.
Per-product API keys. Each product authenticates to Core with its own key, and product tokens are validated per product — a session minted for one app is rejected by another.
Central entitlements registry. One place that knows who owns what, at what tier. Products ask Core instead of keeping their own copy of the answer.
Hosted Stripe checkout and billing portal. Core owns every line of Stripe code. Products link out to Core-hosted checkout and the billing portal and never touch Stripe secrets.
Unified feedback triage. Feedback from every product lands in one inbox with a shared lifecycle: new → reviewing → resolved / dismissed.
Shared observability. Sentry wiring ships in the core-client SDK, so every app gets uniform error capture and per-app tagging from one import.
Cross-app promotion primitives. Building blocks for recommending the right product to the right user, informed by what they already own.
How apps consume Core
Products don't call Core's HTTP API by hand. They import @staffysoft/core-client, the TypeScript SDK that wraps sessions, entitlements, profiles, feedback, billing links, and Sentry setup behind typed functions. The server-safe root export carries no React; feedback, React hooks, and observability live on their own subpaths so each app pulls in only what it uses.
The flavor of the SDK, in one snippet — browser error reporting for a whole product is a single call:
// instrumentation-client.ts — browser Sentry, wired to the shared org
import { initSentry } from "@staffysoft/core-client/observability";
initSentry({ app: "performer-prompter" });Everything else follows the same shape: one import, sensible defaults, and the platform-level concerns (per-app tagging, release naming, token validation) handled inside the SDK rather than in each product. The SDK is public on npm; Core itself — the service and its integration docs — lives in a private repo.
Platform Definition of Done
A product isn't “on the platform” because it links to Core somewhere. It's done when all of the following hold:
- Uses the current published @staffysoft/core-client
- Supports SSO bridge on first request
- Calls Core logout, not just local cookie deletion
- Has /api/core/session, /api/core/entitlements, /api/core/profile as needed
- Feedback widget wired through Core
- Sentry browser/server/edge coverage with release tagging
- Stripe checkout/portal proxies if monetized
- Cross-app smoke test coverage (sign in once → open two apps → both authenticated → sign out from one → both dead)
- Product entry in Core seed/admin and portfolio data
- Clear free/paid boundary and one activation event
This list is the bar every StaffySoft product is held to before it counts as launched — and the point of Core is that clearing it is routine.