Documentation Index
Fetch the complete documentation index at: https://docs.mejik.web.id/llms.txt
Use this file to discover all available pages before exploring further.
MongoDB is a perfect choice for this kind of system due to its flexible schema. The Collection-per-Type pattern you’ve suggested is a great way to maintain clarity and optimize indexes for specific asset types.
Here is a high-level design using this pattern, with detailed document structures for a generalAssets collection and a specific itAssets collection.
1. Design Principle: Collection-per-Type
- Base Fields in Every Collection: We will define a set of common fields (the “base schema”) that will exist in every asset collection. This consistency is enforced at the application layer (e.g., through a base class or a schema validation library like Mongoose or Zod).
- Specific Fields per Collection: Each collection will extend the base schema with fields that are unique to that asset type.
- No Inheritance at the DB Level: Unlike the relational model, there’s no direct inheritance or joining. Each document in a collection is self-contained. To find “all assets assigned to a user,” you would need to query each relevant asset collection (
generalAssets, itAssets, etc.) and merge the results in your application.
2. Base Field Set Structure
This is the common structure that will be part of every asset document, regardless of its collection.
// --- BASE ASSET FIELDS ---
{
"_id": ObjectId("..."), // Automatically generated by MongoDB
"assetTag": "string", // Unique, human-readable identifier (e.g., "GEN-MTR-0012")
"name": "string", // Descriptive name (e.g., "Forklift 3B", "Conference Room Projector")
"status": "string", // e.g., 'In Use', 'In Storage', 'Under Maintenance', 'Decommissioned'
"location": { // Embedded object for location details
"building": "string",
"floor": "string",
"room": "string",
"description": "string" // e.g., "Northwest corner of Warehouse B"
},
"manufacturer": "string", // e.g., "Toyota", "Caterpillar", "Epson"
"purchaseInfo": { // Grouped purchasing information
"purchaseDate": "Date",
"vendor": "string",
"cost": "Number",
"warrantyExpiryDate": "Date"
},
"assignment": { // Grouped assignment information
"assignedToUserId": "ObjectId", // Reference to a 'users' collection
"assignedToName": "string", // Denormalized for quick display
"assignmentDate": "Date"
},
"notes": "string", // General purpose notes field
"audit": { // Timestamps
"createdAt": "Date",
"updatedAt": "Date"
}
}
3. Document Structure for generalAssets Collection
This collection will store assets like vehicles and machinery. We’ll add a category field to differentiate them within this collection and a flexible specifications object.
Example Document: A Vehicle in generalAssets
// Collection: generalAssets
{
// --- BASE ASSET FIELDS (Copied from above) ---
"_id": ObjectId("638d1c7a5d1e4e3f8b0e7a12"),
"assetTag": "VEH-TRK-007",
"name": "Field Operations Pickup Truck",
"status": "In Use",
"location": {
"building": "Main Garage",
"floor": "1",
"room": "Bay 3",
"description": "Parking spot G3"
},
"manufacturer": "Ford",
"purchaseInfo": {
"purchaseDate": "2022-08-15T00:00:00.000Z",
"vendor": "City Ford Dealership",
"cost": 45000.50,
"warrantyExpiryDate": "2025-08-14T00:00:00.000Z"
},
"assignment": {
"assignedToUserId": ObjectId("638d1c0a5d1e4e3f8b0e7a01"),
"assignedToName": "John Doe",
"assignmentDate": "2022-09-01T00:00:00.000Z"
},
"notes": "Equipped with a toolbox and ladder rack.",
"audit": {
"createdAt": "2022-08-15T14:30:00.000Z",
"updatedAt": "2023-11-20T10:00:00.000Z"
},
// --- GENERAL ASSET SPECIFIC FIELDS ---
"category": "VEHICLE", // Discriminator within this collection
"specifications": {
// Fields specific to a VEHICLE
"vin": "1FTRExAMPLEvIN7GA12345",
"licensePlate": "5XYZ123",
"model": "F-150",
"year": 2022,
"mileage": 25480,
"fuelType": "Gasoline",
"lastServiceDate": "2023-10-15T00:00:00.000Z"
}
}
Example Document: Machinery in generalAssets
Notice how the specifications object structure changes based on the category.
// Collection: generalAssets
{
// ... Base Asset Fields ...
"assetTag": "MAC-FL-003",
"name": "Warehouse Forklift 3B",
"category": "MACHINERY",
"specifications": {
// Fields specific to MACHINERY
"serialNumber": "CAT-SN-987654321",
"modelNumber": "DP25N",
"hoursOfOperation": 4120,
"maxLoadKg": 2500,
"lastMaintenanceDate": "2023-09-30T00:00:00.000Z"
}
}
4. Document Structure for itAssets Collection
This collection is specifically for IT equipment and has a different set of specific fields tailored to technology.
Example Document: A Laptop in itAssets
// Collection: itAssets
{
// --- BASE ASSET FIELDS (Copied from above) ---
"_id": ObjectId("638d1d8f5d1e4e3f8b0e7b45"),
"assetTag": "IT-LPT-01124",
"name": "Dell Latitude 7420",
"status": "In Use",
"location": {
"building": "Building A",
"floor": "4",
"room": "401",
"description": "Desk 4-15"
},
"manufacturer": "Dell",
"purchaseInfo": {
"purchaseDate": "2023-01-20T00:00:00.000Z",
"vendor": "Dell Corporate Sales",
"cost": 1850.50,
"warrantyExpiryDate": "2026-01-19T00:00:00.000Z"
},
"assignment": {
"assignedToUserId": ObjectId("638d1c0a5d1e4e3f8b0e7a05"),
"assignedToName": "Jane Smith",
"assignmentDate": "2023-01-25T00:00:00.000Z"
},
"notes": "Docking station and two monitors included.",
"audit": {
"createdAt": "2023-01-20T11:00:00.000Z",
"updatedAt": "2023-01-25T09:15:00.000Z"
},
// --- IT ASSET SPECIFIC FIELDS ---
"network": {
"hostname": "LPT-JSMITH-PROD",
"macAddress": "9C:B6:D0:FF:1A:3E",
"ipAddress": "192.168.1.152"
},
"hardware": {
"cpu": "Intel Core i7-1185G7",
"ram": {
"sizeGb": 16,
"type": "DDR4"
},
"storage": [ // An array to support multiple drives
{
"type": "SSD",
"sizeGb": 512
}
]
},
"software": {
"operatingSystem": {
"name": "Windows 11 Pro",
"version": "22H2"
}
}
}
Summary of Benefits with this MongoDB Design
- Schema Flexibility: You can easily add a new field to
itAssets (e.g., isEncrypted) without affecting any other collection. The specifications object in generalAssets can hold vastly different structures for a vehicle vs. a generator.
- Query Performance: Queries within a single collection are highly optimized. Finding all laptops with 16GB of RAM (
db.itAssets.find({"hardware.ram.sizeGb": 16})) is very fast because the query only scans the relevant collection.
- Clarity and Maintainability: As you requested, separating asset types into their own collections makes the system’s structure intuitive. A developer working on IT asset features can focus entirely on the
itAssets collection and its schema.
- Scalability: Adding a new asset class, like
Furniture, is as simple as creating a new furnitureAssets collection and defining its document structure in your application code.