This repository delivers an offline-first EdTech platform.
Python FastAPI service with AI workers (LangChain/OpenAI) and PostgreSQL via SQLAlchemy.
- Profile: view/edit name, email, password; logout (mobile) and
/profileweb page. - Settings: push-notification permission and registration.
- History: view past chapter progress with timestamps (mobile) and
/historyweb page. - Content: generate AI content via the
/contentAPI. - Admin: (role=admin) mobile panel and web analytics dashboard at
/dashboard. - Teacher Portal: role=teacher (or admin) sees
Teacherscreen which loads/teacherweb portal page; teachers can create classes, enroll students, and assign chapters as lessons. A new mobileClassessection lets both students and teachers browse their classrooms and view assignments. Teachers can also perform these operations from the app; offline actions are queued and synchronized automatically when connectivity returns.
All code is modern ES6 JavaScript; TypeScript is intentionally not used.
Install via expo/npm:
expo install react-native-screens react-native-safe-area-context
npm install @react-navigation/native @react-navigation/native-stack nativewind
expo install react-native-svg
expo install @react-native-community/netinfo expo-sqlite @react-native-async-storage/async-storage expo-notifications
npm install react-native-markdown-display react-native-mathjaxFor the web dashboard we use FastAPI templates; install jinja2 (already pulled by FastAPI) and run the backend normally.
You'll also need a tailwind.config.js and corresponding postcss config for NativeWind.
src/App.js initializes the SQLite database and loads the AppNavigator stack, which contains LessonScreen and QuizScreen.
src/database/db.jsdefines local tablesLocalChaptersandLocalProgress.src/hooks/useSyncState.jsreturns'Offline','Syncing', or'Online'and triggers sync logic viauseSyncEffect.src/services/syncWorker.jspulls chapter data;pushWorker.jspushes unsynced progress.
Further components include HighlightToAsk, and screens for lessons and quizzes.
Backend provides /api/v1/auth/register and /api/v1/auth/login endpoints. The login endpoint uses OAuth2 password grant and returns a JWT. The frontend stores the token in AsyncStorage and includes it in sync requests via an Authorization header.
Default user data is decoded from the JWT to obtain userId which is also persisted locally.
GET /api/v1/profile/mereturns current user details.PUT /api/v1/profile/meupdates name/email/password; email uniqueness enforced.
GET /api/v1/analytics-query/userreturns the authenticated user’s event history (optionalstart/endISO timestamps).GET /api/v1/analytics-query/summaryreturns aggregated event counts by type (filterable byevent_type).
POST /api/v1/content/generateaccepts{input_text}and returns generated markdown, flashcards, and quiz.POST /api/v1/content/translateaccepts generated JSON andtarget_languageto produce translated output.
GET /api/v1/progress/historyreturns the user’s chapter progress records with titles and timestamps.
POST /api/v1/notifications/registeraccepts{token}to register Expo push tokens.POST /api/v1/notifications/send(admin) sends a notification via Expo push API. Payload:{title, body, user_id?}.
Accessible to user ID 1 (stubbed admin). Provide:
GET /api/v1/admin/users– list users.GET /api/v1/admin/chapters– list chapters.GET /api/v1/admin/classrooms– list all classrooms.GET /api/v1/admin/assignments– list all assignments.
The mobile Admin screen now shows classrooms and assignment titles in addition to users and chapters.
Future admin features may include content moderation, user management, etc.
Push operations now send last_updated timestamps, include a version number, and are split into batches of 20. The backend performs richer conflict resolution by comparing versions, averaging when versions match, and returns canonical progress rows (with updated versions) so the client can reconcile and mark them synced. Note: the local SQLite schema adds a version column; existing installations may need a migration or database reset.
Additionally, an offline QueuedTasks table is available. Several services (content generation, classroom creation, enrollment, assignment posting) write to the queue when an operation fails due to network issues. The useSyncEffect hook calls processQueue() whenever connectivity is restored so queued actions are replayed automatically.
Push operations now send last_updated timestamps, include a version number, and are split into batches of 20. The backend performs richer conflict resolution by comparing versions, averaging when versions match, and returns canonical progress rows (with updated versions) so the client can reconcile and mark them synced. Note: the local SQLite schema adds a version column; existing installations may need a migration or database reset.