fix: complete self-hosted staging identity integration
Deploy staging to test server / deploy (push) Successful in 6m34s
Deploy staging to test server / deploy (push) Successful in 6m34s
Align staging deployment, authentication, and admin access with the self-hosted identity boundary, including regression coverage and deployment diagnostics.
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
# Debug Session: admin-payments-500
|
||||
|
||||
Status: [OPEN]
|
||||
|
||||
## Symptom
|
||||
|
||||
Staging admin payment and package endpoints return HTTP 500. Confirmed example:
|
||||
`GET https://staging.jyotisha.chat/api/admin/payments?limit=20&offset=0`
|
||||
|
||||
## Constraints
|
||||
|
||||
- Do not modify business logic before runtime evidence identifies the root cause.
|
||||
- Do not expose database URLs, JWTs, cookies, passwords, or keys.
|
||||
- Preserve unrelated dirty workspace files.
|
||||
|
||||
## Hypotheses
|
||||
|
||||
1. Staging still runs an older SHA and the direct PostgreSQL fix is not deployed.
|
||||
2. `ADMIN_DATABASE_URL` is absent or PostgreSQL is unreachable from the web container.
|
||||
3. `admin_runtime` lacks SELECT privileges on payment/package/identity tables.
|
||||
4. Required staging migrations have not been applied.
|
||||
5. The SQL query does not match the staging schema.
|
||||
|
||||
## Evidence Log
|
||||
|
||||
- Pre-fix staging health reports deployment SHA `dd8e2ad9c7e76d0152b4563c43a45b1e26137035`.
|
||||
- Health reports both local business and identity databases as healthy; deployment drift and general database unreachability are rejected.
|
||||
- SSH application logs are blocked because this workstation has no staging private key; no server stack trace is claimed.
|
||||
- Static migration audit confirms `20260727020000_epay_packages_orders.sql` grants payment objects only to Supabase roles, not `admin_runtime`.
|
||||
- Both failing APIs use `ADMIN_DATABASE_URL` through `queryAdminRows`, so the missing grants and RLS policies explain the shared HTTP 500 failure.
|
||||
|
||||
## Fix
|
||||
|
||||
Added forward migration `20260730010000_admin_payment_permissions.sql` with least privilege:
|
||||
|
||||
- package SELECT/INSERT/UPDATE for `admin_runtime`;
|
||||
- payment-order SELECT only;
|
||||
- matching RLS policies;
|
||||
- epay settings SELECT and save-function EXECUTE.
|
||||
|
||||
No API business logic was changed.
|
||||
|
||||
## Verification
|
||||
|
||||
- Pre-fix contract test failed because the permission migration did not exist.
|
||||
- Post-fix payment/package/epay contract suite: 21/21 passed.
|
||||
- Staging migration and authenticated endpoint smoke are still pending.
|
||||
@@ -0,0 +1,17 @@
|
||||
# Debug Session: gitea-staging-deploy
|
||||
|
||||
- Status: OPEN
|
||||
- Goal: Complete the Gitea staging workflow and verify the deployed revision and health.
|
||||
- Session started: 2026-07-28
|
||||
|
||||
## Hypotheses
|
||||
|
||||
1. Task 3881 passed fetch and fails during image build or push.
|
||||
2. Runner connectivity or repository authentication is intermittently failing.
|
||||
3. Base images pull successfully but a later Dockerfile or BuildKit step fails.
|
||||
4. Images publish successfully but deployment fails during ACR pull, replacement, or health checks.
|
||||
5. Workflow succeeds while staging remains on an older revision due to tag or verification mismatch.
|
||||
|
||||
## Evidence
|
||||
|
||||
Pending collection from Gitea Actions, runner journal, Docker state, and staging health.
|
||||
@@ -0,0 +1,34 @@
|
||||
# Debug Session: npm-integrity-failure
|
||||
|
||||
Status: [OPEN]
|
||||
Started: 2026-07-29
|
||||
|
||||
## Symptom
|
||||
Gitea staging Web image build fails during `npm ci` for `server-only@0.0.1` with `EINTEGRITY`. The downloaded 477-byte tarball digest differs from `package-lock.json`.
|
||||
|
||||
## Constraints
|
||||
- Do not modify business logic during evidence collection.
|
||||
- Do not expose registry credentials or application secrets.
|
||||
- Preserve the current staging deployment until a verified image and migration are ready.
|
||||
|
||||
## Hypotheses
|
||||
1. The lockfile integrity for `server-only@0.0.1` is incorrect.
|
||||
2. The Runner network path receives corrupted or substituted registry bytes.
|
||||
3. BuildKit/npm cache contains a corrupted tarball and retries reuse it.
|
||||
4. A proxy or registry override affects the Runner despite the npmjs URL in logs.
|
||||
5. The upstream tarball changed while registry metadata and lockfile diverged.
|
||||
|
||||
## Evidence
|
||||
- `package-lock.json` expects `server-only@0.0.1` integrity ending in `GNSg==`.
|
||||
- The failed Gitea task downloaded 477 bytes and computed integrity ending in `iswNA==` twice.
|
||||
- Current registry metadata reports integrity ending in `iswNA==`.
|
||||
- A direct download from `registry.npmjs.org` on xiaoxin is 477 bytes and computes the same integrity ending in `iswNA==`.
|
||||
- A clean Docker Hub probe was blocked by an unrelated Docker Hub timeout.
|
||||
|
||||
Conclusion: H1/H5 confirmed. The locked integrity is stale relative to the current tarball. H2/H3/H4 are rejected by the consistent direct-download and metadata evidence.
|
||||
|
||||
## Fix
|
||||
Update only the stale `server-only@0.0.1` integrity entry in `package-lock.json` to the digest proven by registry metadata and direct download.
|
||||
|
||||
## Verification
|
||||
Pending post-fix workflow.
|
||||
@@ -0,0 +1,32 @@
|
||||
# Debug Session: staging-admin-api-500
|
||||
- **Status**: [OPEN]
|
||||
- **Issue**: staging 部署后,支付管理与套餐管理调用后端仍失败;期望两个后台 API 在管理员会话下正常返回。
|
||||
- **Debug Server**: pending
|
||||
- **Log File**: .dbg/trae-debug-log-staging-admin-api-500.ndjson
|
||||
|
||||
## Reproduction Steps
|
||||
1. 登录 https://staging.jyotisha.chat/admin。
|
||||
2. 打开支付管理,触发 GET /api/admin/payments?limit=20&offset=0。
|
||||
3. 打开套餐管理,触发 GET /api/admin/packages。
|
||||
4. 记录 HTTP 状态、当前部署 SHA 与 web 容器脱敏错误类别。
|
||||
|
||||
## Hypotheses & Verification
|
||||
| ID | Hypothesis | Likelihood | Effort | Evidence |
|
||||
|----|------------|------------|--------|----------|
|
||||
| A | admin_runtime 缺支付/套餐对象权限 | High | Low | Pending:预期 PostgreSQL permission denied |
|
||||
| B | staging migration 未执行或仍 pending | High | Low | Pending:预期 migration ledger 缺授权 migration |
|
||||
| C | staging 正在运行旧 SHA/旧镜像 | High | Low | Pending:预期 health SHA 与 staging head 不一致 |
|
||||
| D | ADMIN_DATABASE_URL 指向错误数据库或角色 | Medium | Medium | Pending:预期 current_user/database 与预期不符 |
|
||||
| E | SQL 与 staging schema 不匹配 | Medium | Low | Pending:预期 undefined table/column/function |
|
||||
| F | deploy 用户无法直接访问 Docker socket | Confirmed | Low | run 1309:访问 `/var/run/docker.sock` 返回 permission denied;既有自动部署使用 `sudo docker`。 |
|
||||
|
||||
## Log Evidence
|
||||
| Evidence | Observation |
|
||||
|---|---|
|
||||
| staging health | 当前部署 SHA 仍为 `dd8e2ad`。 |
|
||||
| required permission migration | `d44a414` 尚未部署。 |
|
||||
| Gitea migration | run 1309 在远端 Docker 操作失败,错误为 deploy 用户访问 `/var/run/docker.sock` permission denied。 |
|
||||
| known privilege boundary | `.gitea/workflows/backend-quality-gate.yml` 的同主机自动部署已使用 `sudo docker`,证明可用边界是非交互 sudo Docker,而不是 docker 组直连。 |
|
||||
|
||||
## Verification Conclusion
|
||||
Pre-fix 结论:后台 500 的已知权限迁移尚未落库;run 1309 暴露 Docker socket 权限,run 1313 又证明只将 Docker 子命令改为 sudo 仍不足,root-owned 部署树的 mutation lock 会在迁移执行前拒绝 deploy 用户。修复应以 `sudo -n env` 启动整个受控脚本,脚本内直接使用 `docker`,并以 sudo 清理可能成为 root-owned 的 incoming。修复后仍需实际运行迁移、确认 health 切换到目标 SHA,并完成管理员登录态支付/套餐 smoke;在这些证据完成前保持 OPEN。
|
||||
@@ -0,0 +1,30 @@
|
||||
# Debug Session: staging-image-build-failure
|
||||
|
||||
- Status: OPEN
|
||||
- Started: 2026-07-28
|
||||
- Symptom: Gitea staging workflow fails resolving the API base image with `insufficient_scope`.
|
||||
- Expected: staging push builds and publishes API/Web images, then deploys them to jyotisha-staging successfully.
|
||||
|
||||
## Hypotheses
|
||||
|
||||
1. The Aliyun `library/python` path is not a public mirrored repository.
|
||||
2. The authenticated private ACR context is incorrectly reused for the public image endpoint.
|
||||
3. The Node base image uses the same invalid mirror pattern.
|
||||
4. A stable reachable base-image source or preloaded image exists on xiaoxin.
|
||||
5. Further SSH, Compose, or environment failures remain after the image issue.
|
||||
|
||||
## Evidence
|
||||
|
||||
- Pre-fix Gitea log: `registry.cn-hangzhou.aliyuncs.com/library/python:3.12-slim` returned `pull access denied` and `insufficient_scope`.
|
||||
|
||||
## Iterations
|
||||
|
||||
- Confirmed both Aliyun `library/python` and `library/node` paths reject pulls.
|
||||
- Confirmed direct Docker Hub access times out from xiaoxin.
|
||||
- Confirmed complete pulls of `m.daocloud.io/docker.io/library/python:3.12-slim` and `swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/library/node:22-alpine`.
|
||||
- Minimal fix: replace only the two Dockerfile base-image sources, preserving Python 3.12 slim and Node 22 alpine variants.
|
||||
- Process-tree evidence corrected the initial attribution: the run was blocked in `apt-get update`; the later pip command had not started.
|
||||
- Runtime APT benchmark: Aliyun ~0.11s/~1.29 MB/s; Tsinghua ~0.30s/~461 KB/s; Debian official ~1.22s/~115 KB/s.
|
||||
- Runtime PyPI benchmark: Aliyun ~0.21s/~350 KB/s; Tsinghua ~0.81s/~90 KB/s; official ~1.20s/~88 KB/s.
|
||||
- Added Aliyun Debian and PyPI sources, APT retries and 30-second network timeouts, plus a 60-second pip timeout.
|
||||
- npm official and npmmirror throughput were comparable, so no npm source change was made.
|
||||
Reference in New Issue
Block a user