System Architecture
ShopkeeperProMvp (Bambu) utilizes a robust, modern stack optimized for developer velocity and data security.
High-Level Architecture
The core of Bambu is built around Next.js (App Router) as the single full-stack framework handling both UI rendering and API routes.
- Frontend: React (Next.js 14+), TailwindCSS, Shadcn/UI, Radix Primitives
- Backend APIs: Next.js Route Handlers (
app/api/...) - Database Layer: PostgreSQL managed by Prisma ORM
- In-Memory Store: Redis (for caching, rate limiting, and OTPs)
- File Storage: (Depending on deployment: local or cloud storage for uploaded receipts/images)
Multi-Tenant Schema Design
This is the most critical architectural decision in the product.
Instead of co-mingling all user data into massive shared tables (and identifying rows with a business_id), Bambu implements Schema-per-Tenant architecture in PostgreSQL.
publicschema: Contains global datasets—User,Business,Subscription,Plan.business_{slug}schemas: When a user creates a new business (e.g., named "My Shop"), a new discrete schema is generated dynamically using Prisma. This schema holds all the business logic tables:Product,Customer,Sale,Debt.
Why Schema-per-Tenant?
- Security: Impossible to accidentally query another business's private sales data.
- Backups: Can export a single postgres schema if a business requests their data.
- Scalability: Indexes and queries stay fast since tables only contain one business's data.
To see the decision history outlining this choice, refer to adr/001-multi-tenant-schema-strategy.md (coming soon).
API & Data Flow
sequenceDiagram
participant Client (Browser)
participant Next.js API
participant Middleware
participant Redis
participant Postgres (Prisma)
Client (Browser)->>Next.js API: GET /api/products
Next.js API->>Middleware: Verify Session Context
Middleware-->>Redis: Rate Limit Check
Note over Next.js API: Identifies Tenant Schema (e.g., schema_abc123)
Next.js API->>Postgres (Prisma): Prisma Schema Context -> Query 'business_abc123.Product'
Postgres (Prisma)-->>Next.js API: Returns array of Products
Next.js API-->>Client (Browser): 200 OK + JSON
Folder Structure
The repository is modular and relies heavily on the app/ and lib/ directories:
/app/api: All backend endpoint logic./app/dashboard: The secure area for authenticated users (server/client components)./lib/db: Prisma client singletons and connection handlers./lib/tenant: The core engine that resolves the current business's schema context./lib/middleware: Next.js edge middleware for routing and protective layers./prisma: Containsschema.prisma.
Best Practices
[!IMPORTANT] When querying data inside the tenant, you MUST ensure you are using the wrapped tenant-specific Prisma client instead of the global Prisma client. Failing to do so throws an error as the global client does not have access to the tenant tables.