--- 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 ### Monorepo Architecture ```mermaid graph TB subgraph apps[Apps Layer] webAdmin[web-admin
Next.js Admin] webClient[web-client
Next.js Client] appAdmin[app-admin
Flutter Admin] appClient[app-client
Flutter Client] end subgraph gateway[API Gateway] traefik[Traefik
Path-based Routing] end subgraph services[Services Layer] iamService[iam-service
IAM Service] templateService[_template
Service Template] otherServices[Other Services
Node.js/TypeScript] end subgraph packages[Shared Packages] loggerPackage[@goodgo/logger
Centralized Logging] typesPackage[@goodgo/types
TypeScript Types] httpClientPackage[@goodgo/http-client
API Client] authSdkPackage[@goodgo/auth-sdk
Auth Utilities] tracingPackage[@goodgo/tracing
OpenTelemetry] configPackage[@goodgo/config
Shared Configs] end subgraph infrastructure[Infrastructure] postgres[Neon PostgreSQL
Database] redis[Redis
Cache] prometheus[Prometheus
Metrics] grafana[Grafana
Dashboards] loki[Loki
Log Aggregation] end subgraph deployments[Deployments] dockerCompose[Docker Compose
Local Development] kubernetes[Kubernetes
Staging/Production] end webAdmin --> traefik webClient --> traefik appAdmin --> traefik appClient --> traefik traefik --> iamService traefik --> otherServices iamService --> packages otherServices --> packages iamService --> postgres otherServices --> postgres iamService --> redis otherServices --> redis services --> prometheus services --> loki prometheus --> grafana loki --> grafana services --> deployments ``` ## 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` ### Detailed Structure Diagram ```mermaid graph TB subgraph service[Service Structure] serviceRoot[service-name/] serviceSrc[src/] serviceConfig[config/
Configuration] serviceModules[modules/
Feature Modules] serviceMiddlewares[middlewares/
Express Middlewares] serviceRoutes[routes/
Route Definitions] serviceMain[main.ts
Entry Point] servicePrisma[prisma/
Schema & Migrations] serviceDockerfile[Dockerfile
Container Definition] servicePackageJson[package.json
Dependencies] serviceRoot --> serviceSrc serviceRoot --> servicePrisma serviceRoot --> serviceDockerfile serviceRoot --> servicePackageJson serviceSrc --> serviceConfig serviceSrc --> serviceModules serviceSrc --> serviceMiddlewares serviceSrc --> serviceRoutes serviceSrc --> serviceMain end subgraph package[Package Structure] packageRoot[package-name/] packageSrc[src/] packageIndex[index.ts
Main Export] packagePackageJson[package.json
Package Metadata] packageTsconfig[tsconfig.json
TypeScript Config] packageReadme[README.md
Documentation] packageRoot --> packageSrc packageRoot --> packagePackageJson packageRoot --> packageTsconfig packageRoot --> packageReadme packageSrc --> packageIndex end subgraph app[App Structure - Next.js] appRoot[app-name/] appSrc[src/] appApp[app/
Next.js App Router] appServicesApi[services/api/
API Clients] appStores[stores/
State Management] appDockerfile[Dockerfile
Container Definition] appPackageJson[package.json
Dependencies] appRoot --> appSrc appRoot --> appDockerfile appRoot --> appPackageJson appSrc --> appApp appSrc --> appServicesApi appSrc --> appStores end subgraph module[Module Structure inside modules/] moduleRoot[modules/feature-name/] moduleController[feature.controller.ts
HTTP Handlers] moduleService[feature.service.ts
Business Logic] moduleRepository[feature.repository.ts
Data Access] moduleDto[feature.dto.ts
Zod Schemas] moduleTypes[feature.types.ts
TypeScript Types] moduleTest[feature.controller.test.ts
Unit Tests] moduleRoot --> moduleController moduleRoot --> moduleService moduleRoot --> moduleRepository moduleRoot --> moduleDto moduleRoot --> moduleTypes moduleRoot --> moduleTest moduleController --> moduleService moduleService --> moduleRepository end serviceModules --> moduleRoot ``` ## 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; // 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 { 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)