To create a modern, AI-powered mobile application for learning Dutch vocabulary and phrases using the spaced repetition system (SRS). The app is designed to be a powerful and personalized learning tool, evolving from a core MVP to a feature-rich platform.
-
AI-Powered: Leverage Generative AI (initially Gemini) to provide deep word analysis, context, examples, and audio, making the card creation process seamless and intelligent.
-
Effective Learning: Built around a proven spaced repetition algorithm (similar to SM-2) to maximize long-term retention.
-
Clean & Modern UX: A simple, intuitive, and enjoyable user interface that makes learning feel effortless.
-
Scalable Architecture: Built on a modern, robust tech stack with a flexible architecture that allows for easy expansion of features in the future.
Follow these instructions to get the project running locally for development.
git clone <your-repository-url>
cd <repository-name>
npm install
# or
yarn install
- Copy
env.exampleto.envand fill in your actual values:
cp env.example .env- Copy
env.local.exampleto.env.localfor local development overrides (optional):
cp env.local.example .env.local- Required variables in
.env:
EXPO_PUBLIC_SUPABASE_URL=your_supabase_url
EXPO_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
EXPO_PUBLIC_DEV_USER_ID=your_dev_user_id_from_supabase
EXPO_PUBLIC_DEV_USER_EMAIL=dev@test.com
EXPO_PUBLIC_DEV_USER_PASSWORD=password123
EXPO_PUBLIC_SENTRY_DSN=your_sentry_dsn_here
- Optional variables in
.env.local:
SENTRY_AUTH_TOKEN=your_sentry_auth_token_here
SENTRY_ORG=oldrefery
SENTRY_PROJECT=dutch-learning-app
SENTRY_BASE_URL=https://sentry.io
For proper source map uploads to Sentry during local production builds, create a .sentryclirc file in the project root:
[auth]
token=your_sentry_auth_token_here
This file is required for the local build script to properly upload source maps to Sentry for crash reporting. Note: EAS builds in the cloud handle Sentry configuration automatically through environment variables.
To let Codex query Sentry issues via API, create an auth token that includes event:read (required for Issues API), plus project:read and org:read.
Important: personal tokens in Sentry cannot be edited after creation. If event:read is missing, create a new token and replace SENTRY_AUTH_TOKEN in .env.local.
You can verify access with:
set -a
source ./.env
source ./.env.local
set +a
python3 "$HOME/.codex/skills/sentry/scripts/sentry_api.py" \
--org "${SENTRY_ORG:-oldrefery}" \
--project "${SENTRY_PROJECT:-dutch-learning-app}" \
--base-url "${SENTRY_BASE_URL:-https://sentry.io}" \
list-issues \
--environment prod \
--time-range 24h \
--limit 10 \
--query "is:unresolved"If you see HTTP 403:
# 1) Verify org access and detect region URL for your org
curl -sS "${SENTRY_BASE_URL:-https://sentry.io}/api/0/organizations/${SENTRY_ORG}/" \
-H "Authorization: Bearer $SENTRY_AUTH_TOKEN"
# 2) Verify org issues endpoint with project filter
curl -sS "${SENTRY_BASE_URL:-https://sentry.io}/api/0/organizations/${SENTRY_ORG}/issues/?limit=1&query=project:${SENTRY_PROJECT}" \
-H "Authorization: Bearer $SENTRY_AUTH_TOKEN"
# 3) Verify project issues endpoint used by the script
curl -sS "${SENTRY_BASE_URL:-https://sentry.io}/api/0/projects/${SENTRY_ORG}/${SENTRY_PROJECT}/issues/?limit=1" \
-H "Authorization: Bearer $SENTRY_AUTH_TOKEN"If these calls still return 403, check your Sentry organization role. Billing-only users cannot access Issues; use at least Member/Contributor access to the project.
npm start
# or
yarn start
Revolutionary caching system that delivers 80-90% cost reduction and instant responses for word analysis:
- Intelligent Sharing: Cross-user cache sharing means popular words are analyzed once and shared globally
- Lightning Fast: <100ms response time for cached words vs 3-5s for fresh analysis
- Cost Effective: Dramatic reduction in API costs through smart caching strategy
- Apple HIG UI: Native iOS-style cache indicators with refresh controls
- Force Refresh: Manual override option when fresh analysis is needed
The core of the app is the intelligent word addition flow. Instead of manual data entry, the user leverages AI for a rich, automated experience.
-
The user taps the "Add Word" button.
-
They enter a single Dutch word in any form (e.g., "gekocht").
-
The app checks the smart cache first for instant results.
-
If not cached, the app sends the word to a secure Supabase Edge Function.
-
The function calls the Gemini AI API, requesting a full analysis: lemma (base form), part of speech, translations, and example sentences.
-
The app receives the structured data from the AI and displays it with cache status indicators.
-
The user can review, make minor edits if needed, and save the word to their collection. A new, comprehensive flashcard is created in seconds.
- Status Badge: Shows "π Cache" for cached results or "π€ AI" for fresh analysis
- Smart Refresh Button: Appears only for cached results, allowing force refresh when needed
- Usage Statistics: Toast messages show how many times a word has been cached
- Timestamp Display: Subtle indication of when data was cached
Complete collection sharing functionality that allows users to share their word collections with others:
- In-App Collection Import: Import collections directly in the app using collection codes (no deeplinks required)
- Secure Sharing: UUID-based share tokens with proper access controls and RLS policies
- Native Sharing UX: Long press collections for context menus with copy/share/stop sharing options
- Enhanced Import Flow: Streamlined import experience with duplicate detection and word selection
- Duplicate Word Filter: Toggle to hide/show already added words (hidden by default for cleaner UX)
- Collection Name Display: Shows actual collection names instead of technical IDs
- Smart Word Selection: Automatic detection and marking of duplicate words with collection source
- Batch Import: Select multiple words for efficient batch importing to target collections
Complete password recovery system with secure token-based authentication:
- Forgot Password: Email-based password reset request from login screen
- Email Deep Links: Automatic navigation from password reset emails to the app
- Secure Token Exchange: Atomic session setup with password update using Supabase tokens
- Form Validation: Client-side password strength and match verification
- HIG-Compliant Navigation: Multiple ways to navigate (header back button, swipe gesture, text link)
- Clear User Feedback: Success/error messaging with auto-redirect to login after successful reset
- Token-Based Authentication: Secure access tokens from Supabase Auth
- Non-Blocking Auth State: Optimized session management prevents UI freezing
- Comprehensive Error Handling: Sentry logging for all password reset operations
- Deep Link Parsing: Robust URL parsing with hash fragment to query params conversion
Seamless social login integration for faster onboarding:
- One-Tap Sign In: Sign in with Google account in seconds
- Browser-Based OAuth: Secure OAuth 2.0 flow using Supabase Auth and expo-web-browser
- Deep Linking: Automatic return to app after authentication with custom URL scheme
- HIG-Compliant Button: Google Sign In button following official branding guidelines
- Dual Integration: Available on both login and signup screens with "OR" divider
- Auto-Navigation: Automatic redirect to main app after successful authentication
- No Native Dependencies: Uses expo-web-browser instead of native Google SDK for simpler setup
- Universal Flow: Same implementation works for all OAuth providers (Google, GitHub, etc.)
- Access Control: Automatic access level assignment based on pre-approved email whitelist
- Error Handling: Comprehensive error messages and loading states for better UX
- Production Ready: Fully tested on iOS and Android development builds
Native Apple authentication for seamless iOS user experience:
- Native iOS Integration: Built-in Apple Sign In for iOS devices using expo-apple-authentication
- Secure Authentication: Nonce-based security with SHA-256 hashing to prevent replay attacks
- Privacy-First: Supports Apple's privacy features including email relay and name sharing
- HIG-Compliant Design: Native Apple Sign In button following Apple's design guidelines
- Platform-Specific: Automatically hidden on non-iOS platforms
- Seamless Integration: Works alongside Google OAuth with unified authentication flow
- Nonce Generation: Cryptographically secure random nonce generation using expo-crypto
- Token Validation: Identity token verification through Supabase Auth integration
- Error Handling: Comprehensive error logging with Sentry integration
- User Cancellation: Graceful handling of user-cancelled authentication attempts
- Availability Check: Runtime verification of Apple Sign-In availability on device
Fast and intuitive search functionality within collections:
- Real-time Search: Instant search with 300ms debounce for optimal performance
- Dutch Word Focus: Search specifically by Dutch lemma for precise results
- Substring Matching: Find words by typing any part of the word (beginning, middle, or end)
- Smart Result Counter: Shows "X of Y words" to indicate search results
- HIG-Compliant Design: 44px touch targets and platform-specific clear buttons
- Theme Support: Full dark/light mode with proper contrast and accessibility
- Empty State Handling: Different messages for "no search results" vs "no words in collection"
- Debounced Input: Prevents excessive filtering while maintaining responsive feedback
- Local State Management: Text appears instantly while search is optimized in the background
- Platform-Specific UX: Native iOS clear button, custom Android implementation
- Accessibility: Proper focus states, semantic colors, and touch target sizes
For new users who don't have any collections yet, the app automatically creates a default collection called "My Dutch Words" when they add their first word. This eliminates the barrier of having to create a collection before being able to add words, making the onboarding experience seamless and intuitive.
The application uses a modern Backend-as-a-Service (BaaS) architecture, which minimizes the need for a traditional, self-hosted backend.
+---------------------+
| |
| React Native App |
| (Expo) |
| |
+---------------------+
| ^
| | (User Data, Words)
| |
+------v------|-------+ +---------------------+
| | | |
| Supabase Database | | Supabase Auth |
| (PostgreSQL) | | |
| | | |
+---------------------+ +---------------------+
^ |
| | (Secure API Call)
| |
+------|------v-------+ +---------------------+
| |----->| |
| Supabase Edge Func. | | Gemini AI API |
| (Holds Secret Key) |----->| (External Service) |
| | | |
+---------------------+ +---------------------+
-
Direct Database/Auth: The app communicates directly with Supabase for standard operations like fetching words or authentication, secured by Row Level Security (RLS).
-
Secure AI Calls: To protect the AI API key, the app never calls the AI directly. It calls a trusted Supabase Edge Function, which securely holds the key and forwards the request to the AI service.
- Platform: React Native with Expo SDK 54 (for iOS, Android, and Web)
- React: React 19.1.0 with React Native 0.81.4
- Architecture: New Architecture enabled (Reanimated 4.0)
- Navigation: expo-router (file-based routing)
- Backend: Supabase (PostgreSQL Database, Auth, Edge Functions)
- AI Integration: Google Gemini, accessed securely via Supabase Edge Functions
- Language: TypeScript
- State Management: Zustand
- Animation: React Native Reanimated 4.0 + Worklets
- Gestures: React Native Gesture Handler 2.28.0
- Testing: Jest & React Native Testing Library
- Code Quality: ESLint & Prettier
- Node.js: Version 20+ required
β Phase 0 Complete - Supabase infrastructure fully deployed and tested β Phase 1 Foundation Complete - React Native app initialized and running β Phase 2 Complete - Backend integration and MVP features β Phase 3 Complete - Modern stack upgrade (SDK 54, React 19.1, Reanimated 4.0) π Ready for Enhanced Features - Advanced functionality development
- Database schema with SRS algorithm β
- Edge Function for Gemini AI β
- TypeScript types and Zustand store β
- Expo app running on iOS simulator β
- Analysis notes system with HIG compliance β
- Smart word analysis cache with 80-90% cost reduction β
- Apple HIG cache UI with status indicators β
- Native iOS Authentication: Complete Apple Sign-In integration for iOS devices
- Nonce-based security with SHA-256 hashing to prevent replay attacks
- Native Apple Sign In button following Apple HIG design guidelines
- Seamless integration with Supabase Auth using identity token validation
- Automatic platform detection (iOS only, hidden on other platforms)
- Comprehensive error handling with Sentry logging
- Graceful handling of user-cancelled authentication attempts
- AppleSignInButton: Native Apple authentication button component
- Platform-specific rendering (iOS only)
- Dark/light theme support with adaptive colors
- Loading states and disabled state handling
- Apple icon with proper branding compliance
- Authentication Library: Added
src/lib/appleAuth.tsfor Apple Sign-In logic- Secure nonce generation using expo-crypto
- Identity token validation and session management
- Availability checking for Apple authentication services
- Configuration: Updated app.json with Apple Sign-In capabilities
- Enabled
usesAppleSignInflag for iOS - Added
expo-apple-authenticationplugin
- Enabled
- Dependencies: Added
expo-apple-authentication(~8.0.7) for native Apple Sign-In support
Detailed project documentation is available in the docs/ folder:
- π Project Plan - Phased development approach
- π Changelog - Release notes and version history
- ποΈ Database Schema - Complete database structure
- π€ AI Strategy - Gemini integration approach
- π Task Breakdown - Detailed development tasks
- βοΈ Setup Instructions - Manual configuration steps
- π Current Status - Real-time project progress
- π― Project Structure - Code organization and best practices
- π SRS Algorithm - Spaced repetition system details
- π¨ Constants System - Centralized configuration
The project is ready for MVP feature implementation:
- Modify app screens using Expo Router file-based routing
- Implement word addition flow with AI integration
- Create review session UI with SRS algorithm
- Add flashcard animations and user interactions
Start development by modifying src/app/(tabs)/index.tsx for the home screen.
The project includes an automated build script for creating local production builds:
# Build and submit for both platforms
./scripts/build-and-submit.sh
# Build for specific platform only
./scripts/build-and-submit.sh --platform ios
./scripts/build-and-submit.sh --platform android
# Build only (don't submit to stores)
./scripts/build-and-submit.sh --build-onlyRequirements for Local Builds:
.sentryclircfile must be present in the project root with valid Sentry auth token- EAS CLI must be configured with proper credentials
- Apple ID and Google Play credentials must be set up in EAS
The script automatically:
- Increments build numbers for both platforms
- Builds locally for faster performance
- Uploads source maps to Sentry for crash reporting
- Submits to App Store Connect and Google Play Store
Note: This configuration is only needed for local builds. EAS cloud builds handle Sentry configuration automatically through environment variables and don't require the .sentryclirc file.