Skip to content

oldrefery/dutch-learning-app

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

188 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Dutch Learning App: Project Overview

1. Project Goal

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.

2. Core Philosophy

  • 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.

3. Getting Started

Follow these instructions to get the project running locally for development.

1. Clone the repository:

git clone <your-repository-url>
cd <repository-name>

2. Install dependencies:

npm install
# or
yarn install

3. Set up environment variables:

  • Copy env.example to .env and fill in your actual values:
cp env.example .env
  • Copy env.local.example to .env.local for 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

4. Setup Sentry Configuration (Required for Local Production Builds):

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.

4.1 Codex App Access to Sentry Issues (Read-only)

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.

5. Run the application:

npm start
# or
yarn start

4. Key Features

πŸš€ Smart Word Analysis Cache

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

πŸ€– AI-Powered Word Addition

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.

User Flow:

  1. The user taps the "Add Word" button.

  2. They enter a single Dutch word in any form (e.g., "gekocht").

  3. The app checks the smart cache first for instant results.

  4. If not cached, the app sends the word to a secure Supabase Edge Function.

  5. The function calls the Gemini AI API, requesting a full analysis: lemma (base form), part of speech, translations, and example sentences.

  6. The app receives the structured data from the AI and displays it with cache status indicators.

  7. The user can review, make minor edits if needed, and save the word to their collection. A new, comprehensive flashcard is created in seconds.

Cache UI Features:

  • 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

πŸ“€ Collection Sharing System

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

Import Screen Features:

  • 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

πŸ” Password Reset Flow

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

Security Features:

  • 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

πŸ”‘ Google OAuth Authentication

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

Implementation Details:

  • 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

🍎 Apple Sign-In Authentication

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

Security Features:

  • 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

πŸ” Collection Search

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"

Search Features:

  • 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

New User Experience:

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.

5. Architecture Diagram

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)  |
|                     |      |                     |
+---------------------+      +---------------------+

Flow Explanation:

  • 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.

6. Technology Stack

  • 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

7. Project Status πŸŽ‰

βœ… 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

Current Architecture:

  • 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 βœ…

Recent Updates (Build 45 - Version 1.7.0)

🍎 Apple Sign-In Authentication

  • 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

πŸ“¦ New Components

  • 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

πŸ”§ Technical Improvements

  • Authentication Library: Added src/lib/appleAuth.ts for 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 usesAppleSignIn flag for iOS
    • Added expo-apple-authentication plugin
  • Dependencies: Added expo-apple-authentication (~8.0.7) for native Apple Sign-In support

8. Documentation

Detailed project documentation is available in the docs/ folder:

9. Next Steps

The project is ready for MVP feature implementation:

  1. Modify app screens using Expo Router file-based routing
  2. Implement word addition flow with AI integration
  3. Create review session UI with SRS algorithm
  4. Add flashcard animations and user interactions

Start development by modifying src/app/(tabs)/index.tsx for the home screen.

10. Production Build

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-only

Requirements for Local Builds:

  • .sentryclirc file 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.

About

AI-powered mobile application for learning Dutch vocabulary and phrases using the spaced repetition system (SRS)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors