--- allowed-tools: - Read - Write - Edit - Glob - Task argument-hint: "[template-name] [--list] [--variables key=value]" description: "Sistema di template per workflow comuni e scaffolding rapido" --- # Toduba Template - Template Workflows System πŸ“ ## Obiettivo Fornire template predefiniti per workflow comuni, permettendo scaffolding rapido e consistente di componenti, API, e applicazioni complete. ## Argomenti - `[template-name]`: Nome del template da usare - `--list`: Lista tutti i template disponibili - `--variables`: Variabili per il template (key=value) - `--preview`: Mostra preview senza creare file - `--customize`: ModalitΓ  interattiva per personalizzazione Argomenti ricevuti: $ARGUMENTS ## Template System Architecture ```typescript interface Template { name: string; description: string; category: "api" | "component" | "app" | "test" | "config"; variables: Variable[]; files: FileTemplate[]; hooks?: { preGenerate?: string; postGenerate?: string; }; } interface Variable { name: string; description: string; type: "string" | "boolean" | "select"; default?: any; required: boolean; options?: string[]; } interface FileTemplate { path: string; template: string; condition?: string; } ``` ## Available Templates Gallery ``` πŸ“š TODUBA TEMPLATE GALLERY ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ πŸ”· API TEMPLATES ───────────────── crud-api Complete CRUD API with validation rest-endpoint Single REST endpoint graphql-resolver GraphQL resolver with types websocket-server WebSocket server setup microservice Microservice with Docker πŸ”· COMPONENT TEMPLATES ────────────────────── react-component React component with tests vue-component Vue 3 composition component angular-component Angular component with service flutter-widget Flutter stateful widget web-component Native web component πŸ”· APPLICATION TEMPLATES ──────────────────────── fullstack-app Complete full-stack application mobile-app Flutter mobile app electron-app Electron desktop app cli-tool CLI application chrome-extension Chrome extension πŸ”· TESTING TEMPLATES ──────────────────── unit-test Unit test suite integration-test Integration test setup e2e-test E2E test with Playwright performance-test Performance test suite πŸ”· CONFIGURATION TEMPLATES ─────────────────────────── docker-setup Docker + docker-compose ci-cd-pipeline GitHub Actions/GitLab CI kubernetes K8s deployment configs nginx-config Nginx configuration env-setup Environment setup ``` ## Template Usage Flow ### Step 1: Select Template ```bash /toduba-template crud-api --variables resource=product ``` ### Step 2: Variable Input ``` 🎯 Template: crud-api ━━━━━━━━━━━━━━━━━━━━━━ Required variables: βœ“ resource: product ? database: [postgres/mysql/mongodb]: postgres ? authentication: [jwt/session/oauth]: jwt ? validation: [joi/yup/zod]: joi Optional variables: ? includeTests: [Y/n]: Y ? includeDocker: [y/N]: n ? includeSwagger: [Y/n]: Y ``` ### Step 3: Preview Generation ``` πŸ“‹ Files to be created: ━━━━━━━━━━━━━━━━━━━━━━━ βœ“ api/products/controller.js βœ“ api/products/model.js βœ“ api/products/routes.js βœ“ api/products/validation.js βœ“ api/products/service.js βœ“ tests/products.test.js βœ“ docs/products-api.yaml Total: 7 files Continue? [Y/n]: ``` ## Template Definitions ### CRUD API Template ```yaml name: crud-api description: Complete CRUD API with all operations category: api variables: - name: resource type: string required: true description: Resource name (singular) - name: database type: select options: [postgres, mysql, mongodb] default: postgres required: true - name: authentication type: select options: [jwt, session, oauth, none] default: jwt - name: validation type: select options: [joi, yup, zod, ajv] default: joi - name: includeTests type: boolean default: true files: - path: api/{{resource}}s/controller.js template: | const { {{Resource}}Service } = require('./service'); const { validate{{Resource}} } = require('./validation'); class {{Resource}}Controller { async create(req, res, next) { try { const validated = await validate{{Resource}}(req.body); const result = await {{Resource}}Service.create(validated); res.status(201).json({ success: true, data: result }); } catch (error) { next(error); } } async getAll(req, res, next) { try { const { page = 1, limit = 10, ...filters } = req.query; const result = await {{Resource}}Service.findAll({ page: Number(page), limit: Number(limit), filters }); res.json({ success: true, data: result.data, pagination: result.pagination }); } catch (error) { next(error); } } async getById(req, res, next) { try { const result = await {{Resource}}Service.findById(req.params.id); if (!result) { return res.status(404).json({ success: false, message: '{{Resource}} not found' }); } res.json({ success: true, data: result }); } catch (error) { next(error); } } async update(req, res, next) { try { const validated = await validate{{Resource}}(req.body, true); const result = await {{Resource}}Service.update(req.params.id, validated); res.json({ success: true, data: result }); } catch (error) { next(error); } } async delete(req, res, next) { try { await {{Resource}}Service.delete(req.params.id); res.status(204).send(); } catch (error) { next(error); } } } module.exports = new {{Resource}}Controller(); - path: api/{{resource}}s/routes.js template: | const router = require('express').Router(); const controller = require('./controller'); {{#if authentication}} const { authenticate } = require('../../middleware/auth'); {{/if}} router.post('/', {{#if authentication}}authenticate,{{/if}} controller.create ); router.get('/', {{#if authentication}}authenticate,{{/if}} controller.getAll ); router.get('/:id', {{#if authentication}}authenticate,{{/if}} controller.getById ); router.put('/:id', {{#if authentication}}authenticate,{{/if}} controller.update ); router.delete('/:id', {{#if authentication}}authenticate,{{/if}} controller.delete ); module.exports = router; ``` ### React Component Template ```yaml name: react-component description: React functional component with hooks category: component variables: - name: componentName type: string required: true - name: hasState type: boolean default: true - name: hasProps type: boolean default: true - name: style type: select options: [css, scss, styled-components, tailwind] default: css files: - path: components/{{componentName}}/{{componentName}}.tsx template: | import React{{#if hasState}}, { useState, useEffect }{{/if}} from 'react'; {{#if style === 'styled-components'}} import styled from 'styled-components'; {{else}} import './{{componentName}}.{{style}}'; {{/if}} {{#if hasProps}} interface {{componentName}}Props { title?: string; children?: React.ReactNode; onClick?: () => void; } {{/if}} export const {{componentName}}: React.FC{{#if hasProps}}<{{componentName}}Props>{{/if}}> = ({ {{#if hasProps}} title = 'Default Title', children, onClick {{/if}} }) => { {{#if hasState}} const [isLoading, setIsLoading] = useState(false); const [data, setData] = useState(null); useEffect(() => { // Component mount logic return () => { // Cleanup }; }, []); {{/if}} return (
{{#if hasProps}}

{title}

{{/if}} {{#if hasState}} {isLoading ? (
Loading...
) : (
{children}
)} {{else}} {children} {{/if}} {{#if hasProps}} {{/if}}
); }; - path: components/{{componentName}}/{{componentName}}.test.tsx condition: includeTests template: | import { render, screen, fireEvent } from '@testing-library/react'; import { {{componentName}} } from './{{componentName}}'; describe('{{componentName}}', () => { it('renders without crashing', () => { render(<{{componentName}} />); }); {{#if hasProps}} it('displays the title', () => { render(<{{componentName}} title="Test Title" />); expect(screen.getByText('Test Title')).toBeInTheDocument(); }); it('calls onClick handler', () => { const handleClick = jest.fn(); render(<{{componentName}} onClick={handleClick} />); fireEvent.click(screen.getByText('Click me')); expect(handleClick).toHaveBeenCalled(); }); {{/if}} }); ``` ### Full-Stack App Template ```yaml name: fullstack-app description: Complete full-stack application setup category: app variables: - name: appName type: string required: true - name: frontend type: select options: [react, vue, angular, nextjs] default: react - name: backend type: select options: [express, fastify, nestjs, fastapi] default: express - name: database type: select options: [postgres, mysql, mongodb, sqlite] default: postgres files: # Project structure - path: .gitignore template: | node_modules/ .env .env.local dist/ build/ .DS_Store *.log .vscode/ .idea/ - path: README.md template: | # {{appName}} Full-stack application built with {{frontend}} and {{backend}}. ## Quick Start \`\`\`bash # Install dependencies npm install # Setup database npm run db:setup # Start development npm run dev \`\`\` ## Architecture - Frontend: {{frontend}} - Backend: {{backend}} - Database: {{database}} - path: docker-compose.yml template: | version: '3.8' services: backend: build: ./backend ports: - "3001:3001" environment: - DATABASE_URL={{database}}://user:pass@db:5432/{{appName}} depends_on: - db frontend: build: ./frontend ports: - "3000:3000" depends_on: - backend db: image: {{database}}:latest environment: {{#if database === 'postgres'}} - POSTGRES_USER=user - POSTGRES_PASSWORD=pass - POSTGRES_DB={{appName}} {{/if}} volumes: - db_data:/var/lib/postgresql/data volumes: db_data: ``` ## Template Engine ```javascript class TemplateEngine { async generate(templateName, variables) { const template = await this.loadTemplate(templateName); // Validate required variables this.validateVariables(template, variables); // Process each file template const files = []; for (const fileTemplate of template.files) { if (this.shouldGenerate(fileTemplate, variables)) { const path = this.processPath(fileTemplate.path, variables); const content = this.processTemplate(fileTemplate.template, variables); files.push({ path, content }); } } return files; } processTemplate(template, variables) { // Replace {{variable}} with values // Handle conditionals {{#if condition}}...{{/if}} // Handle loops {{#each array}}...{{/each}} // Transform cases: {{pascalCase var}}, {{kebabCase var}} return processedContent; } } ``` ## Interactive Customization Mode ``` 🎨 TEMPLATE CUSTOMIZATION MODE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Template: react-component [βœ“] Include TypeScript [βœ“] Include tests [ ] Include Storybook stories [βœ“] Include PropTypes [ ] Include Redux connection [βœ“] Include hooks [ ] Include error boundary Style system: β—‹ Plain CSS ● Tailwind CSS β—‹ Styled Components β—‹ CSS Modules State management: β—‹ None ● useState/useReducer β—‹ Redux β—‹ MobX β—‹ Zustand File structure: β—‹ Single file ● Component folder β—‹ Feature folder [Generate] [Preview] [Cancel] ``` ## Template Hooks ```javascript hooks: { preGenerate: async (variables) => { // Validate environment // Check dependencies // Create directories console.log('πŸ” Pre-generation checks...'); if (!fs.existsSync('package.json')) { console.log('⚠️ No package.json found'); const init = await prompt('Initialize npm project? (y/n)'); if (init === 'y') { execSync('npm init -y'); } } }, postGenerate: async (files, variables) => { // Install dependencies // Run formatters // Update indexes console.log('πŸ“¦ Installing dependencies...'); if (variables.frontend === 'react') { execSync('npm install react react-dom'); } console.log('🎨 Formatting files...'); execSync('npx prettier --write .'); console.log('βœ… Template generated successfully!'); } } ``` ## Success Output ``` βœ… Template Generation Complete! πŸ“Š Summary: ━━━━━━━━━━━━━━━━━━━━━━━━ Template: crud-api Resource: product Database: postgres πŸ“ Files Created (7): βœ“ api/products/controller.js βœ“ api/products/model.js βœ“ api/products/routes.js βœ“ api/products/validation.js βœ“ api/products/service.js βœ“ tests/products.test.js βœ“ docs/products-api.yaml πŸ“¦ Dependencies Added: + express@4.18.2 + pg@8.11.3 + joi@17.9.2 πŸš€ Next Steps: 1. Review generated files 2. Update .env with database credentials 3. Run migrations: npm run db:migrate 4. Start server: npm run dev πŸ’‘ Tips: β€’ Customize validation in validation.js β€’ Add custom business logic in service.js β€’ Extend tests in products.test.js ```