mirror of
https://github.com/azaion/ui.git
synced 2026-06-21 11:21:10 +00:00
[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:
@@ -2,7 +2,7 @@ import { useEffect, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { MdOutlineWbSunny, MdOutlineNightlightRound } from 'react-icons/md'
|
||||
import { FaRegSnowflake } from 'react-icons/fa'
|
||||
import { api } from '../api'
|
||||
import { api, endpoints } from '../api'
|
||||
// classColors lives under 06_annotations until F3 moves it to its own home.
|
||||
// Importing through the 06_annotations barrel would create a cycle
|
||||
// (DetectionClasses -> 06_annotations barrel -> AnnotationsPage -> DetectionClasses).
|
||||
@@ -33,7 +33,7 @@ export default function DetectionClasses({ selectedClassNum, onSelect, photoMode
|
||||
const [classes, setClasses] = useState<DetectionClass[]>([])
|
||||
|
||||
useEffect(() => {
|
||||
api.get<DetectionClass[]>('/api/annotations/classes')
|
||||
api.get<DetectionClass[]>(endpoints.annotations.classes())
|
||||
.then(list => setClasses(list?.length ? list : FALLBACK_CLASSES))
|
||||
.catch(() => setClasses(FALLBACK_CLASSES))
|
||||
}, [])
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { createContext, useContext, useState, useEffect, useCallback, type ReactNode } from 'react'
|
||||
import { api } from '../api'
|
||||
import { api, endpoints } from '../api'
|
||||
import type { Flight, UserSettings } from '../types'
|
||||
|
||||
interface FlightState {
|
||||
@@ -21,17 +21,17 @@ export function FlightProvider({ children }: { children: ReactNode }) {
|
||||
|
||||
const refreshFlights = useCallback(async () => {
|
||||
try {
|
||||
const data = await api.get<{ items: Flight[] }>('/api/flights?pageSize=1000')
|
||||
const data = await api.get<{ items: Flight[] }>(endpoints.flights.collection('pageSize=1000'))
|
||||
setFlights(data.items ?? [])
|
||||
} catch {}
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
refreshFlights()
|
||||
api.get<UserSettings>('/api/annotations/settings/user')
|
||||
api.get<UserSettings>(endpoints.annotations.settingsUser())
|
||||
.then(settings => {
|
||||
if (settings?.selectedFlightId) {
|
||||
api.get<Flight>(`/api/flights/${settings.selectedFlightId}`)
|
||||
api.get<Flight>(endpoints.flights.flight(settings.selectedFlightId))
|
||||
.then(f => setSelectedFlight(f))
|
||||
.catch(() => {})
|
||||
}
|
||||
@@ -41,7 +41,7 @@ export function FlightProvider({ children }: { children: ReactNode }) {
|
||||
|
||||
const selectFlight = useCallback((f: Flight | null) => {
|
||||
setSelectedFlight(f)
|
||||
api.put('/api/annotations/settings/user', { selectedFlightId: f?.id ?? null }).catch(() => {})
|
||||
api.put(endpoints.annotations.settingsUser(), { selectedFlightId: f?.id ?? null }).catch(() => {})
|
||||
}, [])
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user