mirror of
https://github.com/azaion/ui.git
synced 2026-06-21 10:51:11 +00:00
[AZ-485] Add Public API barrels + STC-ARCH-01 (F4 close)
Closes architecture baseline finding F4. Every component now exposes its Public API through `src/<component>/index.ts`; cross-component imports go through the barrel. `scripts/check-arch-imports.mjs` plus `STC-ARCH-01` in the static profile enforce the rule; tests in `tests/architecture_imports.test.ts` cover AC-4/AC-5 + 2 exemption cases. One F3-pending exemption (`classColors`) is documented in 5 places (barrel, consumer, script, doc, test) to avoid a circular import. Phase B cycle 1 batch 1 of 2 (epic AZ-447). Batch 2 is AZ-486 (endpoint builders) — blocked on this commit landing. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+8
-10
@@ -1,14 +1,12 @@
|
||||
import { Routes, Route, Navigate } from 'react-router-dom'
|
||||
import { AuthProvider } from './auth/AuthContext'
|
||||
import { FlightProvider } from './components/FlightContext'
|
||||
import ProtectedRoute from './auth/ProtectedRoute'
|
||||
import LoginPage from './features/login/LoginPage'
|
||||
import FlightsPage from './features/flights/FlightsPage'
|
||||
import AnnotationsPage from './features/annotations/AnnotationsPage'
|
||||
import DatasetPage from './features/dataset/DatasetPage'
|
||||
import AdminPage from './features/admin/AdminPage'
|
||||
import SettingsPage from './features/settings/SettingsPage'
|
||||
import Header from './components/Header'
|
||||
import { AuthProvider, ProtectedRoute } from './auth'
|
||||
import { Header, FlightProvider } from './components'
|
||||
import { LoginPage } from './features/login'
|
||||
import { FlightsPage } from './features/flights'
|
||||
import { AnnotationsPage } from './features/annotations'
|
||||
import { DatasetPage } from './features/dataset'
|
||||
import { AdminPage } from './features/admin'
|
||||
import { SettingsPage } from './features/settings'
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
export { api, setToken, getToken, getApiBase, setNavigateToLogin } from './client'
|
||||
export { createSSE } from './sse'
|
||||
@@ -3,7 +3,7 @@ import { http, HttpResponse } from 'msw'
|
||||
import { act, useRef } from 'react'
|
||||
import { server } from '../../tests/msw/server'
|
||||
import { renderWithProviders, screen, waitFor } from '../../tests/helpers/render'
|
||||
import { api, getToken, setToken } from '../api/client'
|
||||
import { api, getToken, setToken } from '../api'
|
||||
import { seedBearer, clearBearer } from '../../tests/helpers/auth'
|
||||
|
||||
// AZ-457 — Auth & token-handling at the React composition root.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { createContext, useContext, useState, useCallback, useEffect, type ReactNode } from 'react'
|
||||
import { api, setToken } from '../api/client'
|
||||
import { api, setToken } from '../api'
|
||||
import type { AuthUser } from '../types'
|
||||
|
||||
interface AuthState {
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
export { AuthProvider, useAuth } from './AuthContext'
|
||||
export { default as ProtectedRoute } from './ProtectedRoute'
|
||||
@@ -2,7 +2,11 @@ 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/client'
|
||||
import { api } 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).
|
||||
// STC-ARCH-01 exempts this single path as an F3-pending edge.
|
||||
import { getClassColor, FALLBACK_CLASS_NAMES } from '../features/annotations/classColors'
|
||||
import type { DetectionClass } from '../types'
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { createContext, useContext, useState, useEffect, useCallback, type ReactNode } from 'react'
|
||||
import { api } from '../api/client'
|
||||
import { api } from '../api'
|
||||
import type { Flight, UserSettings } from '../types'
|
||||
|
||||
interface FlightState {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { NavLink, useNavigate } from 'react-router-dom'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useAuth } from '../auth/AuthContext'
|
||||
import { useAuth } from '../auth'
|
||||
import { useFlight } from './FlightContext'
|
||||
import { useState, useRef, useEffect } from 'react'
|
||||
import HelpModal from './HelpModal'
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
export { default as Header } from './Header'
|
||||
export { default as HelpModal } from './HelpModal'
|
||||
export { default as ConfirmDialog } from './ConfirmDialog'
|
||||
export { default as DetectionClasses } from './DetectionClasses'
|
||||
export { FlightProvider, useFlight } from './FlightContext'
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { api } from '../../api/client'
|
||||
import ConfirmDialog from '../../components/ConfirmDialog'
|
||||
import { api } from '../../api'
|
||||
import { ConfirmDialog } from '../../components'
|
||||
import type { DetectionClass, Aircraft, User } from '../../types'
|
||||
|
||||
export default function AdminPage() {
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export { default as AdminPage } from './AdminPage'
|
||||
@@ -1,11 +1,11 @@
|
||||
import { useState, useCallback, useEffect, useRef } from 'react'
|
||||
import { useResizablePanel } from '../../hooks/useResizablePanel'
|
||||
import { api } from '../../api/client'
|
||||
import { useResizablePanel } from '../../hooks'
|
||||
import { api } from '../../api'
|
||||
import MediaList from './MediaList'
|
||||
import VideoPlayer, { type VideoPlayerHandle } from './VideoPlayer'
|
||||
import CanvasEditor, { type CanvasEditorHandle } from './CanvasEditor'
|
||||
import AnnotationsSidebar from './AnnotationsSidebar'
|
||||
import DetectionClasses from '../../components/DetectionClasses'
|
||||
import { DetectionClasses } from '../../components'
|
||||
import { AnnotationSource, AnnotationStatus, MediaType } from '../../types'
|
||||
import { getClassColor, getClassNameFallback, getPhotoModeSuffix } from './classColors'
|
||||
import type { Media, AnnotationListItem, Detection } from '../../types'
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { FaDownload } from 'react-icons/fa'
|
||||
import { api } from '../../api/client'
|
||||
import { createSSE } from '../../api/sse'
|
||||
import { api, createSSE } from '../../api'
|
||||
import { getClassColor } from './classColors'
|
||||
import type { Media, AnnotationListItem, PaginatedResponse } from '../../types'
|
||||
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { useState, useEffect, useCallback, useRef } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useDropzone } from 'react-dropzone'
|
||||
import { useFlight } from '../../components/FlightContext'
|
||||
import { api } from '../../api/client'
|
||||
import { useDebounce } from '../../hooks/useDebounce'
|
||||
import ConfirmDialog from '../../components/ConfirmDialog'
|
||||
import { useFlight, ConfirmDialog } from '../../components'
|
||||
import { api } from '../../api'
|
||||
import { useDebounce } from '../../hooks'
|
||||
import { MediaType } from '../../types'
|
||||
import type { Media, PaginatedResponse, AnnotationListItem } from '../../types'
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
export { default as AnnotationsPage } from './AnnotationsPage'
|
||||
// CanvasEditor remains in the Public API while F2 (cross-feature edge to
|
||||
// 07_dataset) is open. Closing F2 will remove this re-export.
|
||||
export { default as CanvasEditor } from './CanvasEditor'
|
||||
//
|
||||
// classColors symbols are NOT re-exported here. The file is logically owned
|
||||
// by 11_class-colors but lives under this directory until F3 moves it. Re-
|
||||
// exporting through this barrel creates a circular dependency
|
||||
// AnnotationsPage -> DetectionClasses -> 06_annotations barrel -> AnnotationsPage
|
||||
// because DetectionClasses (03_shared-ui) imports classColors. Consumers
|
||||
// import classColors directly via `src/features/annotations/classColors`
|
||||
// as a documented F3-pending exemption. STC-ARCH-01 carries the exemption.
|
||||
@@ -1,11 +1,8 @@
|
||||
import { useState, useEffect, useCallback } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { api } from '../../api/client'
|
||||
import { useDebounce } from '../../hooks/useDebounce'
|
||||
import { useResizablePanel } from '../../hooks/useResizablePanel'
|
||||
import { useFlight } from '../../components/FlightContext'
|
||||
import DetectionClasses from '../../components/DetectionClasses'
|
||||
import ConfirmDialog from '../../components/ConfirmDialog'
|
||||
import { api } from '../../api'
|
||||
import { useDebounce, useResizablePanel } from '../../hooks'
|
||||
import { useFlight, DetectionClasses, ConfirmDialog } from '../../components'
|
||||
import CanvasEditor from '../annotations/CanvasEditor'
|
||||
import type { DatasetItem, PaginatedResponse, ClassDistributionItem, AnnotationListItem, Detection, Media } from '../../types'
|
||||
import { AnnotationStatus } from '../../types'
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export { default as DatasetPage } from './DatasetPage'
|
||||
@@ -1,10 +1,8 @@
|
||||
import { useState, useEffect, useCallback } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import L from 'leaflet'
|
||||
import { useFlight } from '../../components/FlightContext'
|
||||
import { api } from '../../api/client'
|
||||
import { createSSE } from '../../api/sse'
|
||||
import ConfirmDialog from '../../components/ConfirmDialog'
|
||||
import { useFlight, ConfirmDialog } from '../../components'
|
||||
import { api, createSSE } from '../../api'
|
||||
import FlightListSidebar from './FlightListSidebar'
|
||||
import FlightParamsPanel from './FlightParamsPanel'
|
||||
import FlightMap from './FlightMap'
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export { default as FlightsPage } from './FlightsPage'
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useState, type FormEvent } from 'react'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useAuth } from '../../auth/AuthContext'
|
||||
import { useAuth } from '../../auth'
|
||||
|
||||
type UnlockStep = 'idle' | 'authenticating' | 'downloadingKey' | 'decrypting' | 'startingServices' | 'ready'
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export { default as LoginPage } from './LoginPage'
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { api } from '../../api/client'
|
||||
import { api } from '../../api'
|
||||
import type { SystemSettings, DirectorySettings, Aircraft } from '../../types'
|
||||
|
||||
export default function SettingsPage() {
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export { default as SettingsPage } from './SettingsPage'
|
||||
@@ -0,0 +1,2 @@
|
||||
export { useDebounce } from './useDebounce'
|
||||
export { useResizablePanel } from './useResizablePanel'
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from './i18n'
|
||||
+1
-1
@@ -2,7 +2,7 @@ import { StrictMode } from 'react'
|
||||
import { createRoot } from 'react-dom/client'
|
||||
import { BrowserRouter } from 'react-router-dom'
|
||||
import App from './App'
|
||||
import './i18n/i18n'
|
||||
import './i18n'
|
||||
import './index.css'
|
||||
|
||||
createRoot(document.getElementById('root')!).render(
|
||||
|
||||
Reference in New Issue
Block a user