Files
photo-live/services/api/src/shared/request-with-id.ts
T
浅念 368b1d5b47 feat(api): argon2 password, idempotent admin seed, api-exception infra
Task 12 + Task 7 quality-review carryovers:

Part A - password hashing & controlled initial admin:
- src/auth/password.ts: hashPassword/verifyPassword over @node-rs/argon2
  (napi prebuilt, argon2id default); empty plain rejected at the door
- src/scripts/seed-admin.ts: idempotent admin seed (ADMIN_ACCOUNT/
  ADMIN_PASSWORD env, walk-up root .env load); existing account -> skip,
  never overwrites the password; no audit_logs (system op, no actor)
- pnpm seed script (build + node dist/scripts/seed-admin.js);
  .env.example dev defaults admin/admin-secret-change-me
- tests: test/password.spec.ts (5), test/seed.spec.ts real-DB idempotency (4)

Part B - Task 7 carryovers (all 8):
- ApiException(apiCode, message, httpStatus, details?) recognized first by
  the filter; unmapped-status rule: >=500 -> INTERNAL_ERROR + generic
  message, <500 -> VALIDATION_FAILED keeping original status (warn-logged)
- 5xx/INTERNAL_ERROR responses forced to generic message (leak fix)
- pino redact adds req.headers.cookie / res.headers.set-cookie
- x-request-id echo capped at 128 chars (fresh UUID beyond, no log)
- LOG_LEVEL validated against pino levels at module wiring -> fail fast
- shared/ constants (API_PREFIX), request-with-id, log-level (+spec)
- jest ts-jest reuses tsconfig.json; unit testMatch includes test/*.spec.ts
- build:watch script (no concurrently dep; dev = build:watch + node --watch)

api: 35 unit + 10 e2e tests green; root lint/typecheck/test green.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-17 20:54:30 +08:00

15 lines
840 B
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// services/api/src/shared/request-with-id.ts —— 请求对象带 req.id 的共享类型
// (Task 7 遗留项⑥):request-id 中间件 / pino-http genReqId 写入,异常过滤器、
// 后续 auth guard(req.user)等读取。此前在过滤器与中间件各声明一份局部接口。
// 注意不继承 IncomingMessage:pino-http 经 module augmentation 给后者挂了
// 非可选的 id: ReqId,扩展会与其冲突;组合用 ServerRequestWithId。
import type { IncomingMessage } from 'node:http';
/** 请求 ID 字段约定:上游 x-request-id 透传或 UUID v4(见 request-id.middleware.ts)。 */
export interface RequestWithId {
id?: string;
}
/** 中间件/genReqId 实际操作的请求对象(node 原始请求 + id 字段)。 */
export type ServerRequestWithId = IncomingMessage & RequestWithId;