OpenVolleyScout is organized by application layer and feature area.
The application version and metadata are exported from:
src/lib/constants/app.tssrc/app/config/app-info.ts
src/app/src/components/src/domain/src/features/src/i18n/src/infrastructure/src/lib/src/styles/
Application-wide composition and navigation.
Important files:
components/AppNavigation.tsx- shared navigation.components/UpdateChecker.tsx- Tauri updater check/download UI.layout/AppShell.tsx- standard and compact scouting shells.layout/OrientationGuard.tsx- portrait guard used by selected scouting stages.providers/AppProviders.tsx- provider composition.router/AppRouter.tsx- hash-route definitions.store/app-store.ts- active match project store.
Use this layer for app composition, not feature-specific business logic.
Shared UI components that are not owned by a single feature.
Current example:
layout/AppPageLayout.tsx
Keep this folder small. Prefer feature-local components unless a component is clearly shared.
Pure TypeScript domain models and helpers.
Examples:
match/team/roster/events/scouting/lineup/spatial/systems/tactical/
Rules:
- keep domain helpers pure where possible
- avoid React imports
- avoid direct Dexie/browser storage access
- add domain types before embedding new concepts into JSX state
User-facing workflows and route-level screens.
Current feature areas:
analysisexportimportlandingteamsstartupscoutingsystems
Typical structure:
pages/for route-level componentscomponents/for feature UI piecesmodel/for feature-local state, derived logic, and workflow helpershooks/for feature-specific hooks
Not every feature has every subfolder yet.
Persistence and repository boundaries.
Important folders:
db/- Dexie database setup.storage/- low-level IndexedDB/localStorage access.repositories/- feature-facing wrappers with cloning and error handling.
Feature code should prefer repository wrappers when they exist.
Locale and translation support.
Current responsibilities:
- supported locale list
- browser-locale detection
- locale persistence in
localStorage - translation dictionaries for Italian, English, German, Slovenian, Chinese, and Turkish
I18nProvideruseTranslation
Shared helpers that do not fit cleanly into one feature or domain area.
Current examples:
- application constants
- roster validation
- match-readiness validation
- player-code generation utilities
- sequential Enter-key navigation hook
Global CSS and app-wide styling.
Feature-specific styles currently also exist next to features when needed, such
as src/features/scouting/scouting-screen.css.
Use this order of preference:
- Domain types/helpers in
src/domain/for business concepts. - Storage/repository code in
src/infrastructure/for persistence. - Feature pages/components/model code under
src/features/<feature>/. - Shared utilities in
src/lib/only when they are genuinely cross-feature. - App composition changes in
src/app/only when routing, providers, shells, or global stores change.
Some route-level files still do significant orchestration:
src/features/startup/pages/MatchSetupPage.tsxsrc/features/teams/pages/TeamsPage.tsxsrc/features/scouting/pages/ScoutingPage.tsxsrc/features/analysis/video/VideoAnalysisPanel.tsxsrc/features/analysis/video/MultiVideoAnalysisPanel.tsx
When adding behavior in these areas, prefer extracting:
- pure transformations into
domain/or featuremodel/ - persistence calls into repositories/storage
- interaction state into hooks
- repeated UI into feature components
- Match setup is the boundary between archived data and match-specific data.
- Scouting is event/replay-oriented and persists through the active project.
- Analysis derives reports and dashboards from
MatchProject.eventsandbuildMatchStats(). - Video analysis lives under
src/features/analysis/video/; it persists source references and sync points in the match project, while local file handles are managed separately. - Team-level data study lives under
src/features/teams/; it aggregates saved matches into an existingMatchStatsshape instead of introducing a parallel analytics model. - Systems currently split editor-specific reception/defense block libraries from generic tactical-system definitions.