Who can do what with a program's setup, schedule and enrolment
This page covers all 34 things PTRS can do in the core of the Programs module: setting up a program, moving it through its lifecycle, scheduling it, running its cohorts and consent forms, and enrolling children into it. The delivery side, curriculum, staffing, goals, assessments and surveys, and the money and governance side, charters, budgets, partnerships and grants, are covered on their own pages.
Every row states whether anything in the product actually reaches it.
Who is admitted
Every one of these 34 actions requires the module-wide setting, and twelve of them add a second, narrower one on top.
| Requirement | Count | Effective audience |
|---|---|---|
| The module-wide setting only | 19 | Site directors, regional directors, organisation administrators, super admins |
| The module-wide setting, narrowed further | 12 | Site directors, organisation administrators, super admins |
| No setting at all beyond being signed in to the group | 3 | Site directors, regional directors, organisation administrators, super admins |
None of the 34 widens access beyond the module-wide setting, and none is open with no sign-in check. This module only ever narrows.
Reading a program's sessions, reading room bookings, and checking for a schedule conflict require nothing beyond the module-wide setting. That makes them, along with the nineteen above, the only Programs actions a regional director can actually carry out, and two of the three are the only things the Program Calendar depends on, which is why that screen is the one place in this module that role can fully use.
What a role actually experiences
Twelve of the 34 add the narrower setting, and they include the two reads every screen in this module depends on: the program list and a program's own detail.
| Role | What they can actually reach |
|---|---|
| Site directors, organisation administrators, super admins | All 34 |
| Regional directors | 22 of the 34 by setting alone, and in practice only the Program Calendar, because the list and every program's detail both refuse the role, so no program page ever actually renders for them |
| Staff members | None. The module-wide setting excludes the role entirely, including the twelve that would otherwise admit them |
| Guardians, OCCL auditors, read-only accounts | None |
How to read the "Reachable" column
| Value | Meaning |
|---|---|
| A screen or component name | Something in the product calls this action in normal use |
| Nothing reaches it | The action is built correctly and no screen or control calls it |
| Calls it, always fails | Something calls it every time, and the request as built can never succeed |
| Never sent | A control is wired up to it and PTRS's own side returns before the request goes out |
Summary
| Count | |
|---|---|
| Actions in this subset | 34 |
| Reachable by a screen | 27 |
| Reachable by nothing | 7 |
| Of the 27 reachable, cannot succeed as built | 4 |
| Add a narrower setting | 12 |
| Carry no setting beyond the module-wide one | 3 |
| Open with no sign-in check | 0 |
Program setup, lifecycle and versioning (10 actions)
| Action | Reachable by | Note |
|---|---|---|
| List programs | The program list, and three more screens | Scoped to your organisation. Filters by location, stage, season and pillar |
| Read a program | The program's own page and six more screens | Returns every enrolment ever made against the program, unpaged, including withdrawn ones |
| Create a program | The header's Quick Add dialog | Always creates a Draft, plus one default schedule |
| Edit a program | The Edit dialog | Silently keeps the old value for an unrecognised program type, season, delivery mode or age group, instead of refusing the save the way creating one does |
| Move a program's stage | The Status Workflow card | Enforces the transition table. Writes a history row that nothing ever reads back |
| Clone a program | The Clone dialog | Copies pillars and tags and creates one default schedule. Does not copy the original program's real schedule, curricula, eligibility rules, consent forms, cohorts, staff or goals, although the dialog says it does |
| Snapshot a program | Version History | Saves 15 fields as the next numbered version |
| Read the version list | Version History | |
| Read one version's saved data | Nothing reaches it | The snapshot preview reads the data already included in the list |
| Replace a program's tags | The Tags editor | Trims, drops empties, and de-duplicates without regard to case |
Scheduling and the calendar (8 actions)
| Action | Reachable by | Note |
|---|---|---|
| Save a schedule's recurrence pattern | Never sent | The Schedule Editor is only ever rendered with no schedule to edit, so pressing Save returns before anything is sent |
| Generate sessions from a schedule | Calls it, always fails | The schedule identifier is read from the first existing session, so it is blank until sessions exist |
| Read a program's sessions | The Schedule tab | Works. Permanently empty, because nothing can create a session |
| Record a schedule exception | Calls it, always fails | Same blank identifier, same failure |
| Complete or cancel a session | The Schedule tab | Correct, and only ever rendered on a session row, so it never actually appears |
| Book a room | Nothing reaches it | Complete. Checks for an overlapping booking in the same room and refuses it |
| Read room bookings | The Program Calendar | Permanently empty |
| Check for a schedule conflict | The Program Calendar | Compares bookings with bookings, and sessions with bookings. Both tables are empty, so it always reports nothing |
It reports two kinds of conflict, a booking overlapping another booking, and a session overlapping a booking. It does not detect two sessions overlapping each other in the same room, which is exactly the collision a recurring schedule would produce, because every generated session inherits its schedule's own default room.
The Schedule Editor builds a real, working recurrence pattern and prints back a plain sentence describing it, something like "Repeats every 2 weeks on Mon, Wed". Generating sessions checks only that the pattern is not blank, then walks the date range a day at a time and keeps whichever days of the week were separately ticked. An interval, an end date, a fixed count, and a daily or monthly pattern are all collected, shown back, and ignored: a program meant to run every other week would generate every week instead.
Eligibility, consent and cohorts (10 actions)
| Action | Reachable by | Note |
|---|---|---|
| Replace a program's eligibility rules | The rule builder | Checks each rule's type and comparison against what PTRS recognises and refuses an unrecognised one by name. There is no length check on the rule's own value or its error message |
| Read a program's eligibility rules | The rule builder | |
| Run the eligibility check | Nothing reaches it | A real evaluation exists behind this action. Most rule types are reported as passed no matter what they say, because the engine behind them does not actually implement most of the comparisons the builder offers |
| Create a consent form | The Consent tab | No length check on the form's own wording |
| Correct a consent form | Nothing reaches it | Increases the form's version on every save |
| Read a program's consent forms | The Consent tab | |
| Record a consent | Calls it, always fails | The Record button sends a blank guardian identifier |
| Read the pending-consent queue | The Consent and Enrollment tabs | Combines active and waitlisted children with active forms they have not signed. Ignores an expired consent, so it counts as collected and never returns to the queue |
| Create a cohort | The Cohorts tab | No length check against the name or description |
| Read a program's cohorts | The Cohorts tab | Member count is permanently 0 |
| Add a child to a cohort | Nothing reaches it | Checks the cohort's Max Size correctly. Does not check that the child's enrolment belongs to the cohort's own program |
| Remove a child from a cohort | Nothing reaches it |
A child's enrolment carries its own consent status, starting at Pending, and no code in PTRS ever assigns it a different value. It is read by the Programs tab on a child's record, by promotion from the waitlist, and by one other internal read. Recording a consent saves a separate record and never touches this one, so even if the Record button were fixed tomorrow, the child's record would go on reading Pending forever.
Enrolment and the waitlist (4 actions)
| Action | Reachable by | Note |
|---|---|---|
| Enrol one child | The Enroll button on a program's overview | The one path that checks the site's licensed capacity |
| Withdraw a child | Nothing reaches it | Complete and correct. Neither piece of code behind it is referenced anywhere |
| Promote from the waitlist | The Enrollment tab | No capacity check of any kind, site or program. No upper bound on how many can be promoted at once |
| Bulk Enroll a group | The Enrollment tab | No site capacity check. Respects the program's own capacity and its waitlist setting. No length check on the notes it saves |
Three separate situations, a child already enrolled or waitlisted, a record that cannot be matched, or a program full with the waitlist off, all leave the child out with no entry and no reason given. A request for twelve children that only enrols nine still succeeds, with no sign of who was skipped.
Requests that always fail
| Action | Why | What you see |
|---|---|---|
| Generate sessions | Reads a blank schedule identifier from an empty session list | The dialog stays open; a plain, unhelpful error |
| Add a schedule exception | Same | The dialog stays open; the same plain error |
| Record a consent | The guardian identifier sent is blank | An error message |
| Save a schedule's recurrence pattern | Never sent, because PTRS's own side returns before anything goes out | Nothing at all. No request, no message, no error. The editor simply stays open |
Reachable from no screen
Seven of 34. Grouped by what the absence costs.
| Action | Consequence |
|---|---|
| Withdraw a child | A child cannot be removed from a program. There is no delete option either |
| Add a child to a cohort | A cohort cannot be populated |
| Remove a child from a cohort | A cohort cannot be emptied |
| Book a room | A room cannot be booked, so the calendar and the conflict check both read empty tables |
| Run the eligibility check | The eligibility engine is never actually used |
| Correct a consent form | A consent form cannot be fixed or turned off |
| Read one version's saved data | Cosmetic. The version list already shows the same data |
Statuses and figures with nowhere to go
Several values PTRS defines are never actually set by anything, and several figures are read by a screen and written by nothing.
| What | The gap |
|---|---|
| An enrolment's Inactive and Completed statuses | No code ever sets either one |
| A booking's Confirmed and Cancelled statuses | Both appear in the calendar's legend and neither is ever set |
| A child's consent status on her enrolment | All five possible values have no writer at all |
| A schedule's own capacity figure | Returned on the schedule and read by no decision anywhere |
| The program-stage change history | Written on every move, and read by nothing |
Two waitlist orderings that disagree
The position a person sees and the order used to promote come from different places, and the how-to and explanation pages on enrolment cover this in full. In short: only Bulk Enroll saves a waitlist position, so a child waitlisted through the single Enroll button sorts behind everyone waitlisted through Bulk Enroll, whatever the actual dates say, until the first promotion renumbers the whole queue.
A withdrawn child cannot be re-enrolled
PTRS refuses two enrolments for the same child and schedule at a level deeper than either enrolment action checks. Both actions check only for an existing active enrolment.
A child who was withdrawn from a program therefore passes that check and fails at the deeper level instead, as a plain server error rather than the clear duplicate message the actions otherwise show. In a bulk request the whole group fails together.
The single-child enrolment path is protected from this by accident: its picker filters against the program's full enrolment list, which includes withdrawn rows, so such a child never appears as an option. Bulk Enroll filters the same list and is protected the same way. The exposure is only to someone integrating directly, or to any future screen that does not filter the same way.
Messages and counters
PTRS defines 97 distinct messages across every part of this module. This subset uses 29 of them. Two are declared and never actually shown by anything, which follows directly from nothing ever running the eligibility engine and nothing ever writing the consent status.
There is no set of usage counters for this module at all, unlike Members, CACFP, Staff and Incidents. Nothing here emits a count of how often anything happens.
Where to go next
- Program and enrolment fields, what goes in each box
- What happens when a child is enrolled
- Programs troubleshooting
Checked against PTRS on 7 September 2026.