- 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.
8.0 KiB
name, description
| name | description |
|---|---|
| project-rules | 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/typesand@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:
- Copy
services/_template/ - Update
package.jsonname to@goodgo/service-name - Add to
deployments/local/docker-compose.ymlwith Traefik labels - Configure Prisma schema if needed
- Add health check endpoint
New Package:
- Create in
packages/, export fromsrc/index.ts - Add to
pnpm-workspace.yaml - Use TypeScript strict mode
Dependencies:
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:
pnpm --filter @goodgo/service-name prisma migrate dev
pnpm --filter @goodgo/service-name prisma generate
Code Standards
TypeScript:
- Strict mode, no
any(useunknown) - Zod for runtime validation
- Export shared types from
@goodgo/types
API Responses:
// Success: { success: true, data: any }
// Error: { success: false, error: { code, message, details? } }
Logging:
import { logger } from '@goodgo/logger';
logger.info('Message', { context });
logger.error('Error', { error, context });
Environment:
- Use
.env.exampletemplate, 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:
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:
// 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:
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_URLin.env.local - Module not found: Run
pnpm install - Type errors: Run
pnpm --filter @goodgo/service-name prisma generate
Debug:
cd deployments/local
docker-compose logs -f service-name
docker-compose ps
docker-compose up -d --build