fix template, remove okr, use casan.*

This commit is contained in:
thanhnv
2026-07-18 16:45:31 +07:00
parent 0dfd1742d3
commit 13fae3e6c3
249 changed files with 4881 additions and 5702 deletions
@@ -0,0 +1,20 @@
FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json ./
COPY apps/__PROJECT_SLUG__/backend/package.json apps/__PROJECT_SLUG__/backend/package.json
COPY apps/__PROJECT_SLUG__/frontend/package.json apps/__PROJECT_SLUG__/frontend/package.json
RUN npm ci
COPY apps/__PROJECT_SLUG__/backend apps/__PROJECT_SLUG__/backend
RUN npm run build -w @__PROJECT_SLUG__/backend
FROM node:20-alpine AS runtime
ENV NODE_ENV=production
USER node
WORKDIR /app
COPY --chown=node:node package*.json ./
COPY --chown=node:node apps/__PROJECT_SLUG__/backend/package.json apps/__PROJECT_SLUG__/backend/package.json
COPY --chown=node:node apps/__PROJECT_SLUG__/frontend/package.json apps/__PROJECT_SLUG__/frontend/package.json
RUN npm ci --omit=dev --workspace @__PROJECT_SLUG__/backend --include-workspace-root=false && npm cache clean --force
COPY --from=build --chown=node:node /app/apps/__PROJECT_SLUG__/backend/dist ./apps/__PROJECT_SLUG__/backend/dist
EXPOSE 3000
CMD ["node", "apps/__PROJECT_SLUG__/backend/dist/main.js"]
@@ -0,0 +1,27 @@
{
"name": "@__PROJECT_SLUG__/backend",
"version": "1.0.0",
"private": true,
"license": "UNLICENSED",
"type": "module",
"scripts": {
"build": "tsc -p tsconfig.build.json",
"dev": "tsx watch src/main.ts",
"start": "node dist/main.js",
"test": "node --import tsx --test test/**/*.test.ts"
},
"dependencies": {
"@nestjs/common": "^10.4.20",
"@nestjs/core": "^10.4.20",
"@nestjs/platform-express": "^10.4.20",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.2",
"reflect-metadata": "^0.2.2",
"rxjs": "^7.8.2"
},
"devDependencies": {
"@types/node": "^24.0.8",
"tsx": "^4.20.3",
"typescript": "^5.8.3"
}
}
@@ -0,0 +1,5 @@
import { Module } from '@nestjs/common';
import { HealthController } from './health.controller.js';
@Module({ controllers: [HealthController] })
export class AppModule {}
@@ -0,0 +1,14 @@
import { Controller, Get } from '@nestjs/common';
export interface HealthResponse {
status: 'ok';
service: string;
}
@Controller('health')
export class HealthController {
@Get()
health(): HealthResponse {
return { status: 'ok', service: '__PROJECT_SLUG__-backend' };
}
}
@@ -0,0 +1,15 @@
import 'reflect-metadata';
import { ValidationPipe } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module.js';
async function bootstrap(): Promise<void> {
const app = await NestFactory.create(AppModule, { bufferLogs: true });
app.setGlobalPrefix('api/v1', { exclude: ['health'] });
app.useGlobalPipes(new ValidationPipe({ whitelist: true, forbidNonWhitelisted: true, transform: true }));
app.enableCors({ origin: process.env.CORS_ORIGIN?.split(',') ?? ['http://localhost:5173'], credentials: true });
const port = Number(process.env.PORT ?? 3000);
await app.listen(port, '0.0.0.0');
}
void bootstrap();
@@ -0,0 +1,7 @@
import assert from 'node:assert/strict';
import test from 'node:test';
import { HealthController } from '../src/health.controller.js';
test('health contract is deterministic', () => {
assert.deepEqual(new HealthController().health(), { status: 'ok', service: '__PROJECT_SLUG__-backend' });
});
@@ -0,0 +1,4 @@
{
"extends": "./tsconfig.json",
"exclude": ["test", "dist", "node_modules"]
}
@@ -0,0 +1,17 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"strict": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"skipLibCheck": true,
"outDir": "dist",
"rootDir": "src",
"types": ["node"]
},
"include": ["src/**/*.ts"]
}