# Project Research Summary **Project:** Tessera - Modular Portal Platform with Marketplace **Domain:** Multi-tenant SaaS portal with module marketplace, configurable dashboard, desktop wrapper **Researched:** 2026-06-18 **Confidence:** HIGH ## Executive Summary Tessera is a modular portal platform where tenants activate licensed workflow modules from a marketplace, interact through a configurable drag-and-drop dashboard, and optionally use a lightweight desktop wrapper. The expert consensus for this type of product is a modular monolith backend (NestJS) with PostgreSQL Row-Level Security for tenant isolation, a Next.js frontend shell that lazy-loads module UIs on demand, and Keycloak for identity management. This stack avoids premature microservice complexity while maintaining clean extraction boundaries. The recommended approach is to build foundation-first: Docker infrastructure with network segmentation, database schema with RLS policies, and the frontend shell with i18n and theming baked in from day one. Authentication and tenant context middleware come next, followed by the module system with a versioned API contract, then marketplace and dashboard features. The desktop wrapper (Tauri) is a late-stage concern that wraps the already-working web app. The primary risks are tenant data leakage (mitigated by RLS at the database level, not application-level filtering), module API instability (mitigated by a versioned SDK contract from the start), and i18n/theme retrofitting pain (mitigated by establishing both before the first UI component). Docker network segmentation is a day-one infrastructure requirement to prevent lateral movement between containers. ## Key Findings ### Recommended Stack A pnpm + Turborepo monorepo with three apps (Next.js 16 frontend, NestJS 11 backend, Tauri 2 desktop) and shared packages for types, UI components, config, and database schema. **Core technologies:** - **Next.js 16 + React 19**: App Router, Server Components, Turbopack, multi-tenant middleware support - **NestJS 11**: Modular architecture maps directly to Tessera's module system; DI, guards, interceptors - **PostgreSQL 16 + Prisma 7**: RLS for multi-tenancy, Prisma Client Extensions for tenant context, pure TS runtime in v7 - **Keycloak 26.6**: Native multi-tenancy via realms, LDAP federation, eliminates custom auth - **Tauri 2**: 5MB installer vs Electron's 150MB; thin wrapper around the web app - **Tailwind 4 + shadcn/ui**: Utility-first styling with owned component library, trivial dark mode - **react-grid-layout 2.2**: TypeScript rewrite with hooks API for drag-and-drop dashboard - **Traefik 3**: Docker-native reverse proxy with auto-SSL and label-based config ### Expected Features **Must have (table stakes):** - Authentication with RBAC and multi-tenancy with data isolation - Sidebar navigation with module categories - Module activation/deactivation and admin-managed licensing per tenant - i18n (DE + EN), light/dark theme, responsive layout - Basic dashboard with widgets, session management, error handling/loading states - User profile and settings, search/filter in module lists **Should have (differentiators):** - Drag-and-drop dashboard with resizable widgets - Widget marketplace/gallery - Module hot-activation without restart - Per-tenant branding (logo + accent color) - Module-provided dashboard widgets - Keyboard shortcuts and command palette - LDAP/AD directory sync **Defer (v2+):** - LDAP integration (manual user creation suffices initially) - Desktop wrapper (browser works fine first) - Notification center, admin impersonation, onboarding wizard ### Architecture Approach Modular monolith: single deployable NestJS backend with domain-separated modules (auth, tenant, marketplace, dashboard, module loader) communicating via in-process calls. Frontend is a React shell that lazy-loads module UIs via dynamic imports based on tenant activation state. Shared PostgreSQL database with RLS enforces tenant isolation at the database level. Modules follow a standard interface contract (TesseraModule) for uniform discovery and lifecycle management. **Major components:** 1. **Frontend Shell** -- routing, sidebar, theme, i18n; lazy-loads module UIs 2. **API Gateway (Traefik)** -- reverse proxy, rate limiting, tenant header injection 3. **Auth Module** -- Keycloak integration, JWT, session management 4. **Tenant Module** -- context resolution, RLS activation per request 5. **Module Loader** -- plugin lifecycle: discover, validate, activate, deactivate 6. **Marketplace Service** -- module catalog, licensing, activation per tenant 7. **Dashboard Engine** -- widget grid, layout persistence, module-contributed widgets ### Critical Pitfalls 1. **Tenant data leaks** -- Enforce PostgreSQL RLS from day one; never rely on application-level WHERE clauses alone 2. **Module API contract instability** -- Define a versioned @tessera/sdk with semver before shipping the first module 3. **Flat Docker network** -- Segment into frontend-net, backend-net, data-net from the initial docker-compose.yml 4. **i18n retrofitting** -- Every string through t('key') from the first component; design for German text length 5. **LDAP as direct auth** -- Use Keycloak as identity layer; LDAP for directory sync only, never raw bind for auth ## Implications for Roadmap ### Phase 1: Foundation and Infrastructure **Rationale:** Everything depends on the database, Docker setup, backend skeleton, and frontend shell. RLS, network segmentation, i18n, and theming must exist before any feature code. **Delivers:** Running Docker Compose stack with PostgreSQL (RLS enabled), NestJS skeleton, Next.js shell with routing/layout/sidebar frame, i18n infrastructure, theme/design tokens, Traefik reverse proxy, segmented Docker networks. **Addresses:** Responsive layout, theme system, i18n framework, error handling/loading states (table stakes infrastructure) **Avoids:** Pitfalls 1 (tenant isolation), 4 (flat Docker network), 6 (i18n retrofitting), 14 (theme without design tokens), 11 (volume permissions) ### Phase 2: Authentication, Tenancy, and User Management **Rationale:** Module activation requires knowing who the user is and which tenant they belong to. Auth is the prerequisite for everything else. **Delivers:** Keycloak integration, login/logout, JWT-based sessions, RBAC, tenant context middleware setting RLS per request, user management CRUD, user profile/settings. **Addresses:** Authentication, RBAC, multi-tenancy, session management, user profile (table stakes) **Avoids:** Pitfalls 5 (LDAP as auth), 10 (tenant context lost in async) ### Phase 3: Module System and First Module **Rationale:** The module system must exist before the marketplace can manage it. Building the first real module (Domaincheck) validates the entire architecture. **Delivers:** Module interface contract (@tessera/sdk), database-driven module registry, module loader with activation/deactivation, lazy-loading frontend integration, Domaincheck module as proof of concept. **Addresses:** Module activation/deactivation, sidebar navigation reflecting active modules (table stakes); module dependency declaration (differentiator) **Avoids:** Pitfalls 2 (API contract instability), 3 (monolithic module loading), 8 (scattered licensing), 12 (over-engineered module communication) ### Phase 4: Marketplace and Dashboard **Rationale:** Both depend on the module system but are largely independent of each other. Marketplace manages module catalog and licensing; dashboard provides the user home with widgets. **Delivers:** Marketplace UI (browse, activate, manage licenses), licensing service, dashboard with react-grid-layout, core widgets (clock, search, notes, calendar), drag-and-drop with layout persistence, module-provided widgets. **Addresses:** Marketplace UI with licensing (table stakes); drag-and-drop dashboard, widget gallery, module-provided widgets (differentiators) **Avoids:** Pitfall 7 (widget state explosion -- debounced persistence, JSON column) ### Phase 5: Polish, Desktop, and Advanced Features **Rationale:** Enhancement layer on a stable web platform. Desktop wrapper requires stable web app. LDAP and advanced features add value but are not launch-blocking. **Delivers:** Tauri desktop wrapper, LDAP/AD directory sync via Keycloak, per-tenant branding, keyboard shortcuts/command palette, Gitea CI/CD integration. **Addresses:** Desktop wrapper, LDAP integration, per-tenant branding, command palette (differentiators) **Avoids:** Pitfall 9 (desktop divergence -- keep wrapper thin), 13 (Gitea tight coupling) ### Phase Ordering Rationale - Phases follow strict dependency chains: infrastructure -> auth/tenancy -> modules -> marketplace/dashboard -> polish - i18n and theming are in Phase 1 (not Phase 5) because retrofitting is a known moderate pitfall - Module system before marketplace because the marketplace manages modules -- the registry must exist first - Dashboard is grouped with marketplace (Phase 4) because both depend on the module system and can partially parallelize - Desktop wrapper is last because it wraps an already-working web app and building it earlier risks divergence ### Research Flags Phases likely needing deeper research during planning: - **Phase 2:** Keycloak realm-per-tenant configuration and NestJS integration patterns; RLS session variable management with Prisma Client Extensions - **Phase 3:** Module interface contract design; lazy-loading strategy for module UIs with Next.js App Router - **Phase 4:** react-grid-layout integration with module-provided widgets; layout persistence schema design Phases with standard patterns (skip research-phase): - **Phase 1:** Docker Compose, NestJS/Next.js scaffolding, Tailwind/shadcn setup -- well-documented, established patterns - **Phase 5:** Tauri wrapper is a thin shell; LDAP sync via Keycloak is documented ## Confidence Assessment | Area | Confidence | Notes | |------|------------|-------| | Stack | HIGH | All technologies are mature, well-documented, and version-verified. Clear rationale for each choice with alternatives considered. | | Features | HIGH | Feature landscape is well-defined with clear table stakes vs differentiators. Dependency chain is explicit. | | Architecture | HIGH | Modular monolith with RLS is a proven pattern for multi-tenant SaaS. Multiple authoritative sources confirm the approach. | | Pitfalls | HIGH | Critical pitfalls sourced from production incident reports and authoritative guides. Prevention strategies are concrete. | **Overall confidence:** HIGH ### Gaps to Address - **Prisma + RLS integration specifics:** Prisma Client Extensions for setting session variables per request need validation during Phase 2 implementation. The pattern is documented but not battle-tested at scale with Prisma 7. - **Module hot-activation with Next.js App Router:** Lazy-loading module UIs via dynamic imports is standard React, but integrating with Next.js App Router file-based routing may require a custom module route convention. Needs Phase 3 research. - **Keycloak realm-per-tenant vs single-realm with groups:** Research assumes realm-per-tenant mapping but single-realm with tenant claims may be simpler for the initial scale. Decide during Phase 2 planning. - **react-grid-layout v2 maturity:** The TypeScript rewrite (v2.2) is recent. Fallback to v1 /legacy API if v2 hooks have issues. ## Sources ### Primary (HIGH confidence) - [Next.js 16 Docs](https://nextjs.org/docs) -- App Router, Server Components, middleware - [NestJS Documentation](https://docs.nestjs.com/) -- Modules, guards, interceptors - [Prisma ORM 7](https://www.prisma.io/blog/announcing-prisma-orm-7-0-0) -- Pure TS runtime, Client Extensions - [PostgreSQL RLS](https://aws.amazon.com/blogs/database/multi-tenant-data-isolation-with-postgresql-row-level-security/) -- Multi-tenant isolation - [Keycloak 26.6](https://www.keycloak.org/) -- Identity provider, realm multi-tenancy - [Tauri 2.0](https://v2.tauri.app/) -- Desktop wrapper - [Martin Fowler: Feature Toggles](https://martinfowler.com/articles/feature-toggles.html) -- Module activation as feature gating ### Secondary (MEDIUM confidence) - [Multi-Tenant SaaS Architecture guides](https://apipilot.com/developing-a-multi-tenant-saas-application-the-2026-architecture-guide/) -- Architecture patterns - [Node.js Plugin Architecture](https://medium.com/codeelevation/node-js-plugin-architecture-build-your-own-plugin-system-with-es-modules-5b9a5df19884) -- Module system design - [Docker Network Isolation](https://hexshift.medium.com/docker-network-isolation-pitfalls-that-put-your-applications-at-risk-b60356a14033) -- Network segmentation - [LDAP Authentication Anti-Pattern](https://blog.lithnet.io/2018/03/the-ldap-authentication-anti-pattern.html) -- Auth layer design --- *Research completed: 2026-06-18* *Ready for roadmap: yes*