This document describes the codebase structure and conventions for maintainability and scale.
src/
├── core/ # App-wide constants and design system
│ ├── constants.ts # Magic numbers, storage keys, config
│ ├── theme.ts # Colors, spacing, typography, shadows
│ └── index.ts
├── navigation/ # Navigation setup and types
│ ├── types.ts # Typed param lists (RootStackParamList, etc.)
│ └── AppNavigator.tsx
├── context/ # React context (global state)
│ └── AppContext.tsx # Notes, folders, tags, reminders, filter
├── services/ # Platform & I/O (storage, notifications, voice, attachments)
│ ├── storage.ts # AsyncStorage persistence
│ ├── reminderService.ts
│ ├── voiceService.ts
│ ├── attachmentService.ts
│ └── audioRecordService.ts
├── components/ # Reusable UI components
│ ├── Icons.tsx
│ ├── RichNoteEditor.tsx
│ ├── AttachmentList.tsx
│ ├── SketchCanvas.tsx
│ ├── ErrorBoundary.tsx
│ ├── AppLoading.tsx
│ └── index.ts
├── screens/ # Full-screen views
│ ├── NoteListScreen.tsx
│ ├── NoteEditorScreen.tsx
│ ├── FoldersScreen.tsx
│ └── TagsScreen.tsx
├── types/ # TypeScript types and interfaces
│ └── index.ts
└── utils/ # Pure helpers
├── id.ts
└── stripHtml.ts
theme for styles.navigation/types.ts (RootStackParamList, NoteEditorParams).useNavigation<NavProp>() and useRoute<RouteProp>() in screens.navigation.getParent() to access the stack and navigate to stack screens.AppContext (notes, folders, tags, reminders, filter).isHydrated; app shows AppLoading until storage is loaded.storage service when it changes.Platform.OS === 'android' and optional require().core/constants.theme for all colors, spacing, and typography.components/index.ts for cleaner imports.ErrorBoundary wraps the app to catch render errors and show a fallback with retry.types/index.ts (Note, Folder, Tag, Reminder, etc.).any for navigation or domain data; use proper types or generics.AppProvider reads from storage → sets state and loaded = true → AppContent renders AppNavigator.NoteEditorScreen → local state → auto-save and on blur call updateNote / addNote from context → context updates state → storage.setNotes in useEffect.addReminder in context creates reminder and calls reminderService.scheduleTimeReminder (Notifee) on Android; reminder id and optional notifeeId stored in state and persisted.types/, service in services/ if needed, screen in screens/, register in navigator and (if needed) in context.core/constants.ts.core/theme.ts.useNoteEditor) in a hooks/ folder if a screen grows too large.