Claude Code Updates
GRIO Platform Development Roadmap & Implementation Plan
Project context: GRIO is an AI-powered education platform for East/Southern African schools (Uganda, Kenya, Zambia). A proof-of-concept frontend was built with bolt.new (Next.js 16) and developers started a Django backend. Six technical documents describe the target architecture: a 6-layer system with RAG pipeline, real-time classrooms, 5 learning modes, Redis/Celery, Qdrant vector DB, MinIO storage, K3s orchestration, and monitoring.
Current state: Working but incomplete — 60+ API endpoints, 19 models, 4 learning modes, JWT auth, 4 role portals. Missing: RAG (AI calls go directly to OpenAI), WebSocket, Redis/Celery, tests, rate limiting, API versioning, monitoring, offline support.
Decision: Expand existing repos (not rebuild). The existing code is ~80% aligned in data model and covers all role portals. Rebuilding would lose months of work.
Phase 1: Foundation
Goal: Production infrastructure without breaking existing functionality.
1.1 API Versioning Small
- Create
grio-api/grio_api/api_v1_urls.py— aggregates all app URL includes under/api/v1/ - Modify
grio_api/urls.py— add v1 route, keep existing/api/as backward-compat alias - Add
DEFAULT_VERSIONING_CLASStoREST_FRAMEWORKinsettings.py - Update
grio/services/api.ts— prefix all paths with/api/v1, feature flag for fallback
1.2 Test Infrastructure Medium
Backend
- Add dev deps:
pytest,pytest-django,pytest-cov,factory-boy,faker - Create
grio-api/conftest.py— shared fixtures (auth client, sample school, curriculum hierarchy, user per role) - Create
grio-api/tests/—test_auth.py,test_curriculum.py,test_ai_engine.py,test_permissions.py,test_progress.py,factories.py - Target: 80% coverage on models/views, mock all OpenAI calls
Frontend
- Add:
vitest,@testing-library/react,@testing-library/jest-dom,msw - Create
grio/__tests__/services/api.test.ts,grio/__tests__/components/AiLessonEngine.test.tsx
1.3 Redis + Celery Medium
- Add deps:
django-redis,celery[redis],django-celery-results - Create
grio-api/grio_api/celery.py— Celery app config - Modify
grio_api/__init__.py— import celery app - Add to
settings.py:CACHES(Redis),CELERY_BROKER_URL,CELERY_RESULT_BACKEND - Create
grio-api/ai_engine/tasks.py— async stubs:generate_ai_response_async,aggregate_analytics - Modify
docker-compose.yml— add Redis service + Celery worker service
1.4 Rate Limiting + Pagination Small
- Add DRF throttling to
settings.py:UserRateThrottle(100/min),AnonRateThrottle(20/min) - Add
DEFAULT_PAGINATION_CLASS:PageNumberPagination,PAGE_SIZE: 50 - Add login-specific throttle: 5 attempts per 15 min in
users/views/auth.py - Update
grio/services/api.ts— handle paginated response envelope (results/count/next)
1.5 Django App Reorganization Small
Create 3 new app skeletons (empty, receive code in later phases):
grio-api/learning/— will hold RAG config, mode enginesgrio-api/assessment/— will hold quiz/practice/exam models, mastery trackinggrio-api/analytics_engine/— will hold analytics models and aggregation
Register in settings.py INSTALLED_APPS
1.6 New Models Medium
Add to ai_engine/models.py:
AIContextRules — hierarchical AI behavior constraints (topic > class > subject > global)
scope_level(global/subject/class/topic), FK to curriculum/subject/class_level/topic (all nullable)constraints(JSONField) — max_tokens, temperature, allowed_modesknowledge_source(JSONField) — RAG config: collection_name, chunk_size, top_kprompt_template(TextField),is_active,priority, timestamps
PracticeAttempt — individual question attempt for mastery tracking
- FK to user, session, topic
question_text,question_type(mcq/short_answer),user_answer,correct_answeris_correct,feedback,hint_count,time_spent_seconds,created_at
Model modifications
- Modify
ClassSession: add classroom FK,end_time,session_data(JSONField for step state) - Modify
LessonProgress: addmode,time_spent_seconds,mastery_score - All new fields nullable/defaulted — zero downtime migration
Phase 2: Core AI
Goal: RAG-anchored AI pipeline. Strict Teach mode. New Explore + Practice modes.
2.1 RAG Pipeline + Qdrant Large
- Add deps:
qdrant-client,langchain-qdrant,tiktoken
Create grio-api/learning/rag/ package:
chunker.py— 512-token chunks, 64-token overlap (tiktoken)embedder.py— wraps OpenAItext-embedding-3-smallretriever.py— query + curriculum/subject/topic scope, top-5 retrieval, top-3 concatenatedpipeline.py— orchestrates: retrieve context → build prompt → call LLM → validate responseindexer.py— takes LessonContent, chunks, embeds, upserts to Qdrant with metadata
Create management command: learning/management/commands/index_curriculum.py
Add Qdrant to docker-compose.yml (port 6333)
Refactor ai_engine/services.py
- Rename current class to
LegacyAIService - Create
RAGAIServiceusinglearning.rag.pipeline - Enforce: AI never responds without curriculum context (non-negotiable rule #1)
- Add PII filtering on AI output
- Add prompt injection detection on user input
- Feature flag:
USE_RAG_PIPELINEin settings for gradual rollout
2.2 Strict Teach Mode Medium
Non-negotiable rule #5: Classroom always starts in Teach mode, never chat.
Create grio-api/learning/teach_engine.py:
- Steps: intro → explanation → example → practice → quiz → recap
- Tracks current step in
ClassSession.session_data['current_step'] advance_step(session_id)— validates completion, moves to next- Cannot skip steps, no free-form input during teach
Add endpoints: POST /api/v1/ai/teach/advance/, GET /api/v1/ai/teach/state/{session_id}/
Frontend: components/modes/TeachMode.tsx
- Remove
sleep()auto-advance logic - Step progress bar: Intro | Explanation | Example | Practice | Quiz | Recap
- "Next" button calls API, gated per step
- Teacher gets "Skip Step" and "Repeat Step" controls
2.3 Explore Mode Medium
Create grio-api/learning/explore_engine.py — student Q&A within topic, RAG-scoped. Off-topic questions get polite redirects.
Add endpoint: POST /api/v1/ai/explore/ask/
Frontend: components/modes/ExploreMode.tsx
- Chat interface (reuse
ChatMessageThread) - Topic header, suggested questions sidebar
- Responses show curriculum citations
2.4 Practice Mode Medium
Create grio-api/learning/practice_engine.py:
- One question at a time (MCQ or short answer), immediate feedback
- Records
PracticeAttempt, calculates running accuracy - Adaptive difficulty: >80% harder, <50% easier
Endpoints: POST .../practice/next-question/, POST .../practice/submit-answer/, GET .../practice/mastery/{topic_id}/
Frontend: components/modes/PracticeMode.tsx
- Single question display, mastery progress bar, session stats sidebar
2.5 Mode System Update Small
- Update
ClassSession.MODE_CHOICES— add explore, practice - Update
grio/lib/types.ts— extendSessionModetype - Update
grio/app/classroom/page.tsx— add new modes to selector
Phase 3: Real-time & Classroom
Goal: WebSocket for classroom sync, teacher control, server-side sessions, media storage.
3.1 Django Channels + WebSocket Large
- Add deps:
channels,channels-redis,daphne - Add
daphneto top ofINSTALLED_APPS, configureCHANNEL_LAYERS(Redis) - Modify
asgi.py—ProtocolTypeRouterwith JWT auth middleware for WebSocket
Create ai_engine/consumers.py — ClassroomConsumer:
- Join classroom group on connect
- Handle:
mode_change,step_advance,pause_session,resume_session,end_session - Broadcast updates to all students in group
Create ai_engine/routing.py — ws/classroom/<session_id>/
Switch from Gunicorn to Daphne in Dockerfile
3.2 Teacher Classroom Control Medium
Add REST endpoints for teacher actions:
POST /api/v1/classroom/session/create/— always starts in Teach modePOST .../session/{id}/change-mode/— validates teach completion before allowing chatPOST .../session/{id}/pause/POST .../session/{id}/advance-all/GET .../session/{id}/student-status/
These endpoints also broadcast via WebSocket.
- Create
grio/hooks/useClassroomWebSocket.ts— connect, reconnect, dispatch events - Create
grio/components/TeacherControlBar.tsx— mode switcher, step advance, pause/resume, student status grid
3.3 Server-Side Session State Medium
Create ai_engine/session_manager.py:
- Active state in Redis (
session:{id}:state, TTL 24h) - Updates queue Celery task to persist to PostgreSQL
- Session recovery: check for active session on page load
Remove localStorage session storage from frontend AppContext.tsx
3.4 MinIO Media Storage Medium
- Add deps:
django-storages,boto3 - Configure S3-compatible storage in
settings.pypointing to MinIO - Add MinIO to
docker-compose.yml(ports 9000, 9001) - Update
LessonContentto support MinIO file references
Phase 4: Production Hardening
Goal: Monitoring, security, CI/CD, edge/offline preparation.
4.1 Monitoring Medium
- Add
django-prometheus— middleware, DB wrapper,/metricsendpoint - Add to
docker-compose: Prometheus, Grafana (pre-built dashboards), Loki + Promtail - Dashboards: API latency, error rates, AI response times, active sessions
4.2 Security Hardening Medium
Create grio_api/middleware/security.py:
PIIFilterMiddleware— redact email/phone/ID from AI responsesPromptInjectionMiddleware— detect injection patterns in AI inputSecurityHeadersMiddleware— CSP, HSTS, X-Content-Type-Options
- Add login account lockout (5 failures → 15-min cooldown)
- Create PostgreSQL RLS migration for school-scoped tables (
RunSQL) - Create
users/middleware.py—TenantMiddlewaresetsrequest.tenantfrom auth user
4.3 CI/CD Pipeline Medium
- Create
grio-api/.github/workflows/ci.yml— lint (ruff), type check (mypy), test (pytest + PostgreSQL service), coverage, Docker build, deploy to staging - Create
grio/.github/workflows/ci.yml— lint (eslint), type check (tsc), test (vitest), build (next build), Docker build - Create
grio-api/k3s/— namespace, deployment, service, ingress, configmap, secret manifests
4.4 Edge/Offline Preparation Large
- Create
learning/offline/snapshot.py— generate curriculum JSON pack per school - Create
learning/offline/sync.py— define sync protocol for edge devices - Add Celery task:
generate_offline_pack(school_id, curriculum_id) - Create
grio/lib/offlineStorage.ts— IndexedDB wrapper - Add service worker + PWA manifest to frontend
4.5 Exam Prep Mode Stub Small
- Create stub engine in
assessment/exam_prep.py - Add
exam_preptoClassSession.MODE_CHOICES - Create
grio/components/modes/ExamPrepMode.tsx— "Coming Soon" UI
Critical Files (Most Modified Across Phases)
| File | Phases | Role |
|---|---|---|
grio-api/ai_engine/services.py | 1, 2 | Current AI service → RAG refactor |
grio-api/ai_engine/models.py | 1, 2, 4 | New models + field additions |
grio-api/grio_api/settings.py | 1, 2, 3, 4 | All infrastructure config |
grio-api/docker-compose.yml | 1, 2, 3, 4 | Redis, Qdrant, MinIO, Celery, monitoring |
grio/components/AiLessonEngine.tsx | 2 | Decompose into per-mode components |
grio/services/api.ts | 1, 2, 3 | Versioning, pagination, WebSocket, offline |
grio/lib/types.ts | 2, 3 | New modes, WebSocket events |
grio/app/classroom/page.tsx | 2, 3 | New modes, WebSocket, teacher controls |
Migration Strategy
- All migrations are additive (nullable/defaulted fields). Zero downtime.
- Never remove columns until 2 releases after deprecation.
- Use
db_tableif moving models between apps to avoid table recreation. - Run
makemigrations --checkin CI to ensure migration files are committed.
Verification Criteria
Phase 1: pytest passes, all existing endpoints return same responses, Redis ping succeeds, Celery worker starts.
Phase 2: Index curriculum → query Qdrant returns chunks. Teach mode steps advance correctly. Explore/Practice return RAG-grounded responses. Feature flag toggles between legacy and RAG AI.
Phase 3: WebSocket connects, teacher advance broadcasts to student. Session survives page refresh (Redis). Files upload to MinIO.
Phase 4:
/metricsendpoint returns Prometheus data. Prompt injection attempts blocked. CI pipeline green. Offline pack generates valid JSON.
Document Control
| Version | Date | Author | Change |
|---|---|---|---|
| 1.0 | Mar 24, 2026 | Claude Code | Initial development roadmap and implementation plan |
This document outlines the phased implementation plan for expanding the existing GRIO codebase toward the full architecture described in documents 01–06.