// Composition root for the BFF layer. This Next.js app sits in front of // your real backend (Rails, Django, Go, Java, etc.) and handles: // - authentication / session resolution // - request proxying with auth context attached (see app/api/backend/[...path]) // - any client-side state / SSR shell the SPA needs // // Business logic (billing, persistence, notifications) lives in the backend. // Identity is the one port the BFF owns. Default uses the in-memory provider // so `pnpm dev` runs out of the box; swap to `@raredays/identity-better-auth` // in production (and mount its handler at `app/api/auth/[...all]/route.ts`). import { createInMemoryPermissionProvider, createRaredaysApp, Session, User } from "@raredays/core"; import { createInMemoryProvider } from "@raredays/identity/testing"; // CRDA:imports // — Authorization (what each role can do) ───────────────────────────────── // Checks ask the permission port (framework ADR-0025), as app/protected/page.tsx // does. The in-memory adapter suits dev and tests; production swaps in the // identity provider's adapter. const permissionProvider = createInMemoryPermissionProvider({ rolePermissions: { member: ["content.read"], admin: ["content.read", "content.manage"], }, }); // — Seeded dev user (replace with Better Auth in production) ────────────── const ALICE = User.from({ id: "u_alice", email: "alice@example.com", organizationId: "default", roles: ["member"], emailVerifiedAt: new Date("2026-01-01T00:00:00Z"), }); const ALICE_SESSION = Session.from({ id: "s_alice", userId: ALICE.id, user: ALICE.toJSON(), expiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24), }); const identityProvider = createInMemoryProvider({ users: [ALICE], sessions: [ALICE_SESSION], }); export const SEEDED = { user: ALICE, sessionId: ALICE_SESSION.id }; // CRDA:config export const app = createRaredaysApp({ identityProvider, permissionProvider, // CRDA:ports }); // CRDA:exports