Create Feature
Plan and coordinate implementation of a complete feature using spec-driven development (see the spec-driven-development skill).
BEFORE generating ANY
.tsxfiles (pages, components, forms, lists), you MUSTread_filethe Buildpad component reference at.github/skills/buildpad-reference/SKILL.md. This loads the full 40+ component catalog with import paths and usage patterns. Skipping this step leads to raw Mantine usage violations.
Spec Workflow
Every feature gets spec artifacts in .kiro/specs/<feature-name>/ before implementation. In Kiro, use native specs; in other IDEs, run /buildpad-spec-init → /buildpad-spec-requirements → /buildpad-spec-design → /buildpad-spec-tasks → /buildpad-impl. The DaaS-specific planning below feeds those artifacts:
| Stage | Focus | Artifact |
|---|---|---|
| Requirements | Problem, users, acceptance criteria (EARS) | requirements.md |
| Design | Data model, API, UI, Buildpad components | design.md |
| Tasks | Ordered, verifiable tasks with tests | tasks.md |
| Implement | Task-by-task with review | Working code |
Planning Process
- Understand Requirements — What problem does this solve? Who are the users?
- Check Built-In DaaS Features — Before designing anything, review the Built-in DaaS features reference. If DaaS provides it natively (audit trail, workflow, versioning, file management, cron, RBAC, scoping, import/export), use it — do NOT rebuild it.
- Design Data Model — Collections, fields, types, relationships, permissions. For every collection, follow the Standard Fields decision tree: always include audit fields, add workflow fields if approval/lifecycle needed, add scope field if multi-tenancy needed.
- Plan API Endpoints — CRUD routes with request/response formats
- Design UI — Pages, components, user flows
- Select Components (Buildpad-First MANDATORY) — Check Buildpad's 40+ components before creating custom
- Plan Implementation — Numbered tasks with estimates
- Plan Testing — API tests, page tests, component tests, E2E tests
Feature Planning Checklist
For each collection in the feature, answer these questions during the design stage:
- Audit fields included? → ALWAYS yes (Group A: user_created, date_created, user_updated, date_updated)
- Needs workflow/approval? → Add Group B fields + plan
create-workflowskill invocation - Needs multi-tenancy? → Add Group C field + plan
manage-scopeskill invocation - Needs versioning? → Plan DaaS versioning API integration (NOT custom version tables)
- Needs scheduled tasks? → Plan DaaS cron jobs (NOT Next.js cron routes)
- Needs capability/role gating? → Plan Module-Level Access Keys (
grant-module-accessskill): register key indaas_module_access_keys, grant on policymodule_accessJSONB, check in React withusePermissions().hasModuleAccess(key). NEVER check role names directly — this applies to every button, section, page, or nav item that is conditionally shown/hidden based on role. - Needs audit/change tracking? → Already built-in via
GET /api/activity(do NOT build custom)
Buildpad Component Selection
| Need | Buildpad Component |
|---|---|
| Text input | Input, Textarea |
| Rich text | RichTextHtml, RichTextMarkdown |
| Select/dropdown | SelectDropdown, SelectRadio |
| Multi-select | SelectMultipleDropdown, Tags |
| Toggle | Toggle, Boolean |
| Date/time | DateTime |
| File upload | FileInterface, FileImage, Files |
| Relations | ListM2O, ListM2M, ListO2M, ListM2A |
| Dynamic form | VForm, CollectionForm |
| Listing records | CollectionList (with search, filter, pagination, permissions) |
| Filtering records | FilterPanel (field-type-aware, DaaS-compatible JSON output) |
| Aggregate/stats | DaaS aggregate API (aggregate[count]=id&groupBy=status) |
Custom components allowed ONLY for: app-specific layouts, dashboards, specialized visualizations.
CollectionList Usage (MANDATORY for list pages)
When the design includes a list page, you MUST use CollectionList with the full-featured pattern.
Do NOT create custom tables with Mantine <Table> or raw HTML for collection records.
import { CollectionList } from "@/components/ui";
<CollectionList
collection="articles"
enableSearch
enableFilter // Integrated FilterPanel with badge count
enableSelection // Row selection with bulk actions
enableCreate // Permission-gated create button
enableDelete // Built-in delete with confirmation modal
enableSort
enableResize
enableReorder
enableHeaderMenu
limit={25}
=> router.push("/content/articles/+")}
=> router.push(`/content/articles/${item.id}`)}
/>;
Key features: integrated search + FilterPanel toggle with badge, permission-gated create/bulk actions, pagination (25/50/100/250), field-type-aware cell rendering, column management.
VForm Usage (CRITICAL)
When the design includes a form page, you MUST follow the VForm controlled component pattern. See VForm usage reference for the required pattern.
Key rules:
- VForm has NO
onSubmitprop — passmodelValue+onUpdatefor controlled state - VForm renders a
<div>, NOT a<form>— do NOT usetype="submit"orform="vform" - Handle submission externally via
onClickon a Button - Consider
CollectionFormas an all-in-one alternative to VForm for CRUD pages
Scope-Aware Context Pattern (REQUIRED when feature has tenant-scoped data)
Bug 26: Any React context or component that calls DaaS on mount AND lives inside
ScopeProvidermust wait for the scope to be ready before fetching. Firing the request before thedaas_resource_uricookie is set results in a 401. The.catch()handler will have set state tofalse/empty, and the effect will NOT re-run unlessscopeLoadingis in the dependency array.
When implementing a new context/provider that fetches from DaaS:
import { useScope } from '@/lib/contexts/ScopeContext';
const { resourceUri, isLoading: scopeLoading } = useScope();
useEffect(() => {
if (scopeLoading) return; // ← REQUIRED guard — do not remove
apiRequest('/api/...')
.then(...)
.catch(...);
// Re-fetch when tenant changes (policies/data may differ per scope)
}, [version, resourceUri, scopeLoading]);
// ^^^^^^^^^^ ^^^^^^^^^^^ ← REQUIRED deps
Output Format
Provide a structured plan with:
- Overview and requirements
- Data model design
- API design
- UI design with Buildpad components
- Capability matrix (required for role-gated features):
- module key (
domain:capability) - granted policies
- UI guard points (
hasModuleAccess) - API guard points (policy module_access OR-merge)
- module key (
- Implementation tasks in
tasks.md, ordered by dependency layer - Testing strategy per layer
- Time estimates
Testing Strategy (per layer)
- Schema: API tests for all endpoints
- UI: Page tests for all pages
- Logic: Integration tests for business rules
- Hardening: E2E tests for user flows
Post-Generation Validation (MANDATORY)
After generating ANY .tsx files for this feature, run the Buildpad-First violation check:
# Scan generated files for forbidden raw Mantine form/input imports
grep -rn "from '@mantine/form'\|from '@mantine/dates'\|from '@mantine/dropzone'\|<TextInput\|<NumberInput\|<Select \|<Switch \|<Checkbox \|<DatePicker\|<Dropzone" app/ components/ 2>/dev/null
If any matches are found, replace them with Buildpad equivalents before proceeding.
Then run module-access anti-pattern checks (UI + API):
grep -rn "role === \|roleName\|user\.role\|is_manager\|is_admin\|isManager\b\|currentUser\.role" app/ components/ 2>/dev/null
grep -rn "detectAdminFromMe\|checkAdmin\|roleObj\.name === 'Administrator'\|admin_access\s*===\s*true\|\bisAdmin\b" app/ components/ 2>/dev/null
Any match used for capability gating must be replaced with Module-Level Access Keys checks.
Quick fix reference:
| Violation | Replace With |
|---|---|
<TextInput> / <Textarea> |
Input / Textarea from @/components/ui |
<Select> |
SelectDropdown from @/components/ui |
<DatePicker> |
DateTime from @/components/ui |
<Switch> / <Checkbox> |
Toggle / Boolean / SelectMultipleCheckbox |
<Dropzone> |
Upload / Files from @/components/ui |
useForm (@mantine/form) |
VForm or CollectionForm from @/components/ui |
Custom <Table> for records |
CollectionList from @/components/ui |
For capability gating rules, load and follow:
../grant-module-access/SKILL.md../../references/module-access-checklist.md