Commit Graph

26 Commits

Author SHA1 Message Date
phamnazage-jpg
77b7f7f660 feat: harden runtime import and frontend verification workflows
Some checks failed
CI / Build & Test (push) Has been cancelled
CI / Lint (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / Docker Build (push) Has been cancelled
CI / Release (push) Has been cancelled
2026-06-04 20:02:36 +08:00
phamnazage-jpg
4b743848bc refactor(portal): merge register + login into single auth entry
Some checks failed
CI / Build & Test (push) Has been cancelled
CI / Lint (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / Docker Build (push) Has been cancelled
CI / Release (push) Has been cancelled
- Two separate cards (register + login) -> single unified card
- handleRegister + handleLogin -> single handleAuth that tries login first,
  falls back to register if login fails (new user detection)
- Single email/password input, single button, single status display
- Enter key submits on both fields
- File size 57873 -> 51329 chars (-11%)

Test: test_tksea_portal_assets.sh PASS, verify_frontend_smoke.sh PASS,
      verify_quality_gates.sh PASS (gofmt+vet+cov+integration)
2026-06-04 13:52:18 +08:00
Hermes
62b3c657a9 fix(portal): restore missing inputs in providers.html (revert buggy reorder)
Some checks failed
CI / Build & Test (push) Has been cancelled
CI / Lint (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / Docker Build (push) Has been cancelled
CI / Release (push) Has been cancelled
The reorder_hints.py script incorrectly removed several <input> elements
when moving .hint spans before inputs. This commit restores the file to
the correct state from commit 56474264, preserving all inputs while
keeping the hints in their proper places.

Fixes: admin-username input missing, several other inputs corrupted
2026-06-03 21:02:50 +08:00
Hermes Agent
23fd8db77d refactor(portal): move .hint info-banner ABOVE its <input> + upgrade to teal-accented banner style
Some checks failed
CI / Build & Test (push) Has been cancelled
CI / Lint (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / Docker Build (push) Has been cancelled
CI / Release (push) Has been cancelled
Two-part UX upgrade:

1. CSS — upgrade .hint from a generic "card with slate background" to a
   proper info-banner:
   - background: var(--color-primary-soft) (translucent teal 12%) instead
     of var(--bg-elev-2) (slate card) — visually distinct from any
     <input> card, so it can never be confused with one
   - border-left: 2px solid var(--color-primary) — clear "this is a hint"
     teal accent
   - padding: 8px 12px 8px 14px (smaller, lighter)
   - font-size: 12.5px (slightly larger for readability)
   - margin: 4px 0 8px 0 (sits between field label and input)
   - .hint code { monospace, teal-300, teal-tinted background } for inline
     <code> tokens
   - .hint strong { text-default color } for emphasis

   Also: label > input/select/textarea forced to display:block width:100%
   margin-top:6px (after the hint, hint + input collapse to margin-top:0)

2. HTML — reorder 11 labels across providers.html (7) and
   admin-batch-import.html (4) so the .hint span sits BEFORE the
   <input>/<select>/<textarea> it describes. Datalist stays adjacent to its
   owning input.

   Pattern before: <label>Field
  <input>
  <span class="hint">desc</span>
</label>
   Pattern after:  <label>Field
  <span class="hint">desc</span>
  <input>
</label>

Why: Linear/Vercel canonical form pattern is label + info banner above +
clean input below. The previous "input then hint" layout was just an
artifact of how the inline-script-dedup pass emitted the fields, not a
deliberate UX choice.

Verification (chrome remote-debugging, 7 pages, all .hint elements):
  Page                                            n_hints  covered
  https://sub.tksea.top/portal/                       2        0
  https://sub.tksea.top/portal/admin/                 0        0
  https://sub.tksea.top/portal/admin/providers.html   8        0
  https://sub.tksea.top/portal/admin/accounts.html    0        0
  https://sub.tksea.top/portal/admin/logical-groups   1        0
  https://sub.tksea.top/portal/admin/route-health     0        0
  https://sub.tksea.top/portal/admin-batch-import     4        0
  Total: 7/7 pages, 0 hint covered by any input

Local tests still PASS:
  - test_tksea_portal_assets.sh
  - verify_frontend_smoke.sh
2026-06-03 20:01:44 +08:00
Hermes Agent
3e158e780b fix(portal): prevent .hint description from being covered by <input>
Some checks failed
CI / Build & Test (push) Has been cancelled
CI / Lint (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / Docker Build (push) Has been cancelled
CI / Release (push) Has been cancelled
5 .hint spans (ADMIN TOKEN / PACK PATH / PROVIDER ID / SMOKE TEST MODEL /
COMMIT MESSAGE) were being visually overlapped by their sibling <input>
boxes because:
  - .hint was inline, padding 10px 12px with background+border
  - <input> was inline-block
  - label was display:block, font-size 12px
  - the inline .hint box was being squeezed into the same flow line as the
    input, so its last 8-10px were covered

Verified via getBoundingClientRect + elementFromPoint probe before fix:
  hint.top < input.bottom (5 fields) = hint overlapped by input

Fix: force .hint to display:block with margin-top:6px so it always sits
below its input as a separate block; also force label > input/select/textarea
to display:block width:100% so the form field always stretches and never
inlines with the field label text.

Verified after fix: 0 hints overlapped on providers.html (the worst case
with 8 .hint spans).

CSS-only change; no HTML edits. Affects all 8 portal pages. Smoke +
frontend assets tests still PASS.
2026-06-03 16:31:01 +08:00
Hermes Agent
56474264d6 refactor(portal): dedup inline scripts in accounts + batch-import + providers
Some checks failed
CI / Build & Test (push) Has been cancelled
CI / Lint (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / Docker Build (push) Has been cancelled
CI / Release (push) Has been cancelled
All three admin pages had two parallel inline <script> blocks (a modern S1
that used adminRuntime + a legacy S2 that was self-contained). Both had
a nested <script> text inside S1 that the browser tolerated only because
the second script re-ran any state-affecting calls. Merge into a single
inline script per page; fix the nested <script> comment.

- providers.html: 100371 -> 62761 chars (-37610, -37%)
- accounts.html:  54878 -> 33098 chars  (-21780, -40%)
- batch-import:   43861 -> 26570 chars  (-17291, -39%)

Also rename draftProviderIDInput -> providerIDInput in providers.html
(the old draft-provider-id input was removed during the earlier workflow
merge, leaving the script with a null addEventListener on draft id).

All scripts pass node --check. Both test_tksea_portal_assets.sh and
verify_frontend_smoke.sh PASS.
2026-06-03 13:14:31 +08:00
phamnazage-jpg
09f7c07de3 feat(portal): make provider/batch-import form fields self-explanatory + auto-fill
Some checks failed
CI / Build & Test (push) Has been cancelled
CI / Lint (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / Docker Build (push) Has been cancelled
CI / Release (push) Has been cancelled
Problem: provider manifest form had all-empty fields with cryptic
placeholders, users had to know what model IDs to type.

Fix on /portal/admin/providers.html (Provider Manifest 草稿):
- DISPLAY NAME: datalist of common vendors (OpenAI / DeepSeek /
  硅基流动 / Moonshot / 智谱 / Anthropic / 零一万物 / MiniMax / Qwen / Baichuan / 混元)
- PLATFORM: datalist of common platforms (openai / openai-compatible /
  deepseek / anthropic / gemini / zhipu / moonshot / minimax / qwen / ...)
- SMOKE TEST MODEL: datalist of common smoke models + auto-fills with
  first model from MODELS field if user leaves it empty
- BASE URL PLACEHOLDER: datalist of common base URLs (12 presets)
- MODELS: chip-row of 11 common models (gpt-5.4, gpt-5.4-mini,
  deepseek-chat, MiniMax-M2.7-highspeed, kimi-k2.6, glm-4.6,
  claude-sonnet-4-5, gemini-2.5-pro, qwen3-coder-plus, gpt-4o, o4-mini)
  + clear button. Click chip → append to MODELS field (dedup).
- KEYS textarea: 6 rows + example placeholder (sk-example-1/2/3)

Fix on /portal/admin-batch-import.html (发起导入):
- HOST ID: datalist of common host_ids + hint about loading pack first
- ENTRIES textarea: 6 rows + multi-line hint explaining
  base_url|api_key|model1,model2 format, optional model, batch import

JS change: syncDraftHelperState() in providers.html now auto-fills
smoke_test_model with first model if user hasn't filled it yet.
Also fixed: 2 duplicate copies of syncDraftHelperState (from
earlier batch script restoration) — both now have the new logic.

Verification:
- bash scripts/test/test_tksea_portal_assets.sh → PASS
- bash scripts/test/verify_frontend_smoke.sh → PASS
- browser_console click test: gpt-5.4 + deepseek-chat + kimi-k2.6 chips
  → models='gpt-5.4,deepseek-chat,kimi-k2.6' + smoke='gpt-5.4' auto-fill ✓
- screenshot: /tmp/portal-screenshots/admin-providers-v5.png
2026-06-03 11:24:54 +08:00
phamnazage-jpg
122d6282e1 fix(portal): unify all input/select/textarea/label/button/table styles via global fallback
Some checks failed
CI / Build & Test (push) Has been cancelled
CI / Lint (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / Docker Build (push) Has been cancelled
CI / Release (push) Has been cancelled
Root cause: only admin/index.html had explicit .input / .select / .label classes.
100+ inputs across logical-groups / route-health / accounts / providers /
admin-batch-import + public portal had no class → browser default styling →
页面看起来「未统一」。

Fix:
- portal.css: add global rules that auto-apply design system styling to
  any input/select/textarea/label/button/table that doesn't opt out
  via .raw-input / .field-label. The existing .input / .select /
  .label / .btn classes still win (same styles, just explicit).
- portal.js: detectInitialTheme() now respects HTML's data-theme
  attribute first (page author intent), then localStorage, then OS
  preference. This makes admin pages' explicit data-theme="dark"
  actually stick instead of being overridden.
- admin/index.html: h3 标题 8 个 article 统一用 class="card-title"
  (前 4 个 inline 15px / 后 3 个 inline 16px 已统一)
- 6 admin pages: 修复 critical HTML 结构 bug — 之前 batch 处理的
  残留让 <link> 和 <style> 嵌套在 <style>:root{} 块内,浏览器
  解析时直接忽略,导致所有 stylesheet 不加载、整个页面无样式

Verification:
- bash scripts/test/test_tksea_portal_assets.sh → PASS
- bash scripts/test/verify_frontend_smoke.sh → PASS
- 8 张 screenshot v4 在 /tmp/portal-screenshots/ (各 600KB-1.2MB)
- 浏览器实测:3 stylesheets 加载,103 个 input 全部 38px/12px 圆角输入框
  35 个 label 全部 12px uppercase slate-400
  6 个 select 全部 38px + 自定义箭头
2026-06-03 11:05:10 +08:00
phamnazage-jpg
cc8fc900ca refactor(portal): migrate 8 pages to portal.css+portal.js design system
Each page now uses the new page-hero + stat-card + statusbar pattern
with the Linear/Vercel-aligned token system, while preserving all
admin-common.js nav render contract and 70+ test-contract strings.

- public portal: index.html (1816 → 1280 lines)
- admin entry: admin/index.html
- admin pages: logical-groups / route-health / accounts / providers
- batch import: admin/batch-import.html (39-line redirect to
  admin-batch-import.html for legacy URL compatibility)
- admin-batch-import.html: real legacy URL handler page

Verified:
- bash scripts/test/test_tksea_portal_assets.sh → PASS
- bash scripts/test/verify_frontend_smoke.sh → PASS (all 7 admin
  pages + public portal render with smoke-admin / Smoke Logical
  Group / Smoke Provider Account / smoke-route-primary visible)
- 8 screenshot artifacts at /tmp/portal-screenshots/ (1440×2400
  chromium headless, 269KB–1.2MB each = real content)
2026-06-03 09:11:07 +08:00
phamnazage-jpg
3a9061e11d style(portal): add design system + shared layer (portal.css/portal.js/admin-common.css shim)
- portal.css: 777-line real design system (Linear/Vercel 信息建筑派)
  * tokens: spacing 4/8/12/16/24/32/48, type 12/13/14/15/17/20/24/32/44
  * colors: ink/paper/accent/success/warn/danger × 50/100/500/900
  * teal #14b8a6 1:1 aligned with host sub2api Vue/Tailwind
  * dark-first; light override for public portal
  * components: page-hero, stat-card, card, status, pill, btn-primary,
    toast-host, empty, skeleton, drawer, tabs
- portal.js: window.Sub2ApiPortal — toast, lucide 1.75px stroke SVG
  icon registry (shield/group/activity/route/health/account/provider/
  import/check/x/alert/info/copy/edit/trash/plus/refresh/...),
  copyToClipboard, theme auto/dark/light, drawer, renderModernAdminNav
- admin-common.css: 4KB legacy shim — maps old class names
  (.topnav/.primary/.secondary/.ghost/.danger/.metric/.statusbar/.stat/
  .eyebrow/.hero-points/.page-hero__eyebrow/.shell/.fade-in/.topline/
  .chip/.tag/.mono/.meta-card/.meta-label/.status-pill/.inline-code/
  .tone-*) onto new tokens without breaking admin-common.js nav contract

Evidence:
- bash scripts/test/test_tksea_portal_assets.sh → PASS (70+ string assertions)
- bash scripts/test/verify_frontend_smoke.sh → PASS (chromium headless 7 pages)
2026-06-03 09:10:45 +08:00
phamnazage-jpg
f6600d663a feat(monitoring): add complete Prometheus + Grafana monitoring stack
Some checks failed
CI / Build & Test (push) Has been cancelled
CI / Lint (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / Docker Build (push) Has been cancelled
CI / Release (push) Has been cancelled
Add production-ready monitoring infrastructure:
- 15 alerting rules (4 Critical + 11 Warning)
- Grafana dashboard with service health panels
- Full documentation with deployment guide

Covers: service availability, error rates, latency,
routing health, database connections, and log metrics
2026-06-02 19:54:38 +08:00
phamnazage-jpg
ef33762db5 feat(portal): add logical group packaging config 2026-05-30 10:54:32 +08:00
phamnazage-jpg
3bfd4cfc1c feat(portal): add logical group guidance config 2026-05-30 10:38:59 +08:00
phamnazage-jpg
037e141cc4 feat(portal): add logical group usage guidance 2026-05-30 10:26:53 +08:00
phamnazage-jpg
542c6823a5 feat(portal): add logical group entitlement view 2026-05-30 10:13:31 +08:00
phamnazage-jpg
ac1d8e27cc feat(portal): switch user catalog to logical groups 2026-05-30 08:26:28 +08:00
phamnazage-jpg
649eb13f30 feat(accounts): add explicit route binding workflow 2026-05-29 19:07:01 +08:00
phamnazage-jpg
c982c595b8 feat(accounts): add provider account admin view 2026-05-29 15:50:28 +08:00
phamnazage-jpg
2896e62071 feat(routing): add route health admin view 2026-05-29 13:37:43 +08:00
phamnazage-jpg
2e9b4ab988 feat(portal): add logical group admin page 2026-05-29 13:06:19 +08:00
phamnazage-jpg
6b03eb8fb9 feat(admin): harden provider draft model conflicts 2026-05-28 12:18:10 +08:00
phamnazage-jpg
de33ff3492 feat(admin): add session-based portal login 2026-05-28 11:01:29 +08:00
phamnazage-jpg
3a00f1b859 feat(admin): publish provider drafts into pack repo 2026-05-28 07:30:02 +08:00
phamnazage-jpg
8d7aa925df feat(admin): persist provider drafts in crm 2026-05-27 21:49:12 +08:00
phamnazage-jpg
ebd86a4256 feat(batch): add live reuse admin verification flow 2026-05-27 20:23:42 +08:00
phamnazage-jpg
02580cda0b feat: organize scripts and add portal validation assets 2026-05-27 09:39:05 +08:00