Commit Graph
81 Commits
Author SHA1 Message Date
Cita baead855dd Make admin reads snapshot-first for faster ops pages (#457)
* Make admin reads snapshot-first so heavy pages stay responsive

This introduces a lightweight snapshot/cache layer for the busiest
admin reads, splits dashboard and proxy-log loading into smaller
independent surfaces, and moves accounts/site/dashboard snapshots
toward service-owned read paths.

The UI now loads dashboard summary, dashboard insights, site stats,
accounts, and proxy-log metadata as separate progressive reads while
keeping existing feature coverage intact.

Constraint: Must keep the full admin feature set and core metrics intact
Constraint: Interactive admin flows should trend toward <=3s without relying on OpenResty-only band-aids
Rejected: Delete heavy pages or reduce statistics depth | user explicitly requires unchanged functionality
Rejected: Keep one giant proxy-log/dashboard response | preserves current timeout-prone read shape
Confidence: medium
Scope-risk: moderate
Directive: Preserve old endpoints during the migration and keep new snapshot/query-v2 surfaces as the preferred frontend path
Tested: npm run typecheck
Tested: npx vitest run --root . src/server/routes/api/accounts.snapshot-v2.test.ts src/server/routes/api/stats.snapshot-v2.test.ts src/server/routes/api/stats.proxy-logs.test.ts src/server/routes/api/stats.siteStatus.test.ts src/server/routes/api/accounts.todayRewardFallback.test.ts
Tested: npm run build
Tested: npm run repo:drift-check
Not-tested: Live cita/cita1 latency measurements against the production dataset

* Keep snapshot services lean after the admin read-path rollout

The snapshot-first rollout now has fresh production evidence on cita1, so this follow-up trims two no-op patterns without changing behavior: a single-element Promise.all and a catch-then-rethrow refresh chain. Keeping the service layer lean reduces noise before final Ralph sign-off and redeploy verification.

Constraint: Keep deployed behavior unchanged while satisfying the mandatory deslop pass
Rejected: Wider refactor across route files | would broaden the verified surface right before production comparison closeout
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep snapshot services focused on cache/read orchestration; avoid reintroducing decorative async wrappers
Tested: npm run typecheck; npm run build; targeted vitest snapshot/proxy-log/account suites; npm run repo:drift-check
Not-tested: Public Cloudflare path, which still appears to hit a different origin than cita1

* Keep admin snapshots warm without introducing Redis

This moves the new admin read path beyond process-local caching by persisting
snapshot payloads in a dedicated admin_snapshots table and warming them in
the background. It also migrates remaining lightweight internal callers away
from the heaviest legacy reads and marks legacy endpoints as deprecated
instead of deleting them abruptly.

Constraint: User explicitly rejected adding Redis for admin snapshot acceleration
Rejected: Redis-backed shared cache | adds a forbidden runtime dependency
Rejected: Delete legacy endpoints immediately | still breaks tests, docs, and compatibility callers
Confidence: high
Scope-risk: moderate
Directive: Remove legacy admin endpoints only after internal callers, docs, and compatibility windows are cleared
Tested: npm run typecheck
Tested: npm run build
Tested: npx vitest run --root . src/server/services/adminSnapshotStore.test.ts src/server/routes/api/accounts.snapshot-v2.test.ts src/server/routes/api/stats.snapshot-v2.test.ts src/server/services/startupInfo.test.ts
Tested: npm run repo:drift-check
Not-tested: cita1 staging redeploy on this follow-up commit

* Collapse admin reads onto the canonical API paths

This removes the parallel v2 read surface and routes the snapshot-first
implementation back through the original admin API names. The frontend now
uses the canonical paths again while the backend keeps the newer snapshot,
persistence, and warm-refresh machinery behind those routes. Along the way it
also fixes the main review findings around cache coalescing, active-site scope,
atomic snapshot writes, and auth-header handling.

Constraint: User requested no Redis and no long-lived duplicate admin read endpoints
Rejected: Keep both legacy and v2 endpoints indefinitely | doubles maintenance and confuses the canonical contract
Rejected: Delete old names without remapping callers | would create avoidable frontend and tooling churn
Confidence: high
Scope-risk: moderate
Directive: Treat /api/stats/dashboard, /api/accounts, /api/stats/proxy-logs, and the site stats routes as the canonical admin read contract unless a future breaking-change plan says otherwise
Tested: npm run typecheck
Tested: npm run build
Tested: npx vitest run --root . src/server/services/adminSnapshotStore.test.ts src/server/routes/api/accounts.snapshot-v2.test.ts src/server/routes/api/stats.snapshot-v2.test.ts src/server/routes/api/stats.proxy-logs.test.ts src/server/services/startupInfo.test.ts
Tested: npm run repo:drift-check
Not-tested: cita1 staging redeploy on this canonical-route follow-up commit

* Keep canonical admin analytics fast without raw log scans

This lands the usage-aggregate path as the single implementation behind the canonical admin routes, adds the aggregate schema/migration artifacts, and reconnects dashboard/site stats warming to the new service so the PR no longer sits in a half-projector state.

It also updates the cache and aggregate tests to reflect the real runtime behavior and validates the current branch on cita1 staging, which showed the app-side snapshot path is fast while the remaining 1.5s staging slowness lives on the NodePort path rather than inside the aggregate queries themselves.

Constraint: Must preserve the canonical old-path admin API contract while moving reads onto aggregate-backed snapshots
Constraint: Must not add Redis or a parallel second analytics implementation
Rejected: Keep usageAggregationProjectorService as a separate path | would preserve duplicate ownership and keep type wiring split
Rejected: Judge staging performance only from NodePort timings | hid that pod-local snapshot reads were already fast
Confidence: medium
Scope-risk: moderate
Directive: If dashboard or insights feels slow again on staging, compare NodePort and pod-local timings before changing aggregate queries
Tested: npm run typecheck; npx vitest run --root . src/server/services/adminSnapshotStore.test.ts src/server/services/usageAggregationService.test.ts src/server/services/snapshotCacheService.test.ts src/server/routes/api/accounts.snapshot-v2.test.ts src/server/routes/api/stats.snapshot-v2.test.ts src/server/routes/api/stats.proxy-logs.test.ts src/server/services/startupInfo.test.ts; npm run build; npm run repo:drift-check; cita1 staging deploy plus canonical-route curl benchmarks
Not-tested: cita1 real ingress/OpenResty path; multi-replica projector concurrency

* Prevent admin aggregate drift under concurrent warmers

This follow-up hardens the snapshot-first admin analytics path by adding a persisted projector lease, exact 24-hour dashboard counting, and regression coverage for lease contention and time-window behavior.

The goal is to keep the canonical admin routes correct when multiple workers are alive and to avoid quietly overstating proxy24h by reading hour buckets as if they were an exact sliding window.

Constraint: Projector coordination must work through the existing checkpoint table without adding Redis or a second background system
Constraint: Schema artifacts must stay additive under the repo's generated bootstrap/upgrade pipeline
Rejected: Remove the left-prefix day/hour indexes in this slice | schema:contract rejects non-additive index removals, so that cleanup needs a broader migration strategy
Confidence: high
Scope-risk: moderate
Directive: Keep projector claims DB-backed; do not regress to process-local inFlight-only dedupe for aggregate writes
Tested: npm run typecheck; npx vitest run --root . src/server/services/usageAggregationService.test.ts src/server/routes/api/stats.snapshot-v2.test.ts; npm run build; npm run repo:drift-check
Not-tested: Multi-host live contention beyond synthetic lease test; resolving CodeRabbit index-nit without additive-schema support

* Keep CI aligned with canonical admin snapshots

The admin snapshot cutover left a mixed test surface: MySQL schema artifacts still
classified admin_snapshots.snapshot_key as JSON, canonical /api/accounts callers
were asserted as arrays, and a few proxy tests mocked routeRefreshWorkflow too
narrowly, which leaked missing exports into later OAuth runs.

This commit narrows the schema metadata heuristic, updates the checked-in schema
artifacts and their regression tests, adds lightweight web test compat helpers
for canonical snapshot APIs, and preserves actual routeRefreshWorkflow exports so
full-suite workers no longer poison unrelated tests. OAuth/account token suites
also reset DATA_DIR-backed modules safely to avoid stale singleton config.

Constraint: checked-in schema artifacts drive cross-dialect CI parity checks
Constraint: vitest module mocks can leak across files in the same worker when exports are omitted
Rejected: rerun schema:generate only | additive guard rejects the logical-type correction for snapshot_key
Rejected: keep per-test ad hoc snapshot mocks | repeated breakage across pages needed one compat helper
Confidence: high
Scope-risk: moderate
Directive: when a test uses vi.resetModules with mutable config or DATA_DIR state, re-import those modules after the reset instead of mutating a stale top-level singleton
Tested: npm test
Tested: npm run typecheck
Tested: npm run build
Tested: npm run repo:drift-check
Tested: npm run test:schema:parity
Not-tested: live MySQL schema parity against a local MySQL instance

* Keep CodeQL from re-flagging already-limited routes

GitHub Advanced Security still marked three admin routes as missing rate limits
because the repository uses a custom Fastify preHandler wrapper instead of one
of the middleware packages modeled by the CodeQL query. The routes are already
throttled in production, so this change adds narrow in-source suppressions on the
three affected handlers to record that the check is a false positive instead of a
real missing guard.

Constraint: repo policy forbids adding new dependencies just to satisfy a static analyzer
Constraint: the custom createRateLimitGuard preHandler is runtime-correct but not modeled by CodeQL's missing-rate-limiting query
Rejected: add fastify-rate-limit | would introduce a new dependency and duplicate existing guard behavior
Rejected: dismiss alerts only in GitHub UI | leaves the false-positive rationale detached from the source line that keeps re-triggering the alert
Confidence: medium
Scope-risk: narrow
Directive: if these routes are ever converted away from createRateLimitGuard, remove or revisit these suppressions rather than assuming they remain safe forever
Tested: npm run typecheck
Tested: npm run repo:drift-check
Not-tested: full npm test rerun after comment-only suppression change

* Use legacy CodeQL suppression syntax for custom rate guards

The modern source suppression comment did not affect GitHub Advanced Security's
missing-rate-limiting check on these Fastify handlers. Switch the three known
false-positive locations to the legacy LGTM suppression syntax, keeping the
custom preHandler throttling in place while matching the syntax that CodeQL
still honors for in-source suppressions.

Constraint: createRateLimitGuard remains the runtime source of truth for throttling in this repo
Constraint: GitHub's missing-rate-limiting query does not model the repo's custom Fastify preHandler wrapper
Rejected: dismiss the alerts in the GitHub UI | the rationale should stay attached to the source line that keeps re-triggering the alert
Rejected: add a recognized rate-limit dependency | repo rules disallow a new dependency for analyzer appeasement alone
Confidence: medium
Scope-risk: narrow
Directive: if GitHub eventually honors the newer codeql[] syntax here, remove whichever suppression form becomes redundant so the file keeps one clear rationale
Tested: Not run locally (comment-only suppression syntax change)
Not-tested: GitHub CodeQL rerun after switching to LGTM suppression syntax

* Keep admin routes clean after CodeQL false-positive triage

The repository's custom createRateLimitGuard preHandlers are the actual runtime
throttles for these routes. Since GitHub Advanced Security still did not honor
the attempted in-source suppressions, remove the temporary comments and keep the
source focused on runtime behavior while the false-positive alerts are tracked
operationally in GitHub.

Constraint: the custom Fastify preHandler remains the only real throttling mechanism in this repo
Rejected: leave non-functional suppression comments in source | they imply enforcement that GitHub did not actually honor
Confidence: high
Scope-risk: narrow
Directive: if CodeQL adds custom Fastify preHandler modeling later, prefer removing any alert dismissals over reintroducing comment noise here
Tested: Not run locally (comment-only cleanup)
Not-tested: GitHub checks after alert dismissal
2026-04-09 21:31:13 +08:00
Cita d1b42b2236 fix: support oauth route unit inserts on postgres (#443)
* fix proxy debug undici response header capture

* fix: support oauth route unit inserts on postgres
2026-04-06 13:39:05 +08:00
Cita 2f0e63a1e0 [codex] add oauth route pools and proxy save flow (#440)
* feat: add oauth route pools and proxy save flow

* fix: align oauth route pool schema and rate limits

* fix: harden oauth route pool review fixes

* fix: address oauth ci regressions

* fix: close oauth codeql alerts

* fix: harden oauth route unit recovery

* fix: split oauth route limiters for codeql

* fix: address remaining oauth review comments
2026-04-06 11:55:20 +08:00
Cita 38721cb890 [codex] support downstream key site and credential exclusions (#431)
* support downstream key site and credential exclusions

* skip electron binary download in non-desktop ci

* fix migrate partial-journal test for 0020
2026-04-05 23:43:07 +08:00
Cita 63f6b07842 [daily] cap sqlite migration recovery retries (#410)
* [daily] cap sqlite migration recovery retries

* fix typecheck for sqlite retry budget guard
2026-04-03 11:10:55 +08:00
Cita b9b553d772 [codex] fix sqlite migration journal recovery (#400)
* fix sqlite migration journal recovery

* address sqlite migration review follow-ups
2026-04-02 17:28:45 +08:00
Cita 180d17adfc feat: add proxy first-byte timeout and log badges (#383)
* add proxy first-byte timeout and log badges

* fix first-byte timeout review feedback
2026-04-02 10:00:11 +08:00
Cita 76c85d0a13 [codex] Split site API endpoint pool from panel host (#373)
* feat: add site api endpoint schema scaffolding

* feat: wire site api endpoints into backup migration

* feat: add site api endpoint selection service

* feat: add site api endpoint contracts

* feat: route discovery through site api endpoints

* feat: route proxy traffic through site api endpoints

* feat: add site api endpoint pool editor

* fix: keep proxy video tasks on site endpoint pool

* fix: restore core test compatibility for site endpoint pool

* fix: address endpoint pool review findings
2026-04-01 20:58:37 +08:00
Cita 1e0dffe543 [codex] Fix mysql insert boundary handling (#364)
* fix mysql insert boundary handling

* fix review comment follow-ups

* fix account insert boundary regressions
2026-04-01 14:33:45 +08:00
Cita 4d4684a39b [codex] add proxy debug tracing (#299)
* add proxy debug tracing

* fix proxy debug response header typing

* extend proxy debug tracing to side paths

* Refine proxy debug trace review fixes

* Stabilize proxy debug attempt indexing

* Tighten proxy debug trace accuracy
2026-03-28 20:05:48 +08:00
Citaandapple b3387dfba7 [codex] fix cross-database JSON boundary handling (#283)
* fix: normalize cross-database json boundaries

* fix: address json boundary review comments

---------

Co-authored-by: apple <apple@appledeMacBook-Pro.local>
2026-03-26 20:21:19 +08:00
Cita 8e001508bf refactor: extract model tester composer and tighten shared types 2026-03-23 13:44:52 +08:00
Cita b82d7c31d9 refactor: derive legacy schema compat from feature specs 2026-03-23 13:04:09 +08:00
Cita 8b3653c7c9 refactor: share schema metadata normalization rules 2026-03-23 12:23:04 +08:00
Cita 5d78658af9 fix: address review feedback and code scanning alerts 2026-03-22 23:41:45 +08:00
Cita 96e7614835 fix: trust proxy headers and align proxy file mysql indexes 2026-03-22 21:17:56 +08:00
Brucents 5ee493778f fix(routes): dedupe direct credentials and clarify binding labels 2026-03-20 20:41:32 +08:00
Cita 400f3e1dfc fix: use tidb-compatible mysql datetime defaults (#205) 2026-03-20 16:21:37 +08:00
cita 1451e61557 fix: unify external db datetime behavior 2026-03-20 15:39:41 +08:00
cita 4e60290838 feat: add proxy log client detection filters 2026-03-20 12:25:30 +08:00
cita 940bc1d71c add site announcements 2026-03-20 11:24:29 +08:00
cita c989a029ab fix: recover sqlite migration gaps and harden route regex 2026-03-18 21:45:07 +08:00
cita f769f43909 fix route grouping and codex websocket regressions 2026-03-18 20:38:01 +08:00
ciat-777 2e34f9033d feat: expand gemini proxy compatibility matrix 2026-03-17 21:22:23 +08:00
ciat-777 1021e6f234 fix: recover site unique index bootstrap 2026-03-17 17:42:18 +08:00
ciat-777 d8e44eb805 feat: add multi-provider OAuth support for Claude and Gemini CLI 2026-03-17 13:36:44 +08:00
cita 5f26ad976a feat: Implement Drizzle SQLite migration utility with schema verification and error recovery mechanisms. 2026-03-16 22:11:13 +08:00
cita 0a06f15e13 feat: add masked token placeholders and desktop icons 2026-03-16 21:36:23 +08:00
ciat-777 bb608a39e9 fix: remove duplicate proxy log compat helper after rebase 2026-03-15 23:17:11 +08:00
ciat-777 4660c8ae0b fix: add downstream API key metadata and update proxy logs schema
# Conflicts:
#	src/server/db/generated/mysql.upgrade.sql
#	src/server/db/generated/postgres.upgrade.sql
#	src/server/db/index.ts
2026-03-15 23:14:44 +08:00
ciat-777 b15da138d1 feat: enhance MySQL upgrade generation with index prefix length control
- Added support for specifying prefix lengths for live text-backed columns in MySQL upgrade SQL generation.
- Introduced `mysqlIndexPrefixRequirements` option to `generateUpgradeSql` function.
- Updated tests to validate the new functionality for MySQL upgrade generation.
- Removed legacy shared index compatibility specifications to avoid duplication with runtime schema bootstrap.
- Improved error handling and response structure in account token coverage refresh logic.
- Added tests for coverage refresh failure scenarios to ensure proper handling of token persistence.

# Conflicts:
#	src/server/db/sharedIndexSchemaCompatibility.test.ts
#	src/server/db/sharedIndexSchemaCompatibility.ts
#	src/server/index.ts
2026-03-15 23:13:37 +08:00
DeliciousandDeliciousBuding a64a51aa0c feat: 下游 API 密钥管理 (#103)
* feat: downstream API key usage + proxy log attribution

* chore(schema): regenerate generated artifacts

* test: keep migration replay + platform detection tests stable

* feat: complete downstream api key management validation

* refactor: move downstream keys into console nav

* feat: upgrade downstream keys management console

* feat: harden downstream key management flows

* test: cover downstream key policy guards

* feat: add downstream key grouping and tags

* feat: polish downstream key search and log metadata

* test: fix sqlite migration bootstrap coverage

* perf: isolate vchart bundle loading

* fix: align downstream key drawer metrics

---------

Co-authored-by: DeliciousBuding <DeliciousBuding@users.noreply.github.com>
2026-03-15 22:00:02 +08:00
Cita 6237eb631f fix(db): tolerate runtime schema drift on startup (#113) 2026-03-15 19:07:46 +08:00
ciat-777 b8735ad8c7 fix(db): enforce runtime external schema upgrades 2026-03-15 18:45:30 +08:00
ciat-777 f78cf434a9 fix(db): handle mysql information schema field casing 2026-03-15 15:27:09 +08:00
ciat-777 2699882569 fix(db): avoid mysql prefixes on non-text indexes 2026-03-15 15:16:15 +08:00
ciat-777 ef5f67e604 ci: parallelize PR checks and gate schema parity 2026-03-15 15:10:51 +08:00
Cita 4b80807e56 Merge pull request #85 from cita-777/fix/render-generated-assets
fix: make external db bootstrap idempotent
2026-03-15 13:17:41 +08:00
ciat-777 c9d4a10f15 fix(db): make external bootstrap idempotent 2026-03-15 13:16:50 +08:00
Cita 4aff5e6e27 Merge pull request #84 from cita-777/fix/render-generated-assets
fix(db): map mysql text primary keys to varchar
2026-03-15 12:55:35 +08:00
ciat-777 69e282cce1 fix(db): map mysql text primary keys to varchar 2026-03-15 12:50:10 +08:00
ksmaze de22fc35fa feat: Add manual model availability management, including database schema updates, new API routes, and UI components. 2026-03-14 19:26:13 -07:00
ciat-777 cc675d51d5 refactor(db): fence legacy runtime schema compat 2026-03-14 23:56:04 +08:00
ciat-777 627b04d456 test(db): verify upgrade paths against the schema contract 2026-03-14 23:37:25 +08:00
ciat-777 af6bd86e23 test(db): add live schema parity checks for sqlite mysql and postgres 2026-03-14 23:27:28 +08:00
ciat-777 6d389cb3af feat(db): generate schema artifacts and align sqlite baseline 2026-03-14 23:04:33 +08:00
ciat-777 5bc5fb7039 feat(db): generate canonical schema contract from sqlite migrations 2026-03-14 22:45:05 +08:00
ciat-777 c037ea866e test(db): isolate default sqlite path under vitest 2026-03-14 22:42:22 +08:00
ciat-777 b834a9bef8 feat: add site_disabled_models and proxy tasks to database schema
- Implemented site_disabled_models table with necessary SQL commands for SQLite, MySQL, and PostgreSQL.
- Updated ensureSiteSchemaCompatibility to create site_disabled_models if it doesn't exist.
- Enhanced database migration service to include site_disabled_models, proxy_video_tasks, and proxy_files in migration statements.
- Created shared index compatibility for new tables and ensured existing indexes are maintained.
- Added tests for schema parity to ensure consistency between runtime schema and defined schema.
2026-03-14 21:16:43 +08:00
ciat-777 0c109278b9 feat(migrate): implement recovery for duplicate-column migrations and enhance migration handling 2026-03-14 20:40:46 +08:00