Skip to content

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

Stack flavor: fastapi. ← Back to overview

[!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/