The base schema system for MongoDB models in this project provides a standardized, type-safe foundation for defining Mongoose schemas with features like automatic timestamps, soft delete functionality, query helpers, document methods, and centralized model management. This system is implemented in base.schema.ts and is documented in the models directory README.
Architecture and Purpose#
The base schema system is designed to ensure consistency, maintainability, and type safety across all MongoDB models. It provides utilities to create schemas with common features, reducing boilerplate and enforcing best practices for model definition and usage. All models and schema utilities are exported centrally for organized imports throughout the application [README.md] [index.ts].
Features#
Automatic Timestamps#
All schemas created with the base system automatically include created_at and updated_at fields. These are managed by Mongoose and indexed for efficient queries. The base schema options configure these fields and ensure they are included in JSON and object outputs, with internal fields like __v removed from serialized documents [base.schema.ts].
Soft Delete Functionality#
Soft delete is an optional feature that, when enabled, adds deleted_at (Date) and is_deleted (boolean) fields to the schema. Instead of removing documents from the database, soft delete marks them as deleted. By default, all queries exclude soft-deleted documents. You can access or filter deleted documents using provided query helpers. Document methods softDelete() and restore() allow marking a document as deleted or restoring it [base.schema.ts].
Query Helpers#
The base schema system adds query helpers to filter documents based on their soft delete status:
.notDeleted()returns only active (not deleted) documents (default behavior)..onlyDeleted()returns only soft-deleted documents..withDeleted()returns all documents, regardless of deletion status.
These helpers are available on all queries for models with soft delete enabled. Middleware ensures that soft-deleted documents are excluded from queries unless explicitly included [base.schema.ts].
Document Methods#
For schemas with soft delete enabled, each document includes:
softDelete(): Marks the document as deleted by settingdeleted_atandis_deleted.restore(): Restores a soft-deleted document by clearingdeleted_atand settingis_deletedto false.
These methods are available directly on document instances [base.schema.ts].
TypeScript Type Safety#
Type safety is enforced by defining interfaces for documents. The base system provides BaseDocument (with timestamps) and SoftDeleteDocument (with soft delete fields and methods). Query helpers and document methods are typed via TypeScript module augmentation, ensuring full type inference and autocompletion in editors [base.schema.ts].
Creating New Models#
To create a new model using the base schema system:
- Define a TypeScript interface extending
BaseDocumentorSoftDeleteDocumentas appropriate. - Create a schema using
createBaseSchema, passing the field definitions, schema options, a boolean to enable soft delete, and any additional indexes. - Export the model using Mongoose's
modelfunction.
Example: Basic Schema with Timestamps#
import { createBaseSchema, BaseDocument } from './base.schema';
import { model } from 'mongoose';
interface IUser extends BaseDocument {
email: string;
name: string;
}
const userSchema = createBaseSchema<IUser>({
email: { type: String, required: true, unique: true },
name: { type: String, required: true },
});
export const User = model<IUser>('User', userSchema);
Example: Schema with Soft Delete#
import { createBaseSchema, SoftDeleteDocument } from './base.schema';
import { model } from 'mongoose';
interface IProject extends SoftDeleteDocument {
name: string;
description: string;
}
const projectSchema = createBaseSchema<IProject>(
{
name: { type: String, required: true },
description: { type: String },
},
{}, // Additional schema options
true // Enable soft delete
);
export const Project = model<IProject>('Project', projectSchema);
Using Soft Delete Methods and Query Helpers#
// Soft delete a document
const project = await Project.findById(projectId);
await project.softDelete();
// Restore a soft deleted document
await project.restore();
// Query only active (not deleted) documents (default)
const activeProjects = await Project.find();
// Query only deleted documents
const deletedProjects = await Project.find().onlyDeleted();
// Query all documents including deleted
const allProjects = await Project.find().withDeleted();
Centralized Model Exports and Documentation#
All models and schema utilities are exported from backend/src/models/index.ts. This centralizes imports and keeps model management organized. As you create new models, export them from this file. The base schema utilities are also exported here for reuse [index.ts].
Model documentation, conventions, and usage guidelines are maintained in backend/src/models/README.md. This includes naming conventions (kebab-case for files, PascalCase for interfaces and models, snake_case for collections), schema usage, and export practices [README.md].
For further details and advanced usage, refer to the in-repo documentation.