Skip to content

ayushkaneriya05/notes-application

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

28 Commits
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ“ Notes Application

Node.js Express MongoDB Mongoose React Vite JWT Deploy with Vercel

A full-stack multi-tenant Notes application (backend + frontend) built with strict tenant isolation using a shared-schema approach.
This repository demonstrates multi-tenancy, authentication & authorization, tenant-scoped routing, and a complete frontend workflow.


πŸ“‘ Table of Contents


πŸ”Ž Overview

This application implements a multi-tenant notes system where multiple organizations can sign up and manage their own notes.

  • Strict isolation ensures that users from one tenant can never access another tenant’s data.
  • Includes backend (Node.js/Express/MongoDB) and frontend (React/Vite).
  • Comes with seeded tenants (Acme and Globex) for local testing.

πŸ— Multi-Tenancy Approach

Approach: Shared schema with tenant identifier (tenant ObjectId).

Why this approach?

  • Simple, efficient, and works well with MongoDB + Mongoose.
  • Matches existing code structure: models already include a tenant field.
  • Seed script supports multiple tenants (Acme, Globex) out of the box.

Isolation Enforcement

  1. Schema-level
    • All tenant-scoped models include tenant: ObjectId (ref: Tenant) as a required field.
  2. Authentication Middleware
    • Populates req.user with tenant info from JWT.
  3. Route-level Filtering
    • All queries filter by tenant: req.user.tenant._id.
  4. Seed Validation
    • Use provided tenants (Acme, Globex) to validate isolation.

πŸ“‚ Data Models

Tenant (notes-backend/models/Tenant.js)

  • name: String (required)
  • slug: String (required, unique)
  • plan: Enum (FREE, PRO), default: FREE

User (notes-backend/models/User.js)

  • name: String
  • email: String (required, unique)
  • password: String (hashed, required)
  • role: Enum (ADMIN, MEMBER), default: MEMBER
  • tenant: ObjectId (ref: Tenant, required)

Note (notes-backend/models/Note.js)

  • title: String
  • content: String
  • tenant: ObjectId (ref: Tenant, required)
  • createdBy: ObjectId (ref: User, required)

πŸ” Authentication & Authorization

  • Login: POST /auth/login β†’ returns JWT + user + tenant info.
  • JWT Middleware: verifies token, attaches req.user with tenant.
  • Role Guard: requireRole('ADMIN') β†’ ensures admin-only access.
  • Change Password: POST /auth/change-password.

🚏 Backend Routes

Route Method Description Auth Required Notes
/auth/login POST Authenticate user ❌ Returns token + tenant info
/auth/change-password POST Change password βœ… Verifies old password
/notes GET List notes βœ… Tenant-scoped
/notes POST Create note βœ… Enforces tenant + plan limit
/notes/:id GET View note βœ… Tenant filter applied
/notes/:id PUT Update note βœ… Tenant filter applied
/notes/:id DELETE Delete note βœ… Tenant filter applied
/tenants/:slug/upgrade POST Upgrade plan βœ… (Admin) Validates tenant slug
/tenants/invite POST Invite user βœ… (Admin) Creates new user in tenant

🌱 Seeded Tenants & Test Accounts

Run the seed script:

MONGO_URI="your-mongo-uri" JWT_SECRET="a-secret" node seed.js

Tenants

  • Acme (slug: acme, plan: FREE)
  • Globex (slug: globex, plan: FREE)

Users (default password: password)

  • admin@acme.test β†’ Admin (Acme)
  • user@acme.test β†’ Member (Acme)
  • admin@globex.test β†’ Admin (Globex)
  • user@globex.test β†’ Member (Globex)

πŸš€ Vercel Deployment

This project is configured for a monorepo deployment on Vercel, with separate projects for the backend and frontend.

1. Database Setup (MongoDB Atlas)

  • Create a free cluster on MongoDB Atlas.
  • In the Network Access tab, add 0.0.0.0/0 to the IP Access List.

    This is required to allow Vercel's serverless functions to connect.

  • In the Database Access tab, create a database user and save the password.
  • Get your connection string (Drivers β†’ Node.js) and replace <password> with your user's password.
    This is your MONGO_URI.

2. Backend Deployment

  • Create a New Vercel Project: Import your Git repository.
  • Configure Project:
    • Project Name: e.g., notes-application-backend
    • Root Directory: notes-backend
  • Environment Variables:
    • MONGO_URI: The full connection string from MongoDB Atlas.
    • JWT_SECRET: A secure, random string for signing tokens.
  • Deploy: Vercel will use the notes-backend/vercel.json file to deploy the Express app as a serverless function.
    Note the deployed URL (e.g., https://your-backend.vercel.app).

3. Frontend Deployment

  • Create Another Vercel Project: Import the same Git repository again.
  • Configure Project:
    • Project Name: e.g., notes-application-frontend
    • Root Directory: notes-frontend
  • Environment Variables:
    • VITE_API_URL: The URL of your deployed backend from the previous step.
  • Deploy: Vercel will use the notes-frontend/vercel.json file to correctly handle client-side routing.

🎨 Frontend Structure

Located in notes-frontend/src/:

  • components/ β†’ UI components (Navbar, NoteModal, InviteModal, etc.)
  • context/ β†’ AuthContext, ToastContext for global state & messages
  • lib/ β†’ api.js (centralized API helper)
  • pages/ β†’ LoginPage, NotesPage, UpgradePage
  • App.jsx β†’ App bootstrap & routing

Frontend Auth Flow

  1. User logs in β†’ token stored in AuthContext + localStorage.
  2. All API calls attach Authorization: Bearer <token>.
  3. On 401 Unauthorized, user is logged out automatically.

Local Setup

Backend

cd notes-backend
npm install
# Required ENV variables
export MONGO_URI="your-mongo-uri"
export JWT_SECRET="your-secret"
npm run seed   # seeds Acme & Globex
npm start

Frontend

cd notes-frontend
npm install
npm run dev
# App runs on http://localhost:5173 (default Vite port)

πŸ“‘ API Endpoints Reference

  • POST /auth/login β†’ { token, user, tenant }
  • POST /auth/change-password β†’ Change password
  • GET /notes β†’ List tenant notes
  • POST /notes β†’ Create tenant note (enforces plan limits)
  • GET /notes/:id β†’ View note
  • PUT /notes/:id β†’ Update note
  • DELETE /notes/:id β†’ Delete note
  • POST /tenants/:slug/upgrade β†’ Upgrade plan (Admin only)
  • POST /tenants/invite β†’ Invite user (Admin only)

πŸ”’ Security & Hardening

  • βœ… Indexes: { tenant, createdAt } on notes, { tenant, email } on users

  • βœ… JWT best practices: rotate keys, use HTTPS, HttpOnly cookies if needed

  • βœ… Input validation: enforce via Joi / express-validator

  • βœ… Rate limiting: mitigate brute force attacks

  • πŸ”œ Suggested:

    • Tenant scoping middleware
    • Mongoose plugin to auto-enforce tenant presence

πŸ“¬ Contact

Built and maintained by Ayush Kaneriya.


About

A full-stack multi-tenant Notes application built with React, Vite, Express, Node.js, and MongoDB. Features authentication with JWT, CRUD operations, tenant isolation, and seamless deployment on Vercel (monorepo setup).

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors