create-tigra 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +87 -0
  3. package/bin/create-tigra.js +292 -0
  4. package/package.json +41 -0
  5. package/template/.agent/rules/client/01-project-structure.md +326 -0
  6. package/template/.agent/rules/client/02-component-patterns.md +249 -0
  7. package/template/.agent/rules/client/03-typescript-rules.md +226 -0
  8. package/template/.agent/rules/client/04-state-management.md +474 -0
  9. package/template/.agent/rules/client/05-api-integration.md +129 -0
  10. package/template/.agent/rules/client/06-forms-validation.md +129 -0
  11. package/template/.agent/rules/client/07-common-patterns.md +150 -0
  12. package/template/.agent/rules/client/08-color-system.md +93 -0
  13. package/template/.agent/rules/client/09-security-rules.md +97 -0
  14. package/template/.agent/rules/client/10-testing-strategy.md +370 -0
  15. package/template/.agent/rules/global/ai-edit-safety.md +38 -0
  16. package/template/.agent/rules/server/01-db-and-migrations.md +242 -0
  17. package/template/.agent/rules/server/02-general-rules.md +111 -0
  18. package/template/.agent/rules/server/03-migrations.md +20 -0
  19. package/template/.agent/rules/server/04-pagination.md +130 -0
  20. package/template/.agent/rules/server/05-project-conventions.md +71 -0
  21. package/template/.agent/rules/server/06-response-handling.md +173 -0
  22. package/template/.agent/rules/server/07-testing-strategy.md +506 -0
  23. package/template/.agent/rules/server/08-observability.md +180 -0
  24. package/template/.agent/rules/server/09-api-documentation-v2.md +168 -0
  25. package/template/.agent/rules/server/10-background-jobs-v2.md +185 -0
  26. package/template/.agent/rules/server/11-rate-limiting-v2.md +210 -0
  27. package/template/.agent/rules/server/12-performance-optimization.md +567 -0
  28. package/template/.claude/rules/client-01-project-structure.md +327 -0
  29. package/template/.claude/rules/client-02-component-patterns.md +250 -0
  30. package/template/.claude/rules/client-03-typescript-rules.md +227 -0
  31. package/template/.claude/rules/client-04-state-management.md +475 -0
  32. package/template/.claude/rules/client-05-api-integration.md +130 -0
  33. package/template/.claude/rules/client-06-forms-validation.md +130 -0
  34. package/template/.claude/rules/client-07-common-patterns.md +151 -0
  35. package/template/.claude/rules/client-08-color-system.md +94 -0
  36. package/template/.claude/rules/client-09-security-rules.md +98 -0
  37. package/template/.claude/rules/client-10-testing-strategy.md +371 -0
  38. package/template/.claude/rules/global-ai-edit-safety.md +39 -0
  39. package/template/.claude/rules/server-01-db-and-migrations.md +243 -0
  40. package/template/.claude/rules/server-02-general-rules.md +112 -0
  41. package/template/.claude/rules/server-03-migrations.md +21 -0
  42. package/template/.claude/rules/server-04-pagination.md +131 -0
  43. package/template/.claude/rules/server-05-project-conventions.md +72 -0
  44. package/template/.claude/rules/server-06-response-handling.md +174 -0
  45. package/template/.claude/rules/server-07-testing-strategy.md +507 -0
  46. package/template/.claude/rules/server-08-observability.md +181 -0
  47. package/template/.claude/rules/server-09-api-documentation-v2.md +169 -0
  48. package/template/.claude/rules/server-10-background-jobs-v2.md +186 -0
  49. package/template/.claude/rules/server-11-rate-limiting-v2.md +211 -0
  50. package/template/.claude/rules/server-12-performance-optimization.md +568 -0
  51. package/template/.cursor/rules/client-01-project-structure.mdc +327 -0
  52. package/template/.cursor/rules/client-02-component-patterns.mdc +250 -0
  53. package/template/.cursor/rules/client-03-typescript-rules.mdc +227 -0
  54. package/template/.cursor/rules/client-04-state-management.mdc +475 -0
  55. package/template/.cursor/rules/client-05-api-integration.mdc +130 -0
  56. package/template/.cursor/rules/client-06-forms-validation.mdc +130 -0
  57. package/template/.cursor/rules/client-07-common-patterns.mdc +151 -0
  58. package/template/.cursor/rules/client-08-color-system.mdc +94 -0
  59. package/template/.cursor/rules/client-09-security-rules.mdc +98 -0
  60. package/template/.cursor/rules/client-10-testing-strategy.mdc +371 -0
  61. package/template/.cursor/rules/global-ai-edit-safety.mdc +39 -0
  62. package/template/.cursor/rules/server-01-db-and-migrations.mdc +243 -0
  63. package/template/.cursor/rules/server-02-general-rules.mdc +112 -0
  64. package/template/.cursor/rules/server-03-migrations.mdc +21 -0
  65. package/template/.cursor/rules/server-04-pagination.mdc +131 -0
  66. package/template/.cursor/rules/server-05-project-conventions.mdc +72 -0
  67. package/template/.cursor/rules/server-06-response-handling.mdc +174 -0
  68. package/template/.cursor/rules/server-07-testing-strategy.mdc +507 -0
  69. package/template/.cursor/rules/server-08-observability.mdc +181 -0
  70. package/template/.cursor/rules/server-09-api-documentation-v2.mdc +169 -0
  71. package/template/.cursor/rules/server-10-background-jobs-v2.mdc +186 -0
  72. package/template/.cursor/rules/server-11-rate-limiting-v2.mdc +211 -0
  73. package/template/.cursor/rules/server-12-performance-optimization.mdc +568 -0
  74. package/template/CLAUDE.md +207 -0
  75. package/template/server/.env.example +148 -0
  76. package/template/server/.tsc-aliasrc.json +12 -0
  77. package/template/server/README.md +175 -0
  78. package/template/server/SECURITY.md +190 -0
  79. package/template/server/biome.json +42 -0
  80. package/template/server/docker-compose.yml +111 -0
  81. package/template/server/package.json +83 -0
  82. package/template/server/postman_collection.json +733 -0
  83. package/template/server/prisma/schema.prisma +92 -0
  84. package/template/server/prisma/seed.ts +142 -0
  85. package/template/server/scripts/wait-for-db.js +60 -0
  86. package/template/server/src/app.ts +74 -0
  87. package/template/server/src/config/env.ts +101 -0
  88. package/template/server/src/hooks/request-timing.hook.ts +26 -0
  89. package/template/server/src/libs/auth/authenticate.middleware.ts +22 -0
  90. package/template/server/src/libs/auth/rbac.middleware.test.ts +134 -0
  91. package/template/server/src/libs/auth/rbac.middleware.ts +147 -0
  92. package/template/server/src/libs/db.ts +76 -0
  93. package/template/server/src/libs/error-handler.ts +89 -0
  94. package/template/server/src/libs/logger.ts +60 -0
  95. package/template/server/src/libs/queue.ts +79 -0
  96. package/template/server/src/libs/redis.ts +79 -0
  97. package/template/server/src/libs/swagger-schemas.ts +16 -0
  98. package/template/server/src/modules/admin/admin.controller.ts +122 -0
  99. package/template/server/src/modules/admin/admin.routes.ts +100 -0
  100. package/template/server/src/modules/admin/admin.schemas.ts +35 -0
  101. package/template/server/src/modules/admin/admin.service.ts +167 -0
  102. package/template/server/src/modules/auth/auth.controller.ts +141 -0
  103. package/template/server/src/modules/auth/auth.integration.test.ts +150 -0
  104. package/template/server/src/modules/auth/auth.repo.ts +218 -0
  105. package/template/server/src/modules/auth/auth.routes.ts +204 -0
  106. package/template/server/src/modules/auth/auth.schemas.ts +137 -0
  107. package/template/server/src/modules/auth/auth.service.test.ts +119 -0
  108. package/template/server/src/modules/auth/auth.service.ts +329 -0
  109. package/template/server/src/modules/auth/auth.types.ts +97 -0
  110. package/template/server/src/modules/resources/resources.controller.ts +218 -0
  111. package/template/server/src/modules/resources/resources.repo.ts +253 -0
  112. package/template/server/src/modules/resources/resources.routes.ts +355 -0
  113. package/template/server/src/modules/resources/resources.schemas.ts +146 -0
  114. package/template/server/src/modules/resources/resources.service.ts +218 -0
  115. package/template/server/src/modules/resources/resources.types.ts +73 -0
  116. package/template/server/src/plugins/rate-limit.plugin.ts +21 -0
  117. package/template/server/src/plugins/security.plugin.ts +21 -0
  118. package/template/server/src/plugins/swagger.plugin.ts +41 -0
  119. package/template/server/src/routes/health.routes.ts +31 -0
  120. package/template/server/src/server.ts +142 -0
  121. package/template/server/src/test/setup.ts +38 -0
  122. package/template/server/src/types/fastify.d.ts +36 -0
  123. package/template/server/src/utils/errors.ts +108 -0
  124. package/template/server/src/utils/pagination.ts +120 -0
  125. package/template/server/src/utils/response.ts +110 -0
  126. package/template/server/src/workers/file.worker.ts +106 -0
  127. package/template/server/tsconfig.build.json +30 -0
  128. package/template/server/tsconfig.build.tsbuildinfo +1 -0
  129. package/template/server/tsconfig.json +89 -0
  130. package/template/server/tsconfig.test.json +22 -0
  131. package/template/server/vitest.config.ts +98 -0
@@ -0,0 +1,326 @@
1
+ ---
2
+ trigger: always_on
3
+ ---
4
+
5
+ > **SCOPE**: These rules apply specifically to the **client** directory.
6
+
7
+ # Project Structure & File Naming
8
+
9
+ ## Folder Structure
10
+
11
+ ```
12
+ src/
13
+ ├── app/ # App configuration
14
+ │ ├── App.tsx
15
+ │ ├── router.tsx
16
+ │ └── providers.tsx
17
+ ├── components/
18
+ │ ├── layout/ # Header, Footer, MainLayout
19
+ │ │ ├── Header.tsx
20
+ │ │ ├── Footer.tsx
21
+ │ │ ├── Sidebar.tsx
22
+ │ │ └── MainLayout.tsx
23
+ │ └── common/ # Shared components
24
+ │ ├── LoadingSpinner.tsx
25
+ │ ├── ErrorBoundary.tsx
26
+ │ ├── ProtectedRoute.tsx
27
+ │ ├── Pagination.tsx
28
+ │ └── EmptyState.tsx
29
+ ├── features/ # Feature modules (domain-driven)
30
+ │ ├── auth/
31
+ │ │ ├── components/ # LoginForm, RegisterForm
32
+ │ │ ├── hooks/ # useAuth, useLogin, useRegister
33
+ │ │ ├── pages/ # LoginPage, RegisterPage
34
+ │ │ ├── services/ # auth.service.ts
35
+ │ │ ├── store/ # authSlice.ts (Redux)
36
+ │ │ ├── types/ # auth.types.ts
37
+ │ │ └── utils/ # auth.utils.ts
38
+ │ ├── resources/ # Example feature
39
+ │ │ ├── components/
40
+ │ │ ├── hooks/
41
+ │ │ ├── pages/
42
+ │ │ ├── services/
43
+ │ │ ├── types/
44
+ │ │ └── utils/
45
+ │ └── users/
46
+ ├── hooks/ # Global custom hooks
47
+ │ ├── useDebounce.ts
48
+ │ ├── useLocalStorage.ts
49
+ │ └── useMediaQuery.ts
50
+ ├── lib/
51
+ │ ├── api/
52
+ │ │ ├── axios.config.ts
53
+ │ │ └── api.types.ts
54
+ │ ├── constants/
55
+ │ │ ├── routes.ts
56
+ │ │ ├── api-endpoints.ts
57
+ │ │ └── app.constants.ts
58
+ │ └── utils/
59
+ │ ├── format.ts
60
+ │ ├── validation.ts
61
+ │ └── error.ts
62
+ ├── store/ # Redux store
63
+ │ ├── index.ts
64
+ │ └── hooks.ts
65
+ ├── types/ # Global types
66
+ │ ├── index.ts
67
+ │ └── api.types.ts
68
+ └── styles/
69
+ ├── globals.css # Global CSS
70
+ └── theme.css # Ant Design custom theme (if needed)
71
+ ```
72
+
73
+ ## File Naming Rules
74
+
75
+ ### Components
76
+ - **PascalCase**: `ResourceCard.tsx`, `LoginForm.tsx`
77
+ - **Pattern**: `<ComponentName>.tsx`
78
+ - **CSS**: If using CSS Modules, name as `<ComponentName>.module.css`
79
+
80
+ ### Pages
81
+ - **PascalCase + Page suffix**: `ResourcesPage.tsx`, `LoginPage.tsx`
82
+ - **Pattern**: `<FeatureName>Page.tsx`
83
+
84
+ ### Hooks
85
+ - **camelCase + use prefix**: `useAuth.ts`, `useResources.ts`
86
+ - **Pattern**: `use<HookName>.ts`
87
+
88
+ ### Services
89
+ - **camelCase + .service suffix**: `auth.service.ts`, `resource.service.ts`
90
+ - **Pattern**: `<domain>.service.ts`
91
+
92
+ ### Types
93
+ - **camelCase + .types suffix**: `auth.types.ts`, `resource.types.ts`
94
+ - **Pattern**: `<domain>.types.ts`
95
+
96
+ ### Store (Redux)
97
+ - **camelCase + Slice suffix**: `authSlice.ts`, `resourceSlice.ts`
98
+ - **Pattern**: `<domain>Slice.ts`
99
+
100
+ ### Utils
101
+ - **camelCase + .utils suffix**: `auth.utils.ts`, `date.utils.ts`
102
+ - **Pattern**: `<purpose>.utils.ts`
103
+
104
+ ### Constants
105
+ - **camelCase**: `routes.ts`, `api-endpoints.ts`, `app.constants.ts`
106
+
107
+ ## Module Structure Pattern
108
+
109
+ Every feature module follows this pattern:
110
+
111
+ ```
112
+ features/<domain>/
113
+ ├── components/ # Feature-specific components
114
+ ├── hooks/ # Feature-specific hooks
115
+ ├── pages/ # Feature pages (routes)
116
+ ├── services/ # API service
117
+ ├── store/ # Redux slice (if needed)
118
+ ├── types/ # TypeScript types
119
+ └── utils/ # Feature utilities
120
+ ```
121
+
122
+ ## Import Path Aliases
123
+
124
+ ```json
125
+ // tsconfig.json & vite.config.ts
126
+ {
127
+ "paths": {
128
+ "@/*": ["./src/*"],
129
+ "@/components/*": ["./src/components/*"],
130
+ "@/features/*": ["./src/features/*"],
131
+ "@/lib/*": ["./src/lib/*"],
132
+ "@/hooks/*": ["./src/hooks/*"],
133
+ "@/store/*": ["./src/store/*"],
134
+ "@/types/*": ["./src/types/*"],
135
+ "@/styles/*": ["./src/styles/*"]
136
+ }
137
+ }
138
+ ```
139
+
140
+ ## Import Order
141
+
142
+ ```tsx
143
+ // 1. React and framework
144
+ import { useState, useEffect } from 'react';
145
+ import { useNavigate } from 'react-router-dom';
146
+
147
+ // 2. Third-party libraries (Ant Design first)
148
+ import { Button, Card, Input } from 'antd';
149
+ import { useQuery } from '@tanstack/react-query';
150
+
151
+ // 3. Styles
152
+ import './ResourceCard.css'; // or .module.css
153
+
154
+ // 4. Local components
155
+ import { ResourceCard } from '../components/ResourceCard';
156
+
157
+ // 5. Hooks
158
+ import { useAuth } from '@/features/auth/hooks/useAuth';
159
+ import { useResources } from '../hooks/useResources';
160
+
161
+ // 6. Services
162
+ import { resourceService } from '../services/resource.service';
163
+
164
+ // 7. Types (always use 'type' keyword)
165
+ import type { Resource } from '../types/resource.types';
166
+
167
+ // 8. Utils
168
+ import { formatDate } from '@/lib/utils/format';
169
+ ```
170
+
171
+ ## Constants Structure
172
+
173
+ ### API Endpoints
174
+
175
+ ```tsx
176
+ // lib/constants/api-endpoints.ts
177
+ export const API_ENDPOINTS = {
178
+ AUTH: {
179
+ REGISTER: '/auth/register',
180
+ LOGIN: '/auth/login',
181
+ LOGOUT: '/auth/logout',
182
+ REFRESH: '/auth/refresh',
183
+ ME: '/auth/me',
184
+ VERIFY_EMAIL: '/auth/verify-email',
185
+ RESEND_VERIFICATION: '/auth/resend-verification',
186
+ REQUEST_PASSWORD_RESET: '/auth/request-password-reset',
187
+ RESET_PASSWORD: '/auth/reset-password',
188
+ },
189
+ USERS: {
190
+ ME: '/users/me',
191
+ UPDATE_ME: '/users/me',
192
+ DELETE_ME: '/users/me',
193
+ },
194
+ RESOURCES: {
195
+ LIST: '/resources',
196
+ MY_RESOURCES: '/resources/my',
197
+ CREATE: '/resources',
198
+ GET: (id: string) => `/resources/${id}`,
199
+ UPDATE: (id: string) => `/resources/${id}`,
200
+ DELETE: (id: string) => `/resources/${id}`,
201
+ },
202
+ } as const;
203
+ ```
204
+
205
+ ### Routes
206
+
207
+ ```tsx
208
+ // lib/constants/routes.ts
209
+ export const ROUTES = {
210
+ HOME: '/',
211
+ LOGIN: '/login',
212
+ REGISTER: '/register',
213
+ VERIFY_EMAIL: '/verify-email',
214
+ RESET_PASSWORD: '/reset-password',
215
+ DASHBOARD: '/dashboard',
216
+ PROFILE: '/profile',
217
+ RESOURCES: {
218
+ LIST: '/resources',
219
+ DETAILS: (id: string) => `/resources/${id}`,
220
+ MY_RESOURCES: '/my-resources',
221
+ CREATE: '/resources/create',
222
+ EDIT: (id: string) => `/resources/${id}/edit`,
223
+ },
224
+ } as const;
225
+ ```
226
+
227
+ ### App Constants
228
+
229
+ ```tsx
230
+ // lib/constants/app.constants.ts
231
+ export const APP_NAME = 'My Application';
232
+
233
+ export const PAGINATION = {
234
+ DEFAULT_PAGE: 1,
235
+ DEFAULT_LIMIT: 10,
236
+ MAX_LIMIT: 100,
237
+ } as const;
238
+
239
+ export const USER_ROLES = {
240
+ USER: 'USER',
241
+ ORG: 'ORGANIZATION',
242
+ ADMIN: 'ADMIN',
243
+ } as const;
244
+
245
+ export const CURRENCIES = {
246
+ GEL: 'GEL',
247
+ USD: 'USD',
248
+ EUR: 'EUR',
249
+ } as const;
250
+ ```
251
+
252
+ ## Naming Conventions
253
+
254
+ ### Variables
255
+ - **camelCase**: `userName`, `resourceList`, `isLoading`
256
+
257
+ ### Functions
258
+ - **camelCase**: `getUserData()`, `handleSubmit()`, `formatPrice()`
259
+
260
+ ### Constants
261
+ - **UPPER_SNAKE_CASE**: `API_BASE_URL`, `MAX_FILE_SIZE`
262
+
263
+ ### Types/Interfaces
264
+ - **PascalCase**: `User`, `Resource`, `ResourceFilters`
265
+ - **Interface prefix**: `IUser`, `IResource` (optional, be consistent)
266
+
267
+ ### Enums/Type Unions
268
+ - **PascalCase**: `UserRole`, `ResourceStatus`
269
+
270
+ ## Export Patterns
271
+
272
+ ### Named Exports (Preferred)
273
+ ```tsx
274
+ // ✅ GOOD
275
+ export const ResourceCard = () => {};
276
+ export const ResourceList = () => {};
277
+
278
+ // Import
279
+ import { ResourceCard, ResourceList } from './components';
280
+ ```
281
+
282
+ ### Default Export (Only for app.ts)
283
+ ```tsx
284
+ // ❌ AVOID for components
285
+ export default ResourceCard;
286
+
287
+ // ✅ OK for App
288
+ export default App;
289
+ ```
290
+
291
+ ### Barrel Exports
292
+ ```tsx
293
+ // features/resources/index.ts
294
+ export { ResourceCard } from './components/ResourceCard';
295
+ export { ResourceList } from './components/ResourceList';
296
+ export { useResources } from './hooks/useResources';
297
+ export { resourceService } from './services/resource.service';
298
+ export type * from './types/resource.types';
299
+
300
+ // Usage
301
+ import { ResourceCard, useResources, resourceService } from '@/features/resources';
302
+ ```
303
+
304
+ ## Environment Variables
305
+
306
+ ```env
307
+ # .env.development
308
+ VITE_API_BASE_URL=http://localhost:3000/api/v1
309
+ VITE_APP_NAME=My Application
310
+
311
+ # .env.production
312
+ VITE_API_BASE_URL=https://api.myapplication.com/api/v1
313
+ VITE_APP_NAME=My Application
314
+ ```
315
+
316
+ **Rules:**
317
+ - Prefix with `VITE_` to expose to client
318
+ - Never commit `.env` files
319
+ - Always provide `.env.example`
320
+
321
+ ```tsx
322
+ // Accessing env variables
323
+ const apiUrl = import.meta.env.VITE_API_BASE_URL;
324
+ const isDev = import.meta.env.DEV;
325
+ const isProd = import.meta.env.PROD;
326
+ ```
@@ -0,0 +1,249 @@
1
+ ---
2
+ trigger: always_on
3
+ ---
4
+
5
+ > **SCOPE**: These rules apply specifically to the **client** directory.
6
+
7
+ # Component Patterns & Rules
8
+
9
+ ## Component Structure Template
10
+
11
+ ```tsx
12
+ // 1. IMPORTS (grouped and ordered)
13
+ import { useState, useCallback, useEffect } from 'react';
14
+ import { useNavigate } from 'react-router-dom';
15
+ import { Button, Card } from 'antd'; // Ant Design
16
+ import { useResources } from '../hooks/useResources';
17
+ import type { Resource } from '../types/resource.types';
18
+
19
+ // Import CSS (Vanilla or Module)
20
+ import './ResourceCard.css';
21
+
22
+ // 2. TYPES (component-specific only)
23
+ interface ResourceCardProps {
24
+ resource: Resource;
25
+ onEdit?: (id: string) => void;
26
+ className?: string; // Standard className prop for custom styles
27
+ }
28
+
29
+ // 3. COMPONENT
30
+ export const ResourceCard = ({ resource, onEdit, className }: ResourceCardProps) => {
31
+ // 3a. HOOKS (router → Redux → React Query → state → custom)
32
+ const navigate = useNavigate();
33
+ const [isHovered, setIsHovered] = useState(false);
34
+
35
+ // 3b. EVENT HANDLERS
36
+ const handleClick = useCallback(() => {
37
+ navigate(`/resources/${resource.id}`);
38
+ }, [navigate, resource.id]);
39
+
40
+ // 3c. EFFECTS
41
+ useEffect(() => {
42
+ // Side effects
43
+ }, []);
44
+
45
+ // 3d. EARLY RETURNS
46
+ if (!resource) return null;
47
+
48
+ // 3e. RENDER
49
+ return (
50
+ <Card
51
+ className={`resource-card ${className || ''}`}
52
+ onClick={handleClick}
53
+ hoverable
54
+ >
55
+ <h3>{resource.title}</h3>
56
+ {/* JSX */}
57
+ </Card>
58
+ );
59
+ };
60
+ ```
61
+
62
+ ## Component Types
63
+
64
+ ### 1. Presentational Components
65
+ **Location**: `components/common/` or `features/*/components/`
66
+
67
+ **Rules**:
68
+ - NO business logic
69
+ - NO API calls
70
+ - NO Redux/Context (except theme)
71
+ - Receive ALL data via props
72
+ - Focus ONLY on UI
73
+
74
+ ```tsx
75
+ // ✅ GOOD - Pure presentation
76
+ interface ResourceCardProps {
77
+ resource: Resource;
78
+ onClick: (id: string) => void;
79
+ }
80
+
81
+ export const ResourceCard = ({ resource, onClick }: ResourceCardProps) => {
82
+ return (
83
+ <div className="card-container" onClick={() => onClick(resource.id)}>
84
+ <h3>{resource.title}</h3>
85
+ <p>{resource.price}</p>
86
+ </div>
87
+ );
88
+ };
89
+ ```
90
+
91
+ ### 2. Container Components
92
+ **Location**: `features/*/pages/` or `features/*/components/`
93
+
94
+ **Rules**:
95
+ - Contains business logic
96
+ - Makes API calls via hooks
97
+ - Manages state
98
+ - Passes data to presentational components
99
+
100
+ ```tsx
101
+ // ✅ GOOD - Container component
102
+ export const ResourcesPage = () => {
103
+ const [filters, setFilters] = useState<ResourceFilters>({});
104
+ const { resources, isLoading } = useResources(filters);
105
+ const navigate = useNavigate();
106
+
107
+ const handleResourceClick = (id: string) => {
108
+ navigate(`/resources/${id}`);
109
+ };
110
+
111
+ if (isLoading) return <LoadingSpinner />;
112
+
113
+ return (
114
+ <div className="page-container">
115
+ <ResourceFilters value={filters} onChange={setFilters} />
116
+ <div className="resource-list">
117
+ {resources.map(res => (
118
+ <ResourceCard key={res.id} resource={res} onClick={handleResourceClick} />
119
+ ))}
120
+ </div>
121
+ </div>
122
+ );
123
+ };
124
+ ```
125
+
126
+ ## Styling Rules
127
+
128
+ ### CSS Architecture
129
+ Instead of Tailwind, use Vanilla CSS or CSS Modules.
130
+
131
+ **Vanilla CSS Pattern**:
132
+ ```css
133
+ /* ResourceCard.css */
134
+ .resource-card {
135
+ padding: 16px;
136
+ border: 1px solid var(--border-color);
137
+ transition: all 0.3s ease;
138
+ }
139
+
140
+ .resource-card:hover {
141
+ box-shadow: 0 4px 12px rgba(0,0,0,0.1);
142
+ }
143
+ ```
144
+
145
+ **CSS Modules Pattern**:
146
+ ```tsx
147
+ import styles from './ResourceCard.module.css';
148
+
149
+ <div className={styles.cardContainer}>...</div>
150
+ ```
151
+
152
+ **Rules**:
153
+ 1. **NO Inline styles**: Avoid `<div style={{...}}>`.
154
+ 2. **Use Variables**: Use CSS variables for theme colors (defined in `globals.css`).
155
+ 3. **Consistency**: Use Ant Design's built-in props for standard spacing and layout where possible.
156
+ 4. **Responsive**: Use media queries in CSS files.
157
+
158
+ ```css
159
+ /* ✅ GOOD - Responsive in CSS */
160
+ .page-container {
161
+ padding: 20px;
162
+ }
163
+
164
+ @media (min-width: 768px) {
165
+ .page-container {
166
+ padding: 40px;
167
+ }
168
+ }
169
+ ```
170
+
171
+ ## Component Size Rules
172
+
173
+ ### Limits
174
+ - **Max 250 lines** per component
175
+ - **Max 5 props** (use object if more)
176
+ - **Max 3 levels** of JSX nesting
177
+
178
+ ### When to Split
179
+ Split when:
180
+ 1. Component exceeds 250 lines
181
+ 2. JSX nesting exceeds 3 levels
182
+ 3. Multiple responsibilities
183
+ 4. Part is reusable elsewhere
184
+
185
+ ## Props Rules
186
+
187
+ ### Props Interface
188
+ ```tsx
189
+ // ✅ GOOD - Group related props
190
+ interface ResourceCardProps {
191
+ resource: Resource;
192
+ actions?: ResourceActions;
193
+ className?: string;
194
+ }
195
+ ```
196
+
197
+ ### Children Prop
198
+ ```tsx
199
+ interface LayoutProps {
200
+ children: React.ReactNode;
201
+ headerContent?: React.ReactNode;
202
+ }
203
+
204
+ export const Layout = ({ children, headerContent }: LayoutProps) => {
205
+ return (
206
+ <div className="layout">
207
+ {headerContent && <div className="header">{headerContent}</div>}
208
+ {children}
209
+ </div>
210
+ );
211
+ };
212
+ ```
213
+
214
+ ## Performance Optimization
215
+
216
+ ### React.memo
217
+ ```tsx
218
+ // ✅ Use for components in lists
219
+ export const ResourceCard = React.memo(({ resource }: ResourceCardProps) => {
220
+ return <div>{resource.title}</div>;
221
+ });
222
+
223
+ ResourceCard.displayName = 'ResourceCard';
224
+ ```
225
+
226
+ ### useCallback
227
+ ```tsx
228
+ // ✅ For handlers passed to children
229
+ const handleClick = useCallback((id: string) => {
230
+ navigate(`/resources/${id}`);
231
+ }, [navigate]);
232
+
233
+ <ResourceCard resource={resource} onClick={handleClick} />
234
+ ```
235
+
236
+ ## Accessibility Rules
237
+ - Use semantic HTML tags.
238
+ - Use `aria-*` attributes when standard elements aren't enough.
239
+ - Ensure Ant Design components are used with proper labels.
240
+
241
+ ## Component Checklist
242
+ - [ ] Under 250 lines
243
+ - [ ] Props interface defined (max 5)
244
+ - [ ] Event handlers use useCallback
245
+ - [ ] Expensive computations use useMemo
246
+ - [ ] Early returns for error/loading
247
+ - [ ] CSS files used (no inline styles, no Tailwind)
248
+ - [ ] Accessibility attributes
249
+ - [ ] Named export (not default)