What this domain owns
Whether a feature may be opened and how a confirmed purchase changes plan access.
Feature flow diagram
Premium feature
│
v
Entitlement check ──free──> Paywall
│ premium │
v v
Open feature /api/billing/checkout ──> Stripe
│ webhook
v
idempotent billing event ──> plan update
│
v
refreshed session / entitlementThis diagram shows the normal direction of control and data. Follow it before changing a boundary or adding a dependency.
Class and relationship diagram
┌──────────────┐ asks ┌──────────────────┐ checkout ┌─────────┐
│ Feature UI │──────▶│ Entitlements │─────────▶│ Stripe │
└──────────────┘ ├──────────────────┤ └────┬────┘
│ + canAccess() │ │ webhook
│ + isPremium() │ ▼
└──────────────────┘ ┌──────────────────┐
│ Billing service │
│ + apply event │
└────────┬─────────┘
▼
┌──────────────┐
│ ProductPlan │
└──────────────┘Boxes show the important data types or services. Their fields and main methods are listed inside; arrows show the primary dependency or data relationship.
Sequence diagram
Read this from top to bottom: each arrow is the next interaction in the normal successful path.
Start here in the code
Choose any filename to open it directly in VS Code.
How it works
- Feature asks entitlement rule for access.
- Free learner sees paywall with return route.
- Checkout route creates Stripe session.
- Webhook records an idempotent payment event.
- Session refresh exposes the new plan.
Read this code
src/contexts/entitlements/public.tsOpen in VS Code — Ask one policy boundary about access
export const entitlements = { check: new CheckEntitlement() };
export function canAccessLesson(
input: { plan: ProductPlan }, lessonId: string,
) {
return entitlements.check.canAccessLesson({
plan: input.plan, lessonId,
});
}What each part is doing
- UI code asks this function a question; it does not compare plan strings itself.
- The application service holds the policy for free previews and Premium access.
- Keep checkout confirmation server-side; this function only decides current access.
This is a deliberately short excerpt of the real pattern, with unrelated details omitted. Read the named file for the complete implementation.
Related API and server boundaries
- POST /api/billing/checkout
- POST /api/billing/confirm
- POST /api/billing/portal
- POST /api/billing/webhook
Tests to read and run
Implementation notes
This is the home for detailed explanations, decision records, request examples, and diagrams for this feature. Add new feature-specific documentation here instead of expanding the platform overview.