5.2 KiB
5.2 KiB
Lomda Hub - AI Coding Agent Instructions
Architecture Overview
Stack: React+Vite (TypeScript) frontend, FastAPI backend, PostgreSQL database with SQLAlchemy 2.0 ORM, Alembic migrations.
Deployment: Docker Compose with 3 services (db, backend, frontend). Frontend on 5173, backend on 8000, postgres on 5433.
Auth: JWT access/refresh tokens + Google OAuth. Tokens passed via Authorization: Bearer header. Two roles: admin and learner.
Key Structural Patterns
Backend Structure
- Models (backend/app/models.py): SQLAlchemy 2.0 with type hints (
Mapped[T]). Enums:UserRole,ModuleType,ProgressStatus,QuestionType. - Routers: Three main routers in backend/app/routers:
auth.py(login/register/OAuth),admin.py(course/module CRUD),learner.py(enrollments/progress). - Dependencies (backend/app/deps.py):
get_db()for DB sessions,get_current_user()for auth,require_admin()for admin-only routes. - Config (backend/app/core/config.py): Settings loaded from env vars using Pydantic
BaseSettings.
Frontend Structure
- Pages (frontend/src/pages): Each major view (login, courses, player, admin dashboard/editor) as separate page component.
- API Client (frontend/src/api): Centralized API calls. Token management in
client.tswith localStorage. - Routing: React Router v6 in App.tsx. Admin routes prefixed with
/admin.
Data Flow: Locked Course Progression
Courses have ordered modules. Learner must complete module N before unlocking N+1:
- On enrollment, first module is
unlocked, rest arelocked(seeModuleProgressmodel). - Content modules: mark completed when viewed.
- Quiz modules: mark completed only if attempt passes (
score >= pass_score). - Backend logic in learner.py:
submit_quiz_attemptupdates progress and unlocks next module.
Critical Workflows
Database Migrations
- After model changes:
cd backend && alembic revision --autogenerate -m "description" - Apply:
alembic upgrade head(ordocker compose restart backendfor Docker) - Seed data:
python -m app.scripts.seed(creates admin user + sample data)
Development Commands
Docker: docker compose up --build (runs migrations + seed automatically via Dockerfile CMD)
Local backend: uvicorn app.main:app --reload (from backend dir with venv active)
Local frontend: npm run dev (from frontend dir)
Google OAuth Flow
- Login: GET
/auth/google/login→ redirects to Google → callback at/auth/google/callback - Callback returns
RedirectResponsetoFRONTEND_URL/auth/callback?access_token=...&refresh_token=... - Frontend (GoogleCallbackPage.tsx) extracts tokens from URL params and saves to localStorage
- Critical: FastAPI route must NOT have trailing slash mismatch or it will 307 redirect infinitely
Project-Specific Conventions
API Response Patterns
- Use Pydantic schemas for request/response validation (see schemas.py)
- Admin endpoints return extended models with
group_idsarrays - Learner endpoints filter by current user (never expose other learners' data)
Error Handling
- Raise
HTTPExceptionwith appropriate status codes (400 bad request, 401 unauthorized, 403 forbidden, 404 not found) - No generic try/except unless specific recovery logic needed
Database Relationships
- Use SQLAlchemy relationship cascades:
cascade="all, delete-orphan"for parent→child - Unique constraints for enrollment, progress, group membership: prevent duplicates via
__table_args__
Frontend State Management
- No global state library; use React hooks + fetch in components
- Token refresh: not auto-implemented; tokens expire after 30min (access) / 7days (refresh)
Integration Points
External Dependencies
- Google OAuth: requires
GOOGLE_CLIENT_ID,GOOGLE_CLIENT_SECRET,GOOGLE_REDIRECT_URIenv vars - SMTP: config present but not actively used (future email features)
Cross-Component Communication
- Frontend calls backend REST API; no WebSockets or real-time updates
- CORS: configured in main.py via
CORS_ORIGINSenv var (default:http://localhost:5173)
Common Gotchas
- Trailing slashes: FastAPI auto-redirects
/path/to/path(307). Define routes without trailing slashes consistently. - Password hashing: bcrypt truncates at 72 bytes; see defensive check in auth.py.
- Module ordering:
order_indexis manually managed. No auto-reordering on deletion. - Admin seed: Default admin created with email from
ADMIN_SEED_EMAILenv var (default:admin@example.com).
Key Files to Reference
- models.py: All database schema
- schemas.py: Request/response validation
- deps.py: Auth dependencies
- learner.py: Core learning flow logic
- App.tsx: Frontend routing and navigation