-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path.cursorrules
More file actions
172 lines (123 loc) · 5.32 KB
/
.cursorrules
File metadata and controls
172 lines (123 loc) · 5.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# Architecture – Feature-Sliced Design
We use Feature-Sliced Design (FSD) in this project.
## Layers (from top to bottom)
1. app # Next.js routing only (app/ at repo root)
2. processes # (optional) cross-page flows
3. pages # page-level composition
4. widgets # reusable, page-agnostic UI sections
5. features # user-facing actions / use-cases
6. entities # domain models (Room, Message, User, ...)
7. shared # pure shared utilities, UI primitives, config
### Layer dependency rules
- Upper layers may depend on the same or lower layers.
- Lower layers MUST NOT import upper layers.
Concretely:
- app → can import: processes, pages, widgets, features, entities, shared
- pages → can import: widgets, features, entities, shared
- widgets → can import: features, entities, shared
- features → can import: entities, shared
- entities → can import: shared
- shared → must NOT import from any other layer
## Slices and public API
- Each slice lives under its layer, e.g.:
- src/features/auth/login
- src/pages/home
- src/widgets/room
- src/entities/room
- Inside a slice we use segments:
- ui/ – React components
- model/ – hooks, business logic, side-effects
- lib/ – pure functions
- api/ – API clients (if needed)
- config/ – constants, slice config (if needed)
- Every slice MUST expose a public API via its root index file:
- src/features/auth/login/index.ts
- src/pages/home/index.ts
- src/widgets/room/index.ts
- src/entities/room/index.ts
- Import from slices ONLY through their public API:
- ✅ import { LoginForm } from "@/features/auth/login"
- ❌ import { LoginForm } from "@/features/auth/login/ui/LoginForm"
## Pages vs Widgets vs Features
- Pages (`src/pages/*`):
- Compose widgets, features, and entities into a full page.
- May contain `ui/components/*` for page-specific UI that is not reused.
- Must NOT contain business logic, data fetching, or mutations directly.
- Delegate those to `features/*` or `entities/*`.
- Widgets (`src/widgets/*`):
- Reusable, independent page sections (e.g. HomeHero, RoomHeader, SiteFooter).
- Must NOT depend on specific pages.
- Can compose features, entities, and shared UI.
- If a UI block is only used inside a single page and is tightly coupled to it,
keep it in `src/pages/<page>/ui/components` instead of widgets.
- Features (`src/features/*`):
- Represent user-facing actions / use-cases, e.g.:
- `auth/login`, `auth/signup`, `meeting/create-room`, `meeting/generate-notes`
- Handle side-effects: mutations, data submission, event handlers.
- Can use:
- React Query / fetch clients
- entities’ types and helpers
- shared utilities and UI primitives
- Must NOT know about routing or specific page layouts.
## Entities
- `src/entities/*` hold domain models and their basic UI representations.
- Example: `entities/room`, `entities/message`, `entities/user`.
- May contain:
- model/room.types.ts
- model/room.api.ts (query helpers)
- ui/RoomBadge.tsx, ui/MessageBubble.tsx
- Entities must not depend on features, widgets, pages, or app.
## Shared
- `src/shared/*` is the lowest-level layer.
- Contains:
- shared/ui – design system primitives (Button, Input, Modal, etc.)
- shared/lib – pure utilities (validation, date, audio, etc.)
- shared/config – runtime config, env parsing
- shared/types – global/common types
- Shared must not import from any FSD layer.
- Shared should be implementation-agnostic and reusable across slices.
## Next.js routing
- The routing layer lives in the root `app/` directory only.
- Example:
- app/page.tsx
- app/login/page.tsx
- app/home/page.tsx
- app/room/[roomId]/page.tsx
- Route components MUST:
- Only compose FSD pages/widgets/features.
- Not contain business logic or data fetching directly
(delegate to features/entities).
- Example:
- `app/login/page.tsx` should re-use `src/pages/auth-login`:
- `import { LoginPage } from "@/pages/auth-login"`
- `export default function Page() { return <LoginPage /> }`
## Import path rules
- Always use TS path aliases instead of long relative paths:
- ✅ "@/pages/home"
- ✅ "@/features/auth/login"
- ✅ "@/entities/room"
- ✅ "@/shared/ui/button"
- Do not import across layers using relative paths like:
- ❌ "../../features/auth/login"
- ❌ "../../../shared/lib/validation"
- Do not import deep internal files of other slices:
- ❌ "@/features/auth/login/ui/LoginForm"
- ✅ "@/features/auth/login"
## Same-layer dependencies
- Within a slice (e.g. `entities/room`), segments (`ui/`, `model/`, `lib/`) may depend on each other.
- Avoid circular dependencies where possible.
- Between slices in the same layer:
- Prefer composition from an upper layer or extracting shared logic to a lower layer.
- Features:
- Avoid importing one feature from another feature.
- If two features share logic, move it to `entities/*` or `shared/*`.
- Widgets:
- Avoid widgets importing other widgets.
- Compose multiple widgets inside `pages/*` instead.
- Entities:
- May occasionally import types/helpers from other entities,
but be careful with strong bidirectional coupling.
If it happens often, reconsider the domain boundaries.
- Pages:
- Must not import other pages.
- Shared UI between pages should go to `widgets/*` or `features/*`.