MCP/Rules Improvements + MCP Prompts (#357)

- Use ESM for building the MCP Server
- Added own Postgres dependency to MCP Server for querying tables and other entities in MCP
- Vastly improved AI Agent rules
- Added MCP Prompts for reviewing code and planning features
- Minor refactoring
This commit is contained in:
Giancarlo Buomprisco
2025-09-19 22:57:35 +08:00
committed by GitHub
parent f85035bd01
commit 9712e2354b
27 changed files with 2101 additions and 639 deletions

View File

@@ -36,6 +36,29 @@ Example:
- Team server utils: `app/home/[account]/_lib/server/`
- Marketing components: `app/(marketing)/_components/`
The `[account]` parameter is the `accounts.slug` property, not the ID
## React Server Components - Async Pattern
**CRITICAL**: In Next.js 15, always await params directly in async server components:
```typescript
// ❌ WRONG - Don't use React.use() in async functions
async function Page({ params }: Props) {
const { account } = use(params);
}
// ✅ CORRECT - await params directly in Next.js 15
async function Page({ params }: Props) {
const { account } = await params; // ✅ Server component pattern
}
// ✅ CORRECT - "use" in non-async functions in Next.js 15
function Page({ params }: Props) {
const { account } = use(params); // ✅ Server component pattern
}
```
## Data Fetching Strategy
**Quick Decision Framework:**
@@ -182,7 +205,10 @@ import { Trans } from '@kit/ui/trans';
2. Create translation files in `public/locales/[new-language]/`
3. Copy structure from English files
Translation files: `public/locales/<locale>/<namespace>.json`
### Adding new namespaces
1. Translation files: `public/locales/<locale>/<namespace>.json`
2. Add namespace to `defaultI18nNamespaces` in `apps/web/lib/i18n/i18n.settings.ts`
## Workspace Contexts 🏢
@@ -238,6 +264,55 @@ export const POST = enhanceRouteHandler(
);
```
## Navigation Menu Configuration 🗺️
### Adding Sidebar Menu Items
**Config Files:**
- Personal: `config/personal-account-navigation.config.tsx`
- Team: `config/team-account-navigation.config.tsx`
**Add to Personal Navigation:**
```typescript
{
label: 'common:routes.yourFeature',
path: pathsConfig.app.yourFeaturePath,
Icon: <YourIcon className="w-4" />,
end: true,
},
```
**Add to Team Navigation:**
```typescript
{
label: 'common:routes.yourTeamFeature',
path: createPath(pathsConfig.app.yourTeamFeaturePath, account),
Icon: <YourIcon className="w-4" />,
},
```
**Add Paths:**
```typescript
// config/paths.config.ts
app: {
yourFeaturePath: '/home/your-feature',
yourTeamFeaturePath: '/home/[account]/your-feature',
}
```
**Add Translations:**
```json
// public/locales/en/common.json
"routes": {
"yourFeature": "Your Feature"
}
```
## Security Guidelines 🛡️
### Authentication & Authorization
@@ -252,13 +327,3 @@ export const POST = enhanceRouteHandler(
- **Never pass sensitive data** to Client Components
- **Never expose server environment variables** to client (unless prefixed with NEXT_PUBLIC)
- Always validate user input
### Super Admin Protection
For admin routes, use `AdminGuard` from `@packages/features/admin/src/components/admin-guard.tsx`:
```tsx
import { AdminGuard } from '@kit/admin/components/admin-guard';
export default AdminGuard(AdminPageComponent);
```

View File

@@ -36,6 +36,29 @@ Example:
- Team server utils: `app/home/[account]/_lib/server/`
- Marketing components: `app/(marketing)/_components/`
The `[account]` parameter is the `accounts.slug` property, not the ID
## React Server Components - Async Pattern
**CRITICAL**: In Next.js 15, always await params directly in async server components:
```typescript
// ❌ WRONG - Don't use React.use() in async functions
async function Page({ params }: Props) {
const { account } = use(params);
}
// ✅ CORRECT - await params directly in Next.js 15
async function Page({ params }: Props) {
const { account } = await params; // ✅ Server component pattern
}
// ✅ CORRECT - "use" in non-async functions in Next.js 15
function Page({ params }: Props) {
const { account } = use(params); // ✅ Server component pattern
}
```
## Data Fetching Strategy
**Quick Decision Framework:**
@@ -182,7 +205,10 @@ import { Trans } from '@kit/ui/trans';
2. Create translation files in `public/locales/[new-language]/`
3. Copy structure from English files
Translation files: `public/locales/<locale>/<namespace>.json`
### Adding new namespaces
1. Translation files: `public/locales/<locale>/<namespace>.json`
2. Add namespace to `defaultI18nNamespaces` in `apps/web/lib/i18n/i18n.settings.ts`
## Workspace Contexts 🏢
@@ -238,6 +264,55 @@ export const POST = enhanceRouteHandler(
);
```
## Navigation Menu Configuration 🗺️
### Adding Sidebar Menu Items
**Config Files:**
- Personal: `config/personal-account-navigation.config.tsx`
- Team: `config/team-account-navigation.config.tsx`
**Add to Personal Navigation:**
```typescript
{
label: 'common:routes.yourFeature',
path: pathsConfig.app.yourFeaturePath,
Icon: <YourIcon className="w-4" />,
end: true,
},
```
**Add to Team Navigation:**
```typescript
{
label: 'common:routes.yourTeamFeature',
path: createPath(pathsConfig.app.yourTeamFeaturePath, account),
Icon: <YourIcon className="w-4" />,
},
```
**Add Paths:**
```typescript
// config/paths.config.ts
app: {
yourFeaturePath: '/home/your-feature',
yourTeamFeaturePath: '/home/[account]/your-feature',
}
```
**Add Translations:**
```json
// public/locales/en/common.json
"routes": {
"yourFeature": "Your Feature"
}
```
## Security Guidelines 🛡️
### Authentication & Authorization
@@ -252,13 +327,3 @@ export const POST = enhanceRouteHandler(
- **Never pass sensitive data** to Client Components
- **Never expose server environment variables** to client (unless prefixed with NEXT_PUBLIC)
- Always validate user input
### Super Admin Protection
For admin routes, use `AdminGuard` from `@packages/features/admin/src/components/admin-guard.tsx`:
```tsx
import { AdminGuard } from '@kit/admin/components/admin-guard';
export default AdminGuard(AdminPageComponent);
```

View File

@@ -0,0 +1,119 @@
# Super Admin
This file provides specific guidance for AI agents working in the super admin section of the application.
## Core Admin Principles
### Security-First Development
- **ALWAYS** use `AdminGuard` to protect admin pages
- **NEVER** bypass authentication or authorization checks
- **CRITICAL**: Use admin Supabase client with manual authorization validation
- Validate permissions for every admin operation
### Admin Client Usage Pattern
```typescript
import { isSuperAdmin } from '@kit/admin';
import { getSupabaseServerAdminClient } from '@kit/supabase/server-admin-client';
async function adminOperation() {
const adminClient = getSupabaseServerAdminClient();
// CRITICAL: Always validate admin status first
const currentUser = await getCurrentUser();
if (!(await isSuperAdmin(currentUser))) {
throw new Error('Unauthorized: Admin access required');
}
// Now safe to proceed with admin privileges
const { data } = await adminClient.from('accounts').select('*');
return data;
}
```
## Page Structure Patterns
### Standard Admin Page Template
```typescript
import { AdminGuard } from '@kit/admin/components/admin-guard';
import { PageBody, PageHeader } from '@kit/ui/page';
import { AppBreadcrumbs } from '@kit/ui/app-breadcrumbs';
async function AdminPageComponent() {
return (
<>
<PageHeader description={<AppBreadcrumbs />}>
{/* Page actions go here */}
</PageHeader>
<PageBody>
{/* Main content */}
</PageBody>
</>
);
}
// ALWAYS wrap with AdminGuard
export default AdminGuard(AdminPageComponent);
```
### Async Server Component Pattern
```typescript
// ✅ CORRECT - Next.js 15 pattern
async function AdminPage({ params }: { params: Promise<{ id: string }> }) {
const { id } = await params; // ✅ await params directly
// Fetch admin data
const data = await loadAdminData(id);
return <AdminContent data={data} />;
}
```
## Security Guidelines
### Critical Security Rules
1. **NEVER** expose admin functionality to non-admin users
2. **ALWAYS** validate admin status before operations
3. **NEVER** trust client-side admin checks alone
4. **ALWAYS** use server-side validation for admin actions
5. **NEVER** log sensitive admin data
6. **ALWAYS** audit admin operations
### Admin Action Auditing
```typescript
async function auditedAdminAction(action: string, data: unknown) {
const logger = await getLogger();
await logger.info(
{
name: 'admin-audit',
action,
adminId: currentUser.id,
timestamp: new Date().toISOString(),
data: {
// Log only non-sensitive fields
operation: action,
targetId: data.id,
},
},
'Admin action performed',
);
}
```
## Common Patterns to Follow
1. **Always wrap admin pages with `AdminGuard`**
2. **Use admin client only when RLS bypass is required**
3. **Implement proper error boundaries for admin components**
4. **Add comprehensive logging for admin operations**
5. **Use TypeScript strictly for admin interfaces**
6. **Follow the established admin component naming conventions**
7. **Implement proper loading states for admin operations**
8. **Add proper metadata to admin pages**

View File

@@ -0,0 +1,119 @@
# Super Admin
This file provides specific guidance for AI agents working in the super admin section of the application.
## Core Admin Principles
### Security-First Development
- **ALWAYS** use `AdminGuard` to protect admin pages
- **NEVER** bypass authentication or authorization checks
- **CRITICAL**: Use admin Supabase client with manual authorization validation
- Validate permissions for every admin operation
### Admin Client Usage Pattern
```typescript
import { isSuperAdmin } from '@kit/admin';
import { getSupabaseServerAdminClient } from '@kit/supabase/server-admin-client';
async function adminOperation() {
const adminClient = getSupabaseServerAdminClient();
// CRITICAL: Always validate admin status first
const currentUser = await getCurrentUser();
if (!(await isSuperAdmin(currentUser))) {
throw new Error('Unauthorized: Admin access required');
}
// Now safe to proceed with admin privileges
const { data } = await adminClient.from('accounts').select('*');
return data;
}
```
## Page Structure Patterns
### Standard Admin Page Template
```typescript
import { AdminGuard } from '@kit/admin/components/admin-guard';
import { PageBody, PageHeader } from '@kit/ui/page';
import { AppBreadcrumbs } from '@kit/ui/app-breadcrumbs';
async function AdminPageComponent() {
return (
<>
<PageHeader description={<AppBreadcrumbs />}>
{/* Page actions go here */}
</PageHeader>
<PageBody>
{/* Main content */}
</PageBody>
</>
);
}
// ALWAYS wrap with AdminGuard
export default AdminGuard(AdminPageComponent);
```
### Async Server Component Pattern
```typescript
// ✅ CORRECT - Next.js 15 pattern
async function AdminPage({ params }: { params: Promise<{ id: string }> }) {
const { id } = await params; // ✅ await params directly
// Fetch admin data
const data = await loadAdminData(id);
return <AdminContent data={data} />;
}
```
## Security Guidelines
### Critical Security Rules
1. **NEVER** expose admin functionality to non-admin users
2. **ALWAYS** validate admin status before operations
3. **NEVER** trust client-side admin checks alone
4. **ALWAYS** use server-side validation for admin actions
5. **NEVER** log sensitive admin data
6. **ALWAYS** audit admin operations
### Admin Action Auditing
```typescript
async function auditedAdminAction(action: string, data: unknown) {
const logger = await getLogger();
await logger.info(
{
name: 'admin-audit',
action,
adminId: currentUser.id,
timestamp: new Date().toISOString(),
data: {
// Log only non-sensitive fields
operation: action,
targetId: data.id,
},
},
'Admin action performed',
);
}
```
## Common Patterns to Follow
1. **Always wrap admin pages with `AdminGuard`**
2. **Use admin client only when RLS bypass is required**
3. **Implement proper error boundaries for admin components**
4. **Add comprehensive logging for admin operations**
5. **Use TypeScript strictly for admin interfaces**
6. **Follow the established admin component naming conventions**
7. **Implement proper loading states for admin operations**
8. **Add proper metadata to admin pages**

View File

@@ -6,13 +6,15 @@ This file contains guidance for working with database schemas, migrations, and S
Schemas are organized in numbered files in the `schemas/` directory. Numbers are used to sort dependencies.
## Schema Development Workflow
Migrations are generated from schemas. If creating a new schema, the migration can be created using the exact same content.
If modifying an existing migration, use the `diff` command:
### 1. Creating New Schema Files
```bash
# Create new schema file
touch schemas/15-my-new-feature.sql
touch apps/web/supabase/schemas/15-my-new-feature.sql
# Apply changes and create migration
pnpm --filter web run supabase:db:diff -f my-new-feature
@@ -24,6 +26,8 @@ pnpm supabase:web:reset
pnpm supabase:web:typegen
```
Verify the diff command generated the same content as the schema; if not, take steps to fix the migration.
### 2. Modifying Existing Schemas
```bash
@@ -35,6 +39,8 @@ pnpm --filter web run supabase:db:diff -f update-accounts
# Apply and test
pnpm supabase:web:reset
# After resetting
pnpm supabase:web:typegen
```
@@ -223,47 +229,6 @@ pnpm supabase:web:reset
pnpm run supabase:web:test
```
## Type Generation
### After Schema Changes
```bash
# Generate types after any schema changes
pnpm supabase:web:typegen
# Types are generated to src/lib/supabase/database.types.ts
# Reset DB
pnpm supabase:web:reset
```
### Using Generated Types
```typescript
import { Enums, Tables } from '@kit/supabase/database';
// Table types
type Account = Tables<'accounts'>;
type Note = Tables<'notes'>;
// Enum types
type AppPermission = Enums<'app_permissions'>;
// Insert types
type AccountInsert = Tables<'accounts'>['Insert'];
type AccountUpdate = Tables<'accounts'>['Update'];
// Use in functions
async function createNote(data: Tables<'notes'>['Insert']) {
const { data: note, error } = await supabase
.from('notes')
.insert(data)
.select()
.single();
return note;
}
```
## Common Schema Patterns
### Audit Trail

View File

@@ -6,13 +6,15 @@ This file contains guidance for working with database schemas, migrations, and S
Schemas are organized in numbered files in the `schemas/` directory. Numbers are used to sort dependencies.
## Schema Development Workflow
Migrations are generated from schemas. If creating a new schema, the migration can be created using the exact same content.
If modifying an existing migration, use the `diff` command:
### 1. Creating New Schema Files
```bash
# Create new schema file
touch schemas/15-my-new-feature.sql
touch apps/web/supabase/schemas/15-my-new-feature.sql
# Apply changes and create migration
pnpm --filter web run supabase:db:diff -f my-new-feature
@@ -24,6 +26,8 @@ pnpm supabase:web:reset
pnpm supabase:web:typegen
```
Verify the diff command generated the same content as the schema; if not, take steps to fix the migration.
### 2. Modifying Existing Schemas
```bash
@@ -35,6 +39,8 @@ pnpm --filter web run supabase:db:diff -f update-accounts
# Apply and test
pnpm supabase:web:reset
# After resetting
pnpm supabase:web:typegen
```
@@ -223,47 +229,6 @@ pnpm supabase:web:reset
pnpm run supabase:web:test
```
## Type Generation
### After Schema Changes
```bash
# Generate types after any schema changes
pnpm supabase:web:typegen
# Types are generated to src/lib/supabase/database.types.ts
# Reset DB
pnpm supabase:web:reset
```
### Using Generated Types
```typescript
import { Enums, Tables } from '@kit/supabase/database';
// Table types
type Account = Tables<'accounts'>;
type Note = Tables<'notes'>;
// Enum types
type AppPermission = Enums<'app_permissions'>;
// Insert types
type AccountInsert = Tables<'accounts'>['Insert'];
type AccountUpdate = Tables<'accounts'>['Update'];
// Use in functions
async function createNote(data: Tables<'notes'>['Insert']) {
const { data: note, error } = await supabase
.from('notes')
.insert(data)
.select()
.single();
return note;
}
```
## Common Schema Patterns
### Audit Trail