Skip to content

Project Structure

DiveSuite uses a feature-based folder structure (AD-10) rather than a layer-based structure. This keeps related code together and makes the codebase easier to navigate.

DiveSuite/
├── app/ # Expo Router file-based routes
│ ├── (tabs)/ # Tab layout group
│ │ ├── index.tsx # Plan tab (default)
│ │ ├── log.tsx # Log tab
│ │ ├── community.tsx # Community tab
│ │ ├── stats.tsx # Stats tab
│ │ └── profile.tsx # Profile tab
│ ├── _layout.tsx # Root layout
│ └── +not-found.tsx # 404 fallback
├── src/ # Application source code
│ ├── core/ # Shared core (no UI dependency)
│ │ ├── engine/ # Rust/WASM bridge + TypeScript types
│ │ ├── database/ # WatermelonDB
│ │ │ ├── schema/ # Table definitions
│ │ │ ├── migrations/ # Numbered migration files
│ │ │ └── repositories/ # One repository per entity
│ │ ├── models/ # Domain types (DiveLog, GasMix, etc.)
│ │ ├── services/ # Business logic services
│ │ ├── i18n/ # i18next config
│ │ │ └── locales/ # en.json, de.json
│ │ └── utils/ # Pure utility functions
│ │
│ ├── features/ # Feature modules
│ │ ├── planning/ # Dive planning feature
│ │ │ ├── screens/ # PlanScreen, PlanResultScreen
│ │ │ ├── components/ # GasMixSelector, DepthInput
│ │ │ └── hooks/ # useDivePlan, usePlanValidation
│ │ ├── logging/ # Dive logging feature
│ │ │ ├── screens/
│ │ │ ├── components/
│ │ │ └── hooks/
│ │ ├── analysis/ # Dive analysis feature
│ │ │ ├── screens/
│ │ │ ├── components/
│ │ │ └── hooks/
│ │ ├── community/ # Community & social features
│ │ │ ├── screens/
│ │ │ ├── components/
│ │ │ └── hooks/
│ │ ├── settings/ # Settings & profile
│ │ │ ├── screens/
│ │ │ ├── components/
│ │ │ └── hooks/
│ │ └── ai/ # AI services (embedded in other features)
│ │ ├── services/ # AIService implementation
│ │ ├── prompts/ # LLM prompt templates
│ │ └── components/ # AI-specific UI components
│ │
│ └── shared/ # Shared UI
│ ├── components/ # Button, Card, Input, etc.
│ ├── theme/ # Colors, typography, spacing
│ ├── hooks/ # useTheme, useAuth, etc.
│ └── navigation/ # Navigation utilities
├── rust-engine/ # Rust deco engine (separate crate)
│ ├── src/ # lib.rs, buhlmann.rs, gas.rs, types.rs
│ ├── tests/ # Integration tests
│ └── Cargo.toml
├── assets/ # Static assets
│ ├── images/
│ └── fonts/
├── docs-site/ # MkDocs documentation
├── docs/ # Product documentation (legacy, symlinked)
├── planning/ # Planning documents
├── architecture/ # Architecture documents
├── .github/
│ ├── workflows/ # CI/CD pipelines
│ ├── ISSUE_TEMPLATE/ # Bug report, feature request
│ └── PULL_REQUEST_TEMPLATE.md
├── .claude/ # Claude Code configuration
│ ├── commands/ # Custom slash commands
│ └── settings.json # Permission defaults
├── package.json # Node dependencies
├── tsconfig.json # TypeScript config
├── app.json # Expo config
├── mkdocs.yml # Documentation config
├── .editorconfig # Editor formatting
├── .nvmrc # Node version
├── .gitignore
├── CLAUDE.md # AI assistant instructions
└── AGENTS.md # Agent role definitions

Each feature follows the same internal structure:

features/planning/
├── screens/
│ ├── PlanScreen.tsx # Main planning screen
│ ├── PlanResultScreen.tsx # Plan output display
│ └── PlanHistoryScreen.tsx # Saved plans list
├── components/
│ ├── GasMixSelector.tsx # Gas mix input component
│ ├── DepthInput.tsx # Depth input with units
│ ├── PlanOutput.tsx # Plan result display
│ └── SafetyDisclaimer.tsx # Mandatory disclaimer
├── hooks/
│ ├── useDivePlan.ts # Plan state management
│ ├── usePlanValidation.ts # Input validation
│ └── usePlanHistory.ts # Saved plans access
└── index.ts # Public exports

Features should be self-contained. A feature can import from:

  • @core/ (models, services, utils)
  • @shared/ (UI components, theme, hooks)
  • Other features (creates coupling) — avoid this

Test files live next to their source:

hooks/
├── useDivePlan.ts
├── useDivePlan.test.ts # Co-located test
└── usePlanValidation.ts

Feature-specific types stay in the feature:

features/planning/
├── types.ts # PlanInput, PlanOutput, etc.
└── ...

Shared domain types go in @core/models/.

Each component file exports one component:

GasMixSelector.tsx
export function GasMixSelector() { ... }
// Bad: multiple components in one file
// GasComponents.tsx
// export function GasMixSelector() { ... }
// export function GasDisplay() { ... }

Use index.ts only at feature boundaries:

features/planning/index.ts
export { PlanScreen } from './screens/PlanScreen';
export { useDivePlan } from './hooks/useDivePlan';
// Only export what other features need
TypeConventionExample
ScreensPascalCasePlanScreen.tsx
ComponentsPascalCaseGasMixSelector.tsx
HookscamelCase with useuseDivePlan.ts
Serviceskebab-caseplanning-service.ts
Utilskebab-casegas-calculations.ts
Typeskebab-casedive-types.ts
Tests.test.ts suffixuseDivePlan.test.ts
// 1. React and React Native
import React, { useState } from 'react';
import { View, Text } from 'react-native';
// 2. Third-party libraries
import { useTranslation } from 'react-i18next';
// 3. Core imports (@core/)
import { DiveLog } from '@core/models/dive-log';
import { PlanningService } from '@core/services/planning-service';
// 4. Shared imports (@shared/)
import { Button, Card } from '@shared/components';
import { useTheme } from '@shared/hooks';
// 5. Feature imports (relative)
import { useDivePlan } from '../hooks/useDivePlan';
import { GasMixSelector } from '../components/GasMixSelector';