This commit is contained in:
Ho Ngoc Hai
2025-12-27 01:31:10 +07:00
commit 4da46b5b8e
205 changed files with 21063 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,572 @@
---
name: comment-code
description: Add bilingual code comments in Vietnamese and English for better documentation. Use when adding comments to code, documenting functions/classes, or when user requests Vietnamese/English documentation.
---
# Bilingual Code Comments
Add comprehensive code comments in both Vietnamese and English to improve code readability for international and Vietnamese teams.
## When to Use
- Adding comments to new code
- Documenting existing code
- Creating JSDoc/TSDoc documentation
- Writing function/class descriptions
- Explaining complex logic
- Adding inline comments
## Comment Format
### Single-line Comments
```typescript
// EN: Initialize database connection
// VI: Khởi tạo kết nối database
const db = await createConnection();
```
### Multi-line Comments
```typescript
/**
* EN: Validates user credentials and returns JWT token
* VI: Xác thực thông tin đăng nhập và trả về JWT token
*
* @param email - User email address / Địa chỉ email người dùng
* @param password - User password / Mật khẩu người dùng
* @returns JWT token / Mã JWT token
* @throws AuthenticationError if credentials invalid / Lỗi xác thực nếu thông tin không hợp lệ
*/
async function login(email: string, password: string): Promise<string> {
// Implementation
}
```
## Language-Specific Patterns
### TypeScript/JavaScript
#### Function Documentation
```typescript
/**
* EN: Calculates the total price including tax and discount
* VI: Tính tổng giá bao gồm thuế và giảm giá
*
* @param basePrice - Original price / Giá gốc
* @param taxRate - Tax rate (0-1) / Tỷ lệ thuế (0-1)
* @param discount - Discount amount / Số tiền giảm giá
* @returns Final price / Giá cuối cùng
*/
function calculateTotal(
basePrice: number,
taxRate: number,
discount: number
): number {
// EN: Apply discount first
// VI: Áp dụng giảm giá trước
const discountedPrice = basePrice - discount;
// EN: Then calculate tax
// VI: Sau đó tính thuế
const tax = discountedPrice * taxRate;
return discountedPrice + tax;
}
```
#### Class Documentation
```typescript
/**
* EN: Handles user authentication and authorization
* VI: Xử lý xác thực và phân quyền người dùng
*/
export class AuthService {
/**
* EN: JWT secret key from environment
* VI: Khóa bí mật JWT từ biến môi trường
*/
private readonly jwtSecret: string;
/**
* EN: Initialize auth service with configuration
* VI: Khởi tạo service xác thực với cấu hình
*
* @param config - Authentication configuration / Cấu hình xác thực
*/
constructor(config: AuthConfig) {
this.jwtSecret = config.jwtSecret;
}
/**
* EN: Verify JWT token and return user payload
* VI: Xác minh JWT token và trả về thông tin người dùng
*
* @param token - JWT token to verify / JWT token cần xác minh
* @returns User payload / Thông tin người dùng
* @throws TokenExpiredError if token expired / Lỗi token hết hạn
*/
async verifyToken(token: string): Promise<UserPayload> {
// Implementation
}
}
```
#### Interface/Type Documentation
```typescript
/**
* EN: User data transfer object
* VI: Đối tượng truyền dữ liệu người dùng
*/
interface UserDto {
/** EN: Unique user identifier / VI: Mã định danh duy nhất */
id: string;
/** EN: User email address / VI: Địa chỉ email người dùng */
email: string;
/** EN: User display name / VI: Tên hiển thị người dùng */
name: string;
/** EN: User role for authorization / VI: Vai trò người dùng để phân quyền */
role: 'admin' | 'user' | 'guest';
}
```
#### Complex Logic Comments
```typescript
async function processPayment(order: Order): Promise<PaymentResult> {
// EN: Step 1: Validate order data
// VI: Bước 1: Xác thực dữ liệu đơn hàng
if (!order.items.length) {
throw new Error('Order must have items / Đơn hàng phải có sản phẩm');
}
// EN: Step 2: Calculate total amount
// VI: Bước 2: Tính tổng số tiền
const total = order.items.reduce((sum, item) => {
return sum + (item.price * item.quantity);
}, 0);
// EN: Step 3: Process payment through gateway
// VI: Bước 3: Xử lý thanh toán qua cổng thanh toán
try {
const result = await paymentGateway.charge({
amount: total,
currency: 'VND',
orderId: order.id,
});
// EN: Step 4: Update order status on success
// VI: Bước 4: Cập nhật trạng thái đơn hàng khi thành công
await updateOrderStatus(order.id, 'paid');
return result;
} catch (error) {
// EN: Log error and mark order as failed
// VI: Ghi log lỗi và đánh dấu đơn hàng thất bại
logger.error('Payment failed', { orderId: order.id, error });
await updateOrderStatus(order.id, 'failed');
throw error;
}
}
```
### React/Next.js Components
```typescript
/**
* EN: User profile card component
* VI: Component thẻ hồ sơ người dùng
*
* @param user - User data to display / Dữ liệu người dùng để hiển thị
* @param onEdit - Callback when edit button clicked / Callback khi nhấn nút chỉnh sửa
*/
export function UserCard({ user, onEdit }: UserCardProps) {
// EN: Local state for loading status
// VI: State cục bộ cho trạng thái loading
const [isLoading, setIsLoading] = useState(false);
/**
* EN: Handle user profile update
* VI: Xử lý cập nhật hồ sơ người dùng
*/
const handleUpdate = async () => {
setIsLoading(true);
try {
await updateUser(user.id, user);
onEdit?.();
} finally {
setIsLoading(false);
}
};
return (
<div className="user-card">
{/* EN: Display user avatar / VI: Hiển thị avatar người dùng */}
<img src={user.avatar} alt={user.name} />
{/* EN: User information section / VI: Phần thông tin người dùng */}
<div className="user-info">
<h3>{user.name}</h3>
<p>{user.email}</p>
</div>
</div>
);
}
```
### Prisma Schema
```prisma
/// EN: User model for authentication and profile
/// VI: Model người dùng cho xác thực và hồ sơ
model User {
/// EN: Unique identifier
/// VI: Mã định danh duy nhất
id String @id @default(cuid())
/// EN: User email (unique)
/// VI: Email người dùng (duy nhất)
email String @unique
/// EN: Hashed password
/// VI: Mật khẩu đã mã hóa
password String
/// EN: Display name
/// VI: Tên hiển thị
name String
/// EN: Account creation timestamp
/// VI: Thời gian tạo tài khoản
createdAt DateTime @default(now())
/// EN: Last update timestamp
/// VI: Thời gian cập nhật cuối
updatedAt DateTime @updatedAt
@@map("users")
}
```
### Configuration Files
```typescript
// config/database.config.ts
/**
* EN: Database configuration for Prisma and Neon PostgreSQL
* VI: Cấu hình database cho Prisma và Neon PostgreSQL
*/
export const databaseConfig = {
/**
* EN: Database connection URL from environment
* VI: URL kết nối database từ biến môi trường
*/
url: process.env.DATABASE_URL,
/**
* EN: Connection pool settings
* VI: Cài đặt connection pool
*/
pool: {
// EN: Minimum connections in pool
// VI: Số kết nối tối thiểu trong pool
min: 2,
// EN: Maximum connections in pool
// VI: Số kết nối tối đa trong pool
max: 10,
},
/**
* EN: Enable query logging in development
* VI: Bật ghi log truy vấn trong môi trường phát triển
*/
logging: process.env.NODE_ENV === 'development',
};
```
### API Routes/Controllers
```typescript
/**
* EN: User management controller
* VI: Controller quản lý người dùng
*/
export class UserController {
/**
* EN: Get user by ID
* VI: Lấy thông tin người dùng theo ID
*
* GET /api/users/:id
*/
async getById(req: Request, res: Response) {
try {
// EN: Extract user ID from params
// VI: Lấy ID người dùng từ params
const { id } = req.params;
// EN: Fetch user from database
// VI: Lấy người dùng từ database
const user = await this.userService.findById(id);
// EN: Return 404 if user not found
// VI: Trả về 404 nếu không tìm thấy người dùng
if (!user) {
return res.status(404).json({
success: false,
error: {
code: 'USER_NOT_FOUND',
message: 'User not found / Không tìm thấy người dùng',
},
});
}
// EN: Return user data
// VI: Trả về dữ liệu người dùng
return res.json({
success: true,
data: user,
});
} catch (error) {
// EN: Handle unexpected errors
// VI: Xử lý lỗi không mong đợi
logger.error('Failed to get user', { error, userId: req.params.id });
return res.status(500).json({
success: false,
error: {
code: 'INTERNAL_ERROR',
message: 'Internal server error / Lỗi máy chủ nội bộ',
},
});
}
}
}
```
### Middleware
```typescript
/**
* EN: Authentication middleware to verify JWT tokens
* VI: Middleware xác thực để kiểm tra JWT token
*/
export function authMiddleware(
req: Request,
res: Response,
next: NextFunction
) {
// EN: Extract token from Authorization header
// VI: Lấy token từ header Authorization
const authHeader = req.headers.authorization;
const token = authHeader?.replace('Bearer ', '');
// EN: Return 401 if no token provided
// VI: Trả về 401 nếu không có token
if (!token) {
return res.status(401).json({
success: false,
error: {
code: 'NO_TOKEN',
message: 'Authentication required / Yêu cầu xác thực',
},
});
}
try {
// EN: Verify token and extract payload
// VI: Xác minh token và lấy payload
const payload = jwt.verify(token, JWT_SECRET);
// EN: Attach user info to request
// VI: Gắn thông tin người dùng vào request
req.user = payload;
next();
} catch (error) {
// EN: Return 401 if token invalid or expired
// VI: Trả về 401 nếu token không hợp lệ hoặc hết hạn
return res.status(401).json({
success: false,
error: {
code: 'INVALID_TOKEN',
message: 'Invalid or expired token / Token không hợp lệ hoặc hết hạn',
},
});
}
}
```
## Best Practices
### 1. Comment Placement
- Place bilingual comments together (EN first, then VI)
- Keep comments close to the code they describe
- Use JSDoc format for functions and classes
### 2. Comment Content
- **DO**: Explain WHY, not WHAT (code shows what)
- **DO**: Document complex logic and business rules
- **DO**: Include parameter descriptions and return types
- **DO**: Document error conditions and exceptions
- **DON'T**: State the obvious
- **DON'T**: Write redundant comments
### 3. Language Guidelines
- **English**: Use clear, concise technical English
- **Vietnamese**: Use proper Vietnamese technical terms
- Keep translations accurate and natural
- Use consistent terminology across codebase
### 4. Special Cases
#### TODO Comments
```typescript
// TODO EN: Implement caching for better performance
// TODO VI: Triển khai caching để cải thiện hiệu suất
```
#### FIXME Comments
```typescript
// FIXME EN: This causes memory leak, needs refactoring
// FIXME VI: Đoạn này gây rò rỉ bộ nhớ, cần refactor
```
#### WARNING Comments
```typescript
// WARNING EN: Do not modify this without updating the database schema
// WARNING VI: Không sửa đổi phần này mà không cập nhật schema database
```
### 5. Documentation Priority
**High Priority** (Always document):
- Public APIs and exported functions
- Complex algorithms and business logic
- Security-critical code
- Configuration and environment setup
- Error handling strategies
**Medium Priority** (Document when helpful):
- Helper functions with non-obvious behavior
- Data transformations
- Integration points with external services
**Low Priority** (Optional):
- Simple getters/setters
- Self-explanatory code
- Standard CRUD operations
## Examples by Use Case
### Authentication Flow
```typescript
/**
* EN: Complete authentication flow with refresh token
* VI: Luồng xác thực hoàn chỉnh với refresh token
*/
export class AuthFlow {
/**
* EN: Login user and generate token pair
* VI: Đăng nhập người dùng và tạo cặp token
*/
async login(credentials: LoginDto) {
// EN: Step 1: Validate credentials
// VI: Bước 1: Xác thực thông tin đăng nhập
const user = await this.validateCredentials(credentials);
// EN: Step 2: Generate access token (15min expiry)
// VI: Bước 2: Tạo access token (hết hạn sau 15 phút)
const accessToken = this.generateAccessToken(user);
// EN: Step 3: Generate refresh token (7 days expiry)
// VI: Bước 3: Tạo refresh token (hết hạn sau 7 ngày)
const refreshToken = this.generateRefreshToken(user);
// EN: Step 4: Store refresh token in database
// VI: Bước 4: Lưu refresh token vào database
await this.storeRefreshToken(user.id, refreshToken);
return { accessToken, refreshToken };
}
}
```
### Database Transaction
```typescript
/**
* EN: Transfer money between accounts with transaction
* VI: Chuyển tiền giữa các tài khoản với transaction
*/
async function transferMoney(
fromAccountId: string,
toAccountId: string,
amount: number
) {
// EN: Use transaction to ensure atomicity
// VI: Sử dụng transaction để đảm bảo tính nguyên tử
return await prisma.$transaction(async (tx) => {
// EN: Deduct from sender account
// VI: Trừ tiền từ tài khoản người gửi
await tx.account.update({
where: { id: fromAccountId },
data: { balance: { decrement: amount } },
});
// EN: Add to receiver account
// VI: Cộng tiền vào tài khoản người nhận
await tx.account.update({
where: { id: toAccountId },
data: { balance: { increment: amount } },
});
// EN: Create transaction record
// VI: Tạo bản ghi giao dịch
return await tx.transaction.create({
data: {
fromAccountId,
toAccountId,
amount,
type: 'TRANSFER',
},
});
});
}
```
## Integration with Project Rules
When commenting code in this project:
- Follow the code organization from `project-rules` skill
- Use consistent terminology with project documentation
- Align with the API response format standards
- Document according to the testing standards
- Include security considerations where relevant
## Quick Reference
### Function Comment Template
```typescript
/**
* EN: [Brief description in English]
* VI: [Mô tả ngắn gọn bằng tiếng Việt]
*
* @param paramName - EN description / VI mô tả
* @returns EN description / VI mô tả
* @throws ErrorType EN when / VI khi nào
*/
```
### Inline Comment Template
```typescript
// EN: [English explanation]
// VI: [Giải thích tiếng Việt]
```
### Complex Block Template
```typescript
// EN: Step N: [What this block does]
// VI: Bước N: [Block này làm gì]
```

View File

@@ -0,0 +1,476 @@
---
name: project-rules
description: GoodGo Microservices Platform coding standards, architecture patterns, and development guidelines. Use when working with this monorepo to ensure code follows project conventions for services, apps, packages, infrastructure, or when making architectural decisions.
---
# GoodGo Project Rules
## Architecture Overview
This is an enterprise-grade microservices monorepo with:
- **Apps**: Next.js (web-admin, web-client) + Flutter (app-admin, app-client)
- **Services**: Node.js/TypeScript microservices with Express
- **Packages**: Shared libraries (logger, types, http-client, auth-sdk, tracing, config)
- **Infrastructure**: Traefik, Redis, Neon PostgreSQL, Observability stack
- **Deployments**: Local (Docker Compose), Staging/Production (Kubernetes)
## Tech Stack Requirements
### Frontend
- **Web**: Next.js 14+ with App Router, TypeScript, Tailwind CSS, Zustand
- **Mobile**: Flutter 3.x with Provider pattern
- Use shared types from `@goodgo/types` package
- API calls via `@goodgo/http-client`
### Backend Services
- **Runtime**: Node.js 20+, TypeScript 5+
- **Framework**: Express with modular architecture
- **Database**: Prisma ORM with Neon PostgreSQL
- **Validation**: Zod for DTOs
- **Logging**: Use `@goodgo/logger` package
- **Tracing**: Use `@goodgo/tracing` with OpenTelemetry
- **Auth**: JWT tokens, use `@goodgo/auth-sdk`
### Infrastructure
- **API Gateway**: Traefik with path-based routing
- **Caching**: Redis for sessions/cache
- **Monitoring**: Prometheus + Grafana + Loki
- **Containerization**: Docker with multi-stage builds
## Code Organization Standards
### Service Structure
```
services/service-name/
├── src/
│ ├── config/ # Configuration files
│ ├── modules/ # Feature modules
│ │ └── feature/
│ │ ├── feature.controller.ts
│ │ ├── feature.service.ts
│ │ ├── feature.dto.ts
│ │ └── feature.module.ts
│ ├── middlewares/ # Express middlewares
│ ├── routes/ # Route definitions
│ └── main.ts # Entry point
├── prisma/
│ ├── schema.prisma
│ └── seed.ts
├── Dockerfile
├── package.json
└── tsconfig.json
```
### Package Structure
```
packages/package-name/
├── src/
│ └── index.ts # Main export
├── package.json
├── tsconfig.json
└── README.md
```
### App Structure
```
apps/web-*/
├── src/
│ ├── app/ # Next.js App Router
│ ├── services/api/ # API clients
│ └── stores/ # Zustand stores
├── Dockerfile
└── package.json
```
## Naming Conventions
### Files & Folders
- **Services**: `kebab-case` (e.g., `auth-service`, `user-service`)
- **Packages**: `kebab-case` (e.g., `http-client`, `auth-sdk`)
- **Files**: `kebab-case.type.ts` (e.g., `user.controller.ts`, `auth.service.ts`)
- **Components**: `PascalCase.tsx` for React, `snake_case.dart` for Flutter
### Code
- **Classes**: `PascalCase` (e.g., `UserService`, `AuthController`)
- **Functions/Methods**: `camelCase` (e.g., `getUserById`, `validateToken`)
- **Constants**: `UPPER_SNAKE_CASE` (e.g., `JWT_SECRET`, `API_VERSION`)
- **Interfaces/Types**: `PascalCase` with descriptive names (e.g., `UserResponse`, `LoginDto`)
### Package Names
- Use `@goodgo/` scope for all packages
- Format: `@goodgo/package-name`
## Development Workflow
### Creating New Service
1. Copy `services/_template/` as starting point
2. Update `package.json` with correct name: `@goodgo/service-name`
3. Add Prisma schema if database needed
4. Create modules following modular pattern
5. Add health check endpoint
6. Create Dockerfile with multi-stage build
7. Add to `turbo.json` if needed
8. Update documentation
### Creating New Package
1. Create in `packages/` directory
2. Use TypeScript with strict mode
3. Export from `src/index.ts`
4. Add to `pnpm-workspace.yaml`
5. Document usage in README.md
6. Version with semantic versioning
### Adding Dependencies
```bash
# Service/App dependency
pnpm --filter @goodgo/service-name add package-name
# Workspace package dependency
pnpm --filter @goodgo/service-name add @goodgo/logger
# Dev dependency
pnpm --filter @goodgo/service-name add -D @types/package-name
# Root dependency
pnpm add -w package-name
```
### Database Workflow
1. Update Prisma schema in service
2. Generate migration: `pnpm --filter @goodgo/service-name prisma migrate dev`
3. Generate client: `pnpm --filter @goodgo/service-name prisma generate`
4. Use Neon PostgreSQL (no local PostgreSQL needed)
5. Connection pooling via Prisma
## Code Quality Standards
### TypeScript
- Enable strict mode
- No `any` types (use `unknown` if needed)
- Define interfaces for all DTOs
- Use Zod for runtime validation
- Export types from `@goodgo/types` when shared
### Error Handling
- Use custom error classes
- Implement global error middleware
- Log errors with context using `@goodgo/logger`
- Return consistent error responses:
```typescript
{
success: false,
error: {
code: 'ERROR_CODE',
message: 'Human readable message',
details?: any
}
}
```
### API Response Format
```typescript
// Success
{
success: true,
data: any
}
// Error
{
success: false,
error: {
code: string,
message: string,
details?: any
}
}
```
### Logging
```typescript
import { logger } from '@goodgo/logger';
logger.info('Message', { context: 'data' });
logger.error('Error', { error, context: 'data' });
logger.debug('Debug info', { data });
```
### Environment Variables
- Use `.env.example` as template
- Never commit `.env` files
- Validate env vars at startup
- Use Zod for env validation
- Document all env vars in README
## Testing Standards
### Unit Tests
- Place tests next to source: `feature.service.test.ts`
- Use Jest as test runner
- Mock external dependencies
- Aim for >80% coverage
### Integration Tests
- Test API endpoints end-to-end
- Use test database (Neon branch)
- Clean up test data after tests
### Test Commands
```bash
pnpm test # All tests
pnpm --filter @goodgo/service-name test # Service tests
pnpm test:coverage # With coverage
```
## Docker Standards
### Multi-stage Builds
```dockerfile
# Build stage
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json pnpm-lock.yaml ./
RUN npm install -g pnpm && pnpm install
COPY . .
RUN pnpm build
# Production stage
FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
CMD ["node", "dist/main.js"]
```
### Image Naming
- Format: `goodgo/service-name:version`
- Use semantic versioning
- Tag latest for production
## Git Workflow
### Branch Naming
- Feature: `feature/description`
- Bug fix: `fix/description`
- Hotfix: `hotfix/description`
- Release: `release/version`
### Commit Messages
Follow Conventional Commits:
```
type(scope): subject
body (optional)
footer (optional)
```
Types: `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore`
Examples:
- `feat(auth): add refresh token endpoint`
- `fix(user): resolve email validation bug`
- `docs(readme): update installation steps`
### Pull Requests
- Use PR template
- Link related issues
- Request review from team
- Ensure CI passes
- Squash merge to main
## CI/CD Standards
### GitHub Actions
- Run on PR: lint, test, build
- Deploy to staging on merge to `develop`
- Deploy to production on merge to `main`
- Use secrets for sensitive data
### Deployment Checklist
- [ ] All tests pass
- [ ] No linter errors
- [ ] Environment variables configured
- [ ] Database migrations applied
- [ ] Documentation updated
- [ ] Monitoring configured
## Security Guidelines
### Authentication
- Use JWT with short expiry (15min access, 7d refresh)
- Store tokens securely (httpOnly cookies for web)
- Implement refresh token rotation
- Use `@goodgo/auth-sdk` for consistency
### Authorization
- Implement RBAC (Role-Based Access Control)
- Check permissions at service level
- Use middleware for route protection
### Data Protection
- Hash passwords with bcrypt (cost factor 12)
- Encrypt sensitive data at rest
- Use HTTPS in production
- Sanitize user inputs
- Validate all DTOs with Zod
### Secrets Management
- Use environment variables
- Kubernetes secrets for production
- GitHub secrets for CI/CD
- Never hardcode secrets
- Rotate secrets regularly
## Performance Guidelines
### Backend
- Use Redis for caching
- Implement database connection pooling
- Add pagination for list endpoints
- Use database indexes
- Implement rate limiting
### Frontend
- Use Next.js Image optimization
- Implement code splitting
- Lazy load components
- Use React.memo for expensive renders
- Optimize bundle size
### Database
- Use Prisma query optimization
- Add indexes for frequent queries
- Use database transactions
- Implement soft deletes
- Regular backups (Neon handles this)
## Monitoring & Observability
### Metrics
- Use Prometheus for metrics
- Track: request count, duration, errors
- Set up alerts for critical metrics
### Logging
- Structured logging with `@goodgo/logger`
- Include trace IDs for correlation
- Log levels: error, warn, info, debug
- Aggregate logs with Loki
### Tracing
- Use OpenTelemetry via `@goodgo/tracing`
- Trace cross-service requests
- Include context in traces
## Documentation Standards
### Code Documentation
- JSDoc for public APIs
- Inline comments for complex logic
- README.md for each service/package
- Keep docs up to date
### API Documentation
- OpenAPI/Swagger specs in `docs/api/openapi/`
- Document all endpoints
- Include request/response examples
- Document error codes
### Architecture Documentation
- System design in `docs/architecture/`
- Service communication patterns
- Data flow diagrams
- Decision records (ADRs)
## Common Patterns
### Module Pattern
```typescript
// feature.module.ts
export class FeatureModule {
controller: FeatureController;
service: FeatureService;
constructor() {
this.service = new FeatureService();
this.controller = new FeatureController(this.service);
}
}
```
### DTO Pattern
```typescript
// feature.dto.ts
import { z } from 'zod';
export const CreateFeatureDto = z.object({
name: z.string().min(1),
email: z.string().email(),
});
export type CreateFeatureDto = z.infer<typeof CreateFeatureDto>;
```
### Controller Pattern
```typescript
// feature.controller.ts
export class FeatureController {
constructor(private service: FeatureService) {}
async create(req: Request, res: Response) {
try {
const dto = CreateFeatureDto.parse(req.body);
const result = await this.service.create(dto);
res.json({ success: true, data: result });
} catch (error) {
next(error);
}
}
}
```
### Service Pattern
```typescript
// feature.service.ts
export class FeatureService {
constructor(private prisma: PrismaClient) {}
async create(dto: CreateFeatureDto) {
return this.prisma.feature.create({ data: dto });
}
}
```
## Troubleshooting
### Common Issues
- **Port conflicts**: Check `deployments/local/docker-compose.yml`
- **Database connection**: Verify Neon DATABASE_URL in `.env.local`
- **Module not found**: Run `pnpm install` in root
- **Build errors**: Clear `dist/` and rebuild
- **Type errors**: Run `pnpm --filter @goodgo/service-name prisma generate`
### Debug Commands
```bash
# Check service logs
docker-compose logs -f service-name
# Check database connection
pnpm --filter @goodgo/service-name prisma studio
# Rebuild containers
docker-compose up -d --build
# Check running services
docker-compose ps
```
## Resources
- [Architecture Docs](../../docs/architecture/)
- [API Specs](../../docs/api/openapi/)
- [Development Guide](../../docs/guides/development.md)
- [Deployment Guide](../../docs/guides/deployment.md)
- [Neon Database Guide](../../docs/guides/neon-database.md)
- [Contributing Guide](../../CONTRIBUTING.md)