Cursor rule
.cursor/rules/dal-repository.mdcRules for working with DAL repositories in the Novu monorepo
Cursor rules
Quality
46/100
Scores the file, not the repository.Length
373 words
4 headings · 0 code blocksRepository
39k
— · pushed 0 days agoLast changed
3 days ago
First indexed 3 days ago.1234567### DAL Repository Rules89#### Choosing a base class1011- **New repositories must extend `BaseRepositoryV2`** — it enforces required field selection and provides auto-inferred return types (`Pick<Entity, Keys>`).12- **Existing repositories stay on `BaseRepository`** — `BaseRepository` is deprecated but must not be changed; all 32 existing repos continue to extend it.13- Do NOT extend `BaseRepository` for any new repository going forward.1415#### BaseRepositoryV2 — required `select`1617- Every read method (`find`, `findOne`, `findById`, `findBatch`, `findWithCursorBasedPagination`) requires an explicit `select` argument — there is no default `SELECT *`.18- Use array syntax as the default: `find(query, ['_id', 'name', 'status'])`. Array syntax returns exactly the listed fields — `_id` is excluded unless explicitly included.19- Use object syntax when you need MongoDB-style projections where `_id` is included by default: `findOne(query, { name: 1, email: 1 })`, or explicitly excluded: `findOne(query, { _id: 0, name: 1 })`.20- Exclusion projections for non-`_id` fields (e.g. `{ name: 0 }`) are intentionally unsupported — they are a compile error.21- Return types are automatically inferred as `Pick<Entity, Keys>` — do not manually annotate the return type.22- Use `select: '*'` to retrieve all fields with a fully-typed `Entity` return (instead of a `Pick`). All five read methods support this overload: `find(query, '*')`, `findOne(query, '*')`, `findById(id, '*')`, `findBatch(query, '*')`, and `findWithCursorBasedPagination({ select: '*', ... })`.23- Omitting `select` entirely is still a compile error — `'*'` is the explicit opt-in for SELECT *.2425#### Enforcement (applies to both V1 and V2)2627- **Never use `_model` or `MongooseModel` directly** in repository methods. Always use the inherited methods (`update`, `find`, `findOne`, `delete`, `create`, `bulkWrite`, etc.) which enforce `_environmentId` / `_organizationId` via the `EnforceEnvOrOrgIds` type.28- All query methods must include `_environmentId` or `_organizationId` in their filter to satisfy the enforcement type constraint.29- When adding new repository methods that need `$push`, `$pull`, or other update operators, pass the `environmentId` as a parameter and use `this.update()` with the enforcement fields.30- For bulk operations, use `this.bulkWrite()` instead of `this._model.updateMany()`.31- **Transactions**: start via `repository.withTransaction(async (session) => { ... })` and pass `session` to every repo call inside it (e.g. `repo.findOne(query, select, { session })`). Run all operations sequentially — parallel execution (`Promise.all`, etc.) inside a transaction is undefined behaviour in Mongoose.32
Also in novuhq/novu
Diff this repo’s formatsOne repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| novuhq/novu.cursor/rules/api-property-optionality-hygiene.mdc · 39k | Cursor rules | gitagent-behaviour | 68/100 | 3 days ago | |
| novuhq/novu.cursor/rules/api.mdc · 39k | Cursor rules | styleapi | 72/100 | 3 days ago | |
| novuhq/novu.cursor/rules/clickhouse.mdc · 39k | Cursor rules | style | 42/100 | 3 days ago | |
| novuhq/novu.cursor/rules/context-engineering.mdc · 39k | Cursor rules | no sections | 16/100 | 3 days ago | |
| novuhq/novu.cursor/rules/dashboard.mdc · 39k | Cursor rules | style | 57/100 | 3 days ago | |
| novuhq/novu.cursor/rules/dependency-graph.mdc · 39k | Cursor rules | no sections | 22/100 | 3 days ago | |
| novuhq/novu.cursor/rules/docs-mintlify-steps.mdc · 39k | Cursor rules | do-notagent-behaviour | 43/100 | 3 days ago | |
| novuhq/novu.cursor/rules/infrastructure.mdc · 39k | Cursor rules | no sections | 50/100 | 3 days ago | |
| novuhq/novu.cursor/rules/novu.mdc · 39k | Cursor rules | style | 20/100 | 3 days ago | |
| novuhq/novu.cursor/rules/packages.mdc · 39k | Cursor rules | stylearchdependenciesdocs | 46/100 | 3 days ago | |
| novuhq/novu.cursor/rules/pnpm-release-age.mdc · 39k | Cursor rules | no sections | 24/100 | 3 days ago | |
| novuhq/novu.cursor/rules/pullrequest.mdc · 39k | Cursor rules | gitdo-not | 37/100 | 3 days ago | |
| novuhq/novu.cursor/rules/safe-api-tests.mdc · 39k | Cursor rules | setupteststyletesting-strategy+4 | 88/100 | 3 days ago | |
| novuhq/novu.cursor/rules/testing.mdc · 39k | Cursor rules | teststyletesting-strategy | 54/100 | 3 days ago | |
| novuhq/novu.cursor/rules/worker.mdc · 39k | Cursor rules | style | 65/100 | 3 days ago | |
| novuhq/novu.cursor/rules/ws.mdc · 39k | Cursor rules | style | 51/100 | 3 days ago | |
| novuhq/novu.deepsec/AGENTS.md · 39k | AGENTS.md | setupagent-behaviour | 33/100 | 3 days ago | |
| novuhq/novuAGENTS.md · 39k | AGENTS.md | builddo-notagent-behaviour | 63/100 | 3 days ago |
Diff against .cursor/rules/api-property-optionality-hygiene.mdc Diff against .cursor/rules/api.mdc Diff against .cursor/rules/clickhouse.mdc Diff against .cursor/rules/context-engineering.mdc Diff against .cursor/rules/dashboard.mdc Diff against .cursor/rules/dependency-graph.mdc Diff against .cursor/rules/docs-mintlify-steps.mdc Diff against .cursor/rules/infrastructure.mdc Diff against .cursor/rules/novu.mdc Diff against .cursor/rules/packages.mdc Diff against .cursor/rules/pnpm-release-age.mdc Diff against .cursor/rules/pullrequest.mdc Diff against .cursor/rules/safe-api-tests.mdc Diff against .cursor/rules/testing.mdc Diff against .cursor/rules/worker.mdc Diff against .cursor/rules/ws.mdc Diff against .deepsec/AGENTS.md Diff against AGENTS.md
Similar configs
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| hiromaily/go-crypto-wallet.cursor/rules/typescript.mdc · 126 | Cursor rules | setupbuildtestlint-format+6 | 100/100 | 3 days ago | |
| TechSquidTV/Hermes.cursor/rules/10-hermes-api.mdc · 45 | Cursor rules | testlint-formatstylearch+5 | 100/100 | 3 days ago | |
| markstev/mark-starter.cursor/rules/frontend.mdc · 0 | Cursor rules | setuptestlint-formatstyle+6 | 99/100 | 3 days ago | |
| Allymahmoud/case-intake-platform.cursor/rules/frontend.mdc · 0 | Cursor rules | setuptestlint-formatstyle+7 | 99/100 | 3 days ago | |
| deifos/clipmira-subtitles.cursor/rules/frontend.mdc · 1 | Cursor rules | setuptestlint-formatstyle+7 | 99/100 | 3 days ago | |
| dodgecfr/combatfilms-webapp.cursor/rules/frontend.mdc · 0 | Cursor rules | setuptestlint-formatstyle+7 | 99/100 | 3 days ago | |
| langflow-ai/langflow.cursor/rules/docs_development.mdc · 153k | Cursor rules | setupbuildtestlint-format+7 | 97/100 | 3 days ago | |
| TechSquidTV/Hermes.cursor/rules/20-hermes-api-tests.mdc · 45 | Cursor rules | teststyletesting-strategysecurity+3 | 97/100 | 3 days ago |
