commit 240c84c4654b7f231e9e3804db7d408f7a4a1982 Author: Zhongwei Li Date: Sun Nov 30 09:04:45 2025 +0800 Initial commit diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json new file mode 100644 index 0000000..73505fe --- /dev/null +++ b/.claude-plugin/plugin.json @@ -0,0 +1,12 @@ +{ + "name": "venturo-react", + "description": "React frontend development automation for Venturo skeleton - Guided workflows for features from OpenAPI specs", + "version": "1.0.0", + "author": { + "name": "Venturo", + "email": "dev@venturo.id" + }, + "commands": [ + "./commands" + ] +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..cd37a7a --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# venturo-react + +React frontend development automation for Venturo skeleton - Guided workflows for features from OpenAPI specs diff --git a/commands/new-feature.md b/commands/new-feature.md new file mode 100644 index 0000000..b59762a --- /dev/null +++ b/commands/new-feature.md @@ -0,0 +1,527 @@ +# New Feature Creation Instruction (Frontend) + +## How to Use This Instruction + +**Prompt Claude with:** +``` +Create new feature from OpenAPI, read new-feature-instruction.md +``` + +**Claude will:** +1. Ask for the OpenAPI YAML file location +2. Parse the OpenAPI spec to understand the API structure +3. Guide you through planning the feature architecture +4. Execute implementation using **incremental phases** +5. Stop after each phase for your review before continuing + +--- + +## Implementation Approach + +This instruction uses an **incremental workflow** broken into **5 phases** to save context and allow validation at each step. + +**Incremental phase files are located at:** `.venturo/instructions/new-feature/` + +### Phase Overview + +1. **Phase 1: API Layer** (`01-api-layer.md`) + - Create TypeScript types from OpenAPI schemas + - Create API endpoint functions + - Create React Query hooks (useGetList, usePost, usePut, useDelete) + +2. **Phase 2: Feature Components** (`02-feature-components.md`) + - Create Table component with pagination + - Create Form component (Create/Edit dialog) + - Create Filters component (search bar) + - Create FilterDrawer component (advanced filters) + +3. **Phase 3: Feature Hooks** (`03-feature-hooks.md`) + - Create useTable{Feature} hook for table logic + - Create useForm{Feature} hook for form logic + +4. **Phase 4: Page Integration & Routes** (`04-page-and-routes.md`) + - Create main {Feature}Page component + - Register routes in Router.tsx + - Add sidebar menu items + +5. **Phase 5: Permissions & Constants** (`05-permissions-constants.md`) + - Add permission constants + - Add permission guards to page + +**See:** `.venturo/instructions/new-feature/README.md` for complete incremental workflow details. + +--- + +## Interactive Discovery Process + +When this instruction is invoked, Claude MUST ask these questions: + +### Step 1: OpenAPI File Location +**Question 1:** "What is the path to the OpenAPI YAML file?" +- Expected path format: `/mnt/d/Dev/Venturo/RnD/venturo-skeleton-go/docs/api/openapi-{feature_name}.yaml` +- Example: `/mnt/d/Dev/Venturo/RnD/venturo-skeleton-go/docs/api/openapi-customer_management.yaml` +- Claude will read and parse this file to extract: + - Feature name (from file name) + - Entity schemas (from components/schemas) + - API endpoints (from paths) + - Request/Response types + - Query parameters + - Required permissions (from descriptions) + +### Step 2: Feature Naming +**Question 2:** "What should the feature name be in the frontend?" +- Backend: `customer_management` (snake_case) +- Frontend options: + - PascalCase for components: `CustomerManagement` or `Customer` + - lowercase for files: `customer` or `customer-management` +- Example: "customer" (recommended for simpler names) + +**Question 3:** "What is the base API path for this feature?" +- Extract from OpenAPI `servers.url` or paths +- Example: `/core/v1/customers` +- This helps determine the endpoint structure + +### Step 3: Feature Analysis +**Question 4:** "Review the OpenAPI spec analysis - does this look correct?" +Present a summary showing: +- **Feature Name**: customer +- **Entity Name**: Customer (singular) +- **Base Path**: `/core/v1/customers` +- **Endpoints Detected**: + - POST /customers (Create) + - GET /customers (List with pagination) + - GET /customers/{id} (Get by ID) + - PUT /customers/{id} (Update) + - DELETE /customers/{id} (Delete) +- **Schemas Detected**: + - CreateCustomerRequest + - UpdateCustomerRequest + - CustomerResponse + - PaginatedCustomerResponse +- **Filters Available**: + - search (string) + - status (enum: active, inactive) + - page, page_size (pagination) +- **Permissions Required**: + - customer.create + - customer.read + - customer.update + - customer.delete + +### Step 4: Component Structure Planning +**Question 5:** "What components should we generate?" +Based on OpenAPI analysis, suggest: +- [x] Table (if GET list endpoint exists) +- [x] Form (if POST/PUT endpoints exist) +- [x] Filters (if query parameters exist) +- [x] FilterDrawer (if multiple filter options exist) +- [x] Delete confirmation (if DELETE endpoint exists) + +### Step 5: Additional Features +**Question 6:** "Does this feature need any of these additional features?" +- [ ] Export functionality (CSV, Excel) +- [ ] Bulk operations (Bulk delete, bulk update) +- [ ] Custom actions (Activate, Deactivate, etc.) +- [ ] File upload/download +- [ ] Advanced filtering (date range, etc.) + +### Step 6: Confirmation +Present a complete implementation plan: + +``` +📋 Feature Implementation Plan + +Feature: Customer Management +Entity: Customer +Base Path: /core/v1/customers + +🗂️ Files to Create: + +API Layer (src/app/api/customer/): + ✓ type.ts - TypeScript interfaces + ✓ customerApi.ts - API endpoint functions + ✓ useCustomerApi.ts - React Query hooks + ✓ index.ts - Exports + +Feature Components (src/features/customer/components/): + ✓ CustomerTable.tsx - Data table with pagination + ✓ CustomerForm.tsx - Create/Edit dialog + ✓ CustomerFilters.tsx - Search bar and filter button + ✓ CustomerFilterDrawer.tsx - Advanced filter drawer + +Feature Hooks (src/features/customer/hooks/): + ✓ useTableCustomer.ts - Table state and operations + ✓ useFormCustomer.ts - Form state and validation + +Feature Page (src/features/customer/): + ✓ CustomerPage.tsx - Main page component + +Routes & Constants: + ✓ Update src/app/routes/Router.tsx + ✓ Update src/app/routes/SideBarData.ts + ✓ Update src/app/constants/permission.ts + ✓ Update src/app/constants/router.ts + +Estimated Time: 15-20 minutes +Phases: 5 incremental phases with validation checkpoints +``` + +**Ask:** "Does this plan look correct? Should I proceed with implementation?" + +--- + +## Implementation Workflow (After Confirmation) + +After user confirms the plan, Claude will: + +1. **Read Phase 1 instruction:** `.venturo/instructions/new-feature/01-api-layer.md` +2. **Execute Phase 1:** Create API types, endpoints, and React Query hooks +3. **Stop and report:** Ask user to review the API layer +4. **Wait for "continue"** command from user +5. **Repeat for each phase** (2-5) + +### Example Execution Flow + +``` +User: Create new feature from OpenAPI, read new-feature-instruction.md + +Claude: [Asks for OpenAPI file path] + +User: /mnt/d/Dev/Venturo/RnD/venturo-skeleton-go/docs/api/openapi-customer_management.yaml + +Claude: [Reads and parses OpenAPI] + [Asks remaining discovery questions] + [Presents complete plan] + +User: Yes, proceed + +Claude: [Reads .venturo/instructions/new-feature/01-api-layer.md] + [Executes Phase 1: Creates API layer] + + ✅ Phase 1 Complete: API Layer + + Created: + - src/app/api/customer/type.ts + - src/app/api/customer/customerApi.ts + - src/app/api/customer/useCustomerApi.ts + - src/app/api/customer/index.ts + + Please review the API layer code, especially: + - TypeScript types match OpenAPI schemas + - API endpoints use correct paths + - React Query hooks have proper cache invalidation + + Say "continue" to proceed to Phase 2 (Feature Components). + +User: continue + +Claude: [Reads .venturo/instructions/new-feature/02-feature-components.md] + [Executes Phase 2: Creates components] + + ✅ Phase 2 Complete: Feature Components + + Created: + - src/features/customer/components/CustomerTable.tsx + - src/features/customer/components/CustomerForm.tsx + - src/features/customer/components/CustomerFilters.tsx + - src/features/customer/components/CustomerFilterDrawer.tsx + + Please review the components. + Say "continue" to proceed to Phase 3 (Feature Hooks). + +[Process continues through all 5 phases] +``` + +--- + +## Key Implementation Rules + +### Always Follow These Patterns: + +**1. TypeScript Types from OpenAPI:** +```typescript +// ✅ Correct: Match OpenAPI schema exactly +export interface Customer { + id: string; + name: string; + email: string; + phone?: string; // Optional in OpenAPI + address?: string; + status: 'active' | 'inactive'; // Enum from OpenAPI + created_at: string; + updated_at: string; +} + +// ❌ Wrong: Using different field names or types +export interface Customer { + customerId: string; // Should be 'id' + status: string; // Should be enum +} +``` + +**2. API Service Pattern:** +```typescript +// ✅ Correct: Use apiService from @/app/services +import { apiService } from '@/app/services/apiService'; + +export const customerApi = { + createCustomer: (data: CreateCustomerData) => + apiService.post>('/core/v1/customers', data), +}; + +// ❌ Wrong: Direct axios usage +import axios from 'axios'; +axios.post('/core/v1/customers', data); +``` + +**3. React Query Hooks Pattern:** +```typescript +// ✅ Correct: Follow existing pattern with proper typing +export const customerKeys = { + all: ['customers'] as const, + lists: () => [...customerKeys.all, 'list'] as const, + list: (params?: ListCustomersParams) => [...customerKeys.lists(), params] as const, + details: () => [...customerKeys.all, 'detail'] as const, + detail: (id: string) => [...customerKeys.details(), id] as const, +}; + +export const useGetListCustomers = ( + params?: ListCustomersParams, + options?: Omit>, AxiosError>, 'queryKey' | 'queryFn'> +) => { + return useQuery({ + queryKey: customerKeys.list(params), + queryFn: () => customerApi.listCustomers(params), + ...options, + }); +}; + +// ❌ Wrong: Not using query keys factory pattern +export const useGetListCustomers = () => { + return useQuery(['customers'], () => customerApi.listCustomers()); +}; +``` + +**4. Component Imports:** +```typescript +// ✅ Correct: Import from @/shared/components/venturo-ui +import { Box, Button, Typography, Card } from '@/shared/components/venturo-ui'; +import { IconPlus } from '@tabler/icons-react'; + +// ❌ Wrong: Importing from @mui/material directly +import { Box, Button } from '@mui/material'; +``` + +**5. Permission Checks:** +```typescript +// ✅ Correct: Use usePermission hook and constants +import { usePermission } from '@/shared/hooks'; +import { PERMISSIONS } from '@/app/constants/permission'; + +const { hasPermission } = usePermission(); +const canCreate = hasPermission(PERMISSIONS.CUSTOMER_CREATE); + +// ❌ Wrong: Hardcoded permission strings +const canCreate = hasPermission('customer.create'); +``` + +**6. File Naming Conventions:** +- API Types: `type.ts` (in feature API folder) +- API Functions: `{feature}Api.ts` (e.g., `customerApi.ts`) +- React Query Hooks: `use{Feature}Api.ts` (e.g., `useCustomerApi.ts`) +- Components: `{Feature}{Component}.tsx` (e.g., `CustomerTable.tsx`) +- Feature Hooks: `use{Action}{Feature}.ts` (e.g., `useTableCustomer.ts`) +- Page: `{Feature}Page.tsx` (e.g., `CustomerPage.tsx`) + +--- + +## Common Errors and Solutions + +### Error 1: API Response Type Mismatch +**Solution:** Always use `ResponseApi` or `ResponseApiWithMeta`: +```typescript +// ✅ Correct +apiService.get>('/core/v1/customers') + +// ❌ Wrong +apiService.get('/core/v1/customers') +``` + +### Error 2: Missing Cache Invalidation +**Solution:** Always invalidate related queries in mutations: +```typescript +// ✅ Correct +export const usePostCustomers = (options?: MutationOptions) => { + const queryClient = useQueryClient(); + return useMutation({ + mutationFn: customerApi.createCustomer, + onSuccess: (response, ...args) => { + queryClient.invalidateQueries({ queryKey: customerKeys.lists() }); + options?.onSuccess?.(response, ...args); + }, + ...options, + }); +}; +``` + +### Error 3: Not Using Absolute Imports +**Solution:** Always use `@/` or `src/` prefix: +```typescript +// ✅ Correct +import { apiService } from '@/app/services/apiService'; + +// ❌ Wrong +import { apiService } from '../../../app/services/apiService'; +``` + +### Error 4: Direct State Updates Instead of React Query +**Solution:** Use React Query hooks, not local state for server data: +```typescript +// ✅ Correct +const { data, isLoading } = useGetListCustomers(params); +const customers = data?.data?.data || []; + +// ❌ Wrong +const [customers, setCustomers] = useState([]); +useEffect(() => { + fetchCustomers().then(setCustomers); +}, []); +``` + +### Error 5: Missing Permission Guards +**Solution:** Always check permissions before rendering actions: +```typescript +// ✅ Correct +{canCreate && ( + +)} + +// ❌ Wrong + +``` + +--- + +## Verification Checklist + +After all phases complete, verify: + +### API Layer +- [ ] Types match OpenAPI schemas exactly +- [ ] All CRUD endpoints implemented +- [ ] React Query hooks follow query keys pattern +- [ ] Proper cache invalidation in mutations +- [ ] Types exported from index.ts + +### Feature Components +- [ ] Table component displays all required fields +- [ ] Table has pagination with proper meta handling +- [ ] Form component handles both create and edit modes +- [ ] Form validation matches OpenAPI constraints +- [ ] Filters component has search functionality +- [ ] FilterDrawer has all filter options from OpenAPI + +### Feature Hooks +- [ ] useTable hook manages pagination state +- [ ] useTable hook manages filter state +- [ ] useTable hook integrates delete operation +- [ ] useForm hook manages form state and validation +- [ ] useForm hook handles submit (create/update) + +### Page Integration +- [ ] Main page component integrates all sub-components +- [ ] Permission checks on all actions (create, edit, delete) +- [ ] Error handling for API failures +- [ ] Loading states shown appropriately +- [ ] Route registered in Router.tsx +- [ ] Sidebar menu item added (if applicable) + +### Constants & Permissions +- [ ] Permission constants added to permission.ts +- [ ] Route constants added to router.ts +- [ ] Permission guards applied correctly + +### Code Quality +- [ ] No TypeScript errors (`npm run type-check`) +- [ ] No ESLint warnings (`npm run lint`) +- [ ] Code follows Prettier formatting (`npm run format`) +- [ ] All imports use absolute paths (@/) +- [ ] Components use venturo-ui instead of raw MUI + +--- + +## Testing the Feature + +After implementation, test the feature manually: + +1. **Start the development server:** + ```bash + npm run dev + ``` + +2. **Navigate to the feature page:** + - Go to the route you registered (e.g., `/customers`) + - Verify the page loads without errors + +3. **Test CRUD Operations:** + - **Create**: Click "Add" button, fill form, submit + - **Read**: Verify table displays data correctly + - **Update**: Click edit on a row, modify, submit + - **Delete**: Click delete on a row, confirm deletion + +4. **Test Filters:** + - Use search bar to filter by text + - Open filter drawer and apply advanced filters + - Verify filters affect table results + +5. **Test Pagination:** + - Navigate between pages + - Change items per page + - Verify pagination meta is correct + +6. **Test Permissions:** + - Create a test user with limited permissions + - Verify action buttons respect permissions + - Verify unauthorized actions show appropriate messages + +7. **Test Error Handling:** + - Test with invalid data + - Test network failures (disconnect network) + - Verify error messages display appropriately + +--- + +## Example Prompt Usage + +``` +User: Create new feature from OpenAPI, read new-feature-instruction.md + +Claude: I'll help you create a new frontend feature from an OpenAPI specification. + Let me start by asking some questions: + + 1. What is the path to the OpenAPI YAML file? + +User: /mnt/d/Dev/Venturo/RnD/venturo-skeleton-go/docs/api/openapi-customer_management.yaml + +Claude: [Reads and parses the OpenAPI file] + + Great! I've analyzed the OpenAPI spec. Here's what I found: + + Feature: customer_management + Entity: Customer + Base Path: /core/v1/customers + + Endpoints: + - POST /customers (Create) + - GET /customers (List) + - GET /customers/{id} (Get by ID) + - PUT /customers/{id} (Update) + - DELETE /customers/{id} (Delete) + + 2. What should the feature name be in the frontend? + Suggestion: "customer" (lowercase for files, Customer for components) + +User: customer + +Claude: [Continues with remaining questions, presents plan, executes phases] +``` diff --git a/plugin.lock.json b/plugin.lock.json new file mode 100644 index 0000000..4f72d90 --- /dev/null +++ b/plugin.lock.json @@ -0,0 +1,45 @@ +{ + "$schema": "internal://schemas/plugin.lock.v1.json", + "pluginId": "gh:venturo-id/venturo-claude:plugins/venturo-react", + "normalized": { + "repo": null, + "ref": "refs/tags/v20251128.0", + "commit": "701607fbff958f63820f03a9bfc865623cd23059", + "treeHash": "8b96350cc76fb88f76aa5cc0bf8320f665f77859e38b2282b61803320e1afb9c", + "generatedAt": "2025-11-28T10:28:55.249899Z", + "toolVersion": "publish_plugins.py@0.2.0" + }, + "origin": { + "remote": "git@github.com:zhongweili/42plugin-data.git", + "branch": "master", + "commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390", + "repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data" + }, + "manifest": { + "name": "venturo-react", + "description": "React frontend development automation for Venturo skeleton - Guided workflows for features from OpenAPI specs", + "version": "1.0.0" + }, + "content": { + "files": [ + { + "path": "README.md", + "sha256": "fce71e65cd255ec6937cc71d83e0f90cf09f9aaa75071409b465382c090e5ebf" + }, + { + "path": ".claude-plugin/plugin.json", + "sha256": "a2b559767178e6a53ae16833b5c9c49ed9cf40684b35574379cc3fd6b71522c9" + }, + { + "path": "commands/new-feature.md", + "sha256": "5284ecf5014a99e498f98d32662c74bec72568df1f7c0c3a4356668cd1fed120" + } + ], + "dirSha256": "8b96350cc76fb88f76aa5cc0bf8320f665f77859e38b2282b61803320e1afb9c" + }, + "security": { + "scannedAt": null, + "scannerVersion": null, + "flags": [] + } +} \ No newline at end of file