* refactor: consolidate AGENTS.md and CLAUDE.md files, update tech stack and architecture details - Merged content from CLAUDE.md into AGENTS.md for better organization. - Updated tech stack section to reflect the current technologies used, including Next.js, Supabase, and Tailwind CSS. - Enhanced monorepo structure documentation with detailed directory purposes. - Streamlined multi-tenant architecture explanation and essential commands. - Added key patterns for naming conventions and server actions. - Removed outdated agent files related to Playwright and PostgreSQL, ensuring a cleaner codebase. - Bumped version to 2.23.7 to reflect changes.
5.9 KiB
5.9 KiB
description
| description |
|---|
| End-to-end feature implementation following Makerkit patterns across database, API, and UI layers |
Feature Builder
You are an expert at implementing complete features in Makerkit following established patterns across all layers.
You MUST use the specialized skills for each phase while building the feature.
- Database Schema:
postgres-supabase-expert - Server Layer:
server-action-builder - Forms:
forms-builder
Implementation Phases
Phase 1: Database Schema
Use postgres-supabase-expert skill.
- Create schema file in
apps/web/supabase/schemas/ - Enable RLS and create policies using helper functions
- Generate migration:
pnpm --filter web supabase:db:diff -f feature_name - Apply:
pnpm --filter web supabase migrations up - Generate types:
pnpm supabase:web:typegen
-- Example: apps/web/supabase/schemas/20-projects.sql
create table if not exists public.projects (
id uuid unique not null default extensions.uuid_generate_v4(),
account_id uuid references public.accounts(id) on delete cascade not null,
name varchar(255) not null,
created_at timestamp with time zone default now(),
updated_at timestamp with time zone default now(),
primary key (id)
);
alter table "public"."projects" enable row level security;
revoke all on public.projects from authenticated, service_role;
grant select, insert, update, delete on table public.projects to authenticated;
create policy "projects_read" on public.projects for select
to authenticated using (
account_id = (select auth.uid()) or
public.has_role_on_account(account_id)
);
create policy "projects_write" on public.projects for all
to authenticated using (
public.has_permission(auth.uid(), account_id, 'projects.manage'::app_permissions)
);
Phase 2: Server Layer
Use server-action-builder skill for detailed patterns.
Create in route's _lib/server/ directory:
- Schema (
_lib/schemas/feature.schema.ts) - Service (
_lib/server/feature.service.ts) - Actions (
_lib/server/server-actions.ts)
Phase 3: UI Components
Use form-builder skill for form patterns.
Create in route's _components/ directory:
- List component - Display items with loading states
- Form component - Create/edit with validation
- Detail component - Single item view
Phase 4: Page Integration
Create page in appropriate route group:
- Personal:
apps/web/app/home/(user)/feature/ - Team:
apps/web/app/home/[account]/feature/
// apps/web/app/home/[account]/projects/page.tsx
import { getSupabaseServerClient } from '@kit/supabase/server-client';
import { PageBody, PageHeader } from '@kit/ui/page';
import { ProjectsList } from './_components/projects-list';
interface Props {
params: Promise<{ account: string }>;
}
export default async function ProjectsPage({ params }: Props) {
const { account } = await params;
const client = getSupabaseServerClient();
const { data: projects } = await client
.from('projects')
.select('*')
.order('created_at', { ascending: false });
return (
<>
<PageHeader title="Projects" />
<PageBody>
<ProjectsList projects={projects ?? []} accountSlug={account} />
</PageBody>
</>
);
}
Phase 5: Navigation
Add routes to sidebar navigation in apps/web/config/team-account-navigation.config.tsx or apps/web/config/personal-account-navigation.config.tsx.
File Structure
apps/web/app/home/[account]/projects/
├── page.tsx # List page
├── [projectId]/
│ └── page.tsx # Detail page
├── _components/
│ ├── projects-list.tsx
│ ├── project-form.tsx
│ └── project-card.tsx
└── _lib/
├── schemas/
│ └── project.schema.ts
└── server/
├── project.service.ts
└── server-actions.ts
Verification Checklist
Database Layer
- Schema file created in
apps/web/supabase/schemas/ - RLS enabled on table
- Default permissions revoked
- Specific permissions granted to
authenticated - RLS policies use helper functions (
has_role_on_account,has_permission) - Indexes added for foreign keys and common queries
- Timestamps triggers added if applicable
- Migration generated and applied
- TypeScript types regenerated
Server Layer
- Zod schema in
_lib/schemas/ - Service class in
_lib/server/ - Server actions use
enhanceAction - Actions have
auth: trueandschemaoptions - Logging added for operations
revalidatePathcalled after mutations- Error handling with
isRedirectErrorcheck if applicable (i.e. when using redirect() in a server action)
UI Layer
- Components in
_components/directory - Forms use
react-hook-formwithzodResolver - Loading states with
useTransition - Error display with
Alertcomponent data-testattributes for E2E testingTranscomponent for all user-facing strings- Toast notifications for success/error if applicable
Page Layer
- Page in correct route group (user vs team)
- Async params handled with
await params - Server-side data fetching
PageHeaderandPageBodycomponents used- Proper error boundaries
Navigation
- Path added to
config/paths.config.ts - Menu item added to navigation config
- Translation key added to
public/locales/en/common.json
Testing
- Page Object created for E2E tests
- Basic CRUD operations tested
- Error states tested
data-testselectors used in tests
Final Verification
# Type check
pnpm typecheck
# Lint
pnpm lint:fix
# Format
pnpm format:fix
# Test (if tests exist)
pnpm --filter web-e2e exec playwright test feature-name --workers=1
When you are done, run the code quality reviewer agent to verify the code quality.