> ## Documentation Index
> Fetch the complete documentation index at: https://ayakaleaf-pro.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Tags Collection

`tags` holds the tags (folders) that a user sorts projects into on the project dashboard. One document is one tag of one user. `web` owns it; the schema is `services/web/app/src/models/Tag.mjs`, and all writes go through `services/web/app/src/Features/Tags/TagsHandler.mjs`.

#### Fields

| Field | Type | Meaning | Source |
| - | - | - | - |
| `_id` | ObjectId | Tag id, used in the `/tag/:tagId` routes. | `Tag.mjs:10` |
| `user_id` | String | Owner of the tag. A plain string, not an ObjectId, for legacy reasons. | `Tag.mjs:7-12` |
| `name` | String | Tag name, at most 50 characters (`MAX_TAG_LENGTH`). Unique per user. | `Tag.mjs:13`, `TagsHandler.mjs:4` |
| `color` | String | Optional colour: a hex code like `#a1b2c3` or an `hsl(<n>, 70%, 45%)` value (`TAG_COLOR_REGEX`). | `Tag.mjs:5`, `Tag.mjs:14-22` |
| `project_ids` | Array of String | Ids of the projects in this tag, as strings. | `Tag.mjs:23` |
| `__v` | Number | Mongoose version key, added when `Tag.create` makes the document. | `TagsHandler.mjs:27` |

#### Who Writes It

| Code | What it does |
| - | - |
| `TagsHandler.mjs:18-35` (`createTag`) | `POST /tag` (`services/web/app/src/router.mjs:873-874`). On a duplicate name it returns the existing tag. |
| `TagsHandler.mjs:37-70` (`renameTag`, `editTag`) | `POST /tag/:tagId/rename` and `/tag/:tagId/edit` (`router.mjs:879-886`): set `name`, or `name` and `color`. |
| `TagsHandler.mjs:72-77` (`deleteTag`) | `DELETE /tag/:tagId` (`router.mjs:891-892`). |
| `TagsHandler.mjs:79-113` | Add or remove one or many projects (`$addToSet` / `$pull` / `$pullAll` on `project_ids`), routes `router.mjs:897-916`. |
| `TagsHandler.mjs:124-128` (`removeProjectFromAllTags`) | Called for every member when a project is deleted (`services/web/app/src/Features/Project/ProjectDeleter.mjs:236-238`) and when a user is removed from or leaves a project (`services/web/app/src/Features/Collaborators/CollaboratorsController.mjs:621`). |
| `TagsHandler.mjs:130-134` (`addProjectToTags`) | Puts a copied project into the same tags as the original (`services/web/app/src/Features/Project/ProjectDuplicator.mjs:190-194`). |
| `services/web/modules/server-ce-scripts/scripts/rename-tag.mjs:20-23` | Admin script that renames a tag of one user directly in Mongo. |

#### Who Reads It

| Code | What it does |
| - | - |
| `TagsHandler.mjs:6-8` (`getAllTags`) | Project dashboard (`services/web/app/src/Features/Project/ProjectListController.mjs:313`, `:747`), `GET /tag` and the private API `GET /user/:userId/tag` (`router.mjs:863-869`). |
| `TagsHandler.mjs:14-16` (`getTagsForProject`) | Tags of the open project in the editor (`services/web/app/src/Features/Project/ProjectController.mjs:672`). |
| `TagsHandler.mjs:10-12` (`countTagsForProject`) | Analytics count when a project is copied (`ProjectDuplicator.mjs:98`). |

#### Indexes

| Name | Keys | Options | Migration |
| - | - | - | - |
| `user_id_1_name_1` | `{ user_id: 1, name: 1 }` | unique | `tools/migrations/20190912145029_create_tags_indexes.mjs` |

The same migration also created `user_id_1`; `tools/migrations/20231031164732_drop_redundant_indexes.mjs` drops it again, as the compound index covers it.

#### Notes

* Tags are per user: two collaborators of the same project each keep their own tags for it.
* `user_id` and `project_ids` are strings, so query them with string ids, not ObjectIds.
* Deleting a user (`services/web/app/src/Features/User/UserDeleter.mjs`) does not touch `tags`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.