From: root Date: Thu, 20 Aug 2026 04:24:45 +0000 (+0800) Subject: feat(v2): 建立 v2 隔离分支基线 — /v2 路径部署、独立 DB(bcd_v2.db)、独立 IndexedDB/token/SW 作用域 X-Git-Url: http://acesimba.cloud/gitweb/?a=commitdiff_plain;h=6c4ead2d4282a5bcf4342a2cf7a4d4e23be1db3c;p=words.git feat(v2): 建立 v2 隔离分支基线 — /v2 路径部署、独立 DB(bcd_v2.db)、独立 IndexedDB/token/SW 作用域 --- diff --git a/.gitignore b/.gitignore index aabb8b3..27c2004 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,7 @@ backend/db/tts_cache/ # certbot 一次性 DNS 挑战值(临时文件,不入库) deploy/dns-txt-value.txt + +# v2 隔离部署产物(不入库) +frontend/build-v2/ +backend/db/bcd_v2.db diff --git a/backend/main.py b/backend/main.py index 4646339..346102e 100644 --- a/backend/main.py +++ b/backend/main.py @@ -38,9 +38,12 @@ async def auth_guard(request: Request, call_next): # --- 路径自动修复逻辑 --- BASE_DIR = os.path.dirname(os.path.abspath(__file__)) -DATABASE_PATH = os.path.join(BASE_DIR, "a", "bcd.db") -if not os.path.exists(DATABASE_PATH): - DATABASE_PATH = os.path.join(BASE_DIR, "db", "bcd.db") +# v2 等隔离部署可通过环境变量 WORDS_DB_PATH 指向独立数据库文件 +DATABASE_PATH = os.environ.get("WORDS_DB_PATH") +if not DATABASE_PATH: + DATABASE_PATH = os.path.join(BASE_DIR, "a", "bcd.db") + if not os.path.exists(DATABASE_PATH): + DATABASE_PATH = os.path.join(BASE_DIR, "db", "bcd.db") # --- 简单登录鉴权(单用户;账密可用环境变量覆盖,默认 Simba / Simba+0322)--- # 前端登录后持 token;所有 /api/*(除登录接口)必须带有效 token,否则 401。 diff --git a/frontend/.env.production b/frontend/.env.production index d72a602..82f5e3b 100644 --- a/frontend/.env.production +++ b/frontend/.env.production @@ -1 +1 @@ -REACT_APP_API_BASE= +REACT_APP_API_BASE=/v2 diff --git a/frontend/src/App.js b/frontend/src/App.js index d17f71d..94a6c4e 100644 --- a/frontend/src/App.js +++ b/frontend/src/App.js @@ -15,7 +15,7 @@ function App() { return (
{loggedIn ? ( - + } /> diff --git a/frontend/src/api.js b/frontend/src/api.js index 911d1dd..0f4656b 100644 --- a/frontend/src/api.js +++ b/frontend/src/api.js @@ -24,7 +24,7 @@ http.interceptors.response.use( (err) => { if (err.response && err.response.status === 401) { clearToken(); - window.location.href = '/'; + window.location.href = '/v2/'; } return Promise.reject(err); } diff --git a/frontend/src/auth.js b/frontend/src/auth.js index 4a4bcf0..1470cf4 100644 --- a/frontend/src/auth.js +++ b/frontend/src/auth.js @@ -2,7 +2,7 @@ // 后端在 main.py 校验账密并签发 HMAC token;所有 /api/* 需携带该 token。 import { API_BASE } from './api'; -const TOKEN_KEY = 'words_auth_token'; +const TOKEN_KEY = 'words_auth_token_v2'; export function getToken() { return localStorage.getItem(TOKEN_KEY) || ''; diff --git a/frontend/src/db.js b/frontend/src/db.js index a3603ec..163f44d 100644 --- a/frontend/src/db.js +++ b/frontend/src/db.js @@ -4,7 +4,7 @@ // - progress: 离线进度, keyPath=`${group_id}:${op_type}`, {key, group_id, op_type, completed_at, dirty} // - meta: 元数据, keyPath=key (lastSyncAt, learnableGroups[]) -const DB_NAME = 'words-pwa'; +const DB_NAME = 'words-pwa-v2'; const DB_VERSION = 1; let dbPromise = null; diff --git a/frontend/src/index.js b/frontend/src/index.js index 2b8b867..0417c4a 100644 --- a/frontend/src/index.js +++ b/frontend/src/index.js @@ -20,7 +20,7 @@ reportWebVitals(); // 注册 Service Worker (PWA 离线支持) if ('serviceWorker' in navigator) { window.addEventListener('load', () => { - navigator.serviceWorker.register('/sw.js').catch(err => console.error('SW registration failed:', err)); + navigator.serviceWorker.register('/v2/sw.js').catch(err => console.error('SW registration failed:', err)); // SW 接管页面后, 再触发一次同步+预取, 确保预取请求被 SW 拦截并写入缓存 navigator.serviceWorker.ready.then(() => { if (isLoggedIn()) {