Release Notes

See what's new in NavEd. Product updates, new features, and improvements for micro school, co-op, and homeschool management.

182 releases
Page 1 of 17
v2026.5.21.2

Cumulative GPA now appears prominently at the top of the free transcript PDF.

If you used the free transcript builder, your student's GPA was being calculated correctly, but it only showed up in a small line near the bottom of the page — easy to miss, and not where college admissions officers expect to find it. A parent flagged this after assuming the GPA hadn't been calculated at all.

Now "Cumulative GPA: 3.80 (Unweighted)" and "Total Credits: 5.00" appear directly below the student name and graduation date, right where a transcript should show them. The math is unchanged; this is purely a visual placement fix. If the GPA can't be calculated (for example, every course is marked Pass), the field shows an em-dash rather than a missing value.

If you already generated a PDF before this change, just regenerate it from your transcript link to pick up the new layout.

Internal

  • Modified: student_management_project/student_management_app/static/js/transcript_pdf.js (added GPA + total credits row to renderStudentInfo)
  • Modified: student_management_project/student_management_app/templates/transcript/app.html (bumped transcript_pdf.js cache buster ?v=1.4?v=1.5)
v2026.5.21.1

Class reports no longer crash when a subject has no grades entered.

If you tried to generate a class report PDF for a subject that didn't have any graded assignments—like an attendance-tracking subject or a class where you haven't entered grades yet—the download would fail with an error. You'd click the button and get nothing.

That's fixed. Those reports now generate cleanly and show "N/A" in the Final Grade column for any student who doesn't yet have grades in that subject. The rest of the PDF—the student roster, assignment list, and category breakdown—still prints exactly as expected.

Fixes and Improvements

  • Fixed class report PDF crash for subjects with no assignments or all-excused grades
v2026.5.20.2

Internal: End-to-end integration tests + boot-log audit for Phase 61 (v2.4).

No user-visible behavior changes. Closes out Phase 61 Wave 4 (the v2.4 Public Pages framework's foundational security/infrastructure phase) with goal-backward proof that all five phase success criteria hold simultaneously in a real request flow -- not just in the isolated unit tests from earlier plans.

  • New test_integration.py exercises all five Phase 61 success criteria end-to-end against a single sentinel /public/__healthcheck__/ URL on the compass tenant subdomain: middleware flag set, tenant resolution preserved, public-schema 404, no wildcard auth cookies in response, and CSRF still required on POST. A second Phase61SystemCheckIntegrationTest swaps in a violating URLconf via override_settings(ROOT_URLCONF=...) and confirms E010 (undecorated /public/* URL) fires through the registered Django check.
  • New test_boot_log.py verifies the apps.ready() boot-log helper emits one INFO log line per registered public endpoint (plus a summary "Total registered: N" line), emits the empty-state line when no endpoints are registered, and short-circuits silently when IS_TESTING=True so test runs are not noisy.
  • Tiny test-only URLconf helpers (urls_for_tests_integration.py, urls_for_tests_violating.py, urls_for_tests_empty.py) added next to the existing per-plan URLconfs. Each is owned by Plan 05 alone; no other tests reference them.

Internal

  • New: student_management_project/student_management_app/tests/test_public_pages/test_integration.py
  • New: student_management_project/student_management_app/tests/test_public_pages/urls_for_tests_integration.py
  • New: student_management_project/student_management_app/tests/test_public_pages/urls_for_tests_violating.py
  • New: student_management_project/student_management_app/tests/test_public_pages/test_boot_log.py
  • New: student_management_project/student_management_app/tests/test_public_pages/urls_for_tests_empty.py
v2026.5.20.1

Internal: Deploy-time check --deploy gate + Public Pages cookie audit / regression test for Phase 61 (v2.4).

No user-visible behavior changes. Wires Django's manage.py check --deploy into the Railway web process so misconfigured deploys (missing BREVO_API_KEY, /public/* URLs without @public_endpoint, etc.) refuse to boot instead of starting silently broken.

  • Procfile web: line now runs python student_management_project/manage.py check --deploy && gunicorn .... The && short-circuits gunicorn startup if any Critical/Error check fires. Activates both the new E010/E011 checks (Phase 61 Plan 03) and the pre-existing dormant E001 (BREVO_API_KEY required). worker: and release: lines unchanged. BREVO_API_KEY verified present in both development and production Railway environments before landing.
  • New COOKIE-AUDIT.md documents the v1.6 wildcard cookie leak (SESSION_COOKIE_DOMAIN = .nav.education + SESSION_SAVE_EVERY_REQUEST = True would issue tenant-bridging session cookies on anonymous /public/* visits), names Plan 02's PublicPathMiddleware cookie strip as the chosen remediation, and surfaces Phase 63 follow-ups (CSRF strategy for public POST forms + latent leftmost-XFF bug in legacy rate-limit decorators).
  • New test_cookie_isolation.py regression test asserts that /public/* responses contain no naved_sessionid and no naved_csrftoken cookies under production-equivalent settings (SESSION_SAVE_EVERY_REQUEST=True, wildcard cookie domains). Three test methods cover the two named cookies plus a defense-in-depth check for any naved_-prefixed or session-like cookie name. The test view explicitly touches request.session to force Django to try issuing a cookie -- the test passes only because PublicPathMiddleware strips it anyway.

Internal

  • Modified: Procfile (web process)
  • New: .planning/phases/061-public-url-infrastructure-security-audit/COOKIE-AUDIT.md
  • New: student_management_project/student_management_app/tests/test_public_pages/test_cookie_isolation.py
  • New: student_management_project/student_management_app/tests/test_public_pages/urls_for_tests_cookie.py
v2026.5.19.1

Internal: Public Pages middleware boundary + URLconf discovery for Phase 61 (v2.4).

No user-visible behavior changes. Continues yesterday's foundational work for the v2.4 Public Pages framework by adding the central security boundary that all /public/* requests must pass through.

  • New PublicPathMiddleware at MIDDLEWARE position 4.5 (between TenantSafetyMiddleware and WwwRedirectMiddleware). Sets request.is_public_page = True on /public/* paths, raises Http404 when a /public/* request lands on the public schema (no tenant subdomain), and strips wildcard naved_sessionid / naved_csrftoken cookies from /public/* responses to fix the v1.6 leak (wildcard SESSION_COOKIE_DOMAIN = .nav.education + SESSION_SAVE_EVERY_REQUEST = True would otherwise issue tenant-bridging session cookies on every anonymous public-page visit).
  • Middleware preserves CSRF (POST without token still 403), preserves schema, preserves tenant resolution, and never short-circuits responses outside the public-schema-404 case. Verified with 13 unit + integration tests.
  • 404 path attaches AnonymousUser to the request before raising so Django's 404 handler can render 404.html cleanly (the project's context processors call request.user.is_authenticated without a hasattr guard).
  • New student_management_app.public.discovery URLconf walker + student_management_app.checks E010/E011 system checks enforce a bidirectional invariant: every /public/* URL pattern must resolve to a view decorated with @public_endpoint, and every @public_endpoint-decorated view must be mounted under /public/*. New manage.py list_public_endpoints management command for on-demand audit; AppConfig.ready() logs one line per registered public endpoint at boot.

Internal

  • New: student_management_app/public/middleware.py (PublicPathMiddleware)
  • New: student_management_app/public/discovery.py (walk_url_patterns, discover_public_endpoints, find_misaligned_patterns)
  • New: student_management_app/checks.py (E010/E011 bidirectional system checks)
  • New: student_management_app/management/commands/list_public_endpoints.py
  • New: tests/test_public_pages/test_middleware.py, tests/test_public_pages/urls_for_tests.py, tests/test_public_pages/test_url_discovery.py, tests/test_public_pages/test_system_check.py, tests/test_public_pages/test_management_command.py
  • Modified: settings.py MIDDLEWARE list (inserts PublicPathMiddleware at index 5)
  • Modified: student_management_app/apps.py (registers E010/E011 checks via ready() + emits boot-time INFO log per public endpoint)
v2026.5.18.1

Internal: foundational primitives for the upcoming Public Pages framework (Phase 61, v2.4).

No user-visible behavior changes. This release lands the pure-Python primitives that the v2.4 Public Pages framework (club registration, payment landing pages, guest-accessible URLs) will sit on top of.

  • New student_management_app/public/ package with a bare @public_endpoint marker decorator and is_public_endpoint() detector that work on both function-based views and class-based views (via Django's .as_view() .cls attribute).
  • New get_client_ip(request) utility that returns the rightmost X-Forwarded-For value (Railway's edge proxy convention, NOT the leftmost as in standard XFF) with X-Real-IP and REMOTE_ADDR fallbacks. Phase 63 will build per-IP rate limiting on top of this helper.
  • Unit tests covering FBV + CBV decoration, functools.wraps preservation, idempotent re-decoration, rightmost-XFF parsing, and an explicit XFF spoofing regression test (an attacker prepending a fake IP must NOT defeat the helper).

Internal

  • New: student_management_app/public/decorators.py (public_endpoint, is_public_endpoint)
  • New: student_management_app/public/utils.py (get_client_ip)
  • New: tests/test_public_pages/ test subdirectory with three unit-test files
  • Known follow-up (Phase 63): the existing rate-limit decorators in student_management_app/decorators.py lines 501-576 still use the leftmost XFF pattern, which is a latent rate-limit bypass on Railway. They will be migrated to get_client_ip() when Phase 63 rebuilds the rate-limit story.
v2026.5.10.1

Uploading a school logo or banner in WebP format now works.

If you recently tried to upload a school logo or banner image and kept seeing an error—even after trying several times—this fix is for you. Modern browsers like Chrome on Windows increasingly save images in a format called WebP (you've probably seen .webp files in your downloads folder). NavEd was accepting the file but then quietly rejecting it right before saving, which caused a confusing error with no clear guidance on what was wrong.

We've updated the branding settings page to fully support WebP images alongside the existing JPEG, PNG, and GIF support. If you were affected, please try uploading your logo or banner again—it should work now.

Fixes and Improvements

  • School branding page now accepts WebP image uploads for logos and banners
  • Invalid image formats now show a clear field-level error message instead of a generic failure toast
v2026.5.12.2

Adding a student with a photo from your phone now works reliably.

If you tried to add a student and uploaded a profile picture taken on your phone's camera, you may have hit a silent error and seen the form fail with no explanation. This was especially frustrating because there was nothing obviously wrong — you were just trying to add a student.

The problem was that phone camera photos are typically 3–10 MB, and we had a logging tool inside NavEd that was trying to read the entire file upload into memory before your request even reached the student form. When the photo was larger than 2.5 MB, it would crash before the form could process it. We've fixed this so that file uploads are handled correctly, and added a clear error message if a photo is genuinely too large (over 5 MB).

Fixes and Improvements

  • Fixed: adding a student with a large profile picture from a mobile device now works correctly
  • Improved: if a profile picture is over 5 MB, you'll now see a clear error message explaining the size limit instead of a confusing blank failure

v2026.5.12.1

New schools now get step-by-step guidance right on the dashboard.

When you sign up and log in as a school administrator, NavEd now shows a "Get Started" checklist with four steps — Add a Subject, Add Students, Enroll Students, Enter Grades — that auto-hides once your school is fully set up.

We also added empty-state prompts at the exact spots where new schools get stuck:

  • The enrollment page now shows a clear "Add your first student" button when your school has no students yet, instead of a confusing pre-selection banner.
  • After adding a student, a success banner offers to enroll them in a subject right away (only shown when subjects exist).
  • Opening the gradebook for a class with no enrolled students now shows an "Enroll Students Now" button instead of a blank table.

None of these prompts block you — they're guides, not gates.

Fixes and Improvements

  • Dashboard: 4-step onboarding checklist for new HODs (auto-hides when complete)
  • Enrollment page: empty-state CTA when tenant has zero students
  • Add Student page: post-save callout linking to enrollment when subjects exist
  • Gradebook: "Enroll Students Now" CTA when subject has no enrolled students

2 3

Want to stay updated?

Sign up for NavEd to get notified about new features and improvements

Get Started Free