A modern, full-stack web application designed to streamline the workflow of interior designers. Manage clients, projects, budgets, catalogs, and purchasing all in one place.
- Client Management: Complete CRM functionality for tracking client information
- Project Lifecycle: Track projects from initial consultation to completion
- Space Planning: Organize design elements by specific spaces (living room, bedroom, terrace, office, etc.)
- Visual Documentation: Attach renders, plans, and reference images to projects
- Smart Budgeting: Add items from catalog or create custom entries
- Automatic Calculations: Cost + markup = final price with real-time totals
- Visual Budgets: Generate beautiful, image-rich budget presentations for clients
- PDF Export: Print-ready budget documents
- Product Catalog: Global database of furniture, fixtures, and materials
- Product Images: Upload images (JPG, PNG, WebP) to Backblaze B2 or use external URLs. Images are resized to 1200px max and converted to WebP. Images are deleted from B2 when a product is removed or when the URL is changed.
- Supplier Management: Track vendors and their contact information
- Purchase Orders: Automatically generate POs grouped by supplier
- Logistics Tracking: Monitor order status (pending β ordered β received β delivered)
- Project Notes: Keep a project diary with notes and observations
- Document Management: Attach contracts, plans, and other project files
-
Frontend:
- React 19.2.0 with TypeScript
- Vite for build tooling
- Tailwind CSS v4 with custom natural/pastel theme
- Shadcn/UI components (Radix UI primitives)
- React Router for navigation
- React Hook Form + Zod for form validation
-
Backend:
- Supabase (PostgreSQL database)
- Supabase Auth for authentication
- Supabase Storage for file uploads
- Row Level Security (RLS) for data protection
-
Infrastructure:
- Docker & Docker Compose for local development
- Environment-based configuration
- Docker and Docker Compose
- Supabase account (or local Supabase CLI)
- (Optional) Node.js 20+ and npm for local development without Docker
-
Clone the repository
git clone <repository-url> cd interior-design-project
-
Set up Supabase
Option A: Local Development (Recommended)
npx supabase start
This will start Supabase locally and provide connection details.
Option B: Remote Supabase
- Create a project at supabase.com
- Copy your project URL and anon key
-
Configure environment variables
Copy the example file and fill in your values:
cp .env.example .env.local
Edit
.env.localwith your real credentials. The application uses different Supabase keys based on the environment:Local Development:
- Uses
NEXT_PUBLIC_SUPABASE_ANON_KEYfor both client and server
Production:
- Uses
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEYfor client-side (browser-safe with RLS) - Uses
SUPABASE_SECRET_KEYfor server-side (privileged backend access)
- Uses
-
Run database migrations
If using local Supabase:
npx supabase db reset
If using remote Supabase, run the SQL from
supabase/migrations/20251126035338_initial_schema.sqlin your Supabase SQL Editor.
The project is configured to run in a Docker container for consistent development environments.
Start the development server:
docker compose upThis will:
- Build the Docker image if it doesn't exist
- Start the container with the application
- Mount your code for hot-reload
- Expose the app on
http://localhost:5173
Run in detached mode (background):
docker compose up -dView logs:
docker compose logs -fStop the container:
docker compose downRebuild the container (after dependency changes):
docker compose up --buildIf you prefer to run the application locally without Docker:
-
Install dependencies:
npm install
-
Start the development server:
npm run dev
-
Open your browser Navigate to
http://localhost:5173
interior-design-project/
βββ src/
β βββ components/ # Reusable UI components
β β βββ ui/ # Shadcn UI primitives
β β βββ ... # Domain components
β βββ layouts/ # Layout wrappers
β βββ lib/ # Utilities and configs
β βββ pages/ # Route components
β β βββ clients/ # Client management
β β βββ projects/ # Project management
β β βββ catalog/ # Product catalog
β β βββ suppliers/ # Supplier management
β βββ types/ # TypeScript definitions
β βββ ...
βββ supabase/
β βββ migrations/ # Database migrations
β βββ config.toml # Supabase configuration
βββ memory-bank/ # Project documentation
βββ .agents/skills/ # Agent Skills (SKILL.md per skill)
βββ .cursor/rules/ # Cursor rules (.mdc)
βββ ...
- Terms & Privacy: The app includes a legal page (
/legal) with terms of use, privacy policy, and GDPR rights. Registration requires acceptance of terms via a mandatory checkbox.
This project follows security best practices:
- OWASP Top 10 Compliance: All guidelines implemented
- Row Level Security (RLS): Database-level access control
- Input Validation: Zod schemas for all user inputs
- Authentication: Supabase Auth with secure session management
- No Secrets in Code: Environment variables properly configured
- Rate Limiting: API endpoints protected against abuse and brute force
- Image Hostname Restrictions: Only trusted domains allowed for image optimization
See .cursor/rules/01-security.mdc for detailed security guidelines.
API endpoints are protected by rate limiting to prevent abuse and brute force attacks. Limits are configured per route group in src/lib/rate-limit.ts:
const LIMITS: Record<RouteGroup, number> = {
auth: 10, // Requests per minute for /api/auth/*
upload: 20, // Requests per minute for /api/upload/*
"account-delete": 5, // Requests per minute for /api/account/delete
};
const WINDOW_MS = 60_000; // Time window in milliseconds (default: 60 seconds)To customize limits:
- Edit
LIMITSinsrc/lib/rate-limit.tsto adjust requests per minute for each route group - Modify
WINDOW_MSto change the time window (default: 60 seconds)
Rate limit behavior:
- Limits are applied per IP address
- Each route group has independent counters
- When limit is exceeded, API returns
429 Too Many RequestswithRetry-Afterheader
Image optimization via next/image is restricted to trusted domains for security. Configuration is in next.config.ts:
images: {
remotePatterns: [
{
protocol: "https",
hostname: "**.supabase.co",
pathname: "/storage/v1/object/public/**",
},
{
protocol: "https",
hostname: "**.backblazeb2.com",
pathname: "/**",
},
],
}To add or modify allowed image domains:
- Edit
images.remotePatternsinnext.config.ts - Add new pattern objects with:
protocol:"https"or"http"hostname: Domain pattern (use**for subdomain wildcard, e.g.,**.example.com)pathname: Path pattern (use"/**"for all paths or specific patterns like"/images/**")
- Restart the development server or rebuild for changes to take effect
Current allowed domains:
- Supabase Storage:
**.supabase.co(path:/storage/v1/object/public/**) - Backblaze B2:
**.backblazeb2.com(all paths)
Note: If you need to use next/image with other external URLs, add them to remotePatterns. The wildcard hostname: "**" is not allowed for security reasons.
The application uses a custom natural/pastel color palette:
- Primary: Soft Sage Green (
oklch(0.65 0.08 140)) - Secondary: Warm Beige/Sand tones
- Background: Cream whites and deep earthy greens (dark mode)
All colors are defined using the OKLCH color space for perceptual uniformity.
The project uses Vitest and React Testing Library for testing. Tests can be run both inside Docker containers and locally.
Run all tests:
docker compose exec app npm testOr if the container is not running:
docker compose run --rm app npm testRun tests in watch mode:
docker compose exec app npm run test:watchRun tests with UI (interactive mode):
docker compose exec app npm run test:uiGenerate coverage report:
docker compose exec app npm run test:coverageThe coverage report will be generated in the coverage/ directory.
If you have Node.js installed locally, you can run tests directly:
# Run all tests
npm test
# Run tests in watch mode
npm run test:watch
# Run tests with UI (interactive mode)
npm run test:ui
# Generate coverage report
npm run test:coverageTests are located alongside their source files with the .test.ts or .test.tsx extension:
src/lib/utils.test.ts- Utility function testssrc/components/*.test.tsx- Component testssrc/pages/*.test.tsx- Page component tests
Test utilities and mocks are located in src/test/:
src/test/setup.ts- Test configuration and global setupsrc/test/utils.tsx- Testing utilities and custom render functionssrc/test/mocks/- Mock implementations for external dependencies
Build the production image:
docker compose buildBuild and run production build:
You can create a production Dockerfile or use docker compose with a production configuration.
# Build the application
npm run build
# Preview the production build
npm run previewThe production build will be available in the dist/ directory.
Start services:
docker compose upStart in background:
docker compose up -dStop services:
docker compose downRebuild containers:
docker compose up --buildView logs:
docker compose logs -f appExecute commands in container:
# Run npm commands
docker compose exec app npm <command>
# Access shell
docker compose exec app shClean up (remove containers, volumes, networks):
docker compose down -vThe project includes a CI/CD pipeline configured in .github/workflows/ci.yml:
- Automated testing: Runs on every push and PR
- Dependency verification: Uses
npm cifor reproducible builds - Security audits: Automated vulnerability scanning
- Build verification: Ensures the application builds successfully
See docs/ci-cd.md for detailed documentation on the CI/CD process, including:
- Pipeline configuration and jobs
- Dependency integrity verification
- Local development best practices
- Troubleshooting guide
- Follow the coding standards defined in
.cursor/rules/ - Write tests for new features
- Ensure all security guidelines are met
- Use conventional commits
- Run
npm ciand verify tests pass before pushing
[Specify your license here]
Built with modern web technologies and best practices for interior design professionals.
Made with β€οΈ for interior designers