mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-16 17:19:40 +02:00
Adds the original NestJS backends (backend, audio-backend), Expo mobile app, and Astro landing page as-is from the standalone memoro repo. These are not yet migrated to monorepo standards (migration tracked in memory/CLAUDE.md). Also adds eslint.config.mjs ignore for apps/*/apps/audio-backend/** and .prettierignore entries for legacy memoro dirs. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
459 lines
16 KiB
Markdown
459 lines
16 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Repository Overview
|
|
|
|
Memoro is a monorepo containing an AI-powered voice recording and memo management application with two apps:
|
|
|
|
- **Mobile App** (`apps/mobile/`): React Native + Expo cross-platform app (iOS, Android, Web)
|
|
- **Web App** (`apps/web/`): SvelteKit companion web application
|
|
|
|
Both apps share the same Supabase backend.
|
|
|
|
## Development Commands
|
|
|
|
### Mobile App (`apps/mobile/`)
|
|
|
|
```bash
|
|
# Development
|
|
npm start # Start Expo dev server
|
|
npm run start:dev # Start with dev environment
|
|
npm run start:prod # Start with prod environment
|
|
npm run ios # Run on iOS simulator
|
|
npm run android # Run on Android emulator
|
|
npm run web # Run web version
|
|
npm run web:dev # Run web with dev environment
|
|
|
|
# Code Quality
|
|
npm run lint # Run ESLint and Prettier check
|
|
npm run lint:fix # Auto-fix linting issues
|
|
npm run lint:unused # Find unused imports/vars
|
|
npm run format # Format code with ESLint + Prettier
|
|
|
|
# Build & Deploy
|
|
npm run prebuild # Generate native projects
|
|
npm run rebuild # Clean rebuild (removes node_modules, ios/, android/)
|
|
npm run web:build # Build for web deployment
|
|
eas build --profile development # Development build
|
|
eas build --profile preview # Preview build
|
|
eas build --profile production # Production build
|
|
```
|
|
|
|
### Web App (`apps/web/`)
|
|
|
|
```bash
|
|
npm run dev # Start development server
|
|
npm run build # Build for production
|
|
npm run preview # Preview production build
|
|
npm run check # Run svelte-check
|
|
npm run check:watch # Watch mode for svelte-check
|
|
```
|
|
|
|
## Architecture
|
|
|
|
### Mobile App Architecture
|
|
|
|
**Framework Stack:**
|
|
- React Native 0.83.2 + Expo SDK 55
|
|
- Expo Router (file-based routing)
|
|
- TypeScript
|
|
- NativeWind (Tailwind CSS for React Native)
|
|
- Zustand (state management)
|
|
|
|
**Key Design Patterns:**
|
|
|
|
1. **Feature-Based Architecture** (`features/`):
|
|
- Each feature is self-contained with its own services, hooks, components, and stores
|
|
- Features: auth, audioRecordingV2, memos, spaces, credits, subscription, i18n, theme, etc.
|
|
- 33 feature modules in total
|
|
|
|
2. **Atomic Design System** (`components/`):
|
|
- `atoms/`: Basic UI components (Button, Input, Text, Icon, etc.)
|
|
- `molecules/`: Composite components (MemoPreview, RecordingBar, TagSelector, etc.)
|
|
- `organisms/`: Complex components (AudioRecorder, Memory, TranscriptDisplay, etc.)
|
|
- `statistics/`: Specialized analytics components
|
|
|
|
3. **Route Structure** (`app/`):
|
|
- `(public)/`: Unauthenticated routes (login, register)
|
|
- `(protected)/`: Authenticated routes with auth guard
|
|
- `(tabs)/`: Main tab navigation (home, memos, spaces)
|
|
- `(memo)/[id]`: Dynamic memo detail pages
|
|
- `(space)/[id]`: Dynamic space detail pages
|
|
- Uses Expo Router's file-based routing with typed routes enabled
|
|
|
|
### Authentication System
|
|
|
|
Uses a **middleware-based authentication bridge** between the app and Supabase:
|
|
|
|
```
|
|
Mobile App → Middleware Auth Service → Supabase
|
|
```
|
|
|
|
**Key Points:**
|
|
- Middleware issues three tokens: `manaToken`, `appToken` (Supabase-compatible JWT), `refreshToken`
|
|
- Tokens stored securely via platform-specific `safeStorage` utility
|
|
- Auth state managed via `AuthContext` provider
|
|
- Supabase client configured to use JWT from middleware
|
|
- Row Level Security (RLS) policies use JWT claims (`sub`, `role`, `app_id`)
|
|
- Supports email/password, Google Sign-In, and Apple Sign-In
|
|
- Automatic token refresh mechanism
|
|
|
|
See `apps/mobile/features/auth/README.md` for detailed authentication flow.
|
|
|
|
### Audio Recording System
|
|
|
|
**AudioRecordingV2** is the current audio recording implementation:
|
|
|
|
- Uses `expo-audio` (migrated from deprecated `expo-av`)
|
|
- Platform-specific services: `IOSRecordingService`, `AndroidRecordingService`
|
|
- Zustand store for state management (`recordingStore`)
|
|
- Comprehensive error handling with retry strategies
|
|
- Android: Foreground service with wake locks
|
|
- iOS: Background audio capability with `mixWithOthers` mode
|
|
- Real-time status updates via polling
|
|
- Prevents zero-byte recordings with validation
|
|
- **Background recording works correctly** - continues when app is backgrounded or locked
|
|
|
|
**iOS Background Recording:**
|
|
- Uses `interruptionMode: 'mixWithOthers'` for background recording support
|
|
- Recording continues when pressing home button, switching apps, or locking device
|
|
- Audio session automatically restored when returning to foreground
|
|
- JavaScript timers suspended in background, but native recording continues
|
|
- Handles real interruptions (phone calls, Siri) automatically
|
|
|
|
**Recording Options:**
|
|
- High quality: M4A format with AAC encoding (MONO for compatibility)
|
|
- Presets: HIGH_QUALITY, MEDIUM_QUALITY, LOW_QUALITY, VOICE_MEMO
|
|
- Max duration and size limits
|
|
- Pause/resume support
|
|
- Audio level metering for waveform visualization
|
|
- Optimized for voice (MONO, 96 quality) to prevent FFmpeg 'chnl' box errors
|
|
|
|
**Key Technical Details:**
|
|
- MONO recording prevents iOS spatial audio metadata issues
|
|
- Audio session verification on cold start prevents first-recording failures
|
|
- Status polling restarts when app returns from background
|
|
- Full duration captured (foreground + background time)
|
|
|
|
See `apps/mobile/features/audioRecordingV2/README.md` for full details.
|
|
See `apps/mobile/features/audioRecordingV2/TROUBLESHOOTING.md` for bug fixes and solutions.
|
|
|
|
### AI Processing System
|
|
|
|
**Blueprints:**
|
|
- Reusable AI analysis patterns for different use cases
|
|
- Examples: Text Analysis, Creative Writing, Meeting Notes
|
|
- Each blueprint has localized advice tips (32 languages)
|
|
- Stored in Supabase with public/private visibility
|
|
|
|
**Prompts:**
|
|
- Specific AI tasks for content transformation
|
|
- Examples: Summary, To-Do extraction, Translation, Q&A
|
|
- Associated with blueprints via `blueprint_prompts` join table
|
|
- Multi-language support (German/English minimum)
|
|
|
|
**Content Organization:**
|
|
- 8 categories: Coaching, Crafts, Healthcare, Journal, Journalism, Office, Sales, University
|
|
- Categories provide contextual grouping for blueprints/prompts
|
|
|
|
See `apps/mobile/docs/blueprints_and_prompts.md` for full documentation.
|
|
|
|
### Theme System
|
|
|
|
**Multi-Theme Support:**
|
|
- 4 theme variants: Lume (gold), Nature (green), Stone (slate), Ocean (blue)
|
|
- Each theme has light and dark mode variants
|
|
- 13 semantic color tokens per theme (primary, secondary, borders, backgrounds, text)
|
|
- Theme state managed via `ThemeProvider` context
|
|
- Dark mode detection + manual override
|
|
- All colors defined in `tailwind.config.js`
|
|
|
|
**Markdown Rendering:**
|
|
- Full Markdown support in memo display
|
|
- Theme-aware styles adapt to light/dark mode
|
|
- Centralized styles in `features/theme/markdownStyles.ts`
|
|
- Hybrid rendering with auto-detection
|
|
|
|
### Spaces (Collaboration)
|
|
|
|
**Team Workspaces:**
|
|
- Create unlimited collaborative spaces
|
|
- Role-based permissions (owner, member)
|
|
- Memo sharing within spaces
|
|
- Email-based invitation system
|
|
- Credit pools shared among team members
|
|
- Real-time sync via Supabase Realtime
|
|
|
|
**Backend Integration:**
|
|
- RESTful API for space management
|
|
- RLS policies for access control
|
|
- Space-specific memo filtering
|
|
|
|
See `apps/mobile/docs/SPACES.md` for implementation details.
|
|
|
|
### Subscription & Credits
|
|
|
|
**Mana Credit System:**
|
|
- Backend-driven transparent pricing
|
|
- Real-time credit validation before operations
|
|
- Usage tracking and analytics
|
|
- Credit sharing in team spaces
|
|
- Free tier: 150 Mana + 5 daily Mana
|
|
|
|
**RevenueCat Integration:**
|
|
- Cross-platform (iOS, Android, Web)
|
|
- Subscription lifecycle management
|
|
- User identification tied to auth
|
|
- Purchase restoration across devices
|
|
- 4 individual plans: Stream (€5.99), River (€14.99), Lake (€29.99), Ocean (€49.99)
|
|
- Team and Enterprise plans available
|
|
|
|
### Internationalization
|
|
|
|
**32 Languages Supported:**
|
|
- Arabic, Bengali, Bulgarian, Chinese, Czech, Danish, Dutch, English, Estonian, Finnish, French, Gaelic, German, Greek, Hindi, Croatian, Hungarian, Indonesian, Italian, Japanese, Korean, Lithuanian, Latvian, Maltese, Norwegian, Persian, Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovenian, Spanish, Swedish, Turkish, Ukrainian, Urdu, Vietnamese
|
|
|
|
**Implementation:**
|
|
- `react-i18next` for translations
|
|
- Automatic device language detection
|
|
- Persistent user preference storage
|
|
- RTL support for Arabic/Hebrew
|
|
- Translation files in `features/i18n/translations/`
|
|
|
|
### Real-Time Features
|
|
|
|
**Supabase Realtime:**
|
|
- Live memo updates (INSERT, UPDATE, DELETE)
|
|
- Real-time collaboration in spaces
|
|
- `MemoRealtimeProvider` context for subscriptions
|
|
- Automatic reconnection handling
|
|
- RLS-aware subscriptions
|
|
|
|
### Platform-Specific Notes
|
|
|
|
**Web Platform:**
|
|
- Uses `.web.ts` file extensions for web-specific implementations
|
|
- `safeStorage.web.ts` uses localStorage (vs AsyncStorage on native)
|
|
- Web Audio API for recording (vs expo-audio)
|
|
- Some features unavailable: push notifications, haptics, native gestures
|
|
|
|
**iOS:**
|
|
- Background audio capability required
|
|
- Audio session management
|
|
- Apple Sign-In integration
|
|
- RevenueCat StoreKit 2
|
|
|
|
**Android:**
|
|
- Foreground service for recording
|
|
- Wake lock to prevent sleep
|
|
- Android 16+ requires foreground to start recording
|
|
- Google Sign-In integration
|
|
|
|
## Environment Configuration
|
|
|
|
The mobile app uses environment-specific `.env` files:
|
|
|
|
- `.env.dev`: Development environment (copy from `.env.dev.example`)
|
|
- `.env.prod`: Production environment (copy from `.env.prod.example`)
|
|
- `.env.local`: Active environment (auto-generated by npm scripts)
|
|
|
|
**Key Environment Variables:**
|
|
- `EXPO_PUBLIC_SUPABASE_URL`: Supabase project URL
|
|
- `EXPO_PUBLIC_SUPABASE_ANON_KEY`: Supabase anon key
|
|
- `EXPO_PUBLIC_MIDDLEWARE_API_URL`: Middleware auth service URL
|
|
- `EXPO_PUBLIC_APPID`: Application ID for middleware
|
|
- RevenueCat keys for iOS/Android
|
|
|
|
## Code Quality
|
|
|
|
**Linting:**
|
|
- ESLint with TypeScript plugin
|
|
- React/React Native rules
|
|
- Unused imports auto-removal
|
|
- Configuration in `eslint.config.js`
|
|
|
|
**Formatting:**
|
|
- Prettier with Tailwind plugin
|
|
- Auto-format on save recommended
|
|
|
|
**TypeScript:**
|
|
- Strict mode enabled
|
|
- Typed routes from Expo Router
|
|
- Type definitions in `types/` and feature-specific types
|
|
|
|
## Migration Notes
|
|
|
|
**Expo SDK 55 (Current):**
|
|
- React Native 0.83.2, React 19.2
|
|
- Native `allowsBackgroundRecording` support in expo-audio (no more workarounds needed)
|
|
- All Expo packages use `^55.x.x` version scheme
|
|
- New Architecture is the default (Legacy Architecture dropped)
|
|
- Android compileSdkVersion/targetSdkVersion 36
|
|
|
|
**Expo SDK 54 Migration (Historical):**
|
|
- Migrated from `expo-av` to `expo-audio`
|
|
- New audio recording API (`AudioModule.AudioRecorder`)
|
|
- Status polling instead of callbacks
|
|
- See `EXPO_54_AUDIO_RECORDING_MIGRATION.md`
|
|
|
|
**SvelteKit Web App:**
|
|
- Separate web app being built as companion
|
|
- Shares Supabase backend with mobile app
|
|
- See `SVELTEKIT_MIGRATION_ANALYSIS.md` for migration plan
|
|
|
|
## Testing Strategy
|
|
|
|
**Manual Testing:**
|
|
- Test on both iOS and Android before commits
|
|
- Verify web platform compatibility
|
|
- Check dark mode and all theme variants
|
|
- Test with different languages
|
|
|
|
**Platform Matrix:**
|
|
- iOS (simulator + device)
|
|
- Android (emulator + device)
|
|
- Web (Chrome, Safari, Firefox)
|
|
|
|
## Common Patterns
|
|
|
|
### Creating a New Feature
|
|
|
|
1. Create feature directory in `features/`
|
|
2. Add subdirectories: `components/`, `hooks/`, `services/`, `store/`, `types/`
|
|
3. Export public API via `index.ts`
|
|
4. Add feature-specific README if complex
|
|
5. Update this CLAUDE.md if architectural
|
|
|
|
### Adding a New Route
|
|
|
|
1. Add file in `app/` directory following Expo Router conventions
|
|
2. Use `(protected)/` group if authentication required
|
|
3. Use `[id]` for dynamic routes
|
|
4. Enable typed routes in `app.json` (already enabled)
|
|
5. Import route types from `expo-router`
|
|
|
|
### Working with Zustand Stores
|
|
|
|
```typescript
|
|
// Create store
|
|
export const useMyStore = create<MyState>((set, get) => ({
|
|
// state
|
|
data: null,
|
|
|
|
// actions
|
|
setData: (data) => set({ data }),
|
|
|
|
// computed/derived
|
|
getData: () => get().data,
|
|
}));
|
|
```
|
|
|
|
Stores are located in:
|
|
- Global: `store/store.ts`
|
|
- Feature-specific: `features/[feature]/store/`
|
|
|
|
### Platform-Specific Code
|
|
|
|
Use file extensions for platform-specific implementations:
|
|
- `file.ts`: Default (mobile)
|
|
- `file.web.ts`: Web platform
|
|
- `file.ios.ts`: iOS only
|
|
- `file.android.ts`: Android only
|
|
|
|
Metro bundler automatically resolves based on platform.
|
|
|
|
### Error Handling
|
|
|
|
1. Use feature-specific error types
|
|
2. Provide user-friendly messages
|
|
3. Include retry mechanisms where appropriate
|
|
4. Log errors to console for debugging
|
|
5. Consider Sentry integration for production
|
|
|
|
## Build and Deployment
|
|
|
|
**EAS Build Profiles:**
|
|
- `development`: Dev client with debugging
|
|
- `preview`: Internal distribution (TestFlight/Google Play Internal)
|
|
- `simulator`: iOS simulator build
|
|
- `production`: Auto-increment version, store-ready
|
|
|
|
**Environment Selection:**
|
|
EAS profiles automatically load correct environment via `EXPO_PUBLIC_USE_ENV_FILE` in `eas.json`.
|
|
|
|
**Version Management:**
|
|
- iOS: `buildNumber` in `app.json`
|
|
- Android: `versionCode` in `app.json`
|
|
- Production profile auto-increments both
|
|
|
|
## Important Files
|
|
|
|
- `app.json`: Expo configuration, plugins, permissions
|
|
- `eas.json`: EAS Build configuration
|
|
- `package.json`: Dependencies and scripts
|
|
- `tailwind.config.js`: Theme colors and styling
|
|
- `eslint.config.js`: Linting rules
|
|
- `babel.config.js`: Babel configuration
|
|
- `metro.config.js`: Metro bundler configuration (if present)
|
|
- `types/supabase.ts`: Auto-generated Supabase types
|
|
|
|
## Database Schema
|
|
|
|
The app uses Supabase with the following key tables:
|
|
- `memos`: Audio recordings and transcriptions
|
|
- `memories`: AI-generated insights from memos
|
|
- `blueprints`: AI analysis templates
|
|
- `prompts`: AI task templates
|
|
- `blueprint_prompts`: Many-to-many join table
|
|
- `categories`: Organization categories
|
|
- `tags`: User-defined tags
|
|
- `memo_tags`: Many-to-many join table
|
|
- `spaces`: Collaborative workspaces
|
|
- `space_members`: User-space relationships
|
|
- `profiles`: User profiles and settings
|
|
|
|
All tables use RLS policies based on JWT claims.
|
|
|
|
## Auto-Delete Audio Files (30-Day Retention)
|
|
|
|
When users enable `autoDeleteAudiosAfter30Days` in their settings, audio files older than 30 days are automatically deleted while preserving memo records (transcripts, metadata).
|
|
|
|
**Setting Location:** `app_settings.memoro.autoDeleteAudiosAfter30Days` (default: `false`)
|
|
|
|
**Two Cleanup Mechanisms:**
|
|
|
|
1. **Cloud Storage Cleanup** (memoro-service):
|
|
- Daily cron job at 3 AM UTC via Google Cloud Scheduler
|
|
- Queries `storage.objects` table for files older than 30 days
|
|
- Deletes from Supabase Storage bucket `user-uploads`
|
|
- Updates memo `source` field: `{ audio_path: null, audio_deleted: true, audio_deleted_at: timestamp }`
|
|
|
|
2. **Local Device Cleanup** (mobile app):
|
|
- Runs on app launch after successful authentication
|
|
- Throttled to once per 24 hours
|
|
- Uses `fileStorageService.cleanupOldFiles()` with 30-day retention
|
|
- Implementation: `features/storage/services/localAudioCleanup.ts`
|
|
|
|
**Key Files:**
|
|
- `memoro-service/src/cleanup/` - Cloud cleanup service
|
|
- `mana-core-middleware/src/modules/users/services/user-settings.service.ts` - User settings query
|
|
- `apps/mobile/features/storage/services/localAudioCleanup.ts` - Local device cleanup
|
|
- `apps/mobile/features/auth/contexts/AuthContext.tsx` - Cleanup trigger after auth
|
|
|
|
## Known Issues
|
|
|
|
1. **Android 16+ Recording**: Must be in foreground to start recording
|
|
2. **Zero-byte Recordings**: Occasional issue on some Android devices (retry mechanism in place)
|
|
3. **Token Refresh**: Email may not be in refreshed token (stored separately as workaround)
|
|
4. **Web Platform**: Limited functionality vs native (no push notifications, haptics, etc.)
|
|
|
|
## Additional Documentation
|
|
|
|
- `apps/mobile/README.md`: Full mobile app documentation
|
|
- `apps/web/README.md`: Web app documentation
|
|
- `features/auth/README.md`: Authentication system details
|
|
- `features/audioRecordingV2/README.md`: Audio recording implementation
|
|
- `docs/blueprints_and_prompts.md`: AI processing system
|
|
- `docs/SPACES.md`: Collaboration features
|
|
- `SVELTEKIT_MIGRATION_ANALYSIS.md`: Web app migration plan
|