Overview
Task Manager uses db-local, a lightweight file-based JSON database for Node.js. This solution provides a simple, zero-configuration database that’s perfect for development, prototyping, and small-scale applications.db-local stores data in JSON files on the filesystem, making it easy to inspect, backup, and version control your data.
Why db-local?
Zero Configuration
No database server to install or configure. Just import and start using it.
File-Based Storage
Data is stored in JSON files, making it human-readable and easy to debug.
MongoDB-like API
Familiar query syntax with
find(), findOne(), create(), update(), and remove().Lightweight
Minimal dependencies and small footprint—perfect for learning and prototyping.
Database Setup
The database is configured in a single schema file:When you create a schema named
'tasks', db-local automatically creates a file at ./src/DB/tasks.json to store the data.Schema Definitions
Tasks Schema
The Tasks schema defines the structure for task documents:Tasks Schema Fields
Tasks Schema Fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
_id | String | Yes | - | Unique identifier (UUID) |
title | String | Yes | - | Task title (3-25 chars) |
description | String | No | - | Task description |
completed | Boolean | No | false | Completion status |
createdAt | String | Yes | - | ISO timestamp |
updatedAt | String | No | - | ISO timestamp |
finishedAt | String | No | - | ISO timestamp |
categoryId | String | No | "" | Reference to category |
Example Task Document
TaskCategories Schema
The TaskCategories schema is simpler, with just two fields:TaskCategories Schema Fields
TaskCategories Schema Fields
| Field | Type | Required | Description |
|---|---|---|---|
_id | String | Yes | Unique identifier (UUID) |
name | String | Yes | Category name (2-25 chars) |
Example Category Document
UUID Generation
The application uses Node.js’s built-incrypto module to generate unique identifiers:
UUID v4 Characteristics:
- Format:
xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx - Uniqueness: 122 bits of randomness
- Collision Probability: Negligibly small (1 in 5.3 × 10³⁶)
- Example:
a1b2c3d4-e5f6-7890-abcd-ef1234567890
CRUD Operations
db-local provides a MongoDB-like API for data operations:Create
The
.save() method must be called to persist the data to the JSON file.Read
Supported Query Operators
Supported Query Operators
db-local supports MongoDB-style query operators:
-
$in: Match any value in an array -
Exact Match: Simple equality
-
Multiple Conditions: Object with multiple properties
Update
The
update() method performs a partial update, only modifying the specified fields while leaving others unchanged.Delete
Advanced Patterns
Batch Updates
The application implements a batch update pattern in the Task model:Cascading Deletes
The application implements cascading deletes through the service layer:Timestamp Management
The application automatically manages three types of timestamps:createdAt
Set once when the task is created.
updatedAt
Updated every time the task is modified.
finishedAt
Set when a task is marked as completed.
Smart Completion Handling
The Task model intelligently manages thefinishedAt timestamp:
Timestamp Logic Explanation
Timestamp Logic Explanation
Marking Task as Complete:
- When
completedchanges fromfalsetotrue - Set
finishedAtto current timestamp - Preserves the exact moment of completion
- When
completedchanges fromtruetofalse - Delete the
finishedAtfield - Removes misleading completion timestamp
- If
completedstays the same - Don’t modify
finishedAt - Preserves original completion timestamp
Data Persistence
db-local automatically handles data persistence:Every
.save() call writes the entire collection to disk, so db-local is best suited for small to medium datasets. For large-scale applications, consider PostgreSQL, MongoDB, or MySQL.File Structure
The database files are organized as follows:The JSON files are auto-generated by db-local when you first save data. You should add them to
.gitignore if you don’t want to commit your development data.Data Integrity
Type Validation
Schemas enforce basic type validation:While db-local provides basic type checking, the application uses Zod for comprehensive validation before data reaches the database layer.
Referential Integrity
The application maintains referential integrity through application logic:Query Performance
Small Datasets
db-local loads the entire collection into memory, making queries fast for small datasets (< 10,000 documents).
Large Datasets
For larger datasets, consider migrating to a proper database with indexing and query optimization.
Migration Considerations
When your application grows, you might need to migrate from db-local:Migration Path
Migration Path
Indicators You Need to Migrate:
- More than 10,000 records
- Need for complex queries and joins
- Multiple concurrent users
- Need for transactions
- Performance degradation
- MongoDB: Similar API to db-local, easier transition
- PostgreSQL: Powerful relational database with JSON support
- MySQL: Traditional relational database
- SQLite: File-based like db-local, but more powerful
- Export data from JSON files
- Create schema in new database
- Import data
- Update model layer to use new database client
- Controllers and services remain mostly unchanged
Best Practices
Use UUIDs for IDs
Generate unique identifiers with
randomUUID() instead of auto-incrementing numbers.