Files
message-inbox-web-frontend-sdk/.claude/memory/architecture-decisions.md
T
2026-07-17 21:48:37 +05:30

40 lines
2.4 KiB
Markdown

---
name: architecture-decisions
description: Key architecture choices for the SDK + BFF + workspace and the reasons
metadata:
type: project
---
**pnpm workspace, two packages.** `packages/messaging-inbox-sdk` (the shareable SDK) and
`apps/web` (the demo). The app depends on the SDK via `workspace:*` and Next `transpilePackages`
transpiles the SDK's TS source directly (SDK `main`/`types` point at `src/index.ts`, no build
step). This mirrors the IIOS layout (packages + apps) and keeps the SDK genuinely reusable.
**BFF pattern (explicit client requirement).** The UI/SDK only ever calls `BffClient`, which
hits `/api/bff/**` (Next route handlers). Every route calls `getBackend()` (a formal `Backend`
interface in `apps/web/lib/backend/`), never the store directly. `BFF_BACKEND` env picks the impl:
`mock` (default, wraps `lib/mock/store.ts`) or `iios` (`lib/backend/iios.ts` → real IIOS via
`lib/iios/client.ts` + `map.ts`). Messages/inbox/tickets are wired to IIOS; bootstrap/channels/
reactions/search/notifications delegate to mock until IIOS exposes those endpoints. Flipping to
live IIOS is one env var (needs the IIOS service + Docker/Postgres running — see
`docs/IIOS_INTEGRATION.md`). This is the single swap seam; the SDK and components never change.
**Config resolved on the server.** `getServerConfig()` runs in the root layout (server
component), reads `NEXT_PUBLIC_*` from `process.env`, returns a plain `SdkConfig`, and passes
it to the client `<MessagingInboxProvider config=…>`. Avoids the Next.js gotcha that dynamic
`process.env[key]` doesn't work in the browser bundle. Theme vars are also inlined into
`<head>` on first paint to prevent a flash.
**Theme = CSS variables + Tailwind mapping.** All Tailwind colors resolve to `--c-*` vars set
on `<html>` at runtime by the provider. Light/dark and brand re-skin are just different
variable values; nothing is hard-coded. `darkMode: 'class'`.
**Feature flags are data, not conditionals scattered around.** One `FeatureFlags` interface;
`NEXT_PUBLIC_FEATURE_<UPPER_SNAKE>` overrides each. Components call `useFeature("x")`.
**Why not build the NestJS/DB backend?** The ask was a static demo with everything working.
A NestJS BFF + Postgres adds setup cost with no demo benefit; it's documented as the
production path instead (`docs/IIOS_INTEGRATION.md`, `docs/BFF.md`).
Related: [[design-system]], [[conventions]], [[iios-relationship]].