Files
school_compare/nextjs-app
TudorandClaude Opus 4.8 de943ded19
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m3s
PR Checks / Backend Smoke (pull_request) Successful in 6s
PR Checks / Build Backend (no push) (pull_request) Successful in 11s
PR Checks / Build Frontend (no push) (pull_request) Successful in 49s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 1m48s
fix(review): don't suppress a genuine mainstream 0 in the rows
Review feedback: the rankings/search rows treated any exactly-0 attainment as
not comparable regardless of school type, so a genuine 0 at a mainstream
school rendered as "—" (looks like missing data) and dropped its delta —
stricter and inconsistent with SchoolDetailView's placeholder check.

- SchoolRow: match SchoolDetailView's ks2Placeholder signature — suppress only
  when ALL of RWM + reading + writing + maths are 0 (special/suppressed
  signature), not on a bare rwm === 0. A genuine 0% combined (some pupils met
  individual subjects but not all three) is not all-zero, so it stays
  comparable and shows its real figure + trend.
- SecondarySchoolRow: Attainment 8 is a single 0–80 score with no subject
  breakdown to form an all-zero signature, so key off establishment type only
  (drop the bare att8 === 0 guard). A genuine (if extreme) 0.0 shows its value
  + LA delta.
- For consistency, apply the same to the detail views: drop the bare
  attainment_8_score === 0 guard (KS4 keys off isSpecial only); KS2 keeps the
  all-four-subjects-zero placeholder signature.

Special schools / PRUs / AP are still handled via isSpecialSchool everywhere.
tsc clean; 108/108 unit.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0146VHeLAWjDVE2B5uU67jCB
2026-07-20 21:58:13 +01:00
..

SchoolCompare Next.js Application

Modern Next.js application for comparing primary school KS2 performance across England.

Features

  • Server-Side Rendering (SSR): Fast initial page loads with pre-rendered content
  • Individual School Pages: Dedicated pages for each school with full SEO optimization
  • Side-by-Side Comparison: Compare up to 5 schools simultaneously
  • School Rankings: Top-performing schools by various metrics
  • Interactive Maps: Leaflet integration for geographic visualization
  • Performance Charts: Chart.js visualizations for historical data
  • Responsive Design: Mobile-first approach with full responsive support
  • SEO Optimized: Dynamic sitemaps, meta tags, and structured data

Tech Stack

  • Framework: Next.js 16 (App Router)
  • Language: TypeScript 5
  • Styling: CSS Modules + CSS Variables
  • State Management: React Context API + URL state
  • Data Fetching: SWR (client-side) + Next.js fetch (server-side)
  • Charts: Chart.js + react-chartjs-2
  • Maps: Leaflet + react-leaflet
  • Testing: Jest + React Testing Library
  • Validation: Zod

Getting Started

Prerequisites

  • Node.js 24+ (using nvm recommended)
  • FastAPI backend running on port 8000

Installation

# Install dependencies
npm install

# Copy environment variables
cp .env.example .env.local

# Update .env.local with your configuration

Development

# Start development server
npm run dev

# Open http://localhost:3000

Building

# Build for production
npm run build

# Start production server
npm start

Testing

# Run tests
npm test

# Run tests in watch mode
npm run test:watch

# Run tests with coverage
npm run test:coverage

Linting

# Run ESLint
npm run lint

Project Structure

nextjs-app/
├── app/                      # App Router pages
│   ├── layout.tsx           # Root layout
│   ├── page.tsx             # Home page
│   ├── compare/             # Compare page
│   ├── rankings/            # Rankings page
│   ├── school/[urn]/        # Individual school pages
│   ├── sitemap.ts           # Dynamic sitemap
│   └── robots.ts            # Robots.txt
├── components/              # React components
│   ├── SchoolCard.tsx       # School card component
│   ├── FilterBar.tsx        # Search/filter controls
│   ├── ComparisonView.tsx   # Comparison interface
│   ├── RankingsView.tsx     # Rankings table
│   └── ...
├── lib/                     # Utility libraries
│   ├── api.ts              # API client
│   ├── types.ts            # TypeScript types
│   └── utils.ts            # Helper functions
├── hooks/                   # Custom React hooks
├── context/                 # React Context providers
├── styles/                  # Global styles
├── public/                  # Static assets
└── __tests__/              # Test files

Environment Variables

Variable Description Default
NEXT_PUBLIC_API_URL Public API endpoint (client-side) http://localhost:8000/api
FASTAPI_URL Server-side API endpoint http://localhost:8000/api
NODE_ENV Environment mode development

Performance Optimizations

  • Server-Side Rendering: Initial HTML rendered on server
  • Static Generation: Where possible, pages are pre-generated
  • Image Optimization: Next.js Image component with AVIF/WebP support
  • Code Splitting: Automatic route-based code splitting
  • Dynamic Imports: Heavy components loaded on demand
  • API Caching: Configurable revalidation for data fetching
  • Bundle Optimization: Tree shaking and minification
  • Compression: Gzip compression enabled

SEO Features

  • Dynamic Meta Tags: Generated per page with Next.js Metadata API
  • Open Graph: Social media optimization
  • JSON-LD: Structured data for search engines
  • Sitemap: Auto-generated from database
  • Robots.txt: Search engine crawling rules
  • Canonical URLs: Duplicate content prevention

Browser Support

  • Chrome (latest)
  • Firefox (latest)
  • Safari (latest)
  • Edge (latest)

License

Proprietary - SchoolCompare

Support

For issues and questions, please contact the development team.