10 KiB
10 KiB
Codebase Structure
Analysis Date: 2026-03-16
Directory Layout
SimpleFinanceDash/
├── src/ # All application source code
│ ├── main.tsx # React 19 app entry point with providers
│ ├── App.tsx # Route configuration and guards
│ ├── index.css # Global Tailwind styles
│ ├── pages/ # Page components (routed views)
│ ├── components/ # Reusable and layout components
│ │ └── ui/ # Shadcn/Radix UI primitives (16 components)
│ ├── hooks/ # Custom data-fetching hooks (TanStack Query)
│ ├── lib/ # Utilities, types, configuration
│ └── i18n/ # Internationalization setup and resources
├── supabase/ # Supabase project files
│ └── migrations/ # Database schema migrations
├── public/ # Static assets
├── index.html # HTML entry point for Vite
├── package.json # Dependencies and build scripts
├── vite.config.ts # Vite bundler configuration
├── tsconfig.json # TypeScript base configuration
├── tsconfig.app.json # App-specific TypeScript config
├── tsconfig.node.json # Build script TypeScript config
├── eslint.config.js # ESLint configuration
├── components.json # Shadcn CLI component registry
├── .env.example # Example environment variables template
└── .gitignore # Git ignore rules
Directory Purposes
src/pages/:
- Purpose: Page-level components that correspond to routes in App.tsx
- Contains: 9 page components (all .tsx)
- Key files:
DashboardPage.tsx(316 lines) - Monthly budget dashboard with chartsBudgetDetailPage.tsx(555 lines) - Detailed budget editing and item managementTemplatePage.tsx(459 lines) - Monthly budget template editorBudgetListPage.tsx(261 lines) - List of all budgets with quick actionsCategoriesPage.tsx(214 lines) - Category management (CRUD)QuickAddPage.tsx(202 lines) - Quick-add library editorSettingsPage.tsx(125 lines) - User preferencesLoginPage.tsx(107 lines) - Email/password and OAuth loginRegisterPage.tsx(81 lines) - User registration form
Each page follows pattern:
- Imports hooks at top
- Calls hooks in component body
- Renders UI from state
- Delegates complex logic to sub-components
src/components/:
- Purpose: Reusable UI components and layout wrappers
- Contains: Custom components + UI library primitives
- Key files:
AppLayout.tsx- Sidebar wrapper for authenticated pagesQuickAddPicker.tsx- Multi-modal quick-add workflow componentui/- 16 Shadcn-based components (Button, Dialog, Select, Table, etc.)
src/hooks/:
- Purpose: Encapsulate all server communication and state queries
- Contains: 6 custom hooks
- Key files:
useAuth.ts- Session management and auth operations (signUp, signIn, signOut)useBudgets.ts- Budget CRUD, item management, template generationuseCategories.ts- Category CRUD operationsuseTemplate.ts- Monthly budget template managementuseQuickAdd.ts- Quick-add item library CRUDuse-mobile.ts- Responsive breakpoint detection utility
Each hook:
- Defines typed query keys as const arrays
- Initializes useQuery/useMutation from TanStack Query
- Returns { data, loading, ...mutations }
- Implements onSuccess cache invalidation
src/lib/:
- Purpose: Core utilities, types, and configuration
- Contains: 5 files
- Key files:
types.ts- TypeScript interfaces: Profile, Category, Budget, BudgetItem, Template, TemplateItem, QuickAddItemsupabase.ts- Supabase client creation with environment validationpalette.ts- Category color constants (CSS variables) and labels (en/de)format.ts- Currency formatting with Intl.NumberFormat APIutils.ts- General helpers (like cn for class merging)
src/i18n/:
- Purpose: Internationalization setup and resource files
- Contains:
index.tsand JSON translation files - Key files:
index.ts- i18next initialization with react-i18next bindingsen.json- English translation strings (namespaced by feature)de.json- German translation strings
- Initialized at app startup before any React render
- Provides
useTranslation()hook for all components
src/components/ui/:
- Purpose: Unstyled, accessible UI primitives from Shadcn and Radix UI
- Contains: 16 files of component exports
- Includes: Badge, Button, Card, Dialog, Dropdown Menu, Input, Label, Popover, Select, Separator, Sheet, Sidebar, Skeleton, Table, Tooltip, Sonner Toast wrapper
- Pattern: Each wraps Radix primitive with Tailwind styling
- Do NOT modify these files — regenerate via Shadcn CLI if needed
Key File Locations
Entry Points:
src/main.tsx- DOM mount point, providers initializationsrc/App.tsx- Route definitions and authentication guardsindex.html- Vite HTML template with root div
Configuration:
vite.config.ts- Build tooling (React plugin, Tailwind vite plugin, @ alias)tsconfig.json- Base TS config with @ path aliaseslint.config.js- Linting rulescomponents.json- Shadcn CLI registrypackage.json- Dependencies: react@19, react-router-dom@7, @tanstack/react-query@5, @supabase/supabase-js@2, i18next, lucide-react, recharts, tailwindcss@4, sonner
Core Logic:
src/hooks/useBudgets.ts- Largest hook (369 lines) with factory pattern for detail queriessrc/hooks/useTemplate.ts- Template mutations with sort_order managementsrc/lib/types.ts- Single source of truth for domain typessrc/lib/supabase.ts- Client configuration (2 lines of config + validation)
Testing:
- No test files present (no
*.test.ts,*.spec.ts) - No jest.config.js or vitest.config.ts
Naming Conventions
Files:
- Pages: PascalCase with "Page" suffix (
DashboardPage.tsx) - Hooks: camelCase with "use" prefix (
useAuth.ts,useBudgets.ts) - Components: PascalCase (
AppLayout.tsx,QuickAddPicker.tsx) - Utilities: camelCase descriptive (
format.ts,palette.ts) - Types: camelCase file, PascalCase exports (
types.tsexportsinterface Budget) - UI components: kebab-case file, PascalCase export (
card.tsxexportsCard)
Directories:
- Feature folders: lowercase plural (
src/hooks/,src/pages/,src/components/) - UI library:
ui/subfolder under components
Functions & Variables:
- Functions: camelCase (
formatCurrency,useBudgets) - Component functions: PascalCase (
DashboardPage,QuickAddPicker) - Constants: UPPER_SNAKE_CASE (
CATEGORY_TYPES,EXPENSE_TYPES) - Variables: camelCase (
budgetId,categoryId,isSaving)
Types:
- Interfaces: PascalCase (
Budget,BudgetItem) - Type unions: PascalCase (
CategoryType) - Props interfaces: PascalCase ending with "Props" (
QuickAddPickerProps)
Where to Add New Code
New Feature (e.g., Reports):
- Create page:
src/pages/ReportsPage.tsx - Create hook:
src/hooks/useReports.tswith query keys and mutations - Add types:
src/lib/types.ts- add new interfaces (Report, ReportItem) - Add route:
src/App.tsx- add Route element - Add nav link:
src/components/AppLayout.tsx- add to navItems array - Add i18n:
src/i18n/en.jsonandsrc/i18n/de.json- add new keys
New Component (e.g., CategoryBadge):
- If simple display component:
src/components/CategoryBadge.tsx - If UI primitive wrapper:
src/components/ui/category-badge.tsx(follow shadcn pattern) - Composition: Import from ui/ folder, layer styling via className
New Utility Function:
- General helpers:
src/lib/utils.ts - Domain-specific (e.g., budget math): Add to relevant hook file or create
src/lib/budgetHelpers.ts - Formatting logic:
src/lib/format.ts
New Hook:
- Data fetching:
src/hooks/useFeatureName.ts - Pattern: Export named function, define query keys, use useQuery/useMutation, return typed object
- Example structure from
useTemplate.ts:- Query keys at top (const)
- Helper functions (async functions)
- Main hook function with useQuery/useMutation setup
- Exposed API object return
Styling:
- Component styles: Tailwind className in JSX (no CSS files)
- Global styles:
src/index.css(imports Tailwind directives) - Color system: CSS variables in theme (Tailwind config)
- Category colors:
src/lib/palette.ts(maps to CSS var(--color-X))
Special Directories
src/components/ui/:
- Purpose: Shadcn registry of unstyled, accessible Radix UI components
- Generated: Via
npx shadcn-ui@latest add [component] - Committed: Yes (production code)
- Do NOT hand-edit — regenerate if Shadcn updates
public/:
- Purpose: Static assets (favicon, images, fonts)
- Generated: No
- Committed: Yes
- Served at root by Vite
supabase/migrations/:
- Purpose: Database schema as versioned SQL files
- Generated: Via Supabase CLI
- Committed: Yes (tracked via git)
- Applied: By
supabase db pushcommand
.env files:
- Purpose: Runtime configuration (Supabase URL, API key)
- Generated: Via
.env.exampletemplate - Committed: NO — in .gitignore
- Required for: Local dev and CI/CD
dist/:
- Purpose: Production bundle output
- Generated: Via
npm run build - Committed: No — in .gitignore
- Deployment: Upload contents to CDN or web server
Code Organization Principles
Vertical Slices:
- Feature → Page → Hook → Library
- Minimizes cross-feature coupling
- Easy to add/remove features
Co-location of Related Code:
- Page component near its hooks
- Query keys defined in same hook as queries
- Mutations and queries in same hook for domain entity
Type Safety:
- All Supabase queries cast return value to TypeScript type
- TanStack Query generic parameters:
useQuery<Type>()anduseMutation<Payload, Response>() - Props interfaces for all custom components
Consistent Hook Patterns:
- All data hooks follow: query setup → mutations setup → return typed object
- Mutations always have onSuccess cache invalidation
- Query keys are hierarchical arrays enabling granular invalidation
Structure analysis: 2026-03-16