Tracks
Tracks
Section titled “Tracks”Admin- and mentor-facing tracks group published study plan templates in a fixed order. Tracks model the discipleship hourglass: many entry paths in milk, fewer in transition and meat, then many paths fanning out in higher spiritual phases.
Learner-facing copy may use themed language later; planning and admin APIs use plain track terminology.
Funnel vs specialization is not a stored field — it is conveyed by spiritual_phase, tags, and description (e.g. tag funnel or specialization).
Hourglass
Section titled “Hourglass” Clean slate MILK | Well-known MILK (many tracks — entry by background) \ | / \ | / TRANSITION (fewer — finish / converge milk work / guage if ready for meat by giving a taste of meat) \ | / \ | / MEAT (fewest — shared core) / | \ / | \ / | \ STRONG_MEAT / FEAST \ / GRADUATED \(many specialization-style tracks)| Phase band | Expected cardinality | Role |
|---|---|---|
| Milk | Many | Route mentees by starting point (“where are you coming from?”) |
| Transition | Fewer | Complete milk work; converge toward meat |
| Meat | Fewest | Shared core everyone passes through |
| Strong meat, feast, graduated | Many | Fan-out — gifts, ministry roles, depth areas |
Entity (single tracks table)
Section titled “Entity (single tracks table)”| Concept | Table | Notes |
|---|---|---|
| Track | tracks | One row per ordered curriculum path |
| Module order | track_modules | Unified sort_order for plan rows and elective groups |
| Plan membership | track_study_plan_templates | is_required, mentor_instructions on pivot |
| Elective group | track_elective_groups | Choice slot: title, pick_count, selector |
| Elective pool | track_elective_group_plans | Pool templates + optional per-option mentor_instructions |
| Noop skip | studies + focus_kind = skip_noop | Hidden skip template; ended study with satisfies_plan_template_id |
| Elective noop | focus_kind = elective_noop, focus_value = elective_group_id | Auto-created per group; added to pool as skip option |
| Tag | track_tags | Normalized label (slug + display name) |
| Tagging | track_tag | Pivot track_id, track_tag_id |
tracks columns
Section titled “tracks columns”| Field | Purpose |
|---|---|
spiritual_phase | Required. Browse/assign only when user phase matches exactly |
slug, title, description | Admin catalog metadata; human prerequisites live in description |
is_published | Draft when false; mentors see published tracks only |
Prerequisites
Section titled “Prerequisites”- Programmatic (v1):
spiritual_phaseexact match only. - Human-readable: longer prerequisites in
descriptionprose. No prerequisite graph in v1. - Deferred: server-enforced prerequisites and per-user track progress — see Architecture Questions.
Tags help mentors and admins find the right track when many exist.
| Rule | v1 |
|---|---|
| Who assigns tags | Curriculum designers and platform administrators (manual via tagSlugs on create/update) |
| Tag source of truth | track_tags dictionary; pivots on tracks |
| Discovery | tracks(spiritualPhase, tagSlugs, forUserId) |
| AI-assisted tagging | Deferred |
Example tag slugs: new-believer, funnel, specialization, spiritual-gifts, teaching, mercy.
Admin UI
Section titled “Admin UI”Curriculum designers and platform administrators manage tracks at /admin/tracks and tags at /admin/tracks/tags. Designer guide: Tracks. Review queue: /admin/curriculum/reviews.
| Route | Purpose |
|---|---|
/admin/tracks | List, filter, delete |
/admin/tracks/new, /admin/tracks/[id] | Track form with ordered plan and elective modules |
/admin/tracks/tags | Tag dictionary CRUD |
Editorial workflow
Section titled “Editorial workflow”Unpublished tracks (is_published = false) require curriculum review approval before updateTrack with isPublished: true, same rules as study plan templates. Self-approval is blocked; platform administrators bypass the gate.
Published track edits: staging revisions for published tracks are planned; v1 applies the publish guard on first publish only. Track module merges from staged payloads are not yet supported.
GraphQL (implemented)
Section titled “GraphQL (implemented)”| Operation | Audience |
|---|---|
adminTracks, createTrack, updateTrack, deleteTrack | Curriculum designer or platform administrator |
adminTrackTags | Curriculum designer or platform administrator |
tracks(spiritualPhase, tagSlugs, forUserId) | Authenticated browse (mentors assign using mentee phase via forUserId) |
Track assignment
Section titled “Track assignment”Mentors assign a published track to an active mentorship (mentorships.track_id). Progress is inferred from track-linked studies on the mentee (studies.track_id, plan_template_id, ended_at, and satisfies_plan_template_id for skips). Rules:
- One track per active mentorship pairing.
- At most one open track study (
ended_atis null) at a time. - Assign next study on track auto-assigns only when the next unsatisfied module is a required plan.
assignTrackStudyassigns a specific plan (required, skippable, or elective pool choice).skipTrackPlancreates an immediately ended noop study that satisfies the current skippable module.- Ad-hoc
createMenteeStudyremains available for exceptions (notrack_id).
Deferred: user_course_progress table, server-enforced prerequisite graph — see Architecture Questions.
Skippable plans
Section titled “Skippable plans”Some plan modules are not required (is_required = false on track_study_plan_templates). They do not block track completion. The mentor assigns or skips each skippable plan when it is the current module.
mentor_instructions on the plan pivot is admin-authored prose for the mentor (e.g. “Skip if already baptized as a believer.”). It is mentor-facing only — not shown to the mentee as curriculum content.
A skippable plan is satisfied when the mentee completes a track-linked study for that template or the mentor skips it. Skips create a hidden study plan with focus_kind = skip_noop (slug track-module-noop): an ended track study whose plan_template_id is that template and whose satisfies_plan_template_id points at the skipped module template.
Each elective group automatically gets a companion elective_noop template (focus_value = the group’s id). It is added to the pool as a skip option — assigning it completes the elective slot without real curriculum.
Elective groups
Section titled “Elective groups”Elective groups personalize a track — they are not hourglass fan-out (that remains separate specialization-style tracks at higher phases).
A group is a slot in module order with a curated pool of study plan templates (guided, book, etc.). The mentor or mentee picks from the pool before the track advances:
| Field | Purpose |
|---|---|
title, description | Slot copy (“Choose a book study”) |
pick_count | How many pool studies must be completed (usually 1) |
selector | mentor, mentee, or either — who may assign from the pool |
Example:
1. Foundations (required)2. Baptism deep-dive (skippable) — mentor_instructions on pivot3. [Elective: pick 1 book] → Romans | John | Philippians4. Gospel overview (required)Pool members may include book plan templates; assignment creates a Book study with the template’s focus_value (USFM id), not only guided templates.
Per-option mentor_instructions on track_elective_group_plans give hints (“Good if mentee wants a narrative gospel”).
GraphQL (track modules)
Section titled “GraphQL (track modules)”| Operation | Audience |
|---|---|
createTrack / updateTrack with modules input | Curriculum designer or platform administrator |
assignTrackStudy, skipTrackPlan | Mentor (mentee for mentee/either electives) |
trackProgress.modules on mentorship | Mentor |
Related docs
Section titled “Related docs”- Tracks (designer) — curriculum designer UI guide
- Study Plans — template and step snapshot rules
- Domain Model — study vs session vs log entry
- Vision — curriculum-as-guide philosophy