# Project export: LearnLab: AI Assisted Student Learning Record (SLR)

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: OpenAI Build Week
- Tagline: Student Learning Records (SLR) that turn assessment evidence, confidence, homework and upcoming exam scope into explainable next steps.
- Devpost: https://devpost.com/software/all_in_one_tutor
- GitHub: https://github.com/ua246/learnlab
- Demo: https://learnlabgpt.usairam.co.uk/
- Video: https://www.youtube.com/embed/8eyh87RLbWE?enablejsapi=1&hl=en_US&rel=0&start=&version=3&wmode=transparent
- Team: 1 GitHub contributor(s) — Usairam (45 commits)

## Devpost submission (written by the team)

No Devpost description available.

## README (from the GitHub repository)

# LearnLab

**LearnLab** is a fictional Build Week demonstration of a persistent GCSE Science learning record. It brings assessment evidence, homework, topic mastery, upcoming AQA exams and teacher updates into role-aware student, teacher and parent experiences.

It is not a grading engine and it does not use model output as the source of truth. Deterministic TypeScript calculations create the record; the optional assistants explain the permitted facts from that record.

**Links:** [live demo](https://learnlabgpt.usairam.co.uk) · [source repository](https://github.com/ua246/learnlab) · [fictional demo access](docs/build-week-demo-access.md)

## The problem

Revision is often driven by scattered test marks, homework reminders and vague advice. Students do not see the specific evidence behind a suggested next step; teachers need to piece together class patterns; and upcoming assessments are not usually linked to the exact content being assessed.

LearnLab demonstrates a structured record that keeps these facts together over time. It separates demonstrated mastery from a student's own confidence, links upcoming assessments to curriculum points, and presents explainable priorities rather than invented predictions.

## What is implemented

- Student dashboard: assessment history and score trends, Paper 1/2 topic mastery, homework, upcoming exams, Year 10-to-Year 11 archive, and explainable revision priorities.
- Teacher dashboard: class overview, subject-scoped student records, topic gaps, upcoming-exam authoring linked to AQA specification points and sub-points, and an evidence-grounded class assistant.
- Parent dashboard: one linked student's overview, assessment history, archive and a bounded support assistant. Teacher-only and student-only updates are excluded.
- Curriculum scope: AQA GCSE separate Biology (8461), Chemistry (8462), and Physics (8463), including Paper 1 and Paper 2 points represented in the demo dataset.
- Tutor routes: signed fictional sessions derive the permitted student, teacher or parent context server-side. The dashboard assistants use Groq when configured; they are quota-limited and explicitly unavailable if not configured.
- Custom GPT Action demo: a separate, read-only key-scoped API contract in [`docs/openapi-actions.yaml`](docs/openapi-actions.yaml). It is intentionally for fictional Build Week data only.

## Run locally

Requirements: Node.js 20.9+ and npm.

```bash
npm install
npm run dev
```

Open [http://localhost:3000](http://localhost:3000).

For a production-like local run:

```bash
npm run build
npm start
```

For normal local dashboard use, set a session secret in an uncommitted `.env.local` file:

```env
TUTOR_SESSION_SECRET=replace-with-a-random-local-secret
```

The optional Groq tutor and shared demo persistence additionally require `GROQ_API_KEY`, `UPSTASH_REDIS_REST_URL` and `UPSTASH_REDIS_REST_TOKEN`. See [`.env.example`](.env.example) and [`docs/always-on-tutor.md`](docs/always-on-tutor.md). Never commit secrets.

## Test and build

```bash
npm run lint
npm test
npm run build
```

## Fictional demo access

All records, names, dates, scores and access codes are fabricated. They are not real credentials.

| Role | Example demo code | Result |
| --- | --- | --- |
| Student | `noah_williams_2009_02_16` | Noah's student dashboard |
| Chemistry teacher | `priya_shah_1985_03_05` | Chemistry-scoped teacher dashboard |
| Parent | `rina_patel_1981_06_20` | Maya Patel's linked parent dashboard |

The complete fictional list, including all students and parents, is in [`docs/build-week-demo-access.md`](docs/build-week-demo-access.md). The Custom GPT Action uses its own generated, key-scoped demo access grant; do not use dashboard demo codes as a production authentication scheme.

## Architecture

```text
Role-scoped dashboard or Custom GPT Action
                ↓
Next.js App Router pages and /api route handlers
                ↓
Services: view models, validation and deterministic calculations
                ↓
Domain types + ProgressRepository
                ↓
Fictional seed data / optional Upstash shared demo record
```

- `src/domain/`: types and mastery calculations.
- `src/services/`: student, teacher and parent view models plus exam/specification logic.
- `src/data/`: fictional seed data, curriculum data and the persistence seam.
- `src/app/api/`: validation, role-scoped routes and tutor endpoints.
- `docs/`: Action schema, curriculum index, tutor setup, privacy and demo instructions.

The demo’s topics, assessment results, homework and targets are deterministic. Topic mastery is calculated from recorded, topic-linked assessment evidence; it is not an AI judgement. The optional tutors receive only server-built, role-appropriate context and cannot alter grades, targets, mastery, homework or teacher notes.

## Codex and GPT-5.6 in this Build Week project

Codex, with GPT-5.6, was used as the development agent to inspect the existing codebase, implement and review scoped changes, write regression tests, run lint/test/build validation, and prepare documentation. It helped turn the product decisions into the Next.js UI, API routes, deterministic calculations and test coverage in this repository.

The product itself does **not** call GPT-5.6 at runtime. GPT-5.6/Codex was used to build the project. The optional dashboard assistant is a separate Groq-backed fictional demo, and the Custom GPT is a separate Action-based experience.

## Privacy and scope boundaries

- This is a fictional Build Week demonstration only. Do not enter real pupil, parent or school data.
- Demo access codes are convenience gates, not production authentication.
- Dashboard navigation uses fictional role/session gates: students, teachers and parents land in their corresponding demo view, and each parent view is linked to one fictional student.
- General dashboard API routes are prototype routes, not hardened production authorisation. The stricter server-side scopes in this repository are the dashboard tutor routes and the Custom GPT Action gateway.
- Teacher-only and student-only notes are excluded from parent contexts.
- The dashboard tutor derives identity and permitted record scope from its signed demo session. The browser cannot select an arbitrary student record for the tutor.
- The Custom GPT Action is read-only and key-scoped for fictional data. It must not be used with real learner data.
- A real deployment would require authenticated identity, consent, safeguarding review, audit logs, encryption, retention/deletion controls and a proper database. These are not implemented here.

## Limitations

This is an early prototype, not a production school system. The shared demo uses fictional data and free-tier infrastructure. Groq, Upstash and Vercel availability is quota-dependent. Live classroom integrations, real authentication, production data governance and automated grading are outside this repository's scope.

For additional technical detail, see [`docs/architecture.md`](docs/architecture.md), [`docs/gpt-action.md`](docs/gpt-action.md), [`docs/always-on-tutor.md`](docs/always-on-tutor.md), and [`/privacy`](https://learnlabgpt.usairam.co.uk/privacy).


## Detected evidence (automated analysis)

Indexed codebase: 89 recognized source files, 291 KB.
- CSS (language) — detected in the code
- Next.js (technology) — detected in the code
- React (technology) — detected in the code
- Tailwind CSS (technology) — detected in the code
- TypeScript (language) — detected in the code
- Vercel (technology) — claimed on Devpost, not found in the code
- AI coding agent: Codex — evidence: config files committed to the repository

## Codebase structure (from repository index)

### Files (97 of 97)

```
.env.example
.gitignore
AGENTS.md
CONTRIBUTING.md
data/seed.json
docs/always-on-tutor.md
docs/architecture.md
docs/build-week-demo-access.md
docs/curriculum-index.md
docs/gpt-action.md
docs/gpt-knowledge/README.md
docs/gpt-real-data-roadmap.md
docs/gpt-science-coach-evaluation.md
docs/gpt-science-coach.md
docs/local-model.md
docs/openapi-actions.yaml
docs/openapi.yaml
eslint.config.mjs
next-env.d.ts
next.config.ts
package.json
postcss.config.mjs
README.md
scripts/generate-action-key.mjs
src/app/api/_shared.ts
src/app/api/actions/student-progress/route.ts
src/app/api/actions/student-study-update/route.ts
src/app/api/actions/teacher-class-insights/route.ts
src/app/api/api.test.ts
src/app/api/classes/[classId]/insights/route.ts
src/app/api/classes/[classId]/route.ts
src/app/api/classes/[classId]/students/route.ts
src/app/api/classes/route.ts
src/app/api/demo-login/route.test.ts
src/app/api/demo-login/route.ts
src/app/api/demo-logout/route.ts
src/app/api/demo-session/route.ts
src/app/api/homework/[homeworkId]/route.ts
src/app/api/parent-tutor/route.test.ts
src/app/api/parent-tutor/route.ts
src/app/api/parent/overview/route.ts
src/app/api/student/upcoming-exams/route.ts
src/app/api/students/[studentId]/assessment-results/route.ts
src/app/api/students/[studentId]/progress/route.ts
src/app/api/students/[studentId]/route.ts
src/app/api/students/[studentId]/teacher-record/route.ts
src/app/api/students/route.ts
src/app/api/study-sessions/route.ts
src/app/api/teacher-tutor/route.test.ts
src/app/api/teacher-tutor/route.ts
src/app/api/teacher/exam-timeline/route.ts
src/app/api/teacher/upcoming-exams/route.ts
src/app/api/teacher/updates/route.ts
src/app/api/tutor/route.test.ts
src/app/api/tutor/route.ts
src/app/globals.css
src/app/layout.tsx
src/app/mock/page.tsx
src/app/page.tsx
src/app/parent/page.tsx
src/app/privacy/page.tsx
src/app/student/page.tsx
src/app/teacher/page.tsx
src/components/assessment-chart.tsx
src/components/dashboard-mock.tsx
src/components/demo-login.tsx
src/components/learning-archive.tsx
src/components/parent-dashboard.tsx
src/components/student-dashboard.tsx
src/components/teacher-dashboard.tsx
src/components/teacher-exam-form.tsx
src/components/theme-toggle.tsx
src/components/tutor-panel.tsx
src/components/ui.tsx
src/data/curriculum.ts
src/data/demo-access.ts
src/data/demo-records.ts
src/data/repository.test.ts
src/data/repository.ts
src/domain/mastery.test.ts
src/domain/mastery.ts
src/domain/types.ts
src/lib/demo-session.ts
src/lib/groq-tutor.test.ts
src/lib/groq-tutor.ts
src/lib/tutor-quota.test.ts
src/lib/tutor-quota.ts
src/services/action-access.test.ts
src/services/action-access.ts
src/services/learning-history.test.ts
src/services/progress.ts
src/services/specification-awareness.test.ts
src/services/study-session.test.ts
src/services/tutor-context.test.ts
src/services/tutor-context.ts
tsconfig.json
vitest.config.ts
```

### Dependencies

- package.json: @eslint/eslintrc@^3.0.0, @heroicons/react@^2.2.0, @tailwindcss/postcss@^4.0.0, @testing-library/react@^16.0.0, @types/node@^24.0.0, @types/react@^19.0.0, @types/react-dom@^19.0.0, eslint@^9.0.0, eslint-config-next@^16.0.0, jsdom@^27.0.0, katex@^0.18.1, next@^16.0.0, react@^19.0.0, react-dom@^19.0.0, react-markdown@^10.1.0, rehype-katex@^7.0.1, remark-math@^6.0.0, tailwindcss@^4.0.0, typescript@^5.9.0, vitest@^4.0.0

### Recent commits (newest first)

- Merge pull request #20 from ua246/docs/build-week-submission-readme
- docs: prepare Build Week judge guide
- Merge pull request #19 from ua246/fix/demo-record-recovery
- fix: recover from incompatible demo records
- Merge pull request #18 from ua246/fix/dashboard-accessibility-regressions
- fix: restore dashboard access and readability
- Merge pull request #17 from ua246/feat/learning-record-polish
- feat: persist demo updates and render tutor maths
- feat: improve learning record visualisation and exam scope
- Merge pull request #16 from ua246/feat/learning-experience
- feat: streamline learning dashboard journeys
- Merge pull request #15 from ua246/feat/specification-aware
- feat: add specification-aware exam planning
- Merge pull request #14 from ua246/feat/learning-archive-and-session-updates
- feat: add learning archive and confirmed study updates
- fix: tailor tutor responses to current request
- Merge pull request #13 from ua246/feat/multiyear-learning-record
- feat: add multi-year learning history
- Merge pull request #12 from ua246/feat/subject-teacher-overview
- Merge pull request #10 from ua246/fix/student-tutor-response-template

## Key source files (fetched from GitHub, selected and truncated for size)

### CONTRIBUTING.md

```markdown
# Contributing to LearnLab

Thank you for contributing. Keep each change focused and use a branch-and-pull-request workflow so the repository owner retains final approval.

## Workflow

1. Fetch the latest `main`; do not commit changes directly to it.
2. Create a concise branch such as `feat/topic-detail`, `fix/progress-loading`, `docs/api-guide`, or `chore/dependency-update`.
3. Make only the changes needed for the task and preserve unrelated behaviour.
4. Run the relevant project checks:

   ```bash
   npm run lint
   npm test
   npm run build
   ```

5. Commit with a clear message and push your branch.
6. Open a pull request into `main` describing the change, important decisions, checks run, manual testing, and known risks or limitations. Include screenshots when the interface changes.
7. Use a draft pull request when validation is incomplete or failing for an environmental reason; otherwise mark it ready for review.
8. Do not force push shared history, enable auto-merge, or merge the pull request yourself. Leave final review and merge approval to the repository owner.

```

### AGENTS.md

```markdown
# LearnLab product and engineering guide

## Product purpose

LearnLab is an early Build Week prototype for persistent Year 11 AQA GCSE Science progress. It gives a student and their teacher two useful views of the same structured academic record. A future ChatGPT app or Custom GPT can explain that record and help plan revision, but it must never become the source of truth.

## Current scope

The prototype includes a fictional logged-in state, student and teacher dashboards, a deterministic progress engine, API routes, and local JSON persistence. It deliberately excludes real pupil data, authentication, school information system integrations, notifications, production infrastructure, and OpenAI calls.

## User journeys

- A teacher opens Year 11 Science, filters by subject, identifies pupils below target or with overdue work, and opens a pupil detail panel.
- A student opens their dashboard, compares estimated and target grades, reviews assessment and homework history, and receives three explainable revision priorities.
- Both journeys read the same repository-backed data through the application API.

## Architecture

Next.js App Router provides pages and route handlers. Client dashboard components fetch view models from `/api`. Domain types and pure calculations live under `src/domain`; persistence is hidden behind `src/data/repository.ts`; orchestration and dashboard view models live under `src/services`. The JSON file in `data/seed.json` is a hackathon database substitute and can later be replaced by PostgreSQL without changing UI components.

## Data model

The core model covers users, students, teachers, classes, class memberships, subjects, specification topics, grade targets, assessments, topic-linked scores, homework, and homework assignments. Topic mastery is calculated from recent weighted scores, not stored as an invented AI judgement.

## API design

Read endpoints expose students, student detail and progress, classes, class rosters, and class insights. Mutation endpoints accept an assessment result and update homework status. Route handlers validate input, return useful JSON errors, and call services rather than reading files directly.

## Security boundaries for a future release

The central database is the system of record. AI may explain retrieved records, but it must not invent progress, grades, submissions, identities, or permissions. Production identity must come from per-user OAuth/session claims at the backend; never trust a model or client to choose an arbitrary student ID. Students may read only their own records. Subject teachers may read assigned classes and subjects. Form tutors may read approved cross-subject summaries. Administrators manage enrolment and permissions.

Real deployment also requires audit logs, consent, data minimisation, retention and deletion controls, encryption, safeguarding review, and documented incident response. Do not describe this prototype as production-secure.

## Future ChatGPT integration


[truncated — 2205 more characters]
```

### package.json

```
{
  "name": "learn-gpt",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev --hostname 0.0.0.0",
    "build": "next build",
    "start": "next start --hostname 0.0.0.0",
    "lint": "eslint .",
    "test": "vitest run",
    "test:watch": "vitest"
  },
  "dependencies": {
    "@heroicons/react": "^2.2.0",
    "katex": "^0.18.1",
    "next": "^16.0.0",
    "react": "^19.0.0",
    "react-dom": "^19.0.0",
    "react-markdown": "^10.1.0",
    "rehype-katex": "^7.0.1",
    "remark-math": "^6.0.0"
  },
  "devDependencies": {
    "@eslint/eslintrc": "^3.0.0",
    "@tailwindcss/postcss": "^4.0.0",
    "@testing-library/react": "^16.0.0",
    "@types/node": "^24.0.0",
    "@types/react": "^19.0.0",
    "@types/react-dom": "^19.0.0",
    "eslint": "^9.0.0",
    "eslint-config-next": "^16.0.0",
    "jsdom": "^27.0.0",
    "tailwindcss": "^4.0.0",
    "typescript": "^5.9.0",
    "vitest": "^4.0.0"
  }
}

```

### src/app/page.tsx

```typescript
import { DemoLogin } from "@/components/demo-login";

export default function Home() {
  return <DemoLogin />;
}

```

### src/app/layout.tsx

```typescript
import type { Metadata } from "next";
import "./globals.css";

export const metadata: Metadata = {
  title: "LearnLab | Science progress, made useful",
  description: "A shared progress dashboard for Year 11 AQA GCSE Science.",
};

export default function RootLayout({ children }: Readonly<{ children: React.ReactNode }>) {
  return <html lang="en"><body>{children}</body></html>;
}

```

### src/app/mock/page.tsx

```typescript
import { DashboardMock } from "@/components/dashboard-mock";

export default function MockPage() {
  return <DashboardMock />;
}

```

### src/app/parent/page.tsx

```typescript
import { ParentDashboard } from "@/components/parent-dashboard";
import { cookieName, readDemoSession } from "@/lib/demo-session";
import { cookies } from "next/headers";
import { redirect } from "next/navigation";

export default async function ParentPage() {
  const session = readDemoSession((await cookies()).get(cookieName)?.value);
  if (session?.role !== "parent") redirect("/");
  return <ParentDashboard />;
}

```

### src/app/student/page.tsx

```typescript
import { StudentDashboard } from "@/components/student-dashboard";
import { cookieName, readDemoSession } from "@/lib/demo-session";
import { cookies } from "next/headers";
import { redirect } from "next/navigation";

export default async function StudentPage() {
  const session = readDemoSession((await cookies()).get(cookieName)?.value);
  if (session?.role !== "student") redirect("/");
  return <StudentDashboard />;
}

```

### src/app/teacher/page.tsx

```typescript
import { TeacherDashboard } from "@/components/teacher-dashboard";
import { cookieName, readDemoSession } from "@/lib/demo-session";
import { cookies } from "next/headers";
import { redirect } from "next/navigation";

export default async function TeacherPage() {
  const session = readDemoSession((await cookies()).get(cookieName)?.value);
  if (session?.role !== "teacher") redirect("/");
  return <TeacherDashboard teacherId={session.teacherId} teacherName={session.displayName} allowedSubjects={session.subjectKeys} />;
}

```

### src/app/privacy/page.tsx

```typescript
import Link from "next/link";

export const metadata = {
  title: "Build Week demo privacy notice | LearnLab",
  description: "Privacy notice for the LearnLab Science Coach Build Week demonstration.",
};

export default function PrivacyPage() {
  return (
    <main className="min-h-screen bg-[#f6f7f4] px-6 py-10 text-[#17212b] sm:py-16">
      <article className="mx-auto max-w-3xl rounded-3xl border border-[#e1e6e2] bg-white p-7 shadow-sm sm:p-12">
        <Link href="/" className="text-sm font-semibold text-[#246a69] underline underline-offset-4">
          LearnLab
        </Link>
        <p className="mt-8 text-xs font-bold uppercase tracking-[0.16em] text-[#60707b]">OpenAI Build Week demo</p>
        <h1 className="mt-3 text-4xl font-bold tracking-[-0.045em] text-[#17324d]">Privacy notice</h1>
        <p className="mt-4 text-sm text-[#60707b]">Effective 18 July 2026</p>

        <div className="mt-10 space-y-8 text-[1.02rem] leading-7 text-[#384650]">
          <section>
            <h2 className="text-xl font-bold text-[#17324d]">What this is</h2>
            <p className="mt-2">LearnLab Science Coach is a private, time-limited demonstration created for OpenAI Build Week. It is not a school service, does not provide production safeguarding, and must not be used with real student records.</p>
          </section>

          <section>
            <h2 className="text-xl font-bold text-[#17324d]">Demo data only</h2>
            <p className="mt-2">All learner, teacher, class, progress, grade, homework and assessment information returned by the LearnLab Action is fabricated demonstration data. It does not identify real children, teachers, schools or classes.</p>
          </section>

          <section>
            <h2 className="text-xl font-bold text-[#17324d]">How the Action works</h2>
            <p className="mt-2">The Custom GPT sends the demo key and the requested fictional student or class identifier to <span className="font-medium">learnlabgpt.usairam.co.uk</span> only when a user asks it to retrieve demo progress. The service uses that key to limit the fictional record it returns. It is read-only: it does not save revision plans, change records, contact anyone or make decisions about a person.</p>
          </section>

          <section>
            <h2 className="text-xl font-bold text-[#17324d]">What users should not enter</h2>
            <p className="mt-2">Do not enter real names, school names, student identifiers, assessment results, health or safeguarding information, login credentials, or any other personal data into the GPT or the demo Action. Use only the fictional demo details supplied for the Build Week demonstration.</p>
          </section>

          <section>
            <h2 className="text-xl font-bold text-[#17324d]">Third-party processing</h2>
            <p className="mt-2">Conversations take place in ChatGPT and are subject to the user&apos;s agreement with OpenAI. Build Week submissions and project pages are handled by Devpost under its own terms and privacy policy. This notice describes the LearnLab demo service only.</p>
          </section>

          <section>
            <h2 className="text-xl font-bold text-[#17324d]">Retention and deletion</h2>
            <p className="mt-2">The demo does not intentionally store user-provided information. The fictional seed data is kept only as part of the source repository for the demonstration. This is not a production retention or deletion policy.</p>
          </section>

          <section>
            <h2 className="text-xl font-bold text-[#17324d]">Contact</h2>
            <p className="mt-2">For questions about this Build Week demonstration, contact the project creator through the accompanying Devpost project page. Do not include personal or student information in an enquiry.</p>
          </section>
        </div>

        <p className="mt-12 border-t border-[#e3e8e5] pt-6 text-sm leading-6 text-[#60707b]">A real LearnLab release would require authenticated access, consent, audit logging, data-retention controls, encryption, safeguarding review and a production privacy policy before any real pupil data could be processed.</p>
      </article>
    </main>
  );
}

```

[78 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]