Skip to main content
Swim Lessons is a self-contained module for facilities that run structured swim lesson programs — classes, rosters, a skills-based curriculum, and report cards that go through instructor review before a family can see them.
The module is feature-gated (swim_lessons). If your organization doesn’t have it enabled, Swim Lessons won’t appear in navigation and its pages redirect or show a permission message instead.

Purpose

Use this module to:
  • organize students into classes at a location, each pinned to one swim level
  • build and maintain rosters, including bulk CSV import
  • author the skill checklist each swim level evaluates against
  • record student report cards and route them through co-teacher and final-approver review before they publish
  • let a parent or guardian look up their child’s published report card without an account

Best for

  • season-based or ongoing swim lesson programs with assigned instructors
  • facilities that want sign-off on a report card before a family sees it
  • programs that already have a structured curriculum (e.g. a Red Cross–style progression) they want to adopt instead of building from scratch

Classes

Go to:
The list page shows every active class (or, without classes:manage, just the classes you instruct) with its swim level, grade band, location, instructor count, and active student count.

Creating a class

1

Open Swim Lessons

Select New class. Requires classes:manage.
2

Fill in the basics

Enter a class name and grade band, then pick a location and a swim level.
3

Assign instructors

Check every instructor for this class. Every instructor assigned gets equal access to record and review report cards for the class’s roster — there’s no primary/secondary instructor distinction.
4

Create

The class is created and you’re taken to its detail page to start building the roster.

Managing a class

The class detail page has two cards:
  • Instructors — add or remove instructors (classes:manage). Without that permission you see a read-only list.
  • Roster — every actively-enrolled student, with an Enroll student dialog to add one at a time or Import roster to bulk-add via CSV.
Enrollment is exclusive: enrolling a student who already has an active enrollment elsewhere automatically ends that prior enrollment first (a transfer, not a duplicate). A student can only be actively enrolled in one class at a time.

Bulk roster import

From a class’s detail page, Import roster creates students and enrolls them into that one class in a single step — meant for standing up a whole season’s roster at once, not for adding a student who might already exist. The CSV needs a name column. Optional columns: date_of_birth (YYYY-MM-DD), guardian_name, guardian_phone, plus any org-defined student custom fields (select-type fields must use one of that field’s configured options). Up to 500 rows per import. There’s deliberately no matching against existing students by name — a false-positive match could silently merge two different kids’ records. Every row always creates a new student, so review the parsed preview table carefully before confirming; the imported students inherit the target class’s location.

Curriculum and levels

Each class points at one swim level, and a swim level carries the skill checklist every report card for that class is evaluated against.

Levels

Manage levels from:
A legacy Settings > Lesson Levels link redirects here — levels, curriculum adoption, approval settings, comment prefills, and student custom fields all live on one Swim Lessons settings page.
A level has a name and an ordered list of skills (free-text labels). Requires lesson_levels:manage (lesson_levels:view for read-only). Skill checklists can render in grouped sections — Skills, Safety Focus, Exit Assessment — when a level’s skills came from a curriculum that categorizes them that way. A level you build from scratch in the editor just gets one flat Skills list, since its skills have no category tag.

Adopting a curriculum

Rather than building a skill checklist by hand, use Browse curricula on the Swim Lessons settings page to adopt a shared curriculum template (for example, a Red Cross–style progression) into your org’s own levels. Adopting is fork-on-write and position-based, not a destructive replace:
  • template levels are matched to your org’s levels by their position (sort order), and each is updated in place with the template’s name and skills — a class already pointed at that level keeps working, it just picks up the new content
  • any level you’ve manually edited yourself (or built from scratch, never linked to a template) is left alone on adopt — it’s yours now, and re-adopting won’t overwrite it
  • editing a level’s name or skills at any time detaches it from its template going forward, for the same reason
  • if your org has more levels than the template does, the extras are deleted only if they’re both unlinked-or-unused; a level still assigned to a class, or one you’ve customized, is left in place and reported back as skipped
The curriculum template catalog itself (/admin/curricula) is managed by AquaOps platform staff, not by organization admins. Org admins can browse and adopt from the catalog but can’t add or edit templates in it.

Students

Go to:
The list supports name search and a toggle to show archived students. Requires students:view (students:manage to create, edit, or archive). Each student has a name, location, optional date of birth, guardian name, guardian phone, and any org-defined custom fields. The list flags whether a student has a lookup factor on file — a date of birth or guardian phone — since that’s what a family will need to look up a report card later.

Student custom fields

Configure org-specific student fields (text, number, or single-select) from Settings > Swim Lessons under Student custom fields (students:manage). These are your organization’s own vocabulary — a group name, a unit number, anything not built into the product.
  • a field’s type can’t be changed after creation, since existing stored values might no longer make sense under a new type
  • Archive hides a field from new entry while keeping its stored values
  • Delete is permanent and removes every student’s value for that field — the confirmation dialog shows how many students currently have a value before you commit

Enrollment history and report cards

A student’s detail page lists every past and current enrollment, each with its report cards (status and overall result badges) and, for the active enrollment, buttons to record a new report card or unenroll. If neither a date of birth nor guardian phone is on file, the page calls this out directly: report cards for that student can’t be published (reach approved) until one is added.

Report cards

Each report card belongs to one enrollment and evaluates every skill on that enrollment’s class’s swim level.

Recording

Start a report card from a student’s active enrollment (New report card) or from the report card queue. Requires report_cards:create.
1

Set skill results

Mark each skill Pass, Needs more time, or Not yet evaluated. A draft can be saved with any subset filled in.
2

Set an overall status

Pick the card’s overall result: Pass, Needs more time, or Not yet evaluated.
3

Add comments

Write free-text comments, optionally starting from a comment prefill (see Settings below) — prefills substitute the student’s name in automatically.
4

Submit for review

Submitting requires every skill on the level to have a result, and requires the student to have a date of birth or guardian phone on file. Missing either blocks the submit with an explicit error.
Only the recorder can edit or submit a draft — unless you hold report_cards:manage, which can edit any report card administratively regardless of status or ownership.

Two-stage review

A submitted report card moves through up to two review stages before it publishes:
  1. Co-teacher review — any other instructor assigned to the same class (not the recorder) can approve, reject, or request changes. A class with no other instructors skips this stage automatically: the card goes straight to co-teacher-approved on submit.
  2. Final approval — requires report_cards:approve (or org:manage) and access to the class’s location. Approving here publishes the card.
Each stage’s approval threshold is configurable per organization under Settings > Swim Lessons > Report card approval:
  • Any one — a single qualifying reviewer’s approval advances the card
  • All — every eligible reviewer for that stage must approve
A rejection or request-for-changes from any single authorized reviewer halts the card immediately, regardless of the any/all setting — a single objection doesn’t need consensus, only approval does. Changes requested sends the card back to the recorder; resubmitting clears every review from the prior cycle and restarts both stages. No one can review their own report card at either stage, and the recorder is always excluded from that stage’s eligible-reviewer count.
If a class’s location has zero eligible final approvers, the card does not auto-publish — it’s a misconfiguration, not a vacuous approval. The report card detail page shows an explicit warning asking an org admin to grant report_cards:approve to someone with access to that location.

Statuses

Publishing and printing

Once approved, a report card shows a Print button for a print-friendly copy, and it becomes retrievable through the public parent lookup below.

Report card queue

Go to:
Requires report_cards:create. This is a personal worklist, not a full list of every report card:
  • Awaiting your review — report cards where you’re specifically an eligible reviewer right now (a co-teacher on a submitted card, or, if you hold report_cards:approve, a co_teacher_approved card at a location you have access to)
  • Students without a report card — for a selected report card period (a due date staff define), every active enrollment in a class you instruct that doesn’t have a card for that period yet, with a one-click create
report_cards:manage holders can create and manage report card periods from this page.

Public lookup

Families look up a published report card without an account at:
They enter the student’s name plus exactly one of:
  • date of birth, or
  • the last 4 digits of the guardian phone number on file
Both a name match and one second factor are always required — a single field alone is never enough, to resist someone guessing their way to a match. Name comparison ignores case and extra whitespace. Lookups are rate-limited to 5 attempts per 15 minutes per requester (by hashed IP); if that check itself fails, the lookup fails closed rather than risk running unthrottled. If a name and factor combination matches more than one student, the result is treated as no match — the system never guesses between two candidates. Only report cards with status approved are returned; drafts and cards still in review never appear here. A match shows the student’s name and, per report card, the class, swim level, overall status, skills (grouped the same way the instructor editor groups them), comments, and date.

Settings

Go to:
This single page hosts everything below, each gated by its own permission:
  • Report card approval (lesson_levels:manage) — the co-teacher and final-approver any/all thresholds described above
  • Comment prefills (report_cards:manage) — reusable comment snippets recorders can insert into a report card’s Comments field; use {{name}} in the template text and it’s replaced with the actual student’s name on insert
  • Student custom fields (students:manage) — org-defined per-student fields, described above
  • Levels (lesson_levels:manage) — edit each level’s name and skill checklist, create a level from scratch, or adopt a shared curriculum template
Every section also requires baseline module access (classes:view or classes:manage) — you can’t configure a module you can’t otherwise see.

Permissions

Assign these on the Users and Roles page.

Best practices

  • assign at least two instructors to a class if you want a real co-teacher review, not an auto-skip
  • add a date of birth or guardian phone for every student before report card season starts — it blocks publishing otherwise
  • decide your any/all approval thresholds before your first review cycle; changing them mid-cycle only affects reviews recorded after the change
  • make sure at least one person with report_cards:approve has access to every location that runs classes, or final approval will stall with no way to clear it
  • review a roster CSV’s parsed preview carefully before importing — there’s no dedup, so a mistaken duplicate becomes a second, separate student record
  • prefer Archive over Delete for student custom fields you might need historical data from later

Suggested screenshots

  • Swim Lessons class list
  • new class form with instructor checklist
  • class detail page with roster and instructor manager
  • roster CSV import preview with row errors
  • Settings > Swim Lessons levels editor
  • Browse curricula dialog and the adopt confirmation
  • report card editor with grouped skills and comment prefill picker
  • report card detail page mid-review, showing the review panel and review history
  • the “no eligible final approver” warning state
  • report card queue with pending reviews and a due-date period selected
  • the public parent lookup page and a found report card