create-tigra 1.0.7 → 2.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.
- package/LICENSE +21 -21
- package/README.md +80 -87
- package/bin/create-tigra.js +242 -309
- package/package.json +49 -41
- package/template/_claude/QUICK_REFERENCE.md +193 -0
- package/template/_claude/README.md +53 -0
- package/template/_claude/commands/create-client.md +881 -0
- package/template/_claude/commands/create-server.md +383 -0
- package/template/_claude/rules/client/01-project-structure.md +133 -0
- package/template/_claude/rules/client/02-components-and-types.md +146 -0
- package/template/_claude/rules/client/03-data-and-state.md +156 -0
- package/template/_claude/rules/client/04-design-system.md +185 -0
- package/template/_claude/rules/client/05-security.md +55 -0
- package/template/_claude/rules/client/06-ux-checklist.md +81 -0
- package/template/_claude/rules/client/core.md +42 -0
- package/template/_claude/rules/global/core.md +77 -0
- package/template/_claude/rules/server/core.md +50 -0
- package/template/_claude/rules/server/database.md +124 -0
- package/template/_claude/rules/server/project-conventions.md +150 -0
- package/template/_claude/rules/server/response-handling.md +144 -0
- package/template/client/.env.example +5 -0
- package/template/client/README.md +36 -0
- package/template/client/components.json +23 -0
- package/template/client/eslint.config.mjs +18 -0
- package/template/client/next.config.ts +34 -0
- package/template/client/package.json +44 -0
- package/template/client/postcss.config.mjs +7 -0
- package/template/client/src/app/(auth)/layout.tsx +18 -0
- package/template/client/src/app/(auth)/login/page.tsx +13 -0
- package/template/client/src/app/(auth)/register/page.tsx +13 -0
- package/template/client/src/app/(main)/dashboard/page.tsx +22 -0
- package/template/client/src/app/(main)/layout.tsx +11 -0
- package/template/client/src/app/error.tsx +27 -0
- package/template/client/src/app/favicon.ico +0 -0
- package/template/client/src/app/globals.css +145 -0
- package/template/client/src/app/layout.tsx +36 -0
- package/template/client/src/app/loading.tsx +11 -0
- package/template/client/src/app/not-found.tsx +23 -0
- package/template/client/src/app/page.tsx +45 -0
- package/template/client/src/app/providers.tsx +43 -0
- package/template/client/src/components/common/ConfirmDialog.tsx +56 -0
- package/template/client/src/components/common/EmptyState.tsx +31 -0
- package/template/client/src/components/common/LoadingSpinner.tsx +30 -0
- package/template/client/src/components/common/Pagination.tsx +55 -0
- package/template/client/src/components/layout/Footer.tsx +17 -0
- package/template/client/src/components/layout/Header.tsx +173 -0
- package/template/client/src/components/layout/MainLayout.tsx +18 -0
- package/template/client/src/components/ui/alert-dialog.tsx +196 -0
- package/template/client/src/components/ui/badge.tsx +48 -0
- package/template/client/src/components/ui/button.tsx +64 -0
- package/template/client/src/components/ui/card.tsx +92 -0
- package/template/client/src/components/ui/input.tsx +21 -0
- package/template/client/src/components/ui/label.tsx +24 -0
- package/template/client/src/components/ui/select.tsx +190 -0
- package/template/client/src/components/ui/skeleton.tsx +13 -0
- package/template/client/src/components/ui/table.tsx +116 -0
- package/template/client/src/features/auth/components/AuthInitializer.tsx +55 -0
- package/template/client/src/features/auth/components/LoginForm.tsx +107 -0
- package/template/client/src/features/auth/components/RegisterForm.tsx +178 -0
- package/template/client/src/features/auth/hooks/useAuth.ts +84 -0
- package/template/client/src/features/auth/services/auth.service.ts +52 -0
- package/template/client/src/features/auth/store/authSlice.ts +38 -0
- package/template/client/src/features/auth/types/auth.types.ts +32 -0
- package/template/client/src/hooks/useDebounce.ts +14 -0
- package/template/client/src/hooks/useLocalStorage.ts +55 -0
- package/template/client/src/hooks/useMediaQuery.ts +27 -0
- package/template/client/src/lib/api/api.types.ts +34 -0
- package/template/client/src/lib/api/axios.config.ts +98 -0
- package/template/client/src/lib/constants/api-endpoints.ts +18 -0
- package/template/client/src/lib/constants/app.constants.ts +12 -0
- package/template/client/src/lib/constants/routes.ts +9 -0
- package/template/client/src/lib/utils/error.ts +32 -0
- package/template/client/src/lib/utils/format.ts +37 -0
- package/template/client/src/lib/utils/security.ts +34 -0
- package/template/client/src/lib/utils.ts +6 -0
- package/template/client/src/middleware.ts +57 -0
- package/template/client/src/store/hooks.ts +7 -0
- package/template/client/src/store/index.ts +12 -0
- package/template/client/src/types/index.ts +3 -0
- package/template/client/tsconfig.json +34 -0
- package/template/gitignore +34 -0
- package/template/server/.dockerignore +66 -0
- package/template/server/.env.example +96 -69
- package/template/server/.env.production.example +90 -0
- package/template/server/Dockerfile +94 -0
- package/template/server/docker-compose.yml +80 -111
- package/template/server/docs/logging.md +62 -0
- package/template/server/eslint.config.mjs +17 -0
- package/template/server/package.json +68 -81
- package/template/server/phpmyadmin-config.php +26 -0
- package/template/server/postman_collection.json +666 -0
- package/template/server/prisma/schema.prisma +77 -93
- package/template/server/prisma/seed.ts +46 -142
- package/template/server/scripts/flush-redis.ts +41 -0
- package/template/server/src/app.ts +243 -71
- package/template/server/src/config/env.ts +67 -94
- package/template/server/src/libs/auth.ts +88 -0
- package/template/server/src/libs/cleanup.ts +35 -0
- package/template/server/src/libs/cookies.ts +46 -0
- package/template/server/src/libs/logger.ts +33 -60
- package/template/server/src/libs/monitoring.ts +205 -0
- package/template/server/src/libs/password.ts +38 -0
- package/template/server/src/libs/prisma.ts +68 -0
- package/template/server/src/libs/redis.ts +60 -79
- package/template/server/src/libs/requestLogger.ts +66 -0
- package/template/server/src/libs/storage/file-storage.service.ts +211 -0
- package/template/server/src/libs/storage/file-validator.ts +97 -0
- package/template/server/src/libs/storage/filename-sanitizer.ts +71 -0
- package/template/server/src/libs/storage/image-optimizer.service.ts +144 -0
- package/template/server/src/modules/auth/__tests__/auth.service.test.ts +365 -0
- package/template/server/src/modules/auth/auth.controller.ts +90 -141
- package/template/server/src/modules/auth/auth.repo.ts +120 -218
- package/template/server/src/modules/auth/auth.routes.ts +96 -83
- package/template/server/src/modules/auth/auth.schemas.ts +35 -137
- package/template/server/src/modules/auth/auth.service.ts +286 -329
- package/template/server/src/modules/auth/session.repo.ts +110 -0
- package/template/server/src/modules/users/users.controller.ts +120 -0
- package/template/server/src/modules/users/users.repo.ts +77 -0
- package/template/server/src/modules/users/users.routes.ts +89 -0
- package/template/server/src/modules/users/users.schemas.ts +21 -0
- package/template/server/src/modules/users/users.service.ts +169 -0
- package/template/server/src/server.ts +58 -139
- package/template/server/src/shared/errors/AppError.ts +21 -0
- package/template/server/src/shared/errors/errors.ts +43 -0
- package/template/server/src/shared/responses/paginatedResponse.ts +38 -0
- package/template/server/src/shared/responses/successResponse.ts +17 -0
- package/template/server/src/shared/schemas/pagination.schema.ts +12 -0
- package/template/server/src/shared/types/index.ts +26 -0
- package/template/server/src/test/setup.ts +74 -38
- package/template/server/tsconfig.json +27 -89
- package/template/server/uploads/avatars/.gitkeep +1 -0
- package/template/server/vitest.config.ts +43 -98
- package/template/.agent/rules/client/01-project-structure.md +0 -326
- package/template/.agent/rules/client/02-component-patterns.md +0 -249
- package/template/.agent/rules/client/03-typescript-rules.md +0 -226
- package/template/.agent/rules/client/04-state-management.md +0 -474
- package/template/.agent/rules/client/05-api-integration.md +0 -129
- package/template/.agent/rules/client/06-forms-validation.md +0 -129
- package/template/.agent/rules/client/07-common-patterns.md +0 -150
- package/template/.agent/rules/client/08-color-system.md +0 -93
- package/template/.agent/rules/client/09-security-rules.md +0 -97
- package/template/.agent/rules/client/10-testing-strategy.md +0 -370
- package/template/.agent/rules/global/ai-edit-safety.md +0 -38
- package/template/.agent/rules/server/01-db-and-migrations.md +0 -242
- package/template/.agent/rules/server/02-general-rules.md +0 -111
- package/template/.agent/rules/server/03-migrations.md +0 -20
- package/template/.agent/rules/server/04-pagination.md +0 -130
- package/template/.agent/rules/server/05-project-conventions.md +0 -71
- package/template/.agent/rules/server/06-response-handling.md +0 -173
- package/template/.agent/rules/server/07-testing-strategy.md +0 -506
- package/template/.agent/rules/server/08-observability.md +0 -180
- package/template/.agent/rules/server/10-background-jobs-v2.md +0 -185
- package/template/.agent/rules/server/11-rate-limiting-v2.md +0 -210
- package/template/.agent/rules/server/12-performance-optimization.md +0 -567
- package/template/.claude/rules/client-01-project-structure.md +0 -327
- package/template/.claude/rules/client-02-component-patterns.md +0 -250
- package/template/.claude/rules/client-03-typescript-rules.md +0 -227
- package/template/.claude/rules/client-04-state-management.md +0 -475
- package/template/.claude/rules/client-05-api-integration.md +0 -130
- package/template/.claude/rules/client-06-forms-validation.md +0 -130
- package/template/.claude/rules/client-07-common-patterns.md +0 -151
- package/template/.claude/rules/client-08-color-system.md +0 -94
- package/template/.claude/rules/client-09-security-rules.md +0 -98
- package/template/.claude/rules/client-10-testing-strategy.md +0 -371
- package/template/.claude/rules/global-ai-edit-safety.md +0 -39
- package/template/.claude/rules/server-01-db-and-migrations.md +0 -243
- package/template/.claude/rules/server-02-general-rules.md +0 -112
- package/template/.claude/rules/server-03-migrations.md +0 -21
- package/template/.claude/rules/server-04-pagination.md +0 -131
- package/template/.claude/rules/server-05-project-conventions.md +0 -72
- package/template/.claude/rules/server-06-response-handling.md +0 -174
- package/template/.claude/rules/server-07-testing-strategy.md +0 -507
- package/template/.claude/rules/server-08-observability.md +0 -181
- package/template/.claude/rules/server-10-background-jobs-v2.md +0 -186
- package/template/.claude/rules/server-11-rate-limiting-v2.md +0 -211
- package/template/.claude/rules/server-12-performance-optimization.md +0 -568
- package/template/.cursor/rules/client-01-project-structure.mdc +0 -327
- package/template/.cursor/rules/client-02-component-patterns.mdc +0 -250
- package/template/.cursor/rules/client-03-typescript-rules.mdc +0 -227
- package/template/.cursor/rules/client-04-state-management.mdc +0 -475
- package/template/.cursor/rules/client-05-api-integration.mdc +0 -130
- package/template/.cursor/rules/client-06-forms-validation.mdc +0 -130
- package/template/.cursor/rules/client-07-common-patterns.mdc +0 -151
- package/template/.cursor/rules/client-08-color-system.mdc +0 -94
- package/template/.cursor/rules/client-09-security-rules.mdc +0 -98
- package/template/.cursor/rules/client-10-testing-strategy.mdc +0 -371
- package/template/.cursor/rules/global-ai-edit-safety.mdc +0 -39
- package/template/.cursor/rules/server-01-db-and-migrations.mdc +0 -243
- package/template/.cursor/rules/server-02-general-rules.mdc +0 -112
- package/template/.cursor/rules/server-03-migrations.mdc +0 -21
- package/template/.cursor/rules/server-04-pagination.mdc +0 -131
- package/template/.cursor/rules/server-05-project-conventions.mdc +0 -72
- package/template/.cursor/rules/server-06-response-handling.mdc +0 -174
- package/template/.cursor/rules/server-07-testing-strategy.mdc +0 -507
- package/template/.cursor/rules/server-08-observability.mdc +0 -181
- package/template/.cursor/rules/server-09-api-documentation-v2.mdc +0 -169
- package/template/.cursor/rules/server-10-background-jobs-v2.mdc +0 -186
- package/template/.cursor/rules/server-11-rate-limiting-v2.mdc +0 -211
- package/template/.cursor/rules/server-12-performance-optimization.mdc +0 -568
- package/template/CLAUDE.md +0 -207
- package/template/server/.tsc-aliasrc.json +0 -12
- package/template/server/README.md +0 -183
- package/template/server/SECURITY.md +0 -190
- package/template/server/Tigra-API.postman_collection.json +0 -733
- package/template/server/biome.json +0 -42
- package/template/server/scripts/setup-env.js +0 -50
- package/template/server/scripts/wait-for-db.js +0 -60
- package/template/server/src/hooks/request-timing.hook.ts +0 -26
- package/template/server/src/libs/auth/authenticate.middleware.ts +0 -22
- package/template/server/src/libs/auth/rbac.middleware.test.ts +0 -134
- package/template/server/src/libs/auth/rbac.middleware.ts +0 -147
- package/template/server/src/libs/db.ts +0 -76
- package/template/server/src/libs/error-handler.ts +0 -89
- package/template/server/src/libs/queue.ts +0 -79
- package/template/server/src/modules/admin/admin.controller.ts +0 -122
- package/template/server/src/modules/admin/admin.routes.ts +0 -62
- package/template/server/src/modules/admin/admin.schemas.ts +0 -35
- package/template/server/src/modules/admin/admin.service.ts +0 -167
- package/template/server/src/modules/auth/auth.integration.test.ts +0 -150
- package/template/server/src/modules/auth/auth.service.test.ts +0 -119
- package/template/server/src/modules/auth/auth.types.ts +0 -97
- package/template/server/src/modules/resources/resources.controller.ts +0 -218
- package/template/server/src/modules/resources/resources.repo.ts +0 -253
- package/template/server/src/modules/resources/resources.routes.ts +0 -116
- package/template/server/src/modules/resources/resources.schemas.ts +0 -146
- package/template/server/src/modules/resources/resources.service.ts +0 -218
- package/template/server/src/modules/resources/resources.types.ts +0 -73
- package/template/server/src/plugins/rate-limit.plugin.ts +0 -21
- package/template/server/src/plugins/security.plugin.ts +0 -21
- package/template/server/src/routes/health.routes.ts +0 -31
- package/template/server/src/types/fastify.d.ts +0 -36
- package/template/server/src/utils/errors.ts +0 -108
- package/template/server/src/utils/pagination.ts +0 -120
- package/template/server/src/utils/response.ts +0 -110
- package/template/server/src/workers/file.worker.ts +0 -106
- package/template/server/tsconfig.build.json +0 -30
- package/template/server/tsconfig.test.json +0 -22
|
@@ -1,249 +0,0 @@
|
|
|
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)
|
|
@@ -1,226 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
trigger: always_on
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
> **SCOPE**: These rules apply specifically to the **client** directory.
|
|
6
|
-
|
|
7
|
-
# TypeScript Rules & Types
|
|
8
|
-
|
|
9
|
-
## TypeScript Configuration
|
|
10
|
-
|
|
11
|
-
```json
|
|
12
|
-
// tsconfig.json
|
|
13
|
-
{
|
|
14
|
-
"compilerOptions": {
|
|
15
|
-
"target": "ES2020",
|
|
16
|
-
"useDefineForClassFields": true,
|
|
17
|
-
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
18
|
-
"module": "ESNext",
|
|
19
|
-
"skipLibCheck": true,
|
|
20
|
-
"moduleResolution": "bundler",
|
|
21
|
-
"allowImportingTsExtensions": true,
|
|
22
|
-
"resolveJsonModule": true,
|
|
23
|
-
"isolatedModules": true,
|
|
24
|
-
"noEmit": true,
|
|
25
|
-
"jsx": "react-jsx",
|
|
26
|
-
"strict": true,
|
|
27
|
-
"noUnusedLocals": true,
|
|
28
|
-
"noUnusedParameters": true,
|
|
29
|
-
"noFallthroughCasesInSwitch": true
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
## Strict Mode Rules
|
|
35
|
-
|
|
36
|
-
- **Always use strict mode**
|
|
37
|
-
- **NO `any` type** (use `unknown` if needed)
|
|
38
|
-
- **Explicit return types** for functions
|
|
39
|
-
- **No implicit any**
|
|
40
|
-
|
|
41
|
-
```tsx
|
|
42
|
-
// ❌ BAD
|
|
43
|
-
const fetchResource = async (id) => {
|
|
44
|
-
const response = await api.get(`/resources/${id}`);
|
|
45
|
-
return response.data;
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
// ✅ GOOD
|
|
49
|
-
const fetchResource = async (id: string): Promise<Resource> => {
|
|
50
|
-
const response = await api.get<ApiResponse<Resource>>(`/resources/${id}`);
|
|
51
|
-
return response.data.data;
|
|
52
|
-
};
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
## Type vs Interface
|
|
56
|
-
|
|
57
|
-
### Use `interface` for:
|
|
58
|
-
- Component props
|
|
59
|
-
- Object shapes
|
|
60
|
-
- Extendable structures
|
|
61
|
-
|
|
62
|
-
### Use `type` for:
|
|
63
|
-
- Unions
|
|
64
|
-
- Intersections
|
|
65
|
-
- Utility types
|
|
66
|
-
- Type aliases
|
|
67
|
-
|
|
68
|
-
```tsx
|
|
69
|
-
// ✅ Interface for props
|
|
70
|
-
interface ResourceCardProps {
|
|
71
|
-
resource: Resource;
|
|
72
|
-
onClick?: () => void;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// ✅ Type for unions
|
|
76
|
-
type UserRole = 'USER' | 'ORG' | 'ADMIN';
|
|
77
|
-
type ResourceStatus = 'active' | 'inactive' | 'deleted';
|
|
78
|
-
|
|
79
|
-
// ✅ Type for intersections
|
|
80
|
-
type ResourceWithOwner = Resource & { owner: User };
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
## API Response Types
|
|
84
|
-
|
|
85
|
-
Match backend response structure:
|
|
86
|
-
|
|
87
|
-
```tsx
|
|
88
|
-
// lib/api/api.types.ts
|
|
89
|
-
|
|
90
|
-
// Base response
|
|
91
|
-
export interface ApiResponse<T> {
|
|
92
|
-
success: boolean;
|
|
93
|
-
message: string;
|
|
94
|
-
data: T;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// Paginated response
|
|
98
|
-
export interface PaginatedApiResponse<T> {
|
|
99
|
-
success: boolean;
|
|
100
|
-
message: string;
|
|
101
|
-
data: {
|
|
102
|
-
items: T[];
|
|
103
|
-
pagination: {
|
|
104
|
-
page: number;
|
|
105
|
-
limit: number;
|
|
106
|
-
totalItems: number;
|
|
107
|
-
totalPages: number;
|
|
108
|
-
hasNextPage: boolean;
|
|
109
|
-
hasPreviousPage: boolean;
|
|
110
|
-
};
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// Error response
|
|
115
|
-
export interface ApiError {
|
|
116
|
-
success: false;
|
|
117
|
-
error: {
|
|
118
|
-
code: string;
|
|
119
|
-
message: string;
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
## Domain Types
|
|
125
|
-
|
|
126
|
-
Create types matching backend entities:
|
|
127
|
-
|
|
128
|
-
```tsx
|
|
129
|
-
// features/resources/types/resource.types.ts
|
|
130
|
-
|
|
131
|
-
export interface Resource {
|
|
132
|
-
id: string;
|
|
133
|
-
ownerId: string;
|
|
134
|
-
title: string;
|
|
135
|
-
summary: string | null;
|
|
136
|
-
price: number;
|
|
137
|
-
status: ResourceStatus;
|
|
138
|
-
createdAt: string;
|
|
139
|
-
updatedAt: string;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
export type ResourceStatus = 'active' | 'inactive' | 'deleted';
|
|
143
|
-
|
|
144
|
-
// Request types
|
|
145
|
-
export interface CreateResourceRequest {
|
|
146
|
-
title: string;
|
|
147
|
-
summary?: string;
|
|
148
|
-
price: number;
|
|
149
|
-
}
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
## Function Type Signatures
|
|
153
|
-
|
|
154
|
-
```tsx
|
|
155
|
-
// Event handlers
|
|
156
|
-
type ClickHandler = (event: React.MouseEvent<HTMLElement>) => void;
|
|
157
|
-
type ChangeHandler = (event: React.ChangeEvent<HTMLInputElement>) => void;
|
|
158
|
-
|
|
159
|
-
// Async functions
|
|
160
|
-
type AsyncFunction<T> = () => Promise<T>;
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
## Component Prop Types
|
|
164
|
-
|
|
165
|
-
```tsx
|
|
166
|
-
// Base component props
|
|
167
|
-
interface BaseComponentProps {
|
|
168
|
-
className?: string; // Standard for CSS and Ant Design
|
|
169
|
-
children?: React.ReactNode;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
// With generic data
|
|
173
|
-
interface DataComponentProps<T> extends BaseComponentProps {
|
|
174
|
-
data: T;
|
|
175
|
-
onSelect?: (item: T) => void;
|
|
176
|
-
}
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
## Type Guards
|
|
180
|
-
|
|
181
|
-
```tsx
|
|
182
|
-
// Type guard functions
|
|
183
|
-
export const isApiError = (error: unknown): error is ApiError => {
|
|
184
|
-
return (
|
|
185
|
-
typeof error === 'object' &&
|
|
186
|
-
error !== null &&
|
|
187
|
-
'success' in error &&
|
|
188
|
-
error.success === false
|
|
189
|
-
);
|
|
190
|
-
};
|
|
191
|
-
```
|
|
192
|
-
|
|
193
|
-
## Enum Alternatives (String Unions)
|
|
194
|
-
|
|
195
|
-
```tsx
|
|
196
|
-
// ✅ Use string unions + const object
|
|
197
|
-
export const USER_ROLES = {
|
|
198
|
-
USER: 'USER',
|
|
199
|
-
ORG: 'ORGANIZATION',
|
|
200
|
-
ADMIN: 'ADMIN',
|
|
201
|
-
} as const;
|
|
202
|
-
|
|
203
|
-
export type UserRole = (typeof USER_ROLES)[keyof typeof USER_ROLES];
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
## Discriminated Unions
|
|
207
|
-
|
|
208
|
-
```tsx
|
|
209
|
-
// State machine pattern
|
|
210
|
-
type RequestState<T> =
|
|
211
|
-
| { status: 'idle' }
|
|
212
|
-
| { status: 'loading' }
|
|
213
|
-
| { status: 'success'; data: T }
|
|
214
|
-
| { status: 'error'; error: Error };
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
## Type Safety Checklist
|
|
218
|
-
|
|
219
|
-
- [ ] Strict mode enabled
|
|
220
|
-
- [ ] No `any` types used
|
|
221
|
-
- [ ] All functions have return types
|
|
222
|
-
- [ ] Props interfaces defined
|
|
223
|
-
- [ ] API response types match backend
|
|
224
|
-
- [ ] Domain types match backend models
|
|
225
|
-
- [ ] Type guards for runtime checks
|
|
226
|
-
- [ ] Discriminated unions for state machines
|