Skip to content

Full-Stack Extension (/full-stack-extension)

In plain terms

Use this when adding to something that already exists — a new field, button, tab, or behavior on an existing page or endpoint.

What this skill does

Use when modifying, extending, or enhancing existing functionality — adding fields, columns, buttons, tabs, charts, filters, actions, or behavior to pages, components, or endpoints that already exist. Triggers on any request to change, update, extend, enhance, or modify existing code.

[!TIP] Use this for modifying or extending anything that already exists — adding fields, actions, tabs, charts, filters, or behavior to existing pages, components, or endpoints. For a brand new feature, use /feature-scaffold instead.

Trigger Conditions

  • Any request to modify, extend, update, enhance, change, or add to existing functionality
  • Keywords: "Add a field", "Show X on this screen", "Implement saving", "Add a column", "Add a button", "Add a filter", "Change the behavior of", "Update the form", "Extend this page", "Add an action", "Modify the..."
  • Also trigger when: the user references an existing page/component and wants something new on it, or when backend + frontend changes are needed together

1. Data Analysis

  • [ ] DB Check: Does new data need to be stored?
  • Yes → run /db-migration before continuing
  • No → proceed to step 2
  • [ ] API Check: Is the existing endpoint sufficient, or do we need a new route/field in the response?

2. Backend Extension

  • [ ] Model: If adding a field, update backend/app/models/[resource].py (then run /db-migration)
  • [ ] Schema: Update Pydantic schemas in backend/app/schemas/[resource].py to include new fields
  • [ ] Query: Update the SQLModel query in backend/app/api/[resource].py to select/include new fields
  • [ ] Validation: Update request validation if handling new input
  • [ ] Causal order: Ensure side effects are awaited before returning the response

3. Frontend Service

  • [ ] OpenAPI Sync: Run /openapi-sync to regenerate types from the updated backend
  • [ ] Types: Verify TypeScript interfaces in @/types/api reflect the changed API contract

4. UI Implementation

  • [ ] Hook: Update the relevant domain hook in hooks/use[Resource].ts if the query shape changed
  • Invalidate related queries in onSuccess if other views show this data
  • [ ] Mutation: Use mutateAsync (not mutate) when UI state depends on outcome:
    const handleSave = async () => {
        await updateMutation.mutateAsync({ id, data });
        onClose(); // Only runs after server confirms
    };
    
  • [ ] Component: Add the UI elements (inputs, displays, etc.)
  • Currency: use <FormattedCurrency /> (nl-NL, red for negatives)
  • Dates: use formatDateLocal() from lib/utils
  • Selects: use SearchableSelect, never native <select>
  • Negative values: must show in red (text-destructive)

5. Tests (REQUIRED)

  • [ ] Run /test-sync to automatically update tests for all changed files
  • [ ] Verify: All tests pass before proceeding to review

6. Review

  • [ ] Compliance: Run /architecture-review — especially check button colors and rounded corners
  • [ ] Feedback: Ensure loading uses shimmer effect and success shows a Toast
  • [ ] Types: Run cd frontend && npm run type-check && cd ../backend && python -m mypy app/

[!TIP] Use this for modifying or extending anything that already exists — adding fields, actions, tabs, charts, filters, or behavior to existing pages, components, or endpoints. For a brand new feature, use /feature-scaffold instead.

Trigger Conditions

  • Any request to modify, extend, update, enhance, change, or add to existing functionality
  • Keywords: "Add a field", "Show X on this screen", "Implement saving", "Add a column", "Add a button", "Add a filter", "Change the behavior of", "Update the form", "Extend this page", "Add an action", "Modify the..."
  • Also trigger when: the user references an existing page/component and wants something new on it, or when backend + frontend changes are needed together

1. Data Analysis

  • [ ] DB Check: Does new data need to be stored?
  • Yes → run /db-migration before continuing
  • No → proceed to step 2
  • [ ] API Check: Is the existing endpoint sufficient, or do we need a new route/field in the response?

2. Backend Extension

  • [ ] Schema: If adding a field, update backend/src/db/schema.ts (then run /db-migration)
  • [ ] Drizzle Query: Update the query in backend/src/routes/[resource].ts to select/include new fields
  • [ ] Route / Validation: Update the Express route or Zod schema in backend/src/validation/ to handle new input/output
  • [ ] Causal order: Ensure side effects are awaited with Promise.allSettled() before res.json()

3. Frontend Service

  • [ ] API Client: Update the method in services/domains/[resource]Service.ts (or services/apiClient.ts) to reflect the changed API contract
  • [ ] Types: Update TypeScript interfaces if the response shape changed

4. UI Implementation

  • [ ] Hook: Update the relevant domain hook in hooks/use[Resource].ts if the query shape changed
  • Invalidate related queries in onSuccess if other views show this data
  • [ ] Mutation: Use mutateAsync (not mutate) when UI state depends on outcome:
    const handleSave = async () => {
        await updateMutation.mutateAsync({ id, data });
        onClose(); // Only runs after server confirms
    };
    
  • [ ] Component: Add the UI elements (inputs, displays, etc.)
  • Currency: use <FormattedCurrency /> (nl-NL, red for negatives)
  • Dates: use formatDateLocal() from lib/utils
  • Selects: use SearchableSelect, never native <select>
  • Negative values: must show in red (text-destructive)

5. Tests (REQUIRED)

  • [ ] Run /test-sync to automatically update tests for all changed files
  • [ ] Verify: All tests pass before proceeding to review

6. Review

  • [ ] Compliance: Run /architecture-review — especially check button colors and rounded corners
  • [ ] Feedback: Ensure loading uses shimmer effect and success shows a Toast
  • [ ] Types: Run npm run type-check && cd backend && npm run type-check