refactor(api): migrate to audience-scoped routes

This commit is contained in:
2026-08-03 12:26:09 +08:00
parent d326d7c1bb
commit 20c9e5ffeb
7 changed files with 25 additions and 25 deletions

View File

@@ -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`

View File

@@ -3,13 +3,13 @@ import { apiRequest } from './http';
export const authApi = {
completeOwnerActivation: (request: BrowserOwnerActivationRequest) =>
apiRequest<BrowserAuthenticationResult>('/api/browser-auth/activation/complete', {
apiRequest<BrowserAuthenticationResult>('/api/tenant/auth/browser/activation/complete', {
method: 'POST',
body: JSON.stringify(request),
}),
login: (request: LoginRequest) => apiRequest<BrowserAuthenticationResult>('/api/browser-auth/login/password', {
login: (request: LoginRequest) => apiRequest<BrowserAuthenticationResult>('/api/tenant/auth/browser/login/password', {
method: 'POST',
body: JSON.stringify({ ...request, realm: 'Tenant' }),
}),
logout: () => apiRequest<void>('/api/browser-auth/logout', { method: 'POST' }),
logout: () => apiRequest<void>('/api/tenant/auth/browser/logout', { method: 'POST' }),
};

View File

@@ -19,7 +19,7 @@ const supportedMenuRoutes: Record<string, { path: string; requiresSiteSettings?:
export const backofficeApi = {
bootstrap: async (): Promise<BackofficeBootstrap> => {
const response = await apiRequest<BackofficeUiBootstrapResponse>('/api/backoffice/tenant/ui-bootstrap');
const response = await apiRequest<BackofficeUiBootstrapResponse>('/api/tenant/access/ui-bootstrap');
return {
permissions: response.permissionCodes,
enabledFeatures: response.enabledFeatures,

View File

@@ -2,5 +2,5 @@ import type { TenantOnboardingStatus } from '../contracts';
import { apiRequest } from './http';
export const onboardingApi = {
status: () => apiRequest<TenantOnboardingStatus>('/api/tenant-onboarding/status'),
status: () => apiRequest<TenantOnboardingStatus>('/api/tenant/onboarding/status'),
};

View File

@@ -2,5 +2,5 @@ import type { TenantRuntimeBootstrap } from '../contracts';
import { apiRequest } from './http';
export const runtimeApi = {
bootstrap: () => apiRequest<TenantRuntimeBootstrap>('/api/runtime/bootstrap'),
bootstrap: () => apiRequest<TenantRuntimeBootstrap>('/api/public/runtime/bootstrap'),
};

View File

@@ -2,14 +2,14 @@ import type { TenantFrontendConfigDraft, TenantSiteConfig } from '../contracts';
import { apiRequest } from './http';
export const siteConfigApi = {
get: () => apiRequest<TenantSiteConfig>('/api/tenant-admin/frontend-config'),
get: () => apiRequest<TenantSiteConfig>('/api/tenant/frontend-config'),
saveDraft: (draft: TenantFrontendConfigDraft) =>
apiRequest<TenantSiteConfig>('/api/tenant-admin/frontend-config/draft', {
apiRequest<TenantSiteConfig>('/api/tenant/frontend-config/draft', {
method: 'PUT',
body: JSON.stringify(draft),
}),
publish: (expectedVersion: number) =>
apiRequest<TenantSiteConfig>('/api/tenant-admin/frontend-config/publish', {
apiRequest<TenantSiteConfig>('/api/tenant/frontend-config/publish', {
method: 'POST',
body: JSON.stringify({ expectedVersion }),
}),

View File

@@ -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);