@valentia-ai-skills/framework 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 (29) hide show
  1. package/README.md +103 -0
  2. package/bin/cli.js +482 -0
  3. package/package.json +42 -0
  4. package/scripts/postinstall.js +18 -0
  5. package/skills/global/api-design/SKILL.md +248 -0
  6. package/skills/global/api-design/tests/test-prompts.md +25 -0
  7. package/skills/global/code-standards/SKILL.md +245 -0
  8. package/skills/global/code-standards/tests/test-prompts.md +26 -0
  9. package/skills/global/deployment/SKILL.md +240 -0
  10. package/skills/global/deployment/tests/test-prompts.md +27 -0
  11. package/skills/global/documentation/SKILL.md +298 -0
  12. package/skills/global/documentation/tests/test-prompts.md +26 -0
  13. package/skills/global/git-workflow/SKILL.md +177 -0
  14. package/skills/global/git-workflow/tests/test-prompts.md +11 -0
  15. package/skills/global/security-baseline/SKILL.md +239 -0
  16. package/skills/global/security-baseline/tests/test-prompts.md +23 -0
  17. package/skills/global/testing-standards/SKILL.md +257 -0
  18. package/skills/global/testing-standards/tests/test-prompts.md +25 -0
  19. package/skills/onboarding/SKILL.md +110 -0
  20. package/skills/stack/devops/SKILL.md +220 -0
  21. package/skills/stack/devops/tests/test-prompts.md +29 -0
  22. package/skills/stack/node-backend/SKILL.md +304 -0
  23. package/skills/stack/node-backend/tests/test-prompts.md +27 -0
  24. package/skills/stack/python-backend/SKILL.md +304 -0
  25. package/skills/stack/python-backend/tests/test-prompts.md +27 -0
  26. package/skills/stack/react/SKILL.md +251 -0
  27. package/skills/stack/react/tests/test-prompts.md +26 -0
  28. package/skills/stack/react-native/SKILL.md +255 -0
  29. package/skills/stack/react-native/tests/test-prompts.md +26 -0
@@ -0,0 +1,27 @@
1
+ ## Test 1: Service Creation
2
+ **Prompt**: "Create a user registration service that validates input, checks for duplicate emails, hashes the password, saves to DB, and sends a welcome email"
3
+ **Expected**:
4
+ - Layered: controller → service → repository
5
+ - Dependencies injected
6
+ - Zod validation at controller level
7
+ - Custom errors (ConflictError for duplicate, ValidationError)
8
+ - Password hashed with bcrypt
9
+ - Service doesn't touch req/res objects
10
+
11
+ ## Test 2: API Setup
12
+ **Prompt**: "Set up an Express API with health checks, error handling, structured logging, and graceful shutdown"
13
+ **Expected**:
14
+ - /health endpoint checking DB and Redis
15
+ - Global error handler middleware
16
+ - Pino or Winston structured logging
17
+ - SIGTERM/SIGINT handlers with timeout
18
+ - Config validated at startup with Zod
19
+
20
+ ## Test 3: Database Repository
21
+ **Prompt**: "Create a repository for an e-commerce orders table with CRUD, pagination, and filtering by status and date range"
22
+ **Expected**:
23
+ - Repository class with injected DB client
24
+ - Typed methods for each operation
25
+ - Pagination following api-design standards
26
+ - Transaction for create (order + order items)
27
+ - No business logic in repository
@@ -0,0 +1,304 @@
1
+ ---
2
+ name: python-backend-patterns
3
+ description: >
4
+ Python backend development patterns for FastAPI, Django, and data services.
5
+ Use this skill whenever writing, reviewing, or designing Python backend code
6
+ including API endpoints, data pipelines, background tasks, database models,
7
+ or Python microservices. Triggers on: "FastAPI", "Django", "Flask", "Python API",
8
+ "Pydantic", "SQLAlchemy", "Alembic", "Celery", "asyncio", "uvicorn",
9
+ "gunicorn", "Python service", "data pipeline", "ETL", "pandas backend",
10
+ "Python microservice". Applies to Python backend teams.
11
+ version: "1.0.0"
12
+ scope: stack
13
+ stack: python-backend
14
+ author: Framework Admin
15
+ last_reviewed: 2026-03-19
16
+ ---
17
+
18
+ # Python Backend Patterns
19
+
20
+ ## Overview
21
+
22
+ Standardized Python backend patterns for API services and data pipelines.
23
+ Assumes FastAPI as the default framework (Django sections noted where applicable).
24
+
25
+ **Prerequisites**: `global/code-standards`, `global/security-baseline`, and
26
+ `global/api-design` all apply. This skill adds Python-specific conventions.
27
+
28
+ ## 1. Project Structure (FastAPI)
29
+
30
+ ```
31
+ src/
32
+ app/
33
+ main.py # App factory, startup/shutdown
34
+ config.py # Settings with Pydantic BaseSettings
35
+ dependencies.py # FastAPI dependency injection
36
+
37
+ routers/ # Route definitions
38
+ __init__.py
39
+ users.py
40
+ orders.py
41
+
42
+ services/ # Business logic
43
+ user_service.py
44
+ order_service.py
45
+
46
+ repositories/ # Database access
47
+ user_repository.py
48
+
49
+ models/ # SQLAlchemy models
50
+ user.py
51
+ order.py
52
+
53
+ schemas/ # Pydantic request/response schemas
54
+ user_schemas.py
55
+ order_schemas.py
56
+
57
+ middleware/ # Custom middleware
58
+ logging_middleware.py
59
+
60
+ exceptions/ # Custom exception classes
61
+ base.py
62
+ handlers.py
63
+
64
+ utils/ # Shared utilities
65
+
66
+ tests/
67
+ conftest.py # Shared fixtures
68
+ test_users.py
69
+ test_orders.py
70
+
71
+ alembic/ # Database migrations
72
+ versions/
73
+ env.py
74
+
75
+ pyproject.toml # Project config + dependencies
76
+ ```
77
+
78
+ ### Naming Rules (Python-specific)
79
+ - Files and folders: `snake_case`
80
+ - Classes: `PascalCase`
81
+ - Functions and variables: `snake_case`
82
+ - Constants: `UPPER_SNAKE_CASE`
83
+ - Private methods/attrs: `_single_underscore`
84
+ - Follow PEP 8 — enforced via ruff
85
+
86
+ ## 2. Configuration
87
+
88
+ ```python
89
+ # config.py
90
+ from pydantic_settings import BaseSettings
91
+
92
+ class Settings(BaseSettings):
93
+ """Application settings — loaded from environment variables."""
94
+
95
+ app_name: str = "my-service"
96
+ environment: str = "development"
97
+ debug: bool = False
98
+
99
+ # Database
100
+ database_url: str
101
+ database_pool_size: int = 5
102
+
103
+ # Redis
104
+ redis_url: str
105
+
106
+ # Auth
107
+ jwt_secret: str
108
+ jwt_expiry_minutes: int = 15
109
+
110
+ # External services
111
+ email_api_key: str = ""
112
+
113
+ class Config:
114
+ env_file = ".env"
115
+
116
+ settings = Settings()
117
+ ```
118
+
119
+ ### Rules
120
+ - All config through Pydantic `BaseSettings` — validates at startup
121
+ - Never use `os.getenv()` directly in service code
122
+ - Type all settings — Pydantic will fail fast on invalid values
123
+ - Secrets loaded from env vars, never hardcoded
124
+
125
+ ## 3. Request/Response Schemas
126
+
127
+ ```python
128
+ # schemas/user_schemas.py
129
+ from pydantic import BaseModel, EmailStr, Field
130
+ from datetime import datetime
131
+
132
+ class CreateUserRequest(BaseModel):
133
+ email: EmailStr
134
+ name: str = Field(min_length=1, max_length=100)
135
+ role: str = Field(pattern="^(user|admin|editor)$")
136
+
137
+ class UserResponse(BaseModel):
138
+ id: str
139
+ email: str
140
+ name: str
141
+ role: str
142
+ created_at: datetime
143
+
144
+ class Config:
145
+ from_attributes = True # allows ORM objects
146
+
147
+ class UserListResponse(BaseModel):
148
+ data: list[UserResponse]
149
+ pagination: PaginationResponse
150
+ ```
151
+
152
+ ### Rules
153
+ - Separate schemas for request (input) and response (output)
154
+ - Use Pydantic `Field` for validation rules
155
+ - Response schemas use `from_attributes = True` for ORM compatibility
156
+ - Follow the `data` / `error` envelope from api-design standards
157
+
158
+ ## 4. Dependency Injection (FastAPI)
159
+
160
+ ```python
161
+ # dependencies.py
162
+ from fastapi import Depends
163
+ from sqlalchemy.ext.asyncio import AsyncSession
164
+
165
+ async def get_db() -> AsyncGenerator[AsyncSession, None]:
166
+ async with async_session_maker() as session:
167
+ yield session
168
+
169
+ async def get_user_service(
170
+ db: AsyncSession = Depends(get_db),
171
+ ) -> UserService:
172
+ repo = UserRepository(db)
173
+ return UserService(repo)
174
+
175
+ # In routers:
176
+ @router.post("/users", status_code=201)
177
+ async def create_user(
178
+ data: CreateUserRequest,
179
+ service: UserService = Depends(get_user_service),
180
+ ) -> UserResponse:
181
+ return await service.create_user(data)
182
+ ```
183
+
184
+ ### Rules
185
+ - Use FastAPI's `Depends()` for all dependency injection
186
+ - Database sessions via `yield` dependency (ensures cleanup)
187
+ - Services receive repositories through DI — never import directly
188
+ - All dependencies are explicit and testable
189
+
190
+ ## 5. Async/Await Rules
191
+
192
+ ```python
193
+ # ✅ Good: async for I/O operations
194
+ async def get_user(user_id: str) -> User:
195
+ return await db.execute(select(User).where(User.id == user_id))
196
+
197
+ # ✅ Good: sync for CPU-bound operations
198
+ def calculate_report(data: list[dict]) -> Report:
199
+ return Report(totals=sum(d["amount"] for d in data))
200
+
201
+ # ❌ Bad: blocking I/O in async function
202
+ async def get_user(user_id: str) -> User:
203
+ return requests.get(f"/api/users/{user_id}") # blocks the event loop!
204
+ ```
205
+
206
+ ### Rules
207
+ - Use `async/await` for all I/O (database, HTTP, file system)
208
+ - Use `httpx` (async) instead of `requests` (sync) for HTTP calls
209
+ - Use `asyncpg` or async SQLAlchemy for database access
210
+ - Never mix sync blocking calls in async code paths
211
+ - For CPU-heavy work in async context, use `asyncio.to_thread()`
212
+
213
+ ## 6. Error Handling
214
+
215
+ ```python
216
+ # exceptions/base.py
217
+ class AppError(Exception):
218
+ def __init__(self, message: str, status_code: int, code: str, details=None):
219
+ self.message = message
220
+ self.status_code = status_code
221
+ self.code = code
222
+ self.details = details
223
+ super().__init__(message)
224
+
225
+ class NotFoundError(AppError):
226
+ def __init__(self, resource: str, resource_id: str):
227
+ super().__init__(
228
+ message=f"{resource} with id {resource_id} not found",
229
+ status_code=404,
230
+ code="NOT_FOUND",
231
+ )
232
+
233
+ class ValidationError(AppError):
234
+ def __init__(self, details: list[dict]):
235
+ super().__init__(
236
+ message="Validation failed",
237
+ status_code=400,
238
+ code="VALIDATION_ERROR",
239
+ details=details,
240
+ )
241
+
242
+ # exceptions/handlers.py
243
+ @app.exception_handler(AppError)
244
+ async def app_error_handler(request: Request, exc: AppError):
245
+ return JSONResponse(
246
+ status_code=exc.status_code,
247
+ content={"error": {"code": exc.code, "message": exc.message, "details": exc.details}},
248
+ )
249
+ ```
250
+
251
+ ## 7. Testing (pytest)
252
+
253
+ ```python
254
+ # conftest.py
255
+ import pytest
256
+ from httpx import AsyncClient
257
+
258
+ @pytest.fixture
259
+ async def db_session():
260
+ async with test_engine.begin() as conn:
261
+ await conn.run_sync(Base.metadata.create_all)
262
+ async with async_test_session() as session:
263
+ yield session
264
+ async with test_engine.begin() as conn:
265
+ await conn.run_sync(Base.metadata.drop_all)
266
+
267
+ @pytest.fixture
268
+ async def client(db_session):
269
+ app.dependency_overrides[get_db] = lambda: db_session
270
+ async with AsyncClient(app=app, base_url="http://test") as ac:
271
+ yield ac
272
+ app.dependency_overrides.clear()
273
+
274
+ # test_users.py
275
+ @pytest.mark.asyncio
276
+ async def test_create_user_success(client: AsyncClient):
277
+ response = await client.post("/api/v1/users", json={
278
+ "email": "alice@example.com",
279
+ "name": "Alice",
280
+ "role": "user",
281
+ })
282
+ assert response.status_code == 201
283
+ assert response.json()["data"]["email"] == "alice@example.com"
284
+ ```
285
+
286
+ ### Rules
287
+ - Use `pytest` with `pytest-asyncio` for async tests
288
+ - Override FastAPI dependencies in fixtures (not mocking)
289
+ - Use `httpx.AsyncClient` for integration tests
290
+ - Factory fixtures for test data (see testing-standards skill)
291
+
292
+ ## Checklist
293
+
294
+ Before finalizing Python backend code:
295
+ - [ ] Layered: routers → services → repositories
296
+ - [ ] Config via Pydantic BaseSettings, validated at startup
297
+ - [ ] Request/response schemas separated (Pydantic)
298
+ - [ ] Dependencies injected via FastAPI Depends()
299
+ - [ ] All I/O is async (httpx, async SQLAlchemy)
300
+ - [ ] Custom error classes with status codes
301
+ - [ ] Global exception handler returns standard error envelope
302
+ - [ ] Migrations via Alembic (not manual SQL)
303
+ - [ ] Tests use dependency override, not mocking
304
+ - [ ] ruff for linting, mypy for type checking
@@ -0,0 +1,27 @@
1
+ ## Test 1: FastAPI Service
2
+ **Prompt**: "Create a FastAPI service for managing a product catalog with CRUD endpoints, Pydantic schemas, and SQLAlchemy models"
3
+ **Expected**:
4
+ - Project structure follows the standard layout
5
+ - Separate request/response schemas
6
+ - Repository pattern for DB access
7
+ - Dependency injection via Depends()
8
+ - Async database operations
9
+ - Custom error handling
10
+
11
+ ## Test 2: Configuration & Startup
12
+ **Prompt**: "Set up the application config, database connection, and health check for a FastAPI service"
13
+ **Expected**:
14
+ - Pydantic BaseSettings for config
15
+ - Async SQLAlchemy session factory
16
+ - /health endpoint checking DB
17
+ - Startup/shutdown lifecycle events
18
+ - Graceful error on missing env vars
19
+
20
+ ## Test 3: Background Task
21
+ **Prompt**: "Create an endpoint that accepts a CSV upload, processes it in the background, and returns the job status"
22
+ **Expected**:
23
+ - Upload endpoint with file validation
24
+ - Background task (Celery or FastAPI BackgroundTasks)
25
+ - Job status tracking
26
+ - Async file processing
27
+ - Error handling for bad CSV data
@@ -0,0 +1,251 @@
1
+ ---
2
+ name: react-patterns
3
+ description: >
4
+ React development patterns and conventions for web teams. Use this skill
5
+ whenever writing, reviewing, or refactoring React components, hooks,
6
+ state management, context, effects, forms, routing, or any React-specific
7
+ code. Triggers on: "React", "component", "hook", "useState", "useEffect",
8
+ "useRef", "useContext", "useMemo", "useCallback", "JSX", "TSX", "props",
9
+ "state", "context", "reducer", "render", "virtual DOM", "Next.js", "Remix",
10
+ "React Router", "form handling", "controlled component", "uncontrolled".
11
+ Applies to all web teams using React.
12
+ version: "1.0.0"
13
+ scope: stack
14
+ stack: react
15
+ author: Framework Admin
16
+ last_reviewed: 2026-03-19
17
+ ---
18
+
19
+ # React Patterns
20
+
21
+ ## Overview
22
+
23
+ Standardized React patterns ensure consistent component architecture across
24
+ all web teams. These conventions cover component structure, hooks usage,
25
+ state management, and performance patterns.
26
+
27
+ ## 1. Component Structure
28
+
29
+ ### File Template
30
+ Every component file follows this order:
31
+
32
+ ```tsx
33
+ // 1. Imports (follow code-standards import order)
34
+ import { useState, useCallback } from "react";
35
+ import { Button } from "@/components/ui/button";
36
+ import type { User } from "@/types/user";
37
+
38
+ // 2. Types / Interfaces
39
+ interface UserCardProps {
40
+ user: User;
41
+ onEdit: (userId: string) => void;
42
+ isCompact?: boolean;
43
+ }
44
+
45
+ // 3. Constants (component-specific)
46
+ const MAX_BIO_LENGTH = 200;
47
+
48
+ // 4. Component
49
+ export function UserCard({ user, onEdit, isCompact = false }: UserCardProps) {
50
+ // 4a. Hooks (always at the top, same order every time)
51
+ const [isExpanded, setIsExpanded] = useState(false);
52
+
53
+ // 4b. Derived state (computed from props/state)
54
+ const displayName = `${user.firstName} ${user.lastName}`;
55
+ const truncatedBio = user.bio?.slice(0, MAX_BIO_LENGTH);
56
+
57
+ // 4c. Handlers
58
+ const handleEditClick = useCallback(() => {
59
+ onEdit(user.id);
60
+ }, [onEdit, user.id]);
61
+
62
+ // 4d. Early returns (loading, error, empty states)
63
+ if (!user) return null;
64
+
65
+ // 4e. Render
66
+ return (
67
+ <div className={isCompact ? "p-2" : "p-4"}>
68
+ <h3>{displayName}</h3>
69
+ <p>{isExpanded ? user.bio : truncatedBio}</p>
70
+ <Button onClick={handleEditClick}>Edit</Button>
71
+ </div>
72
+ );
73
+ }
74
+ ```
75
+
76
+ ### Rules
77
+ - One component per file (with small sub-components allowed)
78
+ - Named exports for components (not default, except page-level)
79
+ - Component name matches file name: `user-card.tsx` → `UserCard`
80
+ - Props interface defined above the component
81
+ - All props typed — no `any`
82
+
83
+ ## 2. Hooks
84
+
85
+ ### Hook Order (always consistent)
86
+ ```tsx
87
+ function MyComponent() {
88
+ // 1. External hooks (router, context, etc.)
89
+ const router = useRouter();
90
+ const { user } = useAuth();
91
+
92
+ // 2. State hooks
93
+ const [count, setCount] = useState(0);
94
+ const [isOpen, setIsOpen] = useState(false);
95
+
96
+ // 3. Refs
97
+ const inputRef = useRef<HTMLInputElement>(null);
98
+
99
+ // 4. Derived state (useMemo for expensive computations only)
100
+ const total = useMemo(() => calculateTotal(items), [items]);
101
+
102
+ // 5. Effects
103
+ useEffect(() => { ... }, [dependency]);
104
+
105
+ // 6. Callbacks
106
+ const handleSubmit = useCallback(() => { ... }, [deps]);
107
+ }
108
+ ```
109
+
110
+ ### Custom Hook Rules
111
+ - Prefix with `use`: `useAuth`, `useDebounce`, `usePagination`
112
+ - Extract when logic is reused across 2+ components
113
+ - Put in `hooks/` directory: `hooks/use-debounce.ts`
114
+ - Always return a typed value
115
+
116
+ ```tsx
117
+ // ✅ Good: Clean custom hook
118
+ function useDebounce<T>(value: T, delayMs: number): T {
119
+ const [debouncedValue, setDebouncedValue] = useState(value);
120
+
121
+ useEffect(() => {
122
+ const timer = setTimeout(() => setDebouncedValue(value), delayMs);
123
+ return () => clearTimeout(timer);
124
+ }, [value, delayMs]);
125
+
126
+ return debouncedValue;
127
+ }
128
+ ```
129
+
130
+ ### useEffect Rules
131
+ - Every effect must have a dependency array
132
+ - Empty `[]` only for mount-once effects (and add a comment explaining why)
133
+ - Clean up subscriptions, timers, and listeners in the return function
134
+ - Never lie about dependencies — if ESLint warns, fix the code, don't suppress
135
+
136
+ ✅ Good:
137
+ ```tsx
138
+ useEffect(() => {
139
+ const controller = new AbortController();
140
+
141
+ fetchUser(userId, { signal: controller.signal })
142
+ .then(setUser)
143
+ .catch(err => {
144
+ if (err.name !== "AbortError") setError(err);
145
+ });
146
+
147
+ return () => controller.abort(); // cleanup
148
+ }, [userId]);
149
+ ```
150
+
151
+ ❌ Bad:
152
+ ```tsx
153
+ useEffect(() => {
154
+ fetchUser(userId).then(setUser);
155
+ }); // missing dependency array — runs every render
156
+
157
+ useEffect(() => {
158
+ fetchUser(userId).then(setUser);
159
+ // eslint-disable-next-line react-hooks/exhaustive-deps
160
+ }, []); // suppressing the warning instead of fixing
161
+ ```
162
+
163
+ ## 3. State Management
164
+
165
+ ### Decision Matrix
166
+ | Scope | Solution |
167
+ |-------|----------|
168
+ | Single component | `useState` |
169
+ | Parent → Children (2-3 levels) | Props drilling (it's fine!) |
170
+ | Deep tree (4+ levels) | React Context |
171
+ | Complex state transitions | `useReducer` |
172
+ | Server state (API data) | TanStack Query / SWR |
173
+ | Global client state | Zustand (preferred) or Redux Toolkit |
174
+
175
+ ### Rules
176
+ - Start simple — don't add Zustand/Redux until you actually need it
177
+ - Server state belongs in TanStack Query, not in global state
178
+ - Context is for slow-changing data (theme, auth, locale) — not for frequently updating state
179
+ - Never put derived state in useState — compute it inline
180
+
181
+ ```tsx
182
+ // ❌ Bad: Storing derived state
183
+ const [fullName, setFullName] = useState(`${first} ${last}`);
184
+ useEffect(() => setFullName(`${first} ${last}`), [first, last]);
185
+
186
+ // ✅ Good: Compute inline
187
+ const fullName = `${first} ${last}`;
188
+ ```
189
+
190
+ ## 4. Event Handling
191
+
192
+ - Handlers prefixed with `handle`: `handleClick`, `handleSubmit`
193
+ - Callback props prefixed with `on`: `onClick`, `onSubmit`
194
+ - Use `useCallback` only when passing handlers to memoized children
195
+
196
+ ```tsx
197
+ // In parent:
198
+ const handleUserSelect = useCallback((userId: string) => {
199
+ setSelectedUser(userId);
200
+ }, []);
201
+
202
+ // In child props:
203
+ <UserList onSelect={handleUserSelect} />
204
+ ```
205
+
206
+ ## 5. Conditional Rendering
207
+
208
+ ```tsx
209
+ // Boolean: use &&
210
+ {isLoggedIn && <Dashboard />}
211
+
212
+ // Binary: use ternary
213
+ {isLoading ? <Spinner /> : <Content />}
214
+
215
+ // Multiple conditions: use early return or extracted function
216
+ function StatusBadge({ status }: { status: OrderStatus }) {
217
+ if (status === "pending") return <Badge color="yellow">Pending</Badge>;
218
+ if (status === "shipped") return <Badge color="blue">Shipped</Badge>;
219
+ if (status === "delivered") return <Badge color="green">Delivered</Badge>;
220
+ return null;
221
+ }
222
+ ```
223
+
224
+ ### Watch Out
225
+ ```tsx
226
+ // ❌ Bug: renders "0" when count is 0
227
+ {count && <Tag>{count}</Tag>}
228
+
229
+ // ✅ Fix: explicit boolean check
230
+ {count > 0 && <Tag>{count}</Tag>}
231
+ ```
232
+
233
+ ## 6. Performance
234
+
235
+ - Use `React.memo` only for components that re-render with same props frequently
236
+ - Use `useMemo` only for genuinely expensive computations (not simple lookups)
237
+ - Use `useCallback` only when passing to memoized children
238
+ - Profile first, optimize second — don't premature-optimize
239
+ - Lazy load heavy components: `const HeavyChart = React.lazy(() => import("./heavy-chart"))`
240
+
241
+ ## Checklist
242
+
243
+ Before finalizing React code:
244
+ - [ ] One component per file, named export, props typed
245
+ - [ ] Hooks in consistent order (context → state → refs → memo → effects → callbacks)
246
+ - [ ] All useEffect have dependency arrays and cleanup functions
247
+ - [ ] No derived state in useState — computed inline
248
+ - [ ] Event handlers: handle* (internal) and on* (props)
249
+ - [ ] State management matches scope (don't over-engineer)
250
+ - [ ] No eslint-disable for hook dependency warnings
251
+ - [ ] Loading, error, and empty states handled
@@ -0,0 +1,26 @@
1
+ ## Test 1: Component Creation
2
+ **Prompt**: "Build a product card component that shows image, title, price, rating, and an add-to-cart button with quantity selector"
3
+ **Expected**:
4
+ - Props interface with all fields typed
5
+ - Named export
6
+ - Hooks in correct order
7
+ - Handlers prefixed with handle
8
+ - Loading/empty state handled
9
+
10
+ ## Test 2: Data Fetching Component
11
+ **Prompt**: "Create a user profile page that fetches user data from an API, shows loading state, error state, and allows editing the bio field"
12
+ **Expected**:
13
+ - useEffect with proper cleanup (AbortController)
14
+ - Dependency array correct
15
+ - Loading, error, and success states
16
+ - No derived state in useState
17
+ - Form handling with controlled input
18
+
19
+ ## Test 3: State Management Decision
20
+ **Prompt**: "I have a shopping cart that needs to be accessible from the navbar, product pages, and checkout. What state management should I use?"
21
+ **Expected**:
22
+ - Recommends Zustand or Context based on complexity
23
+ - Explains why not just props (too many levels)
24
+ - Server state (product data) in TanStack Query
25
+ - Client state (cart items) in Zustand/Context
26
+ - Shows code example