diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..c99120c --- /dev/null +++ b/.env.example @@ -0,0 +1,10 @@ +DATABASE_URL_CN=mysql://root:root@localhost:3306/photo_cn?connection_limit=10 +REDIS_URL_CN=redis://localhost:6379 +S3_ENDPOINT=http://localhost:9000 +S3_REGION=us-east-1 +S3_ACCESS_KEY=photo-dev +S3_SECRET_KEY=photo-dev-secret +S3_BUCKET=photo-dev +SIGNED_URL_TTL_SECONDS=900 +AUTH_SESSION_TTL_SECONDS=2592000 +UPLOAD_MAX_BYTES=52428800 diff --git a/docs/plans/2026-09-17-P1a-后端核心链路.md b/docs/plans/2026-09-17-P1a-后端核心链路.md index 6e3d361..f166bbc 100644 --- a/docs/plans/2026-09-17-P1a-后端核心链路.md +++ b/docs/plans/2026-09-17-P1a-后端核心链路.md @@ -6,7 +6,7 @@ **Architecture:** NestJS 单代码库(P1a 仅 cn-app 部署入口)+ Prisma(MySQL) + BullMQ/Redis + sharp worker;对象存储经 StoragePort 接口访问 MinIO(生产替换 OSS 适配器);契约(OpenAPI + 事件 + 错误码)在 packages/contracts 单源生成类型。对齐《实施总纲》P1 与技术实施方案 §3-§7。 -**Tech Stack:** Node 20 · pnpm 9 · Turborepo · NestJS 10 · Prisma ^5.18 (MySQL 8.4 容器) · BullMQ 5 · Redis 7 · @aws-sdk/client-s3(MinIO S3 兼容)· sharp · @node-rs/argon2 · Jest + supertest · OpenAPI 3.1 + openapi-typescript +**Tech Stack:** Node ≥20(实际环境 v24.13.0)· pnpm 10(实际 10.7.1,packageManager pin 对齐实际环境——Task 3 修正;pnpm 10 默认拦截依赖生命周期脚本,sharp 0.33+ 预编译可选依赖不受影响,Prisma client 经显式 db:generate 生成)· Turborepo · NestJS 10 · Prisma ^5.18 (MySQL 8.4 容器;若在 Node 24 出现引擎兼容问题则升 ^6) · BullMQ 5 · Redis 7 · @aws-sdk/client-s3(MinIO S3 兼容)· sharp · @node-rs/argon2 · Jest + supertest · OpenAPI 3.1 + openapi-typescript **对应验收:** A01(API 级)、A02、A03、A06、A13(凭证设计级);A07 后端部分。P1a 完成后另册编写 P1b(viewer + admin 最小页)计划。 @@ -131,12 +131,13 @@ pnpm install Expected: lockfile 生成,无 workspace 报错。 -- [ ] **Step 3: Commit** `chore: pnpm workspace and turbo pipeline` +- [x] **Step 3: Commit** `chore: pnpm workspace and turbo pipeline`(完成:68a7d6a,含质量审查遗留项 .gitattributes/.gitignore/.editorconfig 增补;规格审查通过) ### Task 3: docker-compose 基础设施(cn 侧) **Files:** - Create: `infra/docker-compose.yml`, `.env.example` +- Modify: `package.json` packageManager → `pnpm@10.7.1`(对齐实际环境,Task 2 审查遗留) - [ ] **Step 1: 编写 compose(P1a 仅 cn profile)** diff --git a/infra/docker-compose.yml b/infra/docker-compose.yml new file mode 100644 index 0000000..7932237 --- /dev/null +++ b/infra/docker-compose.yml @@ -0,0 +1,38 @@ +# infra/docker-compose.yml +name: photo-live +services: + mysql-cn: + image: mysql:8.4 + command: --character-set-server=utf8mb4 --collation-server=utf8mb4_0900_bin + environment: + MYSQL_ROOT_PASSWORD: root + MYSQL_DATABASE: photo_cn + ports: ["3306:3306"] + volumes: [mysql-cn-data:/var/lib/mysql] + healthcheck: + test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-uroot", "-proot"] + interval: 5s + retries: 12 + redis-cn: + image: redis:7-alpine + ports: ["6379:6379"] + healthcheck: { test: ["CMD", "redis-cli", "ping"], interval: 5s, retries: 12 } + minio: + image: quay.io/minio/minio:latest + command: server /data --console-address ":9001" + environment: + MINIO_ROOT_USER: photo-dev + MINIO_ROOT_PASSWORD: photo-dev-secret + ports: ["9000:9000", "9001:9001"] + volumes: [minio-data:/data] + minio-init: + image: quay.io/minio/mc:latest + depends_on: { minio: { condition: service_started } } + entrypoint: > + /bin/sh -c " + until mc alias set dev http://minio:9000 photo-dev photo-dev-secret; do sleep 1; done; + mc mb -p dev/photo-dev || true; + mc anonymous set none dev/photo-dev;" +volumes: + mysql-cn-data: + minio-data: diff --git a/package.json b/package.json index 4cf0c40..2a76b12 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "photo-live", "private": true, - "packageManager": "pnpm@9.12.0", + "packageManager": "pnpm@10.7.1", "engines": { "node": ">=20" }, "scripts": { "lint": "turbo run lint",