@malamute/ai-rules 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 (46) hide show
  1. package/README.md +174 -0
  2. package/bin/cli.js +5 -0
  3. package/configs/_shared/.claude/commands/fix-issue.md +38 -0
  4. package/configs/_shared/.claude/commands/generate-tests.md +49 -0
  5. package/configs/_shared/.claude/commands/review-pr.md +77 -0
  6. package/configs/_shared/.claude/rules/accessibility.md +270 -0
  7. package/configs/_shared/.claude/rules/performance.md +226 -0
  8. package/configs/_shared/.claude/rules/security.md +188 -0
  9. package/configs/_shared/.claude/skills/debug/SKILL.md +118 -0
  10. package/configs/_shared/.claude/skills/learning/SKILL.md +224 -0
  11. package/configs/_shared/.claude/skills/review/SKILL.md +86 -0
  12. package/configs/_shared/.claude/skills/spec/SKILL.md +112 -0
  13. package/configs/_shared/CLAUDE.md +174 -0
  14. package/configs/angular/.claude/rules/components.md +257 -0
  15. package/configs/angular/.claude/rules/state.md +250 -0
  16. package/configs/angular/.claude/rules/testing.md +422 -0
  17. package/configs/angular/.claude/settings.json +31 -0
  18. package/configs/angular/CLAUDE.md +251 -0
  19. package/configs/dotnet/.claude/rules/api.md +370 -0
  20. package/configs/dotnet/.claude/rules/architecture.md +199 -0
  21. package/configs/dotnet/.claude/rules/database/efcore.md +408 -0
  22. package/configs/dotnet/.claude/rules/testing.md +389 -0
  23. package/configs/dotnet/.claude/settings.json +9 -0
  24. package/configs/dotnet/CLAUDE.md +319 -0
  25. package/configs/nestjs/.claude/rules/auth.md +321 -0
  26. package/configs/nestjs/.claude/rules/database/prisma.md +305 -0
  27. package/configs/nestjs/.claude/rules/database/typeorm.md +379 -0
  28. package/configs/nestjs/.claude/rules/modules.md +215 -0
  29. package/configs/nestjs/.claude/rules/testing.md +315 -0
  30. package/configs/nestjs/.claude/rules/validation.md +279 -0
  31. package/configs/nestjs/.claude/settings.json +15 -0
  32. package/configs/nestjs/CLAUDE.md +263 -0
  33. package/configs/nextjs/.claude/rules/components.md +211 -0
  34. package/configs/nextjs/.claude/rules/state/redux-toolkit.md +429 -0
  35. package/configs/nextjs/.claude/rules/state/zustand.md +299 -0
  36. package/configs/nextjs/.claude/rules/testing.md +315 -0
  37. package/configs/nextjs/.claude/settings.json +29 -0
  38. package/configs/nextjs/CLAUDE.md +376 -0
  39. package/configs/python/.claude/rules/database/sqlalchemy.md +355 -0
  40. package/configs/python/.claude/rules/fastapi.md +272 -0
  41. package/configs/python/.claude/rules/flask.md +332 -0
  42. package/configs/python/.claude/rules/testing.md +374 -0
  43. package/configs/python/.claude/settings.json +18 -0
  44. package/configs/python/CLAUDE.md +273 -0
  45. package/package.json +41 -0
  46. package/src/install.js +315 -0
@@ -0,0 +1,263 @@
1
+ # NestJS Project Guidelines
2
+
3
+ @../_shared/CLAUDE.md
4
+
5
+ ## Stack
6
+
7
+ - NestJS 10+ (latest stable)
8
+ - TypeScript strict mode
9
+ - Node.js 20+
10
+ - Jest for testing
11
+ - Supertest for E2E
12
+
13
+ ## Architecture
14
+
15
+ ### Modular Monolith (Recommended)
16
+
17
+ ```
18
+ src/
19
+ ├── modules/
20
+ │ ├── users/
21
+ │ │ ├── users.module.ts
22
+ │ │ ├── users.controller.ts
23
+ │ │ ├── users.service.ts
24
+ │ │ ├── dto/
25
+ │ │ │ ├── create-user.dto.ts
26
+ │ │ │ └── update-user.dto.ts
27
+ │ │ ├── entities/
28
+ │ │ │ └── user.entity.ts
29
+ │ │ └── users.repository.ts
30
+ │ │
31
+ │ ├── auth/
32
+ │ │ ├── auth.module.ts
33
+ │ │ ├── auth.controller.ts
34
+ │ │ ├── auth.service.ts
35
+ │ │ ├── strategies/
36
+ │ │ │ ├── jwt.strategy.ts
37
+ │ │ │ └── local.strategy.ts
38
+ │ │ └── guards/
39
+ │ │ └── jwt-auth.guard.ts
40
+ │ │
41
+ │ └── [feature]/
42
+ │ └── ...
43
+
44
+ ├── common/
45
+ │ ├── decorators/
46
+ │ ├── filters/
47
+ │ ├── guards/
48
+ │ ├── interceptors/
49
+ │ └── pipes/
50
+
51
+ ├── config/
52
+ │ ├── config.module.ts
53
+ │ └── database.config.ts
54
+
55
+ ├── app.module.ts
56
+ └── main.ts
57
+ ```
58
+
59
+ ### Module Principles
60
+
61
+ - **Single Responsibility**: Each module owns one domain
62
+ - **Clear Boundaries**: Modules communicate via exported services
63
+ - **In-Memory Communication**: Direct method calls, not HTTP between modules
64
+ - **Barrel Exports**: Use `index.ts` for clean imports
65
+
66
+ ## Code Style
67
+
68
+ ### Controllers
69
+
70
+ - Handle HTTP concerns only (request/response)
71
+ - Delegate business logic to services
72
+ - Use DTOs for all inputs
73
+ - Return consistent response shapes
74
+
75
+ ```typescript
76
+ @Controller('users')
77
+ export class UsersController {
78
+ constructor(private readonly usersService: UsersService) {}
79
+
80
+ @Post()
81
+ @HttpCode(HttpStatus.CREATED)
82
+ create(@Body() createUserDto: CreateUserDto): Promise<User> {
83
+ return this.usersService.create(createUserDto);
84
+ }
85
+
86
+ @Get(':id')
87
+ findOne(@Param('id', ParseUUIDPipe) id: string): Promise<User> {
88
+ return this.usersService.findOne(id);
89
+ }
90
+ }
91
+ ```
92
+
93
+ ### Services
94
+
95
+ - Contain all business logic
96
+ - Inject repositories/other services
97
+ - Throw appropriate NestJS exceptions
98
+
99
+ ```typescript
100
+ @Injectable()
101
+ export class UsersService {
102
+ constructor(private readonly usersRepository: UsersRepository) {}
103
+
104
+ async findOne(id: string): Promise<User> {
105
+ const user = await this.usersRepository.findById(id);
106
+ if (!user) {
107
+ throw new NotFoundException(`User with ID ${id} not found`);
108
+ }
109
+ return user;
110
+ }
111
+ }
112
+ ```
113
+
114
+ ### DTOs
115
+
116
+ - Always use class-validator decorators
117
+ - Use class-transformer for transformation
118
+ - Extend with PartialType/PickType/OmitType for variants
119
+
120
+ ```typescript
121
+ export class CreateUserDto {
122
+ @IsEmail()
123
+ @IsNotEmpty()
124
+ email: string;
125
+
126
+ @IsString()
127
+ @MinLength(8)
128
+ password: string;
129
+
130
+ @IsString()
131
+ @IsOptional()
132
+ name?: string;
133
+ }
134
+
135
+ export class UpdateUserDto extends PartialType(CreateUserDto) {}
136
+ ```
137
+
138
+ ## Commands
139
+
140
+ ```bash
141
+ # Development
142
+ npm run start:dev
143
+
144
+ # Build
145
+ npm run build
146
+
147
+ # Tests
148
+ npm run test # Unit tests
149
+ npm run test:watch # Watch mode
150
+ npm run test:cov # Coverage
151
+ npm run test:e2e # E2E tests
152
+
153
+ # Linting
154
+ npm run lint
155
+ npm run format
156
+ ```
157
+
158
+ ## Global Setup (main.ts)
159
+
160
+ ```typescript
161
+ async function bootstrap() {
162
+ const app = await NestFactory.create(AppModule);
163
+
164
+ // Global validation pipe
165
+ app.useGlobalPipes(
166
+ new ValidationPipe({
167
+ whitelist: true,
168
+ forbidNonWhitelisted: true,
169
+ transform: true,
170
+ transformOptions: {
171
+ enableImplicitConversion: true,
172
+ },
173
+ }),
174
+ );
175
+
176
+ // Global prefix
177
+ app.setGlobalPrefix('api/v1');
178
+
179
+ // CORS
180
+ app.enableCors();
181
+
182
+ // Swagger (dev only)
183
+ if (process.env.NODE_ENV !== 'production') {
184
+ const config = new DocumentBuilder()
185
+ .setTitle('API')
186
+ .setVersion('1.0')
187
+ .addBearerAuth()
188
+ .build();
189
+ const document = SwaggerModule.createDocument(app, config);
190
+ SwaggerModule.setup('docs', app, document);
191
+ }
192
+
193
+ await app.listen(process.env.PORT ?? 3000);
194
+ }
195
+ ```
196
+
197
+ ## Common Patterns
198
+
199
+ ### Custom Decorator
200
+
201
+ ```typescript
202
+ // current-user.decorator.ts
203
+ export const CurrentUser = createParamDecorator(
204
+ (data: keyof User | undefined, ctx: ExecutionContext) => {
205
+ const request = ctx.switchToHttp().getRequest();
206
+ const user = request.user;
207
+ return data ? user?.[data] : user;
208
+ },
209
+ );
210
+
211
+ // Usage
212
+ @Get('profile')
213
+ getProfile(@CurrentUser() user: User) { ... }
214
+ ```
215
+
216
+ ### Global Exception Filter
217
+
218
+ ```typescript
219
+ @Catch()
220
+ export class AllExceptionsFilter implements ExceptionFilter {
221
+ catch(exception: unknown, host: ArgumentsHost) {
222
+ const ctx = host.switchToHttp();
223
+ const response = ctx.getResponse<Response>();
224
+
225
+ const status =
226
+ exception instanceof HttpException
227
+ ? exception.getStatus()
228
+ : HttpStatus.INTERNAL_SERVER_ERROR;
229
+
230
+ const message =
231
+ exception instanceof HttpException
232
+ ? exception.message
233
+ : 'Internal server error';
234
+
235
+ response.status(status).json({
236
+ statusCode: status,
237
+ message,
238
+ timestamp: new Date().toISOString(),
239
+ });
240
+ }
241
+ }
242
+ ```
243
+
244
+ ### Response Interceptor
245
+
246
+ ```typescript
247
+ @Injectable()
248
+ export class TransformInterceptor<T>
249
+ implements NestInterceptor<T, Response<T>>
250
+ {
251
+ intercept(
252
+ context: ExecutionContext,
253
+ next: CallHandler,
254
+ ): Observable<Response<T>> {
255
+ return next.handle().pipe(
256
+ map((data) => ({
257
+ success: true,
258
+ data,
259
+ })),
260
+ );
261
+ }
262
+ }
263
+ ```
@@ -0,0 +1,211 @@
1
+ ---
2
+ paths:
3
+ - "apps/**/*.tsx"
4
+ - "libs/**/*.tsx"
5
+ ---
6
+
7
+ # Component Rules (Next.js 15 / React 19)
8
+
9
+ ## Server vs Client Components
10
+
11
+ ### Server Components (Default)
12
+
13
+ No directive needed. Use for:
14
+ - Data fetching
15
+ - Database access
16
+ - Accessing secrets/environment variables
17
+ - Heavy dependencies that don't need to ship to client
18
+
19
+ ```tsx
20
+ // app/users/page.tsx
21
+ // This is a Server Component by default
22
+ import { db } from '@/lib/db';
23
+
24
+ export default async function UsersPage() {
25
+ const users = await db.user.findMany();
26
+
27
+ return (
28
+ <ul>
29
+ {users.map((user) => (
30
+ <li key={user.id}>{user.name}</li>
31
+ ))}
32
+ </ul>
33
+ );
34
+ }
35
+ ```
36
+
37
+ ### Client Components
38
+
39
+ Add `'use client'` at the top. Use for:
40
+ - Interactivity (onClick, onChange, etc.)
41
+ - React hooks (useState, useEffect, useContext)
42
+ - Browser APIs (localStorage, window, etc.)
43
+
44
+ ```tsx
45
+ 'use client';
46
+
47
+ import { useState } from 'react';
48
+
49
+ export function Counter() {
50
+ const [count, setCount] = useState(0);
51
+
52
+ return (
53
+ <button onClick={() => setCount(count + 1)}>
54
+ Count: {count}
55
+ </button>
56
+ );
57
+ }
58
+ ```
59
+
60
+ ### Decision Tree
61
+
62
+ ```
63
+ Need hooks or interactivity?
64
+ ├── YES → 'use client'
65
+ └── NO → Server Component (default)
66
+ └── Fetching data? → async component
67
+ ```
68
+
69
+ ## Component Patterns
70
+
71
+ ### Props Interface
72
+
73
+ Always define props interface above component:
74
+
75
+ ```tsx
76
+ interface UserCardProps {
77
+ user: User;
78
+ isSelected?: boolean;
79
+ onSelect: (user: User) => void;
80
+ }
81
+
82
+ export function UserCard({ user, isSelected = false, onSelect }: UserCardProps) {
83
+ return (/* ... */);
84
+ }
85
+ ```
86
+
87
+ ### Composition over Props
88
+
89
+ ```tsx
90
+ // BAD - prop drilling
91
+ <Card
92
+ title="User Profile"
93
+ subtitle="Details"
94
+ icon={<UserIcon />}
95
+ footer={<Button>Edit</Button>}
96
+ />
97
+
98
+ // GOOD - composition
99
+ <Card>
100
+ <CardHeader>
101
+ <UserIcon />
102
+ <CardTitle>User Profile</CardTitle>
103
+ <CardDescription>Details</CardDescription>
104
+ </CardHeader>
105
+ <CardFooter>
106
+ <Button>Edit</Button>
107
+ </CardFooter>
108
+ </Card>
109
+ ```
110
+
111
+ ### Async Server Components
112
+
113
+ ```tsx
114
+ // Server Component can be async
115
+ export default async function UsersPage() {
116
+ const users = await getUsers(); // Direct await
117
+
118
+ return <UserList users={users} />;
119
+ }
120
+ ```
121
+
122
+ ### Client Component with Server Data
123
+
124
+ ```tsx
125
+ // page.tsx (Server)
126
+ export default async function Page() {
127
+ const data = await fetchData();
128
+ return <InteractiveComponent initialData={data} />;
129
+ }
130
+
131
+ // interactive-component.tsx (Client)
132
+ 'use client';
133
+
134
+ export function InteractiveComponent({ initialData }: Props) {
135
+ const [data, setData] = useState(initialData);
136
+ // Can now use hooks with server-fetched data
137
+ }
138
+ ```
139
+
140
+ ## File Organization
141
+
142
+ ### Co-located Components
143
+
144
+ ```
145
+ app/
146
+ users/
147
+ page.tsx # Route
148
+ _components/ # Private folder (underscore prefix)
149
+ user-list.tsx # Only used in /users
150
+ user-card.tsx
151
+ user-form.tsx
152
+ actions.ts # Server Actions
153
+ loading.tsx # Loading UI
154
+ error.tsx # Error UI
155
+ ```
156
+
157
+ ### Shared Components
158
+
159
+ ```
160
+ libs/
161
+ shared/
162
+ ui/
163
+ button.tsx
164
+ input.tsx
165
+ card.tsx
166
+ index.ts # Barrel export
167
+ ```
168
+
169
+ ## Naming Conventions
170
+
171
+ ```tsx
172
+ // Component files: kebab-case
173
+ user-card.tsx
174
+ user-list.tsx
175
+
176
+ // Components: PascalCase
177
+ export function UserCard() {}
178
+ export function UserList() {}
179
+
180
+ // Hooks: camelCase with 'use' prefix
181
+ export function useUserData() {}
182
+
183
+ // Event handlers: handle + Event
184
+ const handleClick = () => {};
185
+ const handleSubmit = () => {};
186
+ const handleUserSelect = (user: User) => {};
187
+ ```
188
+
189
+ ## Exports
190
+
191
+ ```tsx
192
+ // Named exports for reusable components
193
+ export function Button() {}
194
+ export function Input() {}
195
+
196
+ // Default export ONLY for:
197
+ // - page.tsx
198
+ // - layout.tsx
199
+ // - loading.tsx
200
+ // - error.tsx
201
+ // - not-found.tsx
202
+ export default function Page() {}
203
+ ```
204
+
205
+ ## Avoid
206
+
207
+ - `useEffect` for data fetching (use Server Components)
208
+ - Default exports for library components
209
+ - Inline styles (use CSS modules or Tailwind)
210
+ - Anonymous components
211
+ - Props spreading without type safety