A production-ready multi-tenant notes application with role-based access control, subscription management, and comprehensive testing.
Warning
- Features
- Tech Stack
- Getting Started
- Configuration
- Testing
- Development Workflow
- API Documentation
- Deployment
- Architecture
- Contributing
- License
- Multi-tenant Architecture - Complete data isolation between organizations
- Role-Based Access Control - Admin and Member roles with fine-grained permissions
- Subscription Management - Free tier (3 notes) and Pro tier (unlimited notes)
- Rich Text Editor - Powered by TipTap for seamless content creation
- Optimistic UI Updates - Real-time feedback for better user experience
- Theme Support - Dark and light modes with system preference detection
- Comprehensive Testing - Unit, integration, and end-to-end test coverage
- Security First - NextAuth.js authentication, bcrypt password hashing, tenant isolation
Layer | Technology |
---|---|
Frontend | Next.js 15 (App Router), React 19 |
Backend | Next.js API Routes (Serverless) |
Database | PostgreSQL with Prisma ORM |
Authentication | NextAuth.js |
Styling | Tailwind CSS + shadcn/ui |
Testing | Jest (Unit/Integration) + Playwright (E2E) |
Deployment | Vercel |
Package Manager | pnpm |
Ensure you have the following installed:
- Node.js 20 or higher
- pnpm (Install via
npm install -g pnpm
) - PostgreSQL database (local installation or cloud provider like Supabase/Neon)
- Clone the repository:
git clone https://github.com/RanitManik/lucide-note.git
cd lucide-note
- Install dependencies:
pnpm install
- Configure environment variables:
Copy the example environment file and update the values:
cd apps/web
cp .env.example .env
Then edit .env
with your actual values:
# Database
DATABASE_URL="postgresql://username:password@host:port/database"
DIRECT_URL="postgresql://username:password@host:port/database"
# Authentication
NEXTAUTH_URL="http://localhost:3000"
NEXTAUTH_SECRET="your-nextauth-secret-here"
# GitHub OAuth
GITHUB_CLIENT_ID="your-github-client-id"
GITHUB_CLIENT_SECRET="your-github-client-secret"
# Email (Brevo)
BREVO_API_KEY="your-brevo-api-key-here"
BREVO_FROM_EMAIL="noreply@yourdomain.com"
BREVO_FROM_NAME="lucide note"
- Run database migrations:
cd apps/web
pnpm db:migrate
- Seed the database with test data:
pnpm db:seed
This creates two test tenants with sample users and notes.
Start the development server:
pnpm dev
Open http://localhost:3000 in your browser.
Use these credentials to explore the application (password: password
for all):
Acme Corporation:
admin@acme.test
- Administrator with full permissionsuser@acme.test
- Regular member
Globex Corporation:
admin@globex.test
- Administrator with full permissionsuser@globex.test
- Regular member
Variable | Description | Url |
---|---|---|
DATABASE_URL |
PostgreSQL connection string (pooled) | Supabase |
DIRECT_URL |
Direct PostgreSQL connection (migrations) | Supabase |
NEXTAUTH_URL |
Base URL of your application | - |
NEXTAUTH_SECRET |
Secret for NextAuth session encryption | Generate |
GITHUB_CLIENT_ID |
GitHub OAuth client ID | GitHub |
GITHUB_CLIENT_SECRET |
GitHub OAuth client secret | GitHub |
GOOGLE_CLIENT_ID |
Google OAuth client ID | |
GOOGLE_CLIENT_SECRET |
Google OAuth client secret | |
BREVO_API_KEY |
Brevo email API key | Brevo |
BREVO_FROM_EMAIL |
Verified sender email for Brevo | Brevo |
BREVO_FROM_NAME |
Sender name for emails | Brevo |
# Development
pnpm dev # Start development server (localhost:3000)
pnpm build # Create production build
pnpm start # Start production server
pnpm lint # Run ESLint
pnpm format # Format code with Prettier
# Database Operations
pnpm db:migrate # Apply database migrations
pnpm db:seed # Seed database with test data
pnpm db:generate # Regenerate Prisma client
pnpm db:studio # Open Prisma Studio (database GUI)
pnpm db:reset # Reset database (⚠️ destroys all data)
# Testing
pnpm test # Run all tests
pnpm test:unit # Run unit tests only
pnpm test:e2e # Run end-to-end tests
pnpm test:watch # Run tests in watch mode
# Git Workflow
pnpm commit # Interactive commit with Commitizen
This project maintains high test coverage across multiple layers:
pnpm test:unit
Tests individual functions, components, and utilities in isolation.
pnpm test:integration
Tests API routes, database interactions, and business logic.
pnpm test:e2e
Tests complete user workflows across the entire application.
This project uses several tools to maintain code quality and consistency:
- EditorConfig - Consistent coding styles across editors
- Prettier - Automatic code formatting
- ESLint - Code linting and best practices
- Husky - Git hooks for automation
- lint-staged - Run checks only on staged files
- Commitlint - Enforce commit message conventions
- Commitizen - Interactive commit creation
Pre-commit: Automatically runs on every commit
- Formats code with Prettier
- Lints code with ESLint
- Fixes auto-fixable issues
Commit-msg: Validates commit message format
This project follows Conventional Commits. Use the interactive prompt:
pnpm commit
Or format manually:
<type>(<scope>): <subject>
[optional body]
[optional footer]
Types:
feat
- New featurefix
- Bug fixdocs
- Documentation changesstyle
- Code style changes (formatting, semicolons, etc.)refactor
- Code refactoringtest
- Adding or updating testschore
- Maintenance tasksperf
- Performance improvementsci
- CI/CD changesbuild
- Build system changesrevert
- Revert previous commit
Examples:
feat(notes): add markdown export functionality
fix(auth): resolve token expiration edge case
docs(readme): update installation instructions
Category | Endpoint | Method | Description |
---|---|---|---|
Authentication | /api/auth/register |
POST | Register new user account with email verification |
Authentication | /api/auth/forgot-password |
POST | Request password reset email |
Authentication | /api/auth/reset-password |
POST | Reset password using reset token |
Authentication | /api/auth/send-verification |
POST | Send email verification link |
Authentication | /api/auth/verify-email |
GET | Verify email address using verification token |
Authentication | /api/auth/[...nextauth] |
GET/POST | NextAuth.js authentication (login, OAuth, session management) |
Notes | /api/notes |
GET | Retrieve all notes for the authenticated user's tenant |
Notes | /api/notes |
POST | Create a new note (enforces free plan limits) |
Notes | /api/notes/:id |
GET | Retrieve a specific note by ID (tenant-scoped) |
Notes | /api/notes/:id |
PUT | Update an existing note (tenant-scoped) |
Notes | /api/notes/:id |
DELETE | Delete a note (tenant-scoped) |
Organization | /api/organization/create |
POST | Create a new organization and assign current user as admin |
Organization | /api/organization/invite |
POST | Send invitation emails to join the organization |
Tenant | /api/tenant |
GET | Get current tenant information including plan and usage |
Tenants | /api/tenants/:slug/upgrade |
POST | Upgrade tenant to Pro plan (admin only) |
Health Check | /api/health |
GET | Service health check endpoint |
- Push code to GitHub:
git push origin main
-
Import project in Vercel:
- Go to vercel.com
- Click "Import Project"
- Select your repository
-
Configure environment variables:
- Add
DATABASE_URL
- Add
NEXTAUTH_SECRET
- Add
-
Deploy:
- Vercel will automatically build and deploy
- Run migrations on first deploy:
npx prisma migrate deploy
# Build the application
pnpm build
# Run production migrations
pnpm db:migrate:prod
# Start production server
pnpm start
This application implements shared schema multi-tenancy:
┌─────────────────────────────────────┐
│ PostgreSQL Database │
├─────────────────────────────────────┤
│ Tables (with tenant_id column) │
│ ├── tenants │
│ ├── users (tenant_id FK) │
│ ├── notes (tenant_id FK) │
│ └── subscriptions (tenant_id FK) │
└─────────────────────────────────────┘
Key Characteristics:
- Single database schema shared by all tenants
- Every table contains a
tenant_id
column - All queries automatically filtered by current tenant
- Complete data isolation enforced at application level
- Cost-effective and scalable for SMB applications
- 🔐 Authentication: NextAuth.js with session-based authentication
- 🔒 Authorization: Role-based access control (Admin/Member)
- 🛡️ Data Isolation: Row-level tenant filtering on all queries
- 🔑 Password Security: Bcrypt hashing with salt rounds
- 🌐 CORS: Configured for secure cross-origin requests
- 🚫 SQL Injection: Parameterized queries via Prisma
Contributions are welcome! Please follow these guidelines:
- Fork the repository
- Create a feature branch (
git checkout -b feat/amazing-feature
) - Make your changes
- Commit using conventional commits (
pnpm commit
) - Push to your branch (
git push origin feat/amazing-feature
) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.