Skip to content

✨ CollabNote is a full-stack note-taking app built with a modern tech-stack: NestJS, Next.js, Vite, and Supabase, designed for collaborative note management. It features user authentication, note sharing, responsive design, and API documentation, making it an efficient and modern tool for organizing and sharing notes.

License

Notifications You must be signed in to change notification settings

hoangsonww/CollabNote-Fullstack-App

Repository files navigation

CollabNote - A NestJS, Next.js, Vite, and Supabase Fullstack Notetaking App

NestJS Next.js Vite Supabase PostgreSQL Swagger GraphQL React TypeScript Docker Nginx Kubernetes Jenkins ShadCN

CollabNote is a collaborative notes platform designed to help you take, share, and manage notes effectively. It features a user-friendly interface, powerful backend APIs, and seamless deployment for both frontend and backend.

Table of Contents

🚀 Features

  • Authentication: Secure user login, registration, and password management.
  • Notes Management: Create, update, delete, and reorder notes.
  • Sharing: Share notes with other users seamlessly.
  • Syncing: Real-time syncing of notes across devices, and across users, thanks to Supabase.
  • Collaboration: Collaborate with others on notes in real-time.
  • Search: Search for notes by title or content.
  • User Profiles: Manage and search user profiles.
  • Profile Settings: Update user profile information.
  • Dark Mode: Toggle between light and dark themes.
  • Testing: Unit and integration tests for backend and frontend.
  • Responsive Design: Works on all devices and screen sizes.
  • Swagger Documentation: Comprehensive API documentation.
  • CI/CD Pipeline: Jenkins pipeline for automated testing and deployment.

🚀 Deployment

The app is deployed on Vercel for the frontend. You can access the live app at CollabNote.

Additionally, the backend API is deployed on Render. You can access the API documentation at CollabNote API.

The backup frontend is also hosted on Netlify, which you can access at CollabNote Netlify.

Note: The backend API may spin down due to inactivity. If you encounter any issues, please try again later. If inactive, the API may take a few seconds to start up, so frontend requests and Swagger may take some time to load initially.

🎯 Tech Stack

Technology Description
NestJS Backend framework for scalable APIs
Next.js React-based framework for SSR
React Frontend library for building UI
Vite Frontend build tool
Supabase Backend-as-a-service for auth & DB
PostgreSQL Database for storing app data
TypeScript Type-safe development
Swagger API documentation and testing tool
ShadCN UI components for a modern design
Docker Containerization for apps
Nginx Web server for load balancing
Kubernetes Container orchestration platform
Jenkins CI/CD tool for automation
Render Cloud platform for hosting apps
Vercel Cloud platform for frontend hosting
Netlify Cloud platform for hosting apps
GraphQL Query language for APIs

🖼️ UI Overview

Home Page

Login Page

Home Page - Dark Mode

Login Page - Dark Mode

Notes Dashboard

Notes Dashboard

Notes Dashboard - Dark Mode

Notes Dashboard - Dark Mode

Add Note Modal

Add Note Modal

Note Details Modal

Note Details Page

Note Editor

Note Editor

Profile Page

Profile Page

Profile Page - Dark Mode

Profile Page - Dark Mode

Login Page

Login Page

Login Page - Dark Mode

Login Page - Dark Mode

Register Page

Register Page

Register Page - Dark Mode

Register Page - Dark Mode

Reset Password Page

Reset Password Page

Reset Password Page - Dark Mode

Reset Password Page - Dark Mode

API Documentation

Swagger Documentation

📂 Project Structure

DocuThinker-AI-App/
├── backend/
│   ├── src/
│   │   ├── auth/
│   │   │   ├── auth.module.ts        # Authentication module
│   │   │   ├── auth.controller.ts    # Authentication controller
│   │   │   ├── auth.service.ts       # Authentication service
│   │   │   ├── auth.schema.ts        # Authentication schema
│   │   │   ├── auth.resolver.ts      # Authentication resolver
│   │   │   └── jwt.strategy.ts       # JWT authentication strategy
│   │   ├── dto/
│   │   │   ├── create-note.input.ts  # Create note DTO
│   │   │   └── update-note.input.ts  # Update note DTO
│   │   ├── notes/
│   │   │   ├── notes.schema.ts       # Notes schema
│   │   │   ├── notes.resolver.ts     # Notes resolver
│   │   │   ├── notes.module.ts       # Notes module
│   │   │   ├── notes.controller.ts   # Notes controller
│   │   │   └── notes.service.ts      # Notes service
│   │   ├── profile/
│   │   │   ├── profile.schema.ts     # Profile schema
│   │   │   ├── profile.resolver.ts   # Profile resolver
│   │   │   ├── profile.module.ts     # Profile module
│   │   │   ├── profile.controller.ts # Profile controller
│   │   │   └── profile.service.ts    # Profile service
│   │   ├── supabase/
│   │   │   ├── supabase.module.ts    # Supabase module
│   │   │   └── supabase.service.ts   # Supabase service
│   │   ├── types/
│   │   │   └── authenticated-request.ts  # Authenticated user type
│   │   ├── schema.gql                # GraphQL schema 
│   │   ├── app.module.ts             # Main app module
│   │   ├── app.test.ts               # App test file
│   │   └── main.ts                   # Main entry point for the backend
│   ├── .env                          # Environment variables (git-ignored)
│   ├── build-backend.sh              # Shell script to build the backend
│   ├── Dockerfile                    # Docker configuration file
│   ├── docker-compose.yml            # Docker Compose file for the backend
│   ├── package.json                  # Project dependencies and scripts
│   ├── package-lock.json             # Lock file for dependencies
│   ├── tsconfig.json                 # TypeScript configuration file
│   └── vercel.json                   # Vercel configuration file
│
├── frontend/
│   ├── public/
│   │   ├── favicon.ico               # Favicon for the app
│   │   ├── (other images...)         # Other images used in the app
│   │   ├── index.html                # Main HTML template
│   │   └── manifest.json             # Manifest for PWA settings
│   ├── src/
│   │   ├── assets/                   # Static assets like images and fonts
│   │   │   └── logo.png              # App logo or images
│   │   ├── components/
│   │   │   ├── LoadingOverlay.tsx    # Loading overlay component
│   │   │   └── PasswordField.tsx     # Password field component
│   │   ├── layout/
│   │   │   ├── ResponsiveDrawer.tsx  # Responsive drawer component
│   │   │   ├── Footer.tsx            # Footer component
│   │   │   ├── Layout.tsx            # Main layout component
│   │   │   └── Navbar.tsx            # Navbar component
│   │   ├── routes/
│   │   │   ├── ForgotPasswordPage.tsx   # Forgot password page
│   │   │   ├── HomePage.tsx          # Home page
│   │   │   ├── LoginPage.tsx         # Login page
│   │   │   ├── NoteDetailsPage.tsx   # Note details page
│   │   │   ├── NotesPage.tsx         # Notes dashboard page
│   │   │   ├── ProfilePage.tsx       # Profile page
│   │   │   └── RegisterPage.tsx      # Register page
│   │   ├── theme/
│   │   │   ├── index.ts              # Theme configuration
│   │   │   ├── ThemeContext.tsx      # Theme context provider
│   │   │   └── ThemeProviderWrapper.tsx  # Theme provider wrapper
│   │   ├── App.tsx                   # Main App component
│   │   ├── App.test.tsx              # App test file
│   │   ├── App.css                   # Global CSS 1
│   │   ├── index.css                 # Global CSS 2
│   │   ├── main.tsx                  # Main entry point for the frontend
│   │   └── vite-env.d.ts             # Vite environment types
│   ├── .gitignore                    # Git ignore file
│   ├── package.json                  # Project dependencies and scripts
│   ├── package-lock.json             # Lock file for dependencies
│   ├── Dockerfile                    # Docker configuration file
│   ├── docker-compose.yml            # Docker Compose file for the frontend
│   ├── index.html                    # Main HTML template
│   ├── build-frontend.sh             # Shell script to build the frontend
│   ├── vercel.json                   # Vercel configuration file
│   ├── vite.config.ts                # Vite configuration file
│   ├── tsconfig.app.json             # TypeScript configuration file for the app
│   ├── tsconfig.node.json            # TypeScript configuration file for Node
│   └── tsconfig.json                 # TypeScript configuration file
│
├── kubernetes/                       # Kubernetes configuration files
│   ├── backend-deployment.yaml       # Deployment configuration for the backend
│   ├── backend-service.yaml          # Service configuration for the backend
│   ├── frontend-deployment.yaml      # Deployment configuration for the frontend
│   ├── frontend-service.yaml         # Service configuration for the frontend
│   └── configmap.yaml                # ConfigMap configuration for environment variables
│
├── nginx/
│   ├── start_nginx.sh                # Shell script to start NGINX
│   ├── nginx.conf                    # NGINX configuration file for load balancing and caching
│   ├── docker-compose.yml            # Docker Compose file for NGINX
│   └── Dockerfile                    # Docker configuration file for NGINX
│
├── images/                           # Images for the README
├── .env                              # Environment variables file for the whole app
├── docker-compose.yml                # Docker Compose file for containerization
├── package.json                      # Project dependencies and scripts
├── package-lock.json                 # Lock file for dependencies
├── vercel.json                       # Vercel configuration file
├── openapi.yaml                      # OpenAPI specification for API documentation
├── jenkins_cicd.sh                   # Shell script for managing the Jenkins CI/CD pipeline
├── .gitignore                        # Git ignore file
├── LICENSE                           # License file for the project
├── README.md                         # Comprehensive README for the whole app
└── (and many more files...)          # Additional files and directories not listed here

🛠️ Getting Started

Follow these steps to set up the project on your local machine.

Prerequisites

Ensure you have the following installed:

  • Node.js: v18 or above
  • npm: v9 or above
  • PostgreSQL: v15 or above
  • Docker (Optional)

Installation

  1. Clone the Repository:

    git clone https://github.com/hoangsonww/CollabNote-Fullstack-App.git
    cd CollabNote-Fullstack-App
  2. Set Up Backend:

    cd backend
    npm install
  3. Set Up Frontend:

    cd ../frontend
    npm install
  4. Configure Environment Variables:

  • Create .env files in the backend and frontend directories.
  • For backend (backend/.env):
    SUPABASE_URL=your_supabase_url
    SUPABASE_SERVICE_KEY=your_supabase_service_key
    JWT_SECRET=your_jwt_secret
    JWT_EXPIRES_IN=jwt_expiry_time(eg. 1d)
    PORT=4000
  • For frontend (frontend/.env):
    VITE_API_URL=http://localhost:4000

Running Locally

  1. Start the Backend:

    cd backend
    npm run start:dev
  2. Start the Frontend:

    cd ../frontend
    npm run dev
  3. Open your browser:

Using Docker

  1. Build and Run Docker Containers:

    docker-compose up --build
  2. Access the Services:

📖 API Documentation

All APIs are documented in Swagger. Access the documentation at http://localhost:4000/api.

API Endpoints

Method Endpoint Description
POST /auth/register Register a new user
POST /auth/login Login an existing user
POST /auth/check-email-exists Check if an email exists
POST /auth/reset-password Reset a user's password
GET /notes Retrieve user notes
POST /notes Create a new note
PATCH /notes/{id} Update a note
DELETE /notes/{id} Delete a note
POST /notes/{id}/share Share a note with another user
POST /notes/reorder Reorder user notes
GET /profile/me Retrieve the authenticated user's profile
GET /profile/userId/{id} Retrieve a user profile by ID
GET /profile/search Search for a user profile by username
PATCH /profile/me Update the authenticated user's profile

Database Schema

The database schema consists of the following tables:

Database Schema

Note the user_id foreign key relationship between the notes and users tables. Additionally, more tables will be added as the app grows in the future!

Detailed Guide for Using the openapi.yaml File

  1. View the API Documentation
  • Open Swagger Editor.
  • Upload the openapi.yaml file or paste its content.
  • Visualize and interact with the API documentation.
  1. Test the API
  • Import openapi.yaml into Postman:
    • Open Postman → Import → Select openapi.yaml.
    • Test the API endpoints directly from Postman.
  • Or use Swagger UI:
    • Provide the file URL or upload it to view and test endpoints.
  1. Generate Client Libraries
  • Install OpenAPI Generator:
    npm install @openapitools/openapi-generator-cli -g
  • Generate a client library:
    openapi-generator-cli generate -i openapi.yaml -g <language> -o ./client
  • Replace <language> with the desired programming language.
  1. Generate Server Stubs
  • Generate a server stub:
    openapi-generator-cli generate -i openapi.yaml -g <framework> -o ./server
  • Replace <framework> with the desired framework.
  1. Run a Mock Server
  • Install Prism:
    npm install -g @stoplight/prism-cli
  • Start the mock server:
    prism mock openapi.yaml
  1. Validate the OpenAPI File
  • Use Swagger Validator:
    • Upload openapi.yaml or paste its content to check for errors.

This guide enables you to view, test, and utilize the API.

🖥️ GraphQL Integration

The CollabNote API also supports GraphQL for querying and manipulating data.

To access, navigate to https://collabnote-fullstack-app.onrender.com/graphql and use the GraphQL Playground to interact with the API.

Alternatively, you can start a local backend server following the steps above and access the GraphQL Playground at http://localhost:4000/graphql.

You should see something like this:

GraphQL Playground

You can query something like this:

query {
  getUserNotes(userId: 1, searchQuery: "", tagFilter: "") {
    id
    title
    content
    tags
    dueDate
    color
    pinned
    sharedWithUserIds
    sortOrder
    username
  }
}

This query fetches all notes for a user with ID 1. You can modify the query to suit your needs.

Feel free to explore the GraphQL API and test different queries and mutations! Consult the GraphQL documentation for more information.

🧰 Nginx Configuration

  • The nginx directory contains an Nginx configuration for reverse proxy and load balancing.
  • Use Nginx to route requests to multiple instances of the API.
  • Configure SSL termination and caching for improved performance.
  • The Nginx configuration looks like this:
server {
    listen 80;
    server_name localhost;

    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}

🌐 Kubernetes Deployment

  1. Create Kubernetes manifests for the services.

  2. Deploy to a cluster:

    kubectl apply -f kubernetes/
  3. Access the application using the service URL.

👨🏻‍💻 Continuous Integration and Deployment with Jenkins

The CollabNote API also includes a Jenkins pipeline for continuous integration and deployment.

  1. Pipeline Configuration: The Jenkinsfile defines the CI/CD pipeline stages, including code checkout, dependency installation, testing, building, and deployment. Add it to the root of the project.

  2. Job Setup: Create a pipeline job in Jenkins, point it to the repository, and configure it to use the Jenkinsfile.

  3. Automated Testing: The pipeline runs npm test to ensure all tests pass before proceeding to the build or deployment stages.

  4. Environment Variables: Use Jenkins environment variables to securely manage secrets like API keys and credentials for services such as MongoDB, Redis, or Render.

  5. Deployment: The pipeline supports deploying the application using Render or directly to a server using SSH and PM2.

  6. Webhooks: Integrate GitHub/GitLab webhooks to trigger builds automatically on code changes.

  7. Notifications: Add Slack or email notifications in the pipeline to inform team members about build and deployment statuses.

🧪 Testing

We also feature Jest unit and integration tests for both the backend and frontend. Run the tests to ensure the app functions as expected.

Backend Tests

cd backend
npm run test

Frontend Tests

cd frontend
npm run test

🤝 Contributing

Contributions are welcome! Please fork the repository and create a pull request.

📄 License

This project is licensed under the MIT License.

🎉 Acknowledgments

  • Son Nguyen: Creator and maintainer of CollabNote.
  • NestJS, Next.js, React, Vite: The tech stack that powers this project.

Thank you for visiting CollabNote today! Happy notetaking! 📝🚀

🔝 Back to Top

About

✨ CollabNote is a full-stack note-taking app built with a modern tech-stack: NestJS, Next.js, Vite, and Supabase, designed for collaborative note management. It features user authentication, note sharing, responsive design, and API documentation, making it an efficient and modern tool for organizing and sharing notes.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published