Skip to main content

Tag

tag is the simplest model in the app โ€” a lightweight label (name + color) used to classify products. It has no relations of its own, but products hold a tags relation to it, so the tag gets a products back-reference injected by the relation engine.

// models/tag.ts (definition, trimmed of the doc comment)
import { coreApp } from "../mod.ts";
import { string } from "lesan";
import { createUpdateAt } from "@lib";

export const tag_pure = {
name: string(),
color: string(),
...createUpdateAt,
};

export const tag_relations = {};

export const tags = () =>
coreApp.odm.newModel("tag", tag_pure, tag_relations, {
createIndex: {
indexSpec: { name: 1 },
options: { unique: true },
},
});

Pure fieldsโ€‹

FieldTypeNotes
namestring()tag text; indexed unique
colorstring()hex code, e.g. #ff5252
createdAt / updatedAtspread from createUpdateAt

Relationsโ€‹

tag_relations is empty. Even so, product.tags declares a back-reference (tag.products), so the model registry still gives tags an implicit products list โ€” populated automatically whenever a product adds the tag.

Factoryโ€‹

export const tags = () =>
coreApp.odm.newModel("tag", tag_pure, tag_relations, {
createIndex: {
indexSpec: { name: 1 },
options: { unique: true },
},
});

The unique name index means you can't create Medical twice โ€” the tag acts as an enforced enum by data.

In the workflowโ€‹

Products attach tags via updateProductRelations โ€” see the product model.

Run itโ€‹

curl -X POST http://localhost:1380/lesan \
-H "Content-Type: application/json" \
-H "token: <jwt>" \
-d '{
"service": "main",
"model": "tag",
"act": "getTags",
"details": { "set": { "page": 1 }, "get": { "name": true, "color": true } }
}'

Errors & fixesโ€‹

ErrorCauseFix
E11000 duplicate key error collection: advancedTutorial.tagsa tag with this name already existsreuse the existing tag, or use a different name
tag not foundupdateTag/removeTag given an unknown _iduse a real tag _id
note

Runtime On npm/Bun import the framework from @hemedani/lesan; on Deno from jsr:@hemedani/lesan. The repo app itself uses the lesan path alias.