Skip to main content

Database Models

Overview

The Notes App uses MongoDB as its database with Mongoose as the Object Document Mapper (ODM). Mongoose provides a schema-based solution to model application data, adding structure and validation to the flexible MongoDB documents.

What is Mongoose?

Mongoose is a JavaScript library that acts as a bridge between Node.js and MongoDB. It provides:

  • Schema definitions - Structure for documents with data types and validation
  • Model creation - JavaScript classes that represent collections in MongoDB
  • Query building - Methods to interact with the database
  • Middleware - Functions that run before or after certain operations

Database Connection

The application connects to MongoDB using the connection string from config.json:

const mongoose = require("mongoose");
const config = require("./config.json");
const db_url = config.connectionString;
mongoose.connect(db_url);

This establishes a connection to the MongoDB database when the server starts.

User Model

File: backend/models/user.model.js

The User model represents user accounts in the system.

const userSchema = new Schema({
fullName: {type: String},
email: {type: String},
password: {type: String},
createOn: {type: Date, default: new Date().getTime()},
})

Schema Fields Explained

  • fullName: Stores the user's display name as a string
  • email: Stores the user's email address for login identification
  • password: Stores the user's password (stored as plain text - security concern)
  • createOn: Timestamp of when the account was created, defaults to current time

Key Characteristics

  • No validation: The schema doesn't enforce required fields or email format validation
  • Plain text passwords: Passwords are stored without encryption (not recommended for production)
  • Simple structure: Minimal fields for basic user management

Usage in Application

The User model is used for:

  • Account creation (/create-account endpoint)
  • User authentication (/login endpoint)
  • User information retrieval (/get-user endpoint)

Note Model

File: backend/models/note.model.js

The Note model represents individual notes created by users.

const noteSchema = new Schema({
title: {type: String, required: true},
content: {type: String, required: true},
tags: {type: [String], default: []},
isPinned: {type: Boolean, default: false},
title: {type: String, required: true}, // Duplicate field
userId: {type: String, required : true},
createOn: {type: Date, default: new Date().getTime()},
})

Schema Fields Explained

  • title: The note's title (required field, appears twice due to error)
  • content: The main text content of the note (required)
  • tags: Array of string tags for categorization (defaults to empty array)
  • isPinned: Boolean flag to mark important notes (defaults to false)
  • userId: Links the note to its owner (required for data isolation)
  • createOn: Timestamp of note creation

Key Characteristics

  • Required fields: Title, content, and userId must be provided
  • Default values: Tags default to empty array, isPinned defaults to false
  • User association: Each note belongs to a specific user via userId
  • Schema error: Title field is defined twice (line 4 and 8)

Usage in Application

The Note model supports all note operations:

  • Creating notes (/add-note endpoint)
  • Editing notes (/edit-note/:noteId endpoint)
  • Deleting notes (/delete-note/:noteId endpoint)
  • Pinning/unpinning (/update-note-pinned/:noteId endpoint)
  • Retrieving all notes (/get-all-notes endpoint)
  • Searching notes (/search-notes endpoint)

Data Relationships

User to Notes Relationship

The application implements a one-to-many relationship:

  • One User can have many Notes
  • Each Note belongs to exactly one User

This is achieved through the userId field in the Note model, which stores the User's MongoDB _id.

// When creating a note
const note = new Note({
title,
content,
tags: tags || [],
userId: user._id, // Links note to user
});

Data Isolation

User data is isolated by always filtering notes by userId:

// Get user's notes only
const notes = await Note.find({ userId: user._id });

// Edit only user's own notes
const note = await Note.findOne({ _id: noteId, userId: user._id });

Database Operations

Common Query Patterns

Find by user: Note.find({ userId: user._id }) Sort by pinned status: .sort({ isPinned: -1 }) (pinned notes first) Search with regex: { title: { $regex: new RegExp(query, "i") } } (case-insensitive) Find one specific note: Note.findOne({ _id: noteId, userId: user._id })

MongoDB Features Used

  • Regular expressions for search functionality
  • Sorting to prioritize pinned notes
  • Array fields for tags storage
  • Boolean fields for pinned status
  • Date fields with default values

Security Considerations

Current Issues

  1. Plain text passwords: User passwords are stored without hashing
  2. No input validation: Schema lacks validation rules for email format
  3. No field constraints: Missing length limits or format requirements

Data Access Control

The application properly implements user data isolation by always including userId in database queries, ensuring users can only access their own notes.