fix(organize,identity,sites,pi): W10-pre backend fixes from v0.2 visual QA

- slot: new manual_verify event (attention -> verifying, with reason); a
  successful organize of a download whose slot is in attention goes back
  through verifying and lands by verify_passed on the actually imported
  assets; the download's organize_blocked decision is resolved with
  resolution {key: manual_organize | organize_retry, organizationRecordId} (U1)
- acquisition: plan purpose is upgrade only when the slot already has a
  current asset; a movie slot gap is a fill (U7)
- identity: entities created from TMDB details get metadata fields projected
  in the same transaction; TMDB aliases deduped by normalized text, site-title
  aliases skipped when the text already exists (U9)
- pi: auth-mode test of a custom Base URL no longer marks the upstream ok, and
  says to use the minimal completion to probe the endpoint (U2)
- sites: PUT /sites/{id}/credentials replaces same-kind secrets in place and
  names new secrets with site id + random suffix (secret.name is unique; was a
  500 on update); M-Team user data uses config/definition apiBaseUrl instead
  of deriving api.<domain> from the site URL (Invalid URL on IP/local bases)
- copy: setup error says 初始化口令; backup job points at umt backup
- tests: schema expected tables add site_user_data; migration round-trip
  timeout 60s; fake secrets honor label as name; vertical/resolve/pi/slot/
  site-center tests for the above
- docs: 09-visual-qa W10-pre status table (U3 root cause: outbox events are
  never mirrored to SSE)

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-09-28 16:29:29 +08:00
1 parent b7a7fd3958
commit 2b8fe667a5
20 files changed
+298 -42

No files matched your search

+5
View File
@@ -158,6 +158,11 @@ describe.skipIf(!hasPg)("Pi 上游(真实 PG)", () => {
const t2 = (await req("POST", `/pi/upstreams/${a.id}/test`, {})).body.data;
expect(t2).toMatchObject({ ok: true, mode: "auth", source: "stored credential", model: "gpt-5" });
expect(t2.upstream.lastVerifiedAt).toBeTruthy();
// 自定义 Base URL:凭证检查不连端点,不改写可用状态,提示用最小补全(QA U2)
await h.db.updateTable("pi_upstream").set({ status: "error" }).where("id", "=", b.id).execute();
const tb = (await req("POST", `/pi/upstreams/${b.id}/test`, {})).body.data;
expect(tb).toMatchObject({ ok: true, mode: "auth", upstream: { status: "error", lastVerifiedAt: null } });
expect(tb.message).toMatch(/最小补全/);
const models = (await req("GET", `/pi/upstreams/${a.id}/models`)).body.data;
expect(models.items.length).toBeGreaterThan(10);
expect(models.refreshed).toBe(false);