Skip to content

Add production readiness audit and infrastructure scaffolding#1

Closed
Rajiv-Rago wants to merge 41 commits intomainfrom
claude/audit-professional-features-l1uuO
Closed

Add production readiness audit and infrastructure scaffolding#1
Rajiv-Rago wants to merge 41 commits intomainfrom
claude/audit-professional-features-l1uuO

Conversation

@Rajiv-Rago
Copy link
Copy Markdown
Owner

Summary

This PR adds comprehensive production readiness documentation and scaffolds two critical infrastructure systems: email notifications and distributed rate limiting. Both systems ship with zero-dependency defaults (console logger / in-memory store) and can be upgraded to production backends via environment variables.

Key Changes

Documentation

  • AUDIT.md — Comprehensive production readiness audit covering legal/compliance, security, infrastructure, monitoring, and operational gaps. Identifies Tier 1 blockers (email service, payment integration, legal pages) and provides detailed status across 10 categories.
  • INFRASTRUCTURE_SETUP.md — Step-by-step setup guide for email providers (SendGrid, AWS SES, Resend) and distributed rate limiting (Redis). Includes environment variable reference and custom provider extension patterns.
  • PAGINATION_PLAN.md — Detailed plan for adding consistent pagination across 4 list-returning endpoints that currently lack it, with migration strategy for frontend consumers.

Email Service (lib/email/)

  • types.tsEmailProvider interface, EmailMessage, and SendResult types
  • index.tssendEmail() entry point with provider resolution and singleton caching
  • templates.ts — Transactional email templates (password reset, welcome email)
  • providers/console.ts — Default console provider (logs emails, no dependency)
  • providers/sendgrid.ts — SendGrid provider scaffold (requires @sendgrid/mail)
  • providers/ses.ts — AWS SES provider scaffold (requires @aws-sdk/client-ses)
  • providers/resend.ts — Resend provider scaffold (requires resend)

Rate Limiting (lib/rateLimit/)

  • types.tsRateLimitStore interface, RateLimitConfig, and RateLimitCheckResult types
  • index.tscheckRateLimit() entry point with store resolution, singleton caching, and centralized rule configuration
  • stores/memory.ts — Default in-memory store with periodic cleanup (no dependency)
  • stores/redis.ts — Redis store scaffold (requires ioredis)

Integration

  • middleware.ts — Refactored to use new checkRateLimit() from lib/rateLimit; removed 60 lines of inline rate limiting logic
  • app/api/auth/forgot-password/route.ts — Integrated sendEmail() to send password reset emails (previously logged to console)
  • lib/env.ts — Added email provider configuration variables (EMAIL_PROVIDER, EMAIL_FROM_ADDRESS, SENDGRID_API_KEY, RESEND_API_KEY, AWS_REGION, APP_URL, APP_NAME)
  • package.json — Pinned TypeScript to 5.9.3 for consistency

Implementation Details

  • Zero-dependency defaults — Both systems work out-of-the-box with console/memory providers; real providers are only loaded when explicitly configured
  • Dynamic requires — Email and rate limit providers use dynamic require() so dependencies are only needed when that provider is active
  • Singleton pattern — Both systems cache provider/store instances to avoid repeated initialization
  • Extensible design — Clear interfaces allow adding custom providers/stores without modifying core code
  • Environment-driven — All configuration via environment variables; no code changes needed to swap providers
  • Backward compatible — Middleware refactor maintains identical behavior; password reset flow now sends emails instead of logging

Notes

The audit identifies several production blockers (email service, payment integration, legal pages, analytics) that are now partially addressed by this infrastructure scaffolding. Email service is now functional; payment and legal pages remain out of scope for this PR.

https://claude.ai/code/session_01H4vpUYToUaNfQk38D8cmdR

Rajiv-Rago and others added 30 commits October 25, 2025 23:38
- Add CLAUDE.md with project overview, commands, architecture docs
- Fix package.json bug where duplicate scripts keys caused dev/build/start/lint to be overwritten

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add database models: Course, Module, Lesson, Assignment, Submission,
  AIChatSession, AIGeneratedContent
- Enhance User model with bcrypt password hashing and role-based access
- Implement JWT authentication with HTTP-only cookies
- Create AI provider abstraction supporting OpenAI and Anthropic
- Add AI tutor service for contextual Q&A
- Add AI content generator for quizzes, summaries, practice problems
- Build complete REST API for courses, modules, lessons, assignments
- Add enrollment, grading, and gradebook functionality
- Create auth pages (login, register)
- Create dashboard with role-based views
- Build course management UI for teachers
- Implement assignment submission and grading workflow
- Add AI tutor chat interface
- Add AI content generation with approval workflow
- Update landing page with feature highlights

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add DatabaseConnectionError class for typed error handling
- Add connection timeouts (5s server selection, 10s connect) to fail fast
- Reset cached connection on failure to allow retries
- Return 503 with specific error message for DB connection issues

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Enable students to create self-study courses using AI:
- Add Gemini as new AI provider with @google/generative-ai SDK
- Extend Course, Module, Lesson models with AI generation fields
- Create SyllabusGeneratorService for course structure generation
- Create LessonContentGeneratorService for on-demand content
- Add AIGenerationLog model for tracking AI generations
- Add API endpoints for syllabus generation, content generation
- Update authorization to allow students to create AI courses

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create lib/ai/utils with providerResolver, jsonParser, and promptUtils
- Create lib/validation/aiSchemas with shared Zod schemas
- Create lib/utils with aiGenerationLogger and moduleStatusUpdater helpers
- Fix race condition: module status now recalculates even on errors
- Add syllabus status validation before content generation
- Add previousLessonsSummary size limit (2000 chars) to prevent prompt bloat
- Optimize PATCH endpoint with batch queries instead of N+1

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create /courses/new/ai page with form for AI-generated courses
- Add topic input, level select, duration, and optional context fields
- Include collapsible advanced settings for provider/model override
- Add multi-phase progress indicator during course generation
- Update dashboard with AI course creation buttons for teachers/students
- Update courses page header with AI creation option
- Add AI promotion banner to manual course creation page
- Use purple-to-blue gradient styling to distinguish AI features

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Extend Assignment model with assignmentType (standard/quiz/project)
- Add quiz questions, settings (time limit, shuffle, show answers)
- Add project instructions and file upload settings
- Extend Submission model with quiz attempts tracking and file uploads
- Create quiz API routes for start/submit with auto-grading
- Create file upload API routes with validation
- Add quiz components (QuestionCard, QuestionBuilder, QuizTimer, QuizResults)
- Add project components (FileUploader, FileList, InstructionsViewer)
- Update assignments UI with type badges and filter tabs
- Update gradebook to show assignment types
- Unlimited quiz retakes with best score tracking

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
These providers were referenced in lib/ai/index.ts but not committed,
causing build failures.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove insecure JWT_SECRET fallback — crash if env var is missing
- Add Next.js edge middleware with rate limiting (in-memory Map),
  security headers, and auth redirect for dashboard routes
- Add CSRF protection via X-Requested-With header check on mutations
- Add X-Requested-With: XMLHttpRequest header to all frontend mutation fetches
- Add verifyTokenForRefresh helper for token refresh (Phase 2)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…hase 2)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…cker, and CI

- Create lib/env.ts with Zod schema validating all env vars at import time
- Create lib/logger.ts with structured logging and captureException (Contract 6)
- Add GET /api/health endpoint with version, uptime, and DB connection state
- Update lib/db.ts to use env.ts and expose getConnectionStatus()
- Add multi-stage Dockerfile, docker-compose.yml (app + MongoDB 7), .dockerignore
- Add GitHub Actions CI pipeline (lint, typecheck, test, build)
- Replace all console.error calls across 26 API routes with captureException

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…and utilities

Set up test foundation with mongodb-memory-server, fixture factories,
API request helpers, and mock AI provider. Added unit tests for JWT,
provider resolver, JSON parser, and quiz grader. Added integration tests
for auth (register, login, me) and courses (CRUD, enrollment).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add Makefile with convenience commands for dev workflow (make up, make
test, make prod, etc). Switch Dockerfile to Next.js standalone output
for smaller production images. Add Docker Compose health checks and
dev/prod profiles so `make up` runs only MongoDB while `make prod`
containerizes everything.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Critical fixes:
- C-1: Wire Session model into login/register/logout/refresh — sessions
  are now created on login/register, rotated on refresh, deleted on logout
- C-2: Fix verifyTokenForRefresh to use jwt.verify with ignoreExpiration
  instead of jwt.decode (which skips signature verification)
- C-3: Add email to reset-password request body and query, preventing
  cross-user password reset when multiple tokens are active
- C-4: Remove plaintext reset token from console.log output

High fixes:
- H-1: Logout now deletes the session record from DB (token revocation)
- H-5: Add requireCsrf() to all routes that call authenticate() directly
  (login, register, logout, refresh, forgot-password, reset-password,
  session revoke)

Medium fixes:
- M-3: Add dummy bcrypt hash on forgot-password "user not found" path
  to prevent timing-based user enumeration
- M-4: Use atomic $inc for lockout counter to prevent TOCTOU race
- M-5: Consolidate login/register Zod schemas into authSchemas.ts
- M-8: Replace console.error with captureException in password routes
- M-9: Extract shared getClientIp into lib/utils/request.ts (DRY)

Low fixes:
- L-2: Remove restrictive Mongoose enum on AuditLog.action, use
  TypeScript union type instead for extensibility
- L-3: Rename REFRESH_GRACE_PERIOD to REFRESH_GRACE_PERIOD_SECONDS
- L-5: Change Session.userAgent default from "" to "unknown"
- M-2: Add JSDoc warning to decodeToken about missing signature check

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The test helper's buildRequest function now includes the
X-Requested-With: XMLHttpRequest header on mutation methods
(POST, PUT, PATCH, DELETE) to satisfy the CSRF check added
in the auth security hardening.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix captureException context key collision: rename formatError fields
  to errorName/errorMessage, rename caller key from message to operation
  across all 57 call sites (H1, M2)
- Health endpoint: return 503 when DB disconnected, eagerly call
  dbConnect(), use process.uptime() instead of module-level timer (H2, H3, L2)
- Fix misplaced import in files/route.ts — move to top of file (M1)
- CI: add MongoDB healthcheck for service readiness, gate test/build
  on lint+typecheck with needs: (M3, M4)
- Enforce JWT_SECRET minimum 32 characters in env validation (M6)
- Add captureException to 3 missed auth routes: logout, sessions,
  sessions/[id] (L5)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…mode, and accessibility

Phase 1: Toast system with auto-dismiss, confirmation dialogs with promise API,
error boundaries (root + dashboard) with captureException, and loading skeleton
components (card, table, text variants).

Phase 2: Notification model with indexes, sendNotification() (Contract 4),
notification API routes (list, mark read, SSE stream), NotificationBell UI
with polling and unread badge. Triggers on enroll, submit, grade, and AI generate.

Phase 3: Dark mode toggle with localStorage persistence and FOUC prevention,
accessibility improvements (ARIA labels, semantic HTML, skip-to-content, focus
trap, keyboard navigation), replaced native confirm() with async dialog,
replaced spinners with skeletons, added toast feedback across all dashboard pages.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix test timeout by increasing default jest timeout to 15s. Add
integration tests for assignment CRUD, submissions, and grading.
Add model validation tests for User, Assignment, and Submission.
Add unit tests for SyllabusGenerator, LessonContentGenerator, and
AITutorService with mocked providers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Introduces a 3-tier model selection system (Fast/Balanced/Powerful) as
the primary UX for choosing AI models, with advanced override for
specific provider+model. Each tier maps to an ordered preference list
and resolves to the first provider with a configured API key.

- Add tier catalog, resolver, and metadata (tierCatalog.ts)
- Expand provider resolver to 6-level priority chain: request >
  tier > course prefs > user prefs > env vars > fallback
- Add aiPreferences subdocument to User model
- Add /api/ai/config and /api/users/preferences endpoints
- Create reusable ModelSelector component with tier buttons
- Add Settings page with AI preferences
- Integrate ModelSelector into AI course creation, content generation,
  and AI tutor pages
- Wire tier + user preferences through all AI API routes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…iting

Centralizes model definitions in a registry with human-friendly display
names (e.g. "GPT 4.1 Mini" instead of "gpt-4.1-mini-2025-04-14") and
adds daily per-user rate limits to all AI endpoints to prevent unchecked
API token consumption.
rajiv_rago and others added 10 commits February 23, 2026 04:26
This file was created in a prior session but never committed. It's
imported by tierCatalog, providerResolver, and the AI config route.
Includes job queue, storage adapters, cache, migrations, seed script,
admin trash, user data export/delete, instrumentation, and updated
model/route/env changes that were on disk but never committed.
After AI syllabus creation produces a course skeleton, users can now
generate lesson content via a dedicated dashboard. Adds a multi-job
polling hook, a batch generate-all API endpoint, and a content
management page with progress tracking, status badges, and per-module/
lesson generation controls. Course detail page shows AI content banner
and status dots. Syllabus creation now redirects to the dashboard.
The dynamic import() of AI handlers was fire-and-forget, creating a race
condition where SyncShim.enqueueJob() called getHandler() before handlers
were registered. Export handlersReady promise and await it in both SyncShim
and worker before looking up handlers.
Remove the separate module detail page and AI content dashboard,
consolidating both into the course detail page. Modules are now
expandable with inline edit/delete/publish and add-lesson forms.
AI generation toolbar with model selector, progress bar, batch
selection, and per-item generate buttons lives directly on the
course page. Old URLs redirect to preserve bookmarks.
…tions

Replace role-based AI rate limiting with subscription tiers (free/plus/admin)
and two currencies: questions (AI tutor chat) and credits (content generation).
Credits support variable cost — module generation charges 1 credit per lesson.
Support revision requests when regenerating lesson content by passing
user feedback and previous content to the LLM. Also expose courseType
in the lesson GET response.
Comprehensive audit of 13 categories: legal/compliance pages, security
posture, email/transactional, payments, SEO, monitoring, analytics,
DevOps, accessibility, performance, account management, admin tools,
and static pages. Identifies 24 items across 3 priority tiers.

https://claude.ai/code/session_01H4vpUYToUaNfQk38D8cmdR
- Email service (lib/email/) with provider interface and console default;
  SendGrid, SES, and Resend scaffolds ready for npm install + env config
- Rate limit store (lib/rateLimit/) with memory default and Redis scaffold;
  middleware refactored to use the new async store abstraction
- Forgot-password route wired to email service (replaces console.log)
- New env vars: EMAIL_PROVIDER, RATE_LIMIT_STORE, APP_URL, APP_NAME
- docs/INFRASTRUCTURE_SETUP.md: step-by-step guide for activating both
- docs/PAGINATION_PLAN.md: endpoint inventory and migration strategy

https://claude.ai/code/session_01H4vpUYToUaNfQk38D8cmdR
@vercel
Copy link
Copy Markdown

vercel bot commented Feb 24, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
lms Ready Ready Preview, Comment Feb 24, 2026 7:00am

- Create shared parsePagination/paginationMeta utility (lib/utils/pagination.ts)
- Add pagination to 4 previously-unbounded endpoints:
  modules (default 50), lessons (50), admin/trash (20), auth/sessions (50)
- Normalize all 11 list endpoints to consistent { data, pagination } response shape
  (gradebook keeps composite shape as exception)
- Update 6 frontend consumers for response key renames
- Update 3 integration test files for new response keys
- All endpoints now enforce max-limit caps

https://claude.ai/code/session_01H4vpUYToUaNfQk38D8cmdR
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants