From 20c9e5ffebaacf747b375964fe6f15fb5750845a Mon Sep 17 00:00:00 2001 From: xiong Date: Mon, 3 Aug 2026 12:26:09 +0800 Subject: [PATCH] refactor(api): migrate to audience-scoped routes --- README.md | 14 +++++++------- src/api/authApi.ts | 6 +++--- src/api/backofficeApi.ts | 2 +- src/api/onboardingApi.ts | 2 +- src/api/runtimeApi.ts | 2 +- src/api/siteConfigApi.ts | 6 +++--- src/mocks/handlers.ts | 18 +++++++++--------- 7 files changed, 25 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index a112f8e..aa7b4ec 100644 --- a/README.md +++ b/README.md @@ -42,18 +42,18 @@ VITE_DEV_API_TARGET=http://localhost:5090 | `/manage/*` | 必须通过租户 Backoffice Bootstrap;无 Permission 的账号统一显示 404 | | `/__demo` | 仅开发环境存在的生命周期启动器 | -后台菜单来自 `GET /api/backoffice/tenant/ui-bootstrap`。进入站点设计还必须包含 `tenant:settings:manage`,前端隐藏菜单不能替代后端 401/403。 +后台菜单来自 `GET /api/tenant/access/ui-bootstrap`。进入站点设计还必须包含 `tenant:settings:manage`,前端隐藏菜单不能替代后端 401/403。 ## 前后端契约 当前前端 Facade 对齐以下接口: -- `GET /api/runtime/bootstrap` -- `POST /api/browser-auth/activation/complete` -- `POST /api/browser-auth/login/password` -- `GET /api/backoffice/tenant/ui-bootstrap` -- `GET /api/tenant-onboarding/status` -- `GET|PUT|POST /api/tenant-admin/frontend-config/**` +- `GET /api/public/runtime/bootstrap` +- `POST /api/tenant/auth/browser/activation/complete` +- `POST /api/tenant/auth/browser/login/password` +- `GET /api/tenant/access/ui-bootstrap` +- `GET /api/tenant/onboarding/status` +- `GET|PUT|POST /api/tenant/frontend-config/**` Browser Auth 激活接口会在完成密码设置后签发 HttpOnly Session Cookie;后续写请求从 `__Host-tiku-csrf` Cookie 读取双提交 Token,并发送 `X-CSRF-Token`。 diff --git a/src/api/authApi.ts b/src/api/authApi.ts index 5973c7f..8c98ec0 100644 --- a/src/api/authApi.ts +++ b/src/api/authApi.ts @@ -3,13 +3,13 @@ import { apiRequest } from './http'; export const authApi = { completeOwnerActivation: (request: BrowserOwnerActivationRequest) => - apiRequest('/api/browser-auth/activation/complete', { + apiRequest('/api/tenant/auth/browser/activation/complete', { method: 'POST', body: JSON.stringify(request), }), - login: (request: LoginRequest) => apiRequest('/api/browser-auth/login/password', { + login: (request: LoginRequest) => apiRequest('/api/tenant/auth/browser/login/password', { method: 'POST', body: JSON.stringify({ ...request, realm: 'Tenant' }), }), - logout: () => apiRequest('/api/browser-auth/logout', { method: 'POST' }), + logout: () => apiRequest('/api/tenant/auth/browser/logout', { method: 'POST' }), }; diff --git a/src/api/backofficeApi.ts b/src/api/backofficeApi.ts index 3f3bd58..1c4e56f 100644 --- a/src/api/backofficeApi.ts +++ b/src/api/backofficeApi.ts @@ -19,7 +19,7 @@ const supportedMenuRoutes: Record => { - const response = await apiRequest('/api/backoffice/tenant/ui-bootstrap'); + const response = await apiRequest('/api/tenant/access/ui-bootstrap'); return { permissions: response.permissionCodes, enabledFeatures: response.enabledFeatures, diff --git a/src/api/onboardingApi.ts b/src/api/onboardingApi.ts index 9acf939..548421f 100644 --- a/src/api/onboardingApi.ts +++ b/src/api/onboardingApi.ts @@ -2,5 +2,5 @@ import type { TenantOnboardingStatus } from '../contracts'; import { apiRequest } from './http'; export const onboardingApi = { - status: () => apiRequest('/api/tenant-onboarding/status'), + status: () => apiRequest('/api/tenant/onboarding/status'), }; diff --git a/src/api/runtimeApi.ts b/src/api/runtimeApi.ts index 1e93508..b738a2d 100644 --- a/src/api/runtimeApi.ts +++ b/src/api/runtimeApi.ts @@ -2,5 +2,5 @@ import type { TenantRuntimeBootstrap } from '../contracts'; import { apiRequest } from './http'; export const runtimeApi = { - bootstrap: () => apiRequest('/api/runtime/bootstrap'), + bootstrap: () => apiRequest('/api/public/runtime/bootstrap'), }; diff --git a/src/api/siteConfigApi.ts b/src/api/siteConfigApi.ts index 63a0127..0eb85b9 100644 --- a/src/api/siteConfigApi.ts +++ b/src/api/siteConfigApi.ts @@ -2,14 +2,14 @@ import type { TenantFrontendConfigDraft, TenantSiteConfig } from '../contracts'; import { apiRequest } from './http'; export const siteConfigApi = { - get: () => apiRequest('/api/tenant-admin/frontend-config'), + get: () => apiRequest('/api/tenant/frontend-config'), saveDraft: (draft: TenantFrontendConfigDraft) => - apiRequest('/api/tenant-admin/frontend-config/draft', { + apiRequest('/api/tenant/frontend-config/draft', { method: 'PUT', body: JSON.stringify(draft), }), publish: (expectedVersion: number) => - apiRequest('/api/tenant-admin/frontend-config/publish', { + apiRequest('/api/tenant/frontend-config/publish', { method: 'POST', body: JSON.stringify({ expectedVersion }), }), diff --git a/src/mocks/handlers.ts b/src/mocks/handlers.ts index fd9e5f6..a0a9e93 100644 --- a/src/mocks/handlers.ts +++ b/src/mocks/handlers.ts @@ -23,9 +23,9 @@ function problem(error: unknown) { } export const handlers = [ - http.get('/api/runtime/bootstrap', ({ request }) => HttpResponse.json(runtimeOf(ensureTenant(hostOf(request))))), + http.get('/api/public/runtime/bootstrap', ({ request }) => HttpResponse.json(runtimeOf(ensureTenant(hostOf(request))))), - http.post('/api/browser-auth/activation/complete', async ({ request }) => { + http.post('/api/tenant/auth/browser/activation/complete', async ({ request }) => { try { const body = await request.json() as BrowserOwnerActivationRequest; return HttpResponse.json({ status: 'Authenticated', user: activateOwner(hostOf(request), body) }); @@ -34,7 +34,7 @@ export const handlers = [ } }), - http.post('/api/browser-auth/login/password', async ({ request }) => { + http.post('/api/tenant/auth/browser/login/password', async ({ request }) => { const host = hostOf(request); const body = await request.json() as LoginRequest; const state = ensureTenant(host); @@ -50,12 +50,12 @@ export const handlers = [ return HttpResponse.json({ status: 'Authenticated', user: next.session!.user }); }), - http.post('/api/browser-auth/logout', ({ request }) => { + http.post('/api/tenant/auth/browser/logout', ({ request }) => { updateTenant(hostOf(request), state => { state.session = null; }); return new HttpResponse(null, { status: 204 }); }), - http.get('/api/backoffice/tenant/ui-bootstrap', ({ request }) => { + http.get('/api/tenant/access/ui-bootstrap', ({ request }) => { try { const bootstrap = backofficeOf(ensureTenant(hostOf(request))); return HttpResponse.json({ @@ -73,7 +73,7 @@ export const handlers = [ } }), - http.get('/api/tenant-onboarding/status', ({ request }) => { + http.get('/api/tenant/onboarding/status', ({ request }) => { try { const state = ensureTenant(hostOf(request)); backofficeOf(state); @@ -83,7 +83,7 @@ export const handlers = [ } }), - http.get('/api/tenant-admin/frontend-config', ({ request }) => { + http.get('/api/tenant/frontend-config', ({ request }) => { try { const state = ensureTenant(hostOf(request)); const bootstrap = backofficeOf(state); @@ -94,7 +94,7 @@ export const handlers = [ } }), - http.put('/api/tenant-admin/frontend-config/draft', async ({ request }) => { + http.put('/api/tenant/frontend-config/draft', async ({ request }) => { try { const host = hostOf(request); const state = ensureTenant(host); @@ -108,7 +108,7 @@ export const handlers = [ } }), - http.post('/api/tenant-admin/frontend-config/publish', async ({ request }) => { + http.post('/api/tenant/frontend-config/publish', async ({ request }) => { try { const host = hostOf(request); const state = ensureTenant(host);