feat(deploy): production deployment setup and fixes
- Debian-based api image (bookworm-slim), docker/debian mirrors, prisma binaryTargets for openssl 3.0 - nginx: admin SPA under /admin, TLS via acme.sh (ZeroSSL) + auto-renewal cron, http->https redirect - prisma: add origin_goods.delisted migration, sync missing schema (good_image/tag_font_color/good_tags), fix users.createdAt Timestamptz - api: CORS wildcard reflection, helmet CORP cross-origin, price backfill in persistProductDetail, categoryIcon ancestor fallback, mediaByColor per-color gallery in public goods detail - admin: /admin base path (vite + router) - import-data.mjs: udt_name casting, serial sequence advance fix
This commit is contained in:
@@ -1,14 +1,14 @@
|
||||
import { Global, Module } from '@nestjs/common';
|
||||
import { PrismaService } from './prisma.service';
|
||||
|
||||
/**
|
||||
* Global Prisma module exporting {@link PrismaService}.
|
||||
*
|
||||
* Marked `@Global()` so feature modules do not need to import it again.
|
||||
*/
|
||||
@Global()
|
||||
@Module({
|
||||
providers: [PrismaService],
|
||||
exports: [PrismaService],
|
||||
})
|
||||
export class PrismaModule {}
|
||||
import { Global, Module } from '@nestjs/common';
|
||||
import { PrismaService } from './prisma.service';
|
||||
|
||||
/**
|
||||
* Global Prisma module exporting {@link PrismaService}.
|
||||
*
|
||||
* Marked `@Global()` so feature modules do not need to import it again.
|
||||
*/
|
||||
@Global()
|
||||
@Module({
|
||||
providers: [PrismaService],
|
||||
exports: [PrismaService],
|
||||
})
|
||||
export class PrismaModule {}
|
||||
|
||||
@@ -1,31 +1,31 @@
|
||||
import { PrismaService } from './prisma.service';
|
||||
import { Test } from '@nestjs/testing';
|
||||
|
||||
describe('PrismaService', () => {
|
||||
let service: PrismaService;
|
||||
|
||||
beforeAll(async () => {
|
||||
const moduleRef = await Test.createTestingModule({
|
||||
providers: [PrismaService],
|
||||
}).compile();
|
||||
|
||||
service = moduleRef.get(PrismaService);
|
||||
await service.onModuleInit();
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await service.onModuleDestroy();
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
|
||||
it('should be able to run a trivial query against the database', async () => {
|
||||
// Execute a raw query that does not depend on application tables
|
||||
const result = await service.$queryRaw<Array<{ now: Date }>>`SELECT now() AS now`;
|
||||
expect(Array.isArray(result)).toBe(true);
|
||||
expect(result.length).toBe(1);
|
||||
expect(result[0].now).toBeInstanceOf(Date);
|
||||
});
|
||||
});
|
||||
import { PrismaService } from './prisma.service';
|
||||
import { Test } from '@nestjs/testing';
|
||||
|
||||
describe('PrismaService', () => {
|
||||
let service: PrismaService;
|
||||
|
||||
beforeAll(async () => {
|
||||
const moduleRef = await Test.createTestingModule({
|
||||
providers: [PrismaService],
|
||||
}).compile();
|
||||
|
||||
service = moduleRef.get(PrismaService);
|
||||
await service.onModuleInit();
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await service.onModuleDestroy();
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
|
||||
it('should be able to run a trivial query against the database', async () => {
|
||||
// Execute a raw query that does not depend on application tables
|
||||
const result = await service.$queryRaw<Array<{ now: Date }>>`SELECT now() AS now`;
|
||||
expect(Array.isArray(result)).toBe(true);
|
||||
expect(result.length).toBe(1);
|
||||
expect(result[0].now).toBeInstanceOf(Date);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
import { Injectable, OnModuleInit, OnModuleDestroy } from '@nestjs/common';
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
|
||||
/**
|
||||
* Global Prisma client wrapper.
|
||||
*
|
||||
* - `onModuleInit`: connects to the database so the first request
|
||||
* does not pay the connection cost.
|
||||
* - `onModuleDestroy`: cleanly disconnects during shutdown.
|
||||
*/
|
||||
@Injectable()
|
||||
export class PrismaService extends PrismaClient implements OnModuleInit, OnModuleDestroy {
|
||||
async onModuleInit(): Promise<void> {
|
||||
await this.$connect();
|
||||
}
|
||||
|
||||
async onModuleDestroy(): Promise<void> {
|
||||
await this.$disconnect();
|
||||
}
|
||||
}
|
||||
import { Injectable, OnModuleInit, OnModuleDestroy } from '@nestjs/common';
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
|
||||
/**
|
||||
* Global Prisma client wrapper.
|
||||
*
|
||||
* - `onModuleInit`: connects to the database so the first request
|
||||
* does not pay the connection cost.
|
||||
* - `onModuleDestroy`: cleanly disconnects during shutdown.
|
||||
*/
|
||||
@Injectable()
|
||||
export class PrismaService extends PrismaClient implements OnModuleInit, OnModuleDestroy {
|
||||
async onModuleInit(): Promise<void> {
|
||||
await this.$connect();
|
||||
}
|
||||
|
||||
async onModuleDestroy(): Promise<void> {
|
||||
await this.$disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user