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:
yeuimu
2026-08-26 14:23:09 +08:00
parent be0b90e68f
commit 6c61a4e871
982 changed files with 74156 additions and 179393 deletions
-119
View File
@@ -1,119 +0,0 @@
// ============================================================
// @inkreach/shared-types — 跨子项目共享类型定义
// ============================================================
// 纯类型 exports,无运行时依赖。子项目通过 import type { ... } from '@inkreach/shared-types' 引入。
// ----------------------------------------------------------
// Generic Response Wrappers
// ----------------------------------------------------------
/** 分页响应包装 */
export interface PaginatedResult<T> {
items: T[];
total: number;
page: number;
pageSize: number;
}
/** NestJS 后端 API 响应包络 */
export interface BackendEnvelope<T> {
data: T;
success: boolean;
}
// ----------------------------------------------------------
// Core Entity Data Interfaces (flat, no decorators)
// ----------------------------------------------------------
export interface CountryData {
id: string;
countryName: string;
countryIcon: string | null;
countryCode: string | null;
createdAt?: string;
updatedAt?: string;
}
export interface CategoryData {
id: string;
categoryName: string;
categoryIcon: string | null;
sdsCategoryId: string | null;
parentCategoryId: string | null;
children?: CategoryData[];
_count?: { goods: number };
}
export interface TagData {
id: string;
tagName: string;
tagColor: string | null;
tagFontColor: string | null;
tagGroupId: string | null;
sortOrder: number;
timing: string | null;
createdAt?: string;
updatedAt?: string;
}
export interface TagGroupData {
id: string;
groupName: string;
groupColor: string | null;
groupIcon: string | null;
sortOrder: number;
_count?: { tags: number };
createdAt?: string;
updatedAt?: string;
}
export interface PositionData {
id: string;
positionName: string;
countryId: string;
categoryId: string;
createdAt?: string;
updatedAt?: string;
}
export interface OriginGoodData {
id: string;
sdsGoodId: string;
goodName: string;
sku: string | null;
mainImage: string | null;
createdAt?: string;
}
export interface TagInline {
id: string;
tagName: string;
tagColor: string | null;
tagFontColor: string | null;
}
export interface GoodData {
id: string;
goodName: string;
goodImage: string | null;
goodPriority: number;
originGoodId: string;
originGood?: OriginGoodData;
countryId: string;
country?: CountryData;
categoryId: string;
category?: CategoryData;
tagId?: string;
tag?: TagInline;
tags: TagInline[];
positionId?: string;
position?: PositionData;
createdAt: string;
updatedAt: string;
}
export interface UserData {
id: string;
username: string;
email?: string;
}