RuleStack

Configs

Stacks

Compare

Diff

RuleStack

Configs

Stacks

Compare

Diff

Read API

RuleStack

Configs

Stacks

Compare

Diff

Read API

Diff/novuhq-novu-cursor-rules-pullrequest ↔ novuhq-novu-cursor-rules-dal-repository

Comparison

A · Cursor rules · novuhq/novuB · Cursor rules · novuhq/novu
What each file covers, counted
DimensionSharedOnly in AOnly in BOverlap
Sections0110%
Commands000—
Section tags11050%

What each file covers

Sections

0 shared · 1 only in A · 1 only in B
  • − Pull Request Rules
  • + DAL Repository Rules

Commands

neither file has any

Section tags

1 shared · 1 only in A · 0 only in B
  • − git-pr
  •   do-not

Line diff

+21 added−8 removed11 unchanged34.4% identical
novuhq/novu · .cursor/rules/pullrequest.mdc
@@ −1 @@
1---
2description: When creating a new pull request on GitHub, use this to specify the contents
 
3alwaysApply: false
4---
5 
6### Pull Request Rules
7 
8**Title format**: `type(scope): Description fixes NOV-<ticket-id>`
9 
10- When creating a pull requests from any run, verify that there is a linear ticket associated with the pr (From branch name or other), if not, create the linear ticket before creating the PR and attach the linear ticket id in title (fixes NV-XXX)
11- Examples: `feat(dashboard): add workflow trigger button fixes NOV-123`, `fix(api-service): handle null subscriber case fixes NOV-456`
 
12 
 
13 
14**Scopes**: `dashboard`, `api-service`, `worker`, `shared`, `js`, `react`, `react-native`, `nextjs`, `providers`, `root`, `docs`
 
 
 
 
 
 
15 
16**Description**: Summarize what changed and why. List breaking changes. Add screenshots for UI changes. For non-trivial logic or architecture changes, include a concise Mermaid diagram (flow, sequence, or component) so reviewers can grasp the change at a glance.
17 
18**Enterprise packages**: When changes touch `enterprise/`, also open a matching PR in `novuhq/packages-enterprise` on a branch from `next`, and cross-link the two PR bodies (monorepo ↔ enterprise). The Validate Submodule Sync test will fail; this is expected when pointing to the `.source` submodule in the novuhq/novu repository. Do not fix it.
 
 
 
 
19 
novuhq/novu · .cursor/rules/dal-repository.mdc
@@ +1 @@
1---
2description: Rules for working with DAL repositories in the Novu monorepo
3globs: libs/dal/**/*.ts, **/repositories/**/*.ts
4alwaysApply: false
5---
6 
7### DAL Repository Rules
8 
9#### Choosing a base class
10 
11- **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.
14 
15#### BaseRepositoryV2 — required `select`
16 
17- 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 *.
24 
25#### Enforcement (applies to both V1 and V2)
26 
27- **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 
@@ −1 +1 @@
11 ---
2−description: When creating a new pull request on GitHub, use this to specify the contents
2+description: Rules for working with DAL repositories in the Novu monorepo
3+globs: libs/dal/**/*.ts, **/repositories/**/*.ts
34 alwaysApply: false
45 ---
56  
6−### Pull Request Rules
7+### DAL Repository Rules
78  
8−**Title format**: `type(scope): Description fixes NOV-<ticket-id>`
9+#### Choosing a base class
910  
10−- When creating a pull requests from any run, verify that there is a linear ticket associated with the pr (From branch name or other), if not, create the linear ticket before creating the PR and attach the linear ticket id in title (fixes NV-XXX)
11−- Examples: `feat(dashboard): add workflow trigger button fixes NOV-123`, `fix(api-service): handle null subscriber case fixes NOV-456`
11+- **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.
1214  
15+#### BaseRepositoryV2 — required `select`
1316  
14−**Scopes**: `dashboard`, `api-service`, `worker`, `shared`, `js`, `react`, `react-native`, `nextjs`, `providers`, `root`, `docs`
17+- 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 *.
1524  
16−**Description**: Summarize what changed and why. List breaking changes. Add screenshots for UI changes. For non-trivial logic or architecture changes, include a concise Mermaid diagram (flow, sequence, or component) so reviewers can grasp the change at a glance.
25+#### Enforcement (applies to both V1 and V2)
1726  
18−**Enterprise packages**: When changes touch `enterprise/`, also open a matching PR in `novuhq/packages-enterprise` on a branch from `next`, and cross-link the two PR bodies (monorepo ↔ enterprise). The Validate Submodule Sync test will fail; this is expected when pointing to the `.source` submodule in the novuhq/novu repository. Do not fix it.
27+- **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.
1932  
RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack