[AZ-486] F7 endpoint builders + STC-ARCH-02 (cycle 1 close)

Single source of truth for every /api/<service>/... URL the UI talks to:
src/api/endpoints.ts (25 typed builders) re-exported via the F4 barrel.
Migrates 13 production callsites in admin / annotations / flights /
settings / dataset / auth / api-client / FlightContext / DetectionClasses
to endpoints.* . Adds the STC-ARCH-02 static gate (--mode=api-literals
in scripts/check-arch-imports.mjs, wired into scripts/run-tests.sh)
that fails any new hardcoded /api/<service>/ literal in src/ outside
endpoints.ts and *.test.tsx? files.

Tests: +36 contract assertions in src/api/endpoints.test.ts (every
builder, character-identical), +6 STC-ARCH-02 architecture cases in
tests/architecture_imports.test.ts (single / double / template literal
fail paths, *.test.* exemption, line-comment skip, migrated codebase
pass). Fast profile 167 -> 209 PASS / 13 SKIP / 0 FAIL, +42 new,
0 regressions. Static profile 31 / 31 PASS.

Closes architecture baseline finding F7. Cycle 1 of Phase B closed.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Oleksandr Bezdieniezhnykh
2026-05-11 23:03:45 +03:00
parent 23746ec61d
commit 8a461a2051
23 changed files with 777 additions and 127 deletions
+4 -4
View File
@@ -1,5 +1,5 @@
import { createContext, useContext, useState, useCallback, useEffect, type ReactNode } from 'react'
import { api, setToken } from '../api'
import { api, endpoints, setToken } from '../api'
import type { AuthUser } from '../types'
interface AuthState {
@@ -21,7 +21,7 @@ export function AuthProvider({ children }: { children: ReactNode }) {
const [loading, setLoading] = useState(true)
useEffect(() => {
api.get<{ user: AuthUser; token: string }>('/api/admin/auth/refresh')
api.get<{ user: AuthUser; token: string }>(endpoints.admin.authRefresh())
.then(data => {
setToken(data.token)
setUser(data.user)
@@ -31,13 +31,13 @@ export function AuthProvider({ children }: { children: ReactNode }) {
}, [])
const login = useCallback(async (email: string, password: string) => {
const data = await api.post<{ token: string; user: AuthUser }>('/api/admin/auth/login', { email, password })
const data = await api.post<{ token: string; user: AuthUser }>(endpoints.admin.authLogin(), { email, password })
setToken(data.token)
setUser(data.user)
}, [])
const logout = useCallback(async () => {
try { await api.post('/api/admin/auth/logout') } catch {}
try { await api.post(endpoints.admin.authLogout()) } catch {}
setToken(null)
setUser(null)
}, [])