website refactor
This commit is contained in:
109
docs/architecture/website/WEBSITE_CONTRACT_WRITE_FLOW.md
Normal file
109
docs/architecture/website/WEBSITE_CONTRACT_WRITE_FLOW.md
Normal file
@@ -0,0 +1,109 @@
|
||||
# Write Flow Update (Mutation Pattern)
|
||||
|
||||
This document updates the write flow section of WEBSITE_CONTRACT.md to use the Mutation pattern.
|
||||
|
||||
## Write Flow (Strict)
|
||||
|
||||
All writes MUST enter through **Next.js Server Actions**.
|
||||
|
||||
### Forbidden
|
||||
|
||||
- client components performing write HTTP requests
|
||||
- client components calling API clients for mutations
|
||||
|
||||
### Allowed
|
||||
|
||||
- client submits intent (FormData, button action)
|
||||
- server action performs UX validation
|
||||
- **server action calls a Mutation** (not Services directly)
|
||||
- Mutation creates infrastructure and calls Service
|
||||
- Service orchestrates API calls and business logic
|
||||
|
||||
### Server Actions must use Mutations
|
||||
|
||||
```typescript
|
||||
// ❌ WRONG - Direct service usage
|
||||
'use server';
|
||||
import { AdminService } from '@/lib/services/admin/AdminService';
|
||||
|
||||
export async function updateUserStatus(userId: string, status: string) {
|
||||
const service = new AdminService(...);
|
||||
await service.updateUserStatus(userId, status); // ❌ Should use mutation
|
||||
}
|
||||
```
|
||||
|
||||
```typescript
|
||||
// ✅ CORRECT - Mutation usage
|
||||
'use server';
|
||||
import { AdminUserMutation } from '@/lib/mutations/admin/AdminUserMutation';
|
||||
import { revalidatePath } from 'next/cache';
|
||||
|
||||
export async function updateUserStatus(userId: string, status: string) {
|
||||
try {
|
||||
const mutation = new AdminUserMutation();
|
||||
await mutation.updateUserStatus(userId, status);
|
||||
revalidatePath('/admin/users');
|
||||
} catch (error) {
|
||||
console.error('updateUserStatus failed:', error);
|
||||
throw new Error('Failed to update user status');
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Mutation Pattern
|
||||
|
||||
```typescript
|
||||
// lib/mutations/admin/AdminUserMutation.ts
|
||||
export class AdminUserMutation {
|
||||
private service: AdminService;
|
||||
|
||||
constructor() {
|
||||
// Manual DI for serverless
|
||||
const logger = new ConsoleLogger();
|
||||
const errorReporter = new EnhancedErrorReporter(logger, {
|
||||
showUserNotifications: true,
|
||||
logToConsole: true,
|
||||
reportToExternal: process.env.NODE_ENV === 'production',
|
||||
});
|
||||
const baseUrl = process.env.NEXT_PUBLIC_API_BASE_URL || 'http://localhost:3001';
|
||||
const apiClient = new AdminApiClient(baseUrl, errorReporter, logger);
|
||||
this.service = new AdminService(apiClient);
|
||||
}
|
||||
|
||||
async updateUserStatus(userId: string, status: string): Promise<void> {
|
||||
await this.service.updateUserStatus(userId, status);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Flow
|
||||
|
||||
1. **Server Action** (thin wrapper) - handles framework concerns (revalidation, redirects)
|
||||
2. **Mutation** (framework-agnostic) - creates infrastructure, calls service
|
||||
3. **Service** (business logic) - orchestrates API calls
|
||||
4. **API Client** (infrastructure) - makes HTTP requests
|
||||
|
||||
### Rationale
|
||||
|
||||
- **Framework independence**: Mutations can be tested without Next.js
|
||||
- **Consistency**: Mirrors PageQuery pattern for reads/writes
|
||||
- **Migration ease**: Can switch frameworks without rewriting business logic
|
||||
- **Testability**: Can unit test mutations in isolation
|
||||
- **Reusability**: Can be called from other contexts (cron jobs, etc.)
|
||||
|
||||
### Comparison with PageQueries
|
||||
|
||||
| Aspect | PageQuery | Mutation |
|
||||
|--------|-----------|----------|
|
||||
| Purpose | Read data | Write data |
|
||||
| Location | `lib/page-queries/` | `lib/mutations/` |
|
||||
| Framework | Called from RSC | Called from Server Actions |
|
||||
| Infrastructure | Manual DI | Manual DI |
|
||||
| Returns | Page DTO | void or result |
|
||||
| Revalidation | N/A | Server Action handles it |
|
||||
|
||||
### See Also
|
||||
|
||||
- [`MUTATIONS.md`](MUTATIONS.md) - Full mutation pattern documentation
|
||||
- [`SERVICES.md`](SERVICES.md) - Service layer documentation
|
||||
- [`WEBSITE_CONTRACT.md`](WEBSITE_CONTRACT.md) - Main contract
|
||||
Reference in New Issue
Block a user