- Innovative Solutions Project for VCE Computing Unit 2
- The proceeding explanation was entirely AI generated *
Modern exam creation app built with Next.js App Router, TypeScript, Tailwind CSS, NextAuth, and MongoDB/Mongoose. It includes an editor for composing questions, user authentication with 2FA, and optional AI-powered helpers (OpenAI) with rate limiting.
- Next.js 15 (App Router) + TypeScript
- Tailwind CSS 4
- NextAuth (credentials provider + session cookie)
- MongoDB + Mongoose
- Zustand for client state (editor)
- OpenAI SDK (optional AI features)
- Mailgun (email delivery)
Prerequisites:
- Node 18+ and Bun (preferred) installed
- MongoDB connection string
Setup:
- bun install
- Copy your environment variables into
.env(see Env Vars below) - bun run dev
Other scripts:
- bun run build – compile the app
- bun run start – start production build (port 80)
- bun run lint – run ESLint
Put these in .env or .env.local (never commit secrets):
- MONGODB_URI – MongoDB connection string
- NEXTAUTH_URL – base URL (e.g. http://localhost:3000 in dev)
- NEXTAUTH_SECRET or AUTH_SECRET – NextAuth secret
- CF_TURNSTILE_SECRET – Cloudflare Turnstile secret (for CAPTCHA on auth)
- MG_SECRET_KEY – Mailgun API key (email verification/notifications)
- OPENAI_API_KEY – enables AI features (MCQ options, solutions, question checking)
Notes:
- Mailgun domain is currently set to
mg.testfly.appinsrc/lib/auth/send_email.ts. Change if needed. - API routes are protected via
middleware.tsand asessionIdcookie persisted in MongoDB.
This section lists the file structure with a brief description of each file.
Top-level
- .env – local environment variables (keep private; not for commit)
- .gitignore – Git ignore rules
- .next/ – Next.js build cache/output (generated)
- .prettierrc – Prettier configuration
- AGENTS.md – Contributor guidance and coding conventions
- README.md – This document
- bun.lock – Bun lockfile
- eslint.config.mjs – ESLint config (Next core-web-vitals + TS)
- middleware.ts – Guards
/api/*routes usingsessionId+ Mongo session - next-env.d.ts – Next.js generated type declarations
- next.config.ts – Next.js config
- node_modules/ – installed dependencies
- package.json – scripts and dependencies
- package-lock.json – npm lockfile (present alongside Bun; use Bun primarily)
- postcss.config.mjs – PostCSS config for Tailwind
- public/test_images/* – sample images used on the homepage
- src/ – application source
- tailwind.config.js – Tailwind configuration + custom tokens
- tsconfig.json – TypeScript config (strict mode, path alias
@/*) - tsconfig.tsbuildinfo – TS incremental build info (generated)
src/app – App Router pages and APIs
- app/layout.tsx – root layout; global fonts, Providers, Navbar
- app/globals.css – Tailwind base and global helpers
- app/Cards.css – homepage card grid styling
- app/page.tsx – marketing/landing homepage
- app/login/layout.tsx – login layout; redirects authed users to dashboard
- app/login/page.tsx – login form with Turnstile and 2FA path
- app/signup/layout.tsx – signup layout; redirects authed users to dashboard
- app/signup/page.tsx – signup form with Turnstile + email verification flow
- app/email/page.tsx – “check your email” notice after signup
- app/verify/page.tsx – verifies email via
userid+tokenquery params
app/(authed)/dashboard – authenticated dashboard
- page.tsx – server component; ensures auth, renders layout
- _components/dashboard_layout.tsx – shell with sidebar + topbar
- _components/documents_launcher.tsx – dashboard welcome launcher
- _components/top_nav.tsx – top nav with class/document actions
- _components/topbar/new_doc.tsx – “New Document” prompt + API call
- _components/sidebar.tsx – collapsible sidebar wrapper
- _components/sidebar/classes_list.tsx – class list with context menu
- _components/sidebar/class_item.tsx – single class row
- _components/sidebar/new_class.tsx – creates new class via prompt + API
- _components/sidebar/recents_list.tsx – recent documents list
- _components/docs/picker.tsx – document grid picker (search/sort)
- _components/docs/document_file.tsx – document card tile
- _components/docs/document_skeleton.tsx – loading skeleton for documents
- _components/docs/use_doc_ctx_menu.tsx – document context menu (rename/delete)
- _hooks/use_classes_list.ts – fetch + manage class list
- _hooks/use_document_picker.ts – fetch + manage documents for class
- _types/document_list.ts – small type for recent docs
- classes/[id]/page.tsx – class view: validates ownership, renders picker
app/(authed)/editor/[id] – document editor
- page.tsx – client entry; loads Editor lazily with loader UI
- loading.tsx – route-level loading indicator
- _components/editor_client_main.tsx – top-level editor integration with store
- _components/types.ts – shared editor types and color tokens
- _components/editor_client/editor_layout.tsx – editor shell (explorer, canvas, sidebar)
- _components/editor_client/page.tsx – canvas rendering, drag/resize, inline edit
- _components/editor_client/bottom_bar.tsx – page tabs (add/rename/delete)
- _components/editor_client/layout.ts – layout helpers (snap/grid/format)
- _components/editor_client/switch.tsx – small UI toggle component
- _components/editor_client/math_input.tsx – input with LaTeX helpers and preview
- _components/editor_client/math_renderer.tsx – KaTeX-based renderer
- _components/editor_client/blocks/editor_block.tsx – block renderers (section/mcq/paragraph)
- _components/editor_client/blocks/registry.ts – block registry + factory
- _components/editor_client/context_menus/element_context_menu.tsx – canvas item menu
- _components/editor_client/context_menus/block_list_context_menu.tsx – explorer block menu
- _components/editor_client/context_menus/explorer_header_context_menu.tsx – explorer header menu
- _components/editor_client/question_explorer.tsx – left explorer (pages/sections/problems)
- _components/editor_client/right_sidebar.tsx – right side inspector + page settings
- _components/editor_client/right_sidebar/page_title.tsx – page title control
- _components/editor_client/right_sidebar/page_background.tsx – page background color
- _components/editor_client/right_sidebar/title_size.tsx – question title size
- _components/editor_client/right_sidebar/title_color.tsx – question title color
- _components/editor_client/right_sidebar/content_size.tsx – question body size
- _components/editor_client/right_sidebar/content_color.tsx – question body color
- _components/editor_client/right_sidebar/horizontal_margin.tsx – horizontal margin
- _components/editor_client/right_sidebar/vertical_margin.tsx – vertical margin
- _components/editor_client/right_sidebar/question_spacing.tsx – question spacing
- _components/editor_client/right_sidebar/font_size.tsx – inline style font size
- _components/editor_client/right_sidebar/text_color.tsx – inline style color
- _components/editor_client/right_sidebar/background_color.tsx – inline style bg color
- _components/editor_client/right_sidebar/border.tsx – inline style border
- _components/editor_client/right_sidebar/padding.tsx – inline style padding
- _components/editor_client/services/question_checker.ts – debounced proofing pipeline calling
/api/completions/check_question_errors - _components/editor_client/store/editor_store.ts – Zustand store (document/page/blocks, selection, AI state)
- _components/editor_client/README.md – internal note for linting
app/(authed)/settings – authenticated settings
- page.tsx – server auth gate + client settings page
- _components/settings.tsx – settings page composition and data fetch
- _components/account_details.tsx – account status + AI plan showcase
- _components/change_email.tsx – email change form and API call
- _components/change_password.tsx – password change form and API call
- _components/two_factor_auth.tsx – 2FA setup/verify/disable flows
- _components/ai_plus/list_item.tsx – bullet list item with check icon
app/api – API routes (protected by middleware unless public)
Auth
- api/auth/[...nextauth]/route.ts – NextAuth route handlers (GET/POST)
- api/auth/signup/route.ts – sign up user, Turnstile verify, send verification email
- api/auth/logout/route.ts – deletes DB session and clears cookie
Classes
- api/classes/check/route.ts – checks if a class name exists (current user)
- api/classes/create/route.ts – create a class (dedup by normalized name)
- api/classes/delete/route.ts – delete a class (owner only)
- api/classes/get/route.ts – fetch a single class (ownership validated)
- api/classes/list/route.ts – list all classes for current user
- api/classes/rename/route.ts – rename class with collision checks
Documents
- api/documents/create/route.ts – create document in class, update recents + class count
- api/documents/delete/route.ts – delete document, update recents + class count
- api/documents/list/route.ts – list documents in a class
- api/documents/read/route.ts – placeholder read endpoint
- api/documents/rename/route.ts – rename document with collision checks
- api/documents/save/route.ts – placeholder save endpoint (persist to storage)
User
- api/user/get_details/route.ts – returns current user document
- api/user/get_recent/route.ts – recent documents (populated)
- api/user/update/email/route.ts – initiate email change + verification
- api/user/update/password/route.ts – change password + notify via email
- api/user/update/two_factor/setup/route.ts – start 2FA (generate secret + URI)
- api/user/update/two_factor/verify_secret/route.ts – confirm 2FA with OTP
- api/user/update/two_factor/disable/route.ts – disable 2FA (password + OTP required)
Completions (AI)
- api/completions/multi_choice/route.ts – generate 4 MCQ options (OpenAI)
- api/completions/check_question_errors/route.ts – question proofing (spelling/grammar/etc)
- api/completions/solutions/route.ts – step-by-step solution and marks
- api/completions/pick_multi_choice/route.ts – choose correct MCQ option among candidates
src/components – Reusable UI
- providers.tsx – NextAuth
SessionProviderwrapper - navbar_wrapper.tsx – conditionally render navbar
- navbar.tsx – responsive navbar (shows recents, auth state)
- footer.tsx – simple footer
- backgrounds/login.tsx – SVG background (login)
- backgrounds/signup.tsx – SVG background (signup)
- badges/message.tsx – styled message badge
- badges/messages.tsx – stack of message badges
- ui/button.tsx – primary button
- ui/compact_button.tsx – compact secondary button
- ui/back_button.tsx – icon back button
- ui/horizontal_divider.tsx – simple divider
- ui/input.tsx – labeled input
- ui/select.tsx – labeled select with caret
- ui/toggle_arrow_button.tsx – up/down toggle for sort direction
- ui/context_menus/ContextMenu.tsx – context menu container
- ui/context_menus/ContextMenuItem.tsx – context menu item
- ui/modals/modal.tsx – accessible modal core (focus trap, esc, backdrop)
- ui/modals/prompt_modal.tsx – modal with input + validation
- ui/modals/message_modal.tsx – confirm/alert modal
- ui/modals/hooks/use_prompt.tsx – imperative prompt hook returning a Promise
- ui/modals/hooks/use_message_modal.tsx – imperative message modal hook
src/lib – Server/lib code
- config/db.ts – Mongoose connection helper
- auth.ts – NextAuth credentials provider with Turnstile + custom session cookie
- auth_errors.ts – custom NextAuth error classes (typed
code) - auth/check_logged_in.ts – server util to redirect unauthenticated
- auth/get_user_from_cookie.ts – read
sessionIdcookie → Session → User - auth/get_api_user.ts – read
x-user-idheader injected by middleware - auth/send_email.ts – send email via Mailgun
- auth/user/generate_email_confirm_token.ts – generate token + verify URL
- models/user.ts – Mongoose
Userschema - models/session.ts – Mongoose
Sessionschema (sessionId, userId, expires) - models/document.ts – Mongoose
Documentschema - models/class.ts – Mongoose
Classschema - functions/validate_email.ts – email format validator
- functions/clean_email.ts – normalize plus-addressing
- completions/infer.ts – OpenAI wrapper (text or Zod-typed JSON)
- completions/multi_choice.ts – generate MCQ options (4)
- completions/solution.ts – generate solution steps + marks
- completions/pick_multi_choice_solution.ts – select correct MCQ option
- completions/check_question_errors.ts – detect issues + corrected version
- api/responses/fail.ts – JSON error helper
{ success:false, code, message } - api/completions/rate_limit.ts – per-user rate limit window + counters
- Use the
@/*path alias for imports (seetsconfig.json). - Components and hooks prefer lowercase with underscores (e.g.,
navbar_wrapper.tsx). - Tailwind tokens are in
tailwind.config.jsundercolors.custom.*. - Middleware protects
/api/*and injectsx-user-idheader for handlers if the session is valid. - AI endpoints check
user.has_ai_permsand apply a per-user rate limit.
Generative AI was used to an extent in this project, particularly ChatGPT Codex to make quick fixes and resolve small issues quickly. Use of Generative AI was limited to this purpose. You can view changes made by Generative AI by looking for Pull Requests with the tag "codex".