feat(docs): Remove outdated service templates and enhance Vietnamese architecture documentation

- Deleted obsolete service architecture templates in both English and Vietnamese to streamline content.
- Updated the Vietnamese architecture documentation with improved Mermaid diagrams for better visual clarity.
- Enhanced color coding in diagrams to improve readability and consistency across documentation.
- Added a new section detailing visual indicators for better understanding of architecture components.
This commit is contained in:
Ho Ngoc Hai
2026-01-10 21:00:02 +07:00
parent b89e07f4cb
commit 4e595d0746
50 changed files with 36 additions and 28 deletions

View File

@@ -0,0 +1,83 @@
import path from 'path';
import dotenv from 'dotenv';
import { z } from 'zod';
// EN: Load environment variables (optional for local development without Docker)
// VI: Tải biến môi trường (tùy chọn cho phát triển local không dùng Docker)
// EN: In production, environment variables are set via Docker Compose or Kubernetes
// VI: Trong production, biến môi trường được set qua Docker Compose hoặc Kubernetes
// EN: Priority: Docker Compose > .env.local > .env > System environment
// VI: Ưu tiên: Docker Compose > .env.local > .env > Môi trường hệ thống
dotenv.config({ path: path.resolve(process.cwd(), '.env') });
dotenv.config({ path: path.resolve(process.cwd(), '.env.local'), override: true });
/**
* EN: Environment variable schema
* VI: Schema biến môi trường
*/
const envSchema = z.object({
PORT: z.string().default('5000').transform(Number), // Reorder: default before transform
NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),
API_VERSION: z.string().default('v1'),
CORS_ORIGIN: z.string().optional().default('http://localhost:3000'),
SERVICE_NAME: z.string().default('microservice-template'),
TRACING_ENABLED: z.enum(['true', 'false']).default('false'),
JAEGER_ENDPOINT: z.string().optional(),
JWT_SECRET: z.string().default('default-jwt-secret-change-in-production'),
REDIS_URL: z.string().default('redis://localhost:6379'),
});
/**
* EN: Parse and validate environment variables
* VI: Phân tích và validate biến môi trường
*/
const env = envSchema.safeParse(process.env);
if (!env.success) {
console.error('❌ Invalid environment variables:', JSON.stringify(env.error.format(), null, 2));
process.exit(1);
}
const config = env.data;
/**
* EN: Application configuration object
* VI: Đối tượng cấu hình ứng dụng
*/
export const appConfig = {
// EN: Server port
// VI: Cổng server
port: config.PORT,
// EN: Node environment
// VI: Môi trường Node
nodeEnv: config.NODE_ENV,
// EN: API version
// VI: Phiên bản API
apiVersion: config.API_VERSION,
// EN: CORS origins
// VI: Các origin cho CORS
corsOrigin: config.CORS_ORIGIN.split(','),
// EN: Service name
// VI: Tên dịch vụ
serviceName: config.SERVICE_NAME,
// EN: Tracing configuration
// VI: Cấu hình tracing
tracing: {
enabled: config.TRACING_ENABLED === 'true',
jaegerEndpoint: config.JAEGER_ENDPOINT,
},
// EN: Redis URL
// VI: URL Redis
redisUrl: config.REDIS_URL,
// EN: JWT Secret for authentication
// VI: JWT Secret để xác thực
jwtSecret: config.JWT_SECRET,
};

View File

@@ -0,0 +1,39 @@
import { logger } from '@goodgo/logger';
import { PrismaClient } from '@prisma/client';
/**
* EN: Prisma client instance configured for the application
* VI: Instance Prisma client được cấu hình cho ứng dụng
*/
export const prisma = new PrismaClient({
// EN: Enable detailed logging in development, minimal in production
// VI: Bật ghi log chi tiết trong development, tối thiểu trong production
log: process.env.NODE_ENV === 'development' ? ['query', 'error', 'warn'] : ['error'],
});
/**
* EN: Establish database connection on application startup
* VI: Thiết lập kết nối database khi khởi động ứng dụng
*/
export const connectDatabase = async (): Promise<void> => {
try {
// EN: Connect to database using Prisma
// VI: Kết nối tới database sử dụng Prisma
await prisma.$connect();
logger.info('Database connected successfully / Kết nối database thành công');
} catch (error) {
// EN: Log error and exit if database connection fails
// VI: Ghi log lỗi và thoát nếu kết nối database thất bại
logger.error('Database connection failed / Kết nối database thất bại', { error });
process.exit(1);
}
};
/**
* EN: Close database connection on application shutdown
* VI: Đóng kết nối database khi tắt ứng dụng
*/
export const disconnectDatabase = async (): Promise<void> => {
await prisma.$disconnect();
logger.info('Database disconnected / Đã ngắt kết nối database');
};

View File

@@ -0,0 +1,38 @@
import { logger } from '@goodgo/logger';
import Redis from 'ioredis';
import { appConfig } from './app.config';
// EN: Redis connection instance
// VI: Instance kết nối Redis
let redisClient: Redis | undefined;
/**
* EN: Get or create Redis client
* VI: Lấy hoặc tạo Redis client
*/
export const getRedisClient = (): Redis => {
if (!redisClient) {
redisClient = new Redis(appConfig.redisUrl, {
// EN: Retry strategy
// VI: Chiến lược thử lại
retryStrategy(times) {
const delay = Math.min(times * 50, 2000);
return delay;
},
// EN: Reconnect on error
// VI: Tự động kết nối lại khi lỗi
maxRetriesPerRequest: 3,
});
redisClient.on('error', (err) => {
logger.error('Redis connection error', { error: err.message });
});
redisClient.on('connect', () => {
logger.info('Redis connected successfully');
});
}
return redisClient;
};