Smart education analytics for Google Classroom quiz assignments.
- Hackathon: KitaHack 2026
- SDG focus: SDG 4 (Quality Education)
- Core value: convert quiz response data into teacher-ready intervention insights
- Current delivery model: Next.js web app with Google OAuth, Firestore-backed sync, and Gemini-powered analysis
- Docs index:
docs/README.md - Product docs:
- Planning docs:
- Technical resources:
Google Classroom API + Google Forms API -> Sync and normalization -> Gemini structured analysis -> Firestore -> Teacher dashboard
- Frontend: Next.js App Router pages for landing, onboarding, dashboard, course/quiz workspace, history, settings, and error recovery
- Backend: Next.js Route Handlers for auth, sync orchestration, analysis execution, and dashboard reads
- Data store: Firebase Firestore collections for users, courses, quizzes, responses, analyses, and notes
- AI layer: Gemini structured-output calls with schema and semantic validation before persistence
lib/auth/*: server-side OAuth, token storage, and encrypted session cookie handlingapp/api/sync/*: Classroom and Forms ingestion into Firestoreapp/api/analyze/*: quiz, history, and course-material analysis endpointslib/analysis/*: prompt builders, output schemas, and validation logicapp/dashboard/*+components/*: teacher workflow UI and insight panels
| Route | Method | Purpose |
|---|---|---|
/api/auth/login |
GET | Start Google OAuth consent flow |
/api/auth/callback |
GET | Exchange auth code, create session, persist user token profile |
/api/auth/status |
GET | Return authenticated state and integration status |
/api/auth/logout |
POST | Destroy session cookie |
/api/bootstrap/run |
POST | Orchestrate first sync and optional seed analysis |
/api/bootstrap/status |
GET | Return bootstrap/sync status |
/api/sync/courses |
POST | Sync Classroom courses and roster counts |
/api/sync/quiz |
POST | Sync course quiz metadata, questions, and responses |
/api/analyze/run |
POST | Run Gemini quiz analysis and persist validated output |
/api/analyze/history |
POST | Run longitudinal history analysis |
/api/analyze/course-materials |
POST | Run course-level material analysis |
/api/dashboard/courses |
GET | Read synced courses |
/api/dashboard/quizzes |
GET | Read quizzes for selected course |
/api/dashboard/analysis |
GET | Read persisted analysis output |
/api/notes + related routes |
GET/POST | Read and generate student notes |
- Language: TypeScript
- Runtime and package manager: Bun (preferred), npm-compatible scripts available
- Frontend: Next.js 16, React 19, Tailwind CSS v4
- Backend: Next.js Route Handlers (
runtime = "nodejs") - Database: Firebase Firestore (Admin SDK on server)
- Charts: Recharts
- AI SDK:
@google/genai
- OAuth is server-side using Google consent + callback routes
- Required scopes cover Classroom courses/rosters/submissions and Forms body/responses
- User OAuth tokens are stored in
users/{googleId}documents - App session is an encrypted HTTP-only cookie (
edu_session) using AES-256-GCM - Token refresh is handled in server utilities before Google API calls
- Course sync pulls active Classroom courses and student counts.
- Quiz sync fetches courseWork, resolves linked Google Form IDs, reads questions and responses.
- Data is written to Firestore collections:
coursesquizzesquizzes/{courseId_quizId}/responses
- Bootstrap orchestration can run an initial sync plus seed analysis run.
Firestore collection contracts are documented in docs/resources/Firestore-Schema.md.
/api/analyze/runbuilds a normalized quiz-analysis input from synced Firestore data- Gemini is called in JSON mode with
responseJsonSchema - Output is validated in two layers:
- schema-level structure checks
- semantic checks against input fixture invariants
- Retry and fallback strategies are applied for transient model failures and malformed outputs
- Validated outputs are persisted into
analyses/{courseId_quizId}with derived metrics
- Canonical flow follows docs navigation:
/->/onboarding/integrations->/dashboard-> course -> quiz workspace
- Quiz workspace uses query-driven tabs:
?view=analysis?view=insights?view=students(and optionalstudentId)
- Dashboard routes share a persistent shell (sidebar + breadcrumb context)
- Install dependencies:
bun install- Create
.env.local:
# Firebase client
NEXT_PUBLIC_FIREBASE_API_KEY=
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=
NEXT_PUBLIC_FIREBASE_PROJECT_ID=
NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=
NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=
NEXT_PUBLIC_FIREBASE_APP_ID=
NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID=
# Firebase admin
FIREBASE_CLIENT_EMAIL=
FIREBASE_PRIVATE_KEY=
FIREBASE_PROJECT_ID=
# Google OAuth
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
GOOGLE_REDIRECT_URI=http://localhost:3000/api/auth/callback
SESSION_SECRET=
# Gemini
GEMINI_API_KEY=
GEMINI_API_KEY2=
GEMINI_API_KEY3=
GEMINI_API_KEY4=
GEMINI_API_KEY5=- Run development server:
bun run dev- Optional validation scripts:
bun run lint
bun run build
bun run analysis:quiz-harness
bun run analysis:structured-smoke- OAuth and scope complexity:
- Managing correct Classroom/Forms scopes, refresh behavior, and reconnect handling required careful server-side token lifecycle logic.
- Classroom-to-Forms data correlation:
- Mapping course roster identities to form respondents is not always perfect, especially when response identity signals are incomplete.
- Structured AI output reliability:
- Complex/deep schemas can fail with
INVALID_ARGUMENT; flatter API-facing schemas plus strict local validation were needed.
- Complex/deep schemas can fail with
- Model quota and availability constraints:
- Free-tier limits can block specific Gemini model IDs, so fallback chains and key rotation logic were introduced.
- Incomplete upstream data conditions:
- Some quizzes can sync without full grading metadata, requiring defensive parsing and partial-data fallbacks.
- Limited automated QA:
- Project validation currently relies on manual testing and script-based smoke checks; no full CI suite is in place yet.
- Complete Google Classroom depth first:
- fully support Classroom workflows beyond baseline quiz sync (assignment lifecycle coverage, richer roster and submission states, grading context continuity)
- improve Classroom-native UX so teachers can operate end-to-end without manual data workarounds
- Expand within the Google ecosystem:
- deepen Google Forms ingestion fidelity (question types, grading modes, edge-case response mapping)
- integrate additional Google Workspace surfaces where useful (for example Drive/Docs-backed intervention artifacts and reporting exports)
- Become LMS-agnostic over time:
- introduce a connector architecture so analysis is not tied only to Google Classroom
- add adapters for other ecosystems (for example Moodle, Canvas, Microsoft Teams for Education) while preserving one shared analysis contract
- Evolve into a broader instructional intelligence layer:
- track longitudinal learning signals across classes, terms, and assessment formats
- shift from reactive reporting to proactive early-warning and intervention planning
- Expand stakeholder value:
- provide role-based views for department heads and school leadership while keeping teacher workflows simple
- generate clearer communication artifacts for parent/student follow-up when needed
- Strengthen reliability and production readiness:
- add automated tests for sync, analysis validation, and route-level regression coverage
- harden quota controls, observability, and deployment guardrails for sustained real-world usage