- Updated skill documentation files to include structured metadata for better organization. - Enhanced bilingual descriptions and guidelines for clarity in both English and Vietnamese. - Refined sections on usage, best practices, and related skills to ensure consistency across all documentation. - Improved formatting and removed outdated references to streamline the documentation experience. - Added best practices checklists to relevant skills for better usability and adherence to standards.
258 lines
8.0 KiB
Markdown
258 lines
8.0 KiB
Markdown
---
|
|
name: project-rules
|
|
description: GoodGo Microservices Platform coding standards and architecture patterns. Use when working with services, apps, packages, or infrastructure.
|
|
---
|
|
|
|
# GoodGo Project Rules
|
|
|
|
## Architecture
|
|
|
|
**Monorepo Structure:**
|
|
- **Apps**: Next.js (web) + Flutter (mobile)
|
|
- **Services**: Node.js/TypeScript microservices (Express)
|
|
- **Packages**: Shared libraries (logger, types, http-client, auth-sdk, tracing)
|
|
- **Infrastructure**: Traefik (API Gateway), Redis, Neon PostgreSQL, Observability
|
|
- **Deployments**: Local (Docker Compose), Staging/Production (Kubernetes)
|
|
|
|
**Template Location**: `services/_template/` - Use as starting point for new services
|
|
|
|
## Tech Stack
|
|
|
|
**Frontend:**
|
|
- Next.js 14+ (App Router), TypeScript, Tailwind CSS, Zustand
|
|
- Flutter 3.x with Provider pattern
|
|
- Use `@goodgo/types` and `@goodgo/http-client`
|
|
|
|
**Backend:**
|
|
- Node.js 20+, TypeScript 5+, Express
|
|
- Prisma ORM + Neon PostgreSQL
|
|
- Zod validation, `@goodgo/logger`, `@goodgo/tracing`, `@goodgo/auth-sdk`
|
|
|
|
**Infrastructure:**
|
|
- Traefik (path-based routing), Redis (cache), Prometheus + Grafana + Loki
|
|
|
|
## Project Structure
|
|
|
|
**Service:** `src/{config,modules,middlewares,routes,main.ts}` + `prisma/` + `Dockerfile`
|
|
**Package:** `src/index.ts` + `package.json` + `tsconfig.json` + `README.md`
|
|
**App:** `src/{app,services/api,stores}` + `Dockerfile`
|
|
|
|
## Naming Conventions
|
|
|
|
- **Services/Packages**: `kebab-case` (e.g., `auth-service`, `http-client`)
|
|
- **Files**: `kebab-case.type.ts` (e.g., `user.controller.ts`)
|
|
- **Components**: `PascalCase.tsx` (React), `snake_case.dart` (Flutter)
|
|
- **Classes**: `PascalCase`, **Functions**: `camelCase`, **Constants**: `UPPER_SNAKE_CASE`
|
|
- **Package Names**: `@goodgo/package-name`
|
|
|
|
## Workflows
|
|
|
|
**New Service:**
|
|
1. Copy `services/_template/`
|
|
2. Update `package.json` name to `@goodgo/service-name`
|
|
3. Add to `deployments/local/docker-compose.yml` with Traefik labels
|
|
4. Configure Prisma schema if needed
|
|
5. Add health check endpoint
|
|
|
|
**New Package:**
|
|
1. Create in `packages/`, export from `src/index.ts`
|
|
2. Add to `pnpm-workspace.yaml`
|
|
3. Use TypeScript strict mode
|
|
|
|
**Dependencies:**
|
|
```bash
|
|
pnpm --filter @goodgo/service-name add package-name
|
|
pnpm --filter @goodgo/service-name add @goodgo/logger # workspace
|
|
pnpm --filter @goodgo/service-name add -D @types/pkg # dev
|
|
```
|
|
|
|
**Database:**
|
|
```bash
|
|
pnpm --filter @goodgo/service-name prisma migrate dev
|
|
pnpm --filter @goodgo/service-name prisma generate
|
|
```
|
|
|
|
## Code Standards
|
|
|
|
**TypeScript:**
|
|
- Strict mode, no `any` (use `unknown`)
|
|
- Zod for runtime validation
|
|
- Export shared types from `@goodgo/types`
|
|
|
|
**API Responses:**
|
|
```typescript
|
|
// Success: { success: true, data: any }
|
|
// Error: { success: false, error: { code, message, details? } }
|
|
```
|
|
|
|
**Logging:**
|
|
```typescript
|
|
import { logger } from '@goodgo/logger';
|
|
logger.info('Message', { context });
|
|
logger.error('Error', { error, context });
|
|
```
|
|
|
|
**Environment:**
|
|
- Use `.env.example` template, never commit `.env`
|
|
- Validate with Zod at startup
|
|
- Document all vars in README
|
|
|
|
## Testing
|
|
|
|
- **Unit**: Place tests next to source (`*.test.ts`), use Jest, mock dependencies, >80% coverage
|
|
- **Integration**: Test API endpoints, use test database, cleanup after
|
|
- **Commands**: `pnpm test`, `pnpm --filter @goodgo/service-name test`, `pnpm test:coverage`
|
|
|
|
## Docker
|
|
|
|
**Multi-stage Build Pattern:**
|
|
```dockerfile
|
|
FROM node:20-alpine AS builder
|
|
# ... build stage
|
|
FROM node:20-alpine
|
|
# ... production stage with non-root user
|
|
```
|
|
|
|
**Image Naming:** `goodgo/service-name:version` (semantic versioning)
|
|
|
|
## Git Workflow
|
|
|
|
**Branches:** `feature/`, `fix/`, `hotfix/`, `release/`
|
|
|
|
**Commits:** Conventional Commits format
|
|
```
|
|
type(scope): subject
|
|
```
|
|
Types: `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore`
|
|
|
|
**PRs:** Use template, link issues, ensure CI passes, squash merge to main
|
|
|
|
## CI/CD
|
|
|
|
**GitHub Actions:** PR (lint, test, build) → `develop` (staging) → `main` (production)
|
|
|
|
**Deployment Checklist:** Tests pass, no lint errors, env vars set, migrations applied, docs updated, monitoring configured
|
|
|
|
## Security
|
|
|
|
**Auth:** JWT (15min access, 7d refresh), httpOnly cookies, use `@goodgo/auth-sdk`
|
|
**Authorization:** RBAC, check permissions at service level, middleware for routes
|
|
**Data:** bcrypt (cost 12), HTTPS, sanitize inputs, Zod validation
|
|
**Secrets:** Environment variables, Kubernetes secrets, never hardcode, rotate regularly
|
|
|
|
## Performance
|
|
|
|
**Backend:** Redis caching, connection pooling, pagination, database indexes, rate limiting
|
|
**Frontend:** Next.js Image optimization, code splitting, lazy loading, React.memo, bundle optimization
|
|
**Database:** Prisma optimization, indexes, transactions, soft deletes
|
|
|
|
## Observability
|
|
|
|
**Metrics:** Prometheus (request count, duration, errors), set alerts
|
|
**Logging:** `@goodgo/logger` with trace IDs, levels (error, warn, info, debug), Loki aggregation
|
|
**Tracing:** OpenTelemetry via `@goodgo/tracing`, trace cross-service requests
|
|
|
|
## Documentation
|
|
|
|
**Code:** JSDoc for public APIs, inline comments for complex logic, README per service/package
|
|
**API:** OpenAPI/Swagger specs in `docs/api/openapi/`, document endpoints with examples
|
|
**Architecture:** System design in `docs/architecture/`, service communication, data flows, ADRs
|
|
|
|
## Architecture Patterns
|
|
|
|
**Modular Structure:** Controller → Service → Repository pattern
|
|
**DTO Validation:** Zod schemas with type inference
|
|
**Error Handling:** Custom error classes, global error middleware
|
|
**Dependency Injection:** Constructor injection for testability
|
|
|
|
**Example Module:**
|
|
```typescript
|
|
// DTO with Zod
|
|
export const CreateFeatureDto = z.object({
|
|
name: z.string().min(1),
|
|
email: z.string().email()
|
|
});
|
|
export type CreateFeatureDto = z.infer<typeof CreateFeatureDto>;
|
|
|
|
// Controller
|
|
export class FeatureController {
|
|
constructor(private service: FeatureService) {}
|
|
async create(req: Request, res: Response, next: NextFunction) {
|
|
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
|
|
export class FeatureService {
|
|
constructor(private repository: FeatureRepository) {}
|
|
async create(dto: CreateFeatureDto) {
|
|
return this.repository.create(dto);
|
|
}
|
|
}
|
|
|
|
// Repository
|
|
export class FeatureRepository extends BaseRepository<Feature> {
|
|
async create(data: CreateFeatureDto) {
|
|
return this.prisma.feature.create({ data });
|
|
}
|
|
}
|
|
```
|
|
|
|
## Deployment & Traefik
|
|
|
|
**Service Registration:**
|
|
Services are deployed via `deployments/local/docker-compose.yml` and auto-discovered by Traefik:
|
|
|
|
```yaml
|
|
services:
|
|
my-service:
|
|
build:
|
|
context: ../..
|
|
dockerfile: services/my-service/Dockerfile
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.my-service.rule=PathPrefix(`/api/v1/my-service`)"
|
|
- "traefik.http.services.my-service.loadbalancer.server.port=5002"
|
|
- "traefik.http.services.my-service.loadbalancer.healthcheck.path=/health/live"
|
|
```
|
|
|
|
**Traefik Configuration:**
|
|
- **Location**: `infra/traefik/` (platform-level, not per-service)
|
|
- **Static Config**: `traefik.yml` - Entry points, providers, dashboard
|
|
- **Dynamic Config**: `dynamic/middlewares.yml`, `dynamic/routes.yml`
|
|
- **Dashboard**: http://localhost:8080
|
|
|
|
**Access Points:**
|
|
- API: `http://localhost/api/v1/service-name`
|
|
- Health: `http://localhost/api/v1/service-name/health`
|
|
- Docs: `http://localhost/api/v1/service-name/api-docs`
|
|
|
|
## Troubleshooting
|
|
|
|
**Common Issues:**
|
|
- Port conflicts: Check `deployments/local/docker-compose.yml`
|
|
- Database: Verify `DATABASE_URL` in `.env.local`
|
|
- Module not found: Run `pnpm install`
|
|
- Type errors: Run `pnpm --filter @goodgo/service-name prisma generate`
|
|
|
|
**Debug:**
|
|
```bash
|
|
cd deployments/local
|
|
docker-compose logs -f service-name
|
|
docker-compose ps
|
|
docker-compose up -d --build
|
|
```
|
|
|
|
## 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)
|