Full-Stack Extension (/full-stack-extension) — express¶
Stack flavor: express. ← 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-scaffoldinstead.
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-migrationbefore 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].tsto 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()beforeres.json()
3. Frontend Service¶
- [ ] API Client: Update the method in
services/domains/[resource]Service.ts(orservices/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].tsif the query shape changed - Invalidate related queries in
onSuccessif other views show this data - [ ] Mutation: Use
mutateAsync(notmutate) 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()fromlib/utils - Selects: use
SearchableSelect, never native<select> - Negative values: must show in red (
text-destructive)
5. Tests (REQUIRED)¶
- [ ] Run
/test-syncto 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