The recommended approach in Modelence is to group code by modules/domains into separate directories. For our Todo app, create an src/server/todo directory and add a db.ts file:
src/server/todo/db.ts
Copy
Ask AI
import { Store, schema } from 'modelence/server';export const dbTodos = new Store('todos', { // Define the schema for your documents. Modelence schema is based on and closely resembles Zod types. schema: { title: schema.string(), isCompleted: schema.boolean(), dueDate: schema.date().optional(), userId: schema.userId(), // Built-in Modelence type for user references createdAt: schema.date(), }, // Configure MongoDB indexes indexes: [ { key: { userId: 1 } }, { key: { dueDate: 1 } }, ], // Add custom methods to documents methods: { isOverdue() { return this.dueDate ? this.dueDate < new Date() : false; } }});
Stores provide a comprehensive set of methods for working with MongoDB documents, including finding, inserting, updating, and deleting records. All methods are fully typed with TypeScript.See the Store API Reference for a complete list of available methods and their usage.
Stores automatically handle MongoDB connection management, collection provisioning and index creation. Just define your Store and start using it - Modelence takes care of the rest.
Modules are the core building blocks of a Modelence application. They help you organize your application’s functionality into cohesive units that can contain queries, mutations, stores, cron jobs and configurations.Create a new file at src/server/todo/index.ts:
src/server/todo/index.ts
Copy
Ask AI
import { Module } from 'modelence/server';import { dbTodos } from './db';export default new Module('todo', { /* Include the store we created earlier so it will be automatically provisioned in MongoDB when the server starts. */ stores: [dbTodos], /* Module queries and mutations are similar to the corresponding concepts from GraphQL. */ queries: { async getOne({ id }) { return await dbTodos.findById(id); }, async getAll() { return await dbTodos.fetch({}); } }, mutations: { async create({ title, dueDate }, { user }) { const { insertedId } = await dbTodos.insertOne({ title, dueDate, userId: user.id, isCompleted: false, createdAt: new Date() }); return insertedId; }, async update({ id, title, dueDate, isCompleted }) { return await dbTodos.updateOne({ id }, { $set: { title, dueDate, isCompleted } }); }, async delete({ id }) { return await dbTodos.deleteOne({ id }); } },});
Modelence is frontend-agnostic, so you are free to use any routing library you like.
We will use React Router for this example, which is what’s included in the default Modelence starter.