refactor(auth): replace dashboard sessions with stateless tokens and session control (#6329)

* refactor(auth): replace dashboard sessions with stateless tokens

* feat(auth): harden session issuance and distributed enforcement

* fix(proxy): preserve trusted proxy compatibility defaults

* refactor: address dashboard auth review feedback

* refactor: remove classic frontend and flatten web app
This commit is contained in:
Calcium-Ion
2026-07-20 16:48:43 +08:00
committed by GitHub
parent 5a6c53d496
commit 31d70fca39
1605 changed files with 17511 additions and 147913 deletions
@@ -1,83 +0,0 @@
---
name: classic-to-default-sync
description: Inspect a given commit's web/classic changes and sync all features/fixes to web/default. Use when the user provides a commit ID and wants to audit whether web/default already has the same features as web/classic, port missing features, improve suboptimal implementations, fix bugs, and remove redundant code. Trigger phrases include: "/classic-to-default-sync <hash>", "classic-to-default-sync <hash>", "sync classic to default", "port from classic", "compare classic commit", "classic 和 default 对比", "把这次 classic 的修改同步到 default", "查看这次提交 classic 中的修改并同步", or any request supplying a commit hash together with classic/default comparison intent.
---
# Classic-to-Default Sync
Given a **commit ID**, audit all `web/classic` changes and ensure `web/default` reaches feature parity with the best possible implementation.
## Input
The user must supply a `<commit-id>`.
## Workflow
### Step 1 — Extract classic diff
```bash
git show <commit-id> -- web/classic
```
Read every changed file in `web/classic`. Identify the **logical changes** (new features, UI/UX improvements, bug fixes, config tweaks, removed dead code, etc.) — not just line diffs.
### Step 2 — Map to default counterparts
For each logical change found in Step 1, locate the equivalent file(s) in `web/default/src/`. Use Glob/Grep/SemanticSearch as needed. Consider that:
- `web/classic` uses **React 18 + Vite + Semi Design**
- `web/default` uses **React 19 + Rsbuild + Base UI + Tailwind CSS**
- Component names, file paths, and API shapes may differ; match by **functionality**, not filename.
### Step 3 — Triage each change
Classify every logical change as one of:
| Status | Meaning |
|--------|---------|
| ✅ Already present & optimal | No action needed |
| ⚠️ Present but suboptimal | Improve: logic, layout, style, or code quality |
| ❌ Missing | Implement from scratch in default's stack |
### Step 4 — Implement
For each **⚠️** or **❌** item:
1. **Read the target file(s) in `web/default`** before editing (required by project conventions).
2. Implement using `web/default` conventions:
- React 19 patterns (hooks, Suspense, etc.)
- Base UI primitives where applicable
- Tailwind CSS for styling (no inline styles or Semi Design imports)
- `useTranslation()` + `t('English key')` for all user-visible strings
- TypeScript — explicit types, no `any`
- No dead code, no redundant comments
3. Follow **Rule 6** (pointer types for optional relay DTOs) if touching relay-related TS types.
4. After editing, run `ReadLints` on changed files and fix any introduced lint errors.
### Step 5 — i18n
If any new user-visible strings were added, run the i18n sync:
```bash
cd web/default && bun run i18n:sync
```
Then add missing translations for all supported locales (en, zh, fr, ja, ru, vi) following the **i18n-translate** skill.
### Step 6 — Report
Summarise the work in a concise table:
| # | Change (from classic commit) | Status | Action taken |
|---|------------------------------|--------|--------------|
| 1 | … | ✅ / ⚠️ / ❌ | None / Improved / Implemented |
If every item is ✅ with no action needed, simply reply: **"已完成 — web/default 已具备此次提交的所有功能,且实现质量良好,无需修改。"**
## Quality bar
- No unused imports, variables, or components
- No commented-out code left behind
- Consistent naming with surrounding `web/default` code
- All interactive elements accessible (keyboard nav, ARIA labels where Radix doesn't provide them automatically)
- No regressions: existing behaviour in `web/default` must not break
+17 -15
View File
@@ -3,7 +3,7 @@ name: i18n-translate
description: >-
Complete and maintain frontend i18n translations for this project. Covers
finding missing translation keys, detecting untranslated entries, and adding
translations for all supported locales (en, zh, fr, ja, ru, vi). Use for any
translations for all supported locales (en, zh, zh-TW, fr, ja, ru, vi). Use for any
task involving frontend locale files, missing translation keys, untranslated
UI text, `t(...)` keys, `useTranslation()`, static i18n keys, button/label/
toast/dialog/placeholder/validation copy, or adding/fixing even a single
@@ -24,12 +24,12 @@ description: >-
### Hard Constraint: Locale Writes Go Through the Script
- You MUST NOT edit `web/default/src/i18n/locales/*.json` directly with text-editing tools (StrReplace, Write, search-and-replace, manual JSON edits, etc.). This applies even to a single key.
- You MUST NOT edit `web/src/i18n/locales/*.json` directly with text-editing tools (StrReplace, Write, search-and-replace, manual JSON edits, etc.). This applies even to a single key.
- ALL locale writes MUST go through the `add-missing-keys.mjs` script, followed by `bun run i18n:sync`. The script is the only sanctioned way to add or change locale values.
- Why this is mandatory, not optional:
- Hand-editing reliably drops one or more of the six locales (`en`, `zh`, `fr`, `ja`, `ru`, `vi`), leaving keys missing in some languages.
- Hand-editing reliably drops one or more of the seven locales (`en`, `zh`, `zh-TW`, `fr`, `ja`, `ru`, `vi`), leaving keys missing in some languages.
- Hand-editing breaks the required alphabetical key order and introduces JSON syntax errors (trailing commas, mismatched quotes).
- The script writes all six files atomically with consistent sorting, so the locale set stays in sync by construction.
- The script writes all seven files atomically with consistent sorting, so the locale set stays in sync by construction.
- The script does not do the translation for you. You still must reason out each locale's copy and populate the script's `newKeys` object; the script only handles insertion, sorting, and writing. Do not skip the script just because the thinking happens regardless.
## Scope Checklist
@@ -45,10 +45,10 @@ Do not skip this workflow because the fix is "just one key".
## Overview
- Locale files: `web/default/src/i18n/locales/{en,zh,fr,ja,ru,vi}.json`
- Locale files: `web/src/i18n/locales/{en,zh,zh-TW,fr,ja,ru,vi}.json`
- Format: flat JSON under `"translation"` key, keys are English source strings
- Base locale: `en.json` (most keys), fallback: `zh` (Chinese)
- Sync script: `bun run i18n:sync` (from `web/default/`)
- Sync script: `bun run i18n:sync` (from `web/`)
- All `t()` calls must have corresponding keys in every locale file
## Small Fix Path
@@ -56,7 +56,7 @@ Do not skip this workflow because the fix is "just one key".
For a single known missing key (still script-only, no direct JSON edits):
1. Confirm the exact key at the call site and verify it is absent from all locale files.
2. Add the key via `add-missing-keys.mjs`, populating its `newKeys` object for every supported locale: `en`, `zh`, `fr`, `ja`, `ru`, `vi`. Even one key goes through the script; do not hand-edit the JSON.
2. Add the key via `add-missing-keys.mjs`, populating its `newKeys` object for every supported locale: `en`, `zh`, `zh-TW`, `fr`, `ja`, `ru`, `vi`. Even one key goes through the script; do not hand-edit the JSON.
3. The script preserves the flat `"translation"` object and keeps keys alphabetically sorted automatically.
4. Run a targeted search for the key in code and locale files.
5. Run `bun run i18n:sync` to normalize file order. This step is mandatory, not optional.
@@ -66,14 +66,14 @@ For a single known missing key (still script-only, no direct JSON edits):
### Step 1: Run sync and read report
```bash
cd web/default && bun run i18n:sync
cd web && bun run i18n:sync
```
Read `web/default/src/i18n/locales/_reports/_sync-report.json` to see per-locale status (missingCount, extrasCount, untranslatedCount).
Read `web/src/i18n/locales/_reports/_sync-report.json` to see per-locale status (missingCount, extrasCount, untranslatedCount).
### Step 2: Find missing keys (used in code but not in locale files)
Create and run `web/default/scripts/find-missing-keys.mjs`:
Create and run `web/scripts/find-missing-keys.mjs`:
```javascript
import fs from 'node:fs/promises'
@@ -136,7 +136,7 @@ if (missingKeys.size === 0) {
### Step 3: Find untranslated entries (value equals English)
Create and run `web/default/scripts/find-untranslated.mjs`:
Create and run `web/scripts/find-untranslated.mjs`:
```javascript
import fs from 'node:fs/promises'
@@ -167,7 +167,7 @@ const brandNames = new Set([
'WeChat','Xinference','Xunfei','AI Proxy','One API',
])
const locales = ['fr', 'ja', 'ru', 'zh', 'vi']
const locales = ['fr', 'ja', 'ru', 'zh', 'zh-TW', 'vi']
for (const locale of locales) {
const locFile = JSON.parse(await fs.readFile(path.join(LOCALES_DIR, `${locale}.json`), 'utf8'))
@@ -196,7 +196,7 @@ for (const locale of locales) {
### Step 4: Add translations
This script is the ONLY sanctioned way to write locale values. You MUST NOT bypass it by hand-filling the JSON files. Create `web/default/scripts/add-missing-keys.mjs` with this exact structure:
This script is the ONLY sanctioned way to write locale values. You MUST NOT bypass it by hand-filling the JSON files. Create `web/scripts/add-missing-keys.mjs` with this exact structure:
```javascript
import fs from 'node:fs/promises'
@@ -211,6 +211,7 @@ function stableStringify(obj) {
const newKeys = {
en: { /* "key": "English value" */ },
zh: { /* "key": "中文翻译" */ },
'zh-TW': { /* "key": "繁體中文翻譯" */ },
fr: { /* "key": "Traduction française" */ },
ja: { /* "key": "日本語翻訳" */ },
ru: { /* "key": "Русский перевод" */ },
@@ -257,7 +258,7 @@ Populate the `newKeys` object with actual translations for each locale.
### Step 5: Verify and clean up
```bash
cd web/default
cd web
node scripts/add-missing-keys.mjs # apply translations
node scripts/find-missing-keys.mjs # verify: should say "All t() keys found"
bun run i18n:sync # normalize file order
@@ -285,6 +286,7 @@ Delete temporary scripts after completion.
|----------|------|-------|
| English | en | Base locale, key = value |
| Chinese | zh | Fallback locale, must be complete |
| Traditional Chinese | zh-TW | Use natural Traditional Chinese wording |
| French | fr | Many English cognates are valid (e.g., "Configuration") |
| Japanese | ja | Use katakana for technical loanwords |
| Russian | ru | Use formal register |
@@ -303,7 +305,7 @@ Delete temporary scripts after completion.
## Key Rules
1. All scripts run from `web/default/` directory
1. All scripts run from `web/` directory
2. Use `node scripts/xxx.mjs` (ESM format with top-level await)
3. Sort keys alphabetically when writing locale files
4. Always run `bun run i18n:sync` as the final step
+5 -5
View File
@@ -3,7 +3,7 @@ name: shadcn-ui
description: >-
Give the assistant project-aware shadcn/ui context: components.json,
composition patterns, CLI, registries, theming, and MCP. Use when working on
web/default UI, shadcn components, or presets. Overview aligns with
web UI, shadcn components, or presets. Overview aligns with
https://ui.shadcn.com/docs/skills.md; full upstream skill text is vendored
under vendor/shadcn/.
---
@@ -37,7 +37,7 @@ npx skills add shadcn/ui
That installs the skill where the `skills` CLI is available. **This repository** keeps the same intent under `.agents/skills/shadcn-ui/` (overview here + **vendored** upstream docs in [`vendor/shadcn/`](./vendor/shadcn/)) and runs the shadcn CLI from the frontend app root:
```bash
cd web/default && bunx shadcn@latest info --json
cd web && bunx shadcn@latest info --json
```
Learn more about skills at [skills.sh](https://skills.sh).
@@ -48,7 +48,7 @@ Learn more about skills at [skills.sh](https://skills.sh).
### Project context
Run **`shadcn info --json`** (here: `cd web/default && bunx shadcn@latest info --json`) for framework, Tailwind version, aliases, base (`radix` | `base`), icon library, installed components, and resolved paths.
Run **`shadcn info --json`** (here: `cd web && bunx shadcn@latest info --json`) for framework, Tailwind version, aliases, base (`radix` | `base`), icon library, installed components, and resolved paths.
### CLI commands
@@ -70,7 +70,7 @@ Vendored: [`vendor/shadcn/mcp.md`](./vendor/shadcn/mcp.md). Live docs: [MCP Serv
## How it works
1. **Project detection** — Applies when `components.json` exists (here: `web/default/components.json`).
1. **Project detection** — Applies when `components.json` exists (here: `web/components.json`).
2. **Context injection** — Use `shadcn info --json` as ground truth for imports and APIs.
3. **Pattern enforcement** — Use [`vendor/shadcn/rules/`](./vendor/shadcn/rules/) for concrete markup checks; the complete official workflow reference is listed below for deeper CLI, registry, and preset questions.
4. **Component discovery**`shadcn docs`, `shadcn search`, MCP, or registries — see the official workflow reference and MCP doc when deeper context is needed.
@@ -102,4 +102,4 @@ Snapshot from [shadcn-ui/ui `skills/shadcn`](https://github.com/shadcn-ui/ui/tre
| Styling | [`vendor/shadcn/rules/styling.md`](./vendor/shadcn/rules/styling.md) |
| Base vs Radix | [`vendor/shadcn/rules/base-vs-radix.md`](./vendor/shadcn/rules/base-vs-radix.md) |
**Workflow:** Prefer this **root** `SKILL.md` for repo paths (`web/default`, Bun). Read **`vendor/shadcn/official-shadcn-ui-workflow.md`** only when you need the complete official component, registry, or preset workflow. Use **`vendor/shadcn/rules/*.md`** when validating concrete markup.
**Workflow:** Prefer this **root** `SKILL.md` for repo paths (`web`, Bun). Read **`vendor/shadcn/official-shadcn-ui-workflow.md`** only when you need the complete official component, registry, or preset workflow. Use **`vendor/shadcn/rules/*.md`** when validating concrete markup.