Claude sub-agents, PRD, MCP improvements (#359)

1. Added Claude Code sub-agents
2. Added PRD tool to MCP Server
3. Added MCP Server UI to Dev Tools
4. Improved MCP Server Database Tool
5. Updated dependencies
This commit is contained in:
Giancarlo Buomprisco
2025-09-25 12:03:53 +08:00
committed by GitHub
parent 02e2502dcc
commit 2b8572baaa
62 changed files with 5661 additions and 1231 deletions

View File

@@ -2,28 +2,45 @@
This file contains instructions for working with Next.js utilities including server actions and route handlers.
## Guidelines
- Don't use Server Actions for data-fetching, use for mutations only
- Best Practice: Keep actions light, move business logic to ad-hoc services
- Authorization logic must be defined in RLS and DB, not Server Actions or application code (unless using the admin client, use sparinlgy!)
- Do not expose sensitive data
- Log async operations
- Validate body with Zod
- Use 'use server' at the top of the file. No need for 'server only';
## Server Actions Implementation
Always use `enhanceAction` from `@packages/next/src/actions/index.ts`:
Always use `enhanceAction` from `@packages/next/src/actions/index.ts`.
```typescript
'use server';
Define a schema:
import { enhanceAction } from '@kit/next/actions';
```tsx
import { z } from 'zod';
// Define your schema
const CreateNoteSchema = z.object({
// Define your schema in its own file
export const CreateNoteSchema = z.object({
title: z.string().min(1, 'Title is required'),
content: z.string().min(1, 'Content is required'),
accountId: z.string().uuid('Invalid account ID'),
});
```
export const createNoteAction = enhanceAction(
async function (data, user) {
// data is automatically validated against the schema
// user is automatically authenticated if auth: true
Then we define a service for crossing the network boundary:
```tsx
import { CreateNoteSchema } from '../schemas/notes.schemas.ts';
import * as z from 'zod';
export function createNotesService() {
return new NotesService();
}
class NotesService {
createNote(data: z.infer<CreateNoteSchema>) {
const client = getSupabaseServerClient();
const { data: note, error } = await client
@@ -40,11 +57,51 @@ export const createNoteAction = enhanceAction(
if (error) {
throw error;
}
}
}
```
Finally, we use Server Actions for exposing POST handlers:
```typescript
'use server';
import { enhanceAction } from '@kit/next/actions';
import { createNotesService } from '../notes.service.ts';
export const createNoteAction = enhanceAction(
async function (data, user) {
// data is automatically validated against the schema
// user is automatically authenticated if auth: true
return { success: true, note };
const service = createNotesService();
const logger = await getLogger();
logger.info({
userId: user.id,
}, `Creating note...`);
const { data: note, error } = await service.createNote(data);
if (error) {
logger.error({
error: error.message
}, `Error creating note`);
throw error;
}
logger.info({
noteId: note.id
}, `Note successfully created`);
return {
success: true,
note
};
},
{
auth: true, // Require authentication
auth: true, // Require authentication (true by default, can omit)
schema: CreateNoteSchema, // Validate input with Zod
},
);
@@ -75,7 +132,15 @@ export const myAction = enhanceAction(
## Route Handlers (API Routes)
Use `enhanceRouteHandler` from `@packages/next/src/routes/index.ts`:
Use `enhanceRouteHandler` from `@packages/next/src/routes/index.ts`.
### Guidelines
- Use when data must be exposed to externally
- Use for receiving requests from external clients (such as webhooks)
- Can be used for fetching data to client side fetchers (such as React Query) if cannot use client-side Supabase queries
### Usage
```typescript
import { enhanceRouteHandler } from '@kit/next/routes';
@@ -370,44 +435,6 @@ const handleCreateItem = async (data) => {
};
```
## Security Best Practices
### Input Validation
Always use Zod schemas for input validation:
```typescript
// Define strict schemas
const UpdateUserSchema = z.object({
name: z.string().min(1).max(100),
email: z.string().email(),
age: z.number().int().min(18).max(120),
});
// Server action with validation
export const updateUserAction = enhanceAction(
async function (data, user) {
// data is guaranteed to match the schema
// Additional business logic validation can go here
if (data.email !== user.email) {
// Check if email change is allowed
const canChangeEmail = await checkEmailChangePermission(user);
if (!canChangeEmail) {
throw new Error('Email change not allowed');
}
}
// Update user
return await updateUser(user.id, data);
},
{
auth: true,
schema: UpdateUserSchema,
},
);
```
### Authorization Checks
```typescript