浅念
fb3c278e50
test(mobile): integration suite against real backend on mumu
...
P3 Task 11 (WRITE & COMPILE phase; device run pending MuMu availability).
- integration_test/p3_flow_test.dart: login -> album (zh+en) -> category
-> invite -> enqueue 3 real JPEGs -> queue completed -> server history
(sourceDeviceId) -> ov public API sees 3 -> hide via API + UI sync ->
DIO fault-gate offline (waitingNetwork -> retry -> 4 completed) ->
password change (session kept) -> relogin -> in-app locale smoke.
- integration_test/p3_background_test.dart: IT_PHASE=prepare/verify spec
for HOME-background continuation and force-stop kill-restart recovery
(2 x ~14MB noise JPEGs give a deterministic mid-flight window).
- helpers: dart-define config, fault-injecting DIO adapter, app harness
(picker/notification/locale provider overrides), UI step library with
live-binding polling (no pumpAndSettle).
- scripts/run-mobile-it.sh: device detect (exit 2), backend ensure
(compose + api/ov/worker/sync, exit 3), idempotent per-run user seed
(no DB reset), APK build/install + adb push of testdata, phase 1 /
--background phase 2 orchestration with server-side confirmed-count
truth via curl.
- services/api seed:it script (create-if-absent staff accounts).
- debug-only network security config: cleartext HTTP permitted to
10.0.2.2/127.0.0.1/localhost only (release unaffected).
- testdata: 3 x ~120KB + 2 x ~14MB generated JPEGs.
Co-Authored-By: Claude Code <noreply@anthropic.com >
2026-09-19 05:35:16 +08:00
浅念
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