Content
Content items are the publishable units of Cursare: each one can be a standalone experience, a reusable part of another content, a sellable root, or all three at once. This page describes the unified model, ownership, settings, and lifecycle.
The model: one row, updated in place
Each content item is a single row in the database, with two documents:
| Field | Role |
|---|---|
draftDocument | The editable draft — what the team sees in the editor. |
publishedDocument | What learners read — a frozen copy, written only when you publish. |
The row's id is the content item's stable identity across the entire platform: enrollments, purchases, reviews, quiz history, and the reference edges of a composition all point to it. As long as publishedDocument is null, the content is a draft — invisible to learners and absent from the catalog.
One recursive content model
Creation has one door: New content. You enter the title and its URL segment is derived automatically, remaining editable before confirmation. Creating content does not create an offer or decide a permanent role.
Every content can contain learning blocks and reference blocks. A reference places another content in the graph with its own route segment, release rule, prerequisites, and stable placement id. The same target may appear in several roots without copying it.
Commercial behavior is orthogonal: adding an offer makes a published content enrollable or sellable; archiving its final active offer stops new entry without changing the content graph.
The route segment rules are:
- 1 to 120 characters, only lowercase letters, numbers, and hyphens (
^[a-z0-9-]+$); - unique within the organization.
On creation you can also pick the owning team (optional) — see Ownership below.
From the list's ⋯ menu you can also Duplicate a content item: this creates a new draft with the title renamed to <title> (copy) and a free route segment in the -copy, -copy-2, … series. The copy carries the document, tags, theme, and ownership, but never the published manifest, offers, learners, reviews, or sales.
Configuration areas
A content item's configuration is organized into grouped submenus. Every content always exposes Edit and Graph; audience and commercial areas appear from actual capabilities and records, never from a persisted type.
| Group | Submenu | Purpose |
|---|---|---|
| Authoring | Edit | The canonical document: identity, learning blocks, and recursive references. |
| Authoring | Graph | Incoming and outgoing references, offers, delivery, health, impact, and performance projections. |
| Setup | Basics | Route segment and theme — the content's address and look. The title and description stay in the document header. |
| Setup | Discovery | Tags, search appearance, social image, and catalog visibility. |
| Audience | Learners, Cohort, Insights | Who is enrolled through this root, its cohorts, and reports. |
| Business | Pricing / Enrollment / Offers | Explicit sellable packages: price, installments, approval, intake, capacity, and listing. |
| Manage | Advanced | Ownership and the danger zone. |
Recursive authoring
The canonical document accepts the full block library everywhere. A reference block can point to any same-organization content and carries a stable placement id, local title, URL segment, release delay, and prerequisites. Nesting supports multiple levels; cycles and self-references are rejected.
Publishing validates every reachable target and atomically writes publishedDocument plus a versioned publishedManifest. The manifest is the complete learner navigation snapshot, including branches and repeated placements; graph views are rebuildable projections of it.
Ownership of a content item
Every content item belongs to exactly one side — never both:
| Owner | How it looks | Who is responsible |
|---|---|---|
| Team | teamId set, ownerId null | The team's members, according to each one's role. |
| Person | ownerId set, teamId null | The owning person is responsible for all functions. |
| Organization | both null | Only organization owners/admins (content created via API). |
When there is no team, the owning person is responsible for everything. Reassigning ownership (to a team or to an organization member) always leaves exactly one side set. Organization owners and admins are a fallback over any content item.
Functions and roles
A content item has three functions, and each function corresponds to a per-member role in the owning team (team_member_role):
| Role (team_member_role) | Function | What it authorizes |
|---|---|---|
editor | content | Edit the draft, publish, rename the handle, tags, theme, and duplicate. |
finance | finance | Price, currency, installments. |
cohort | cohort | Manage cohorts: administer, moderate, and make up the tutor pool. |
Authorization resolution, from the highest ceiling down to the lowest:
- Organization owner/admin — passes on any function and also in the danger zone.
- Owning person — holds all of the content's functions.
- Member of the owning team — only the function whose role they carry.
- Organization content (no owner and no team) — grants only to organization owners/admins.
Catalog, listed, and unlisted but sellable
An organization's public catalog gathers content that is published AND listed (listed = true), from most recent to oldest. Listing and offers are independent:
- Referenced but unlisted content stays out of the catalog while remaining navigable inside enrolled roots.
- Unlisted but sellable content can be purchased by direct link without appearing in the catalog.
Pricing and access
A content's commercial life lives in Enrollment — entry, price, delivery, and rules. With one offer the workspace edits that path directly; with two or more it becomes Ways to enroll. The full model is in Pricing & checkout; the enrollment journey is in Learners and enrollments.
Two rules worth carrying everywhere: the currency locks after the first sale, and archiving the final active offer deliberately stops new enrollments while preserving history.
Tags and theme
- Tags — free-text labels: type anything and it sticks. Names are normalized to lowercase and deduplicated, limited to 12 tags per content item, each up to 32 characters. The editor suggests tags your other contents already use, so spellings converge naturally.
- Theme — sets the trio of accent colors the components render with; it must be a known theme.
Renaming the handle
Renaming a content's route segment is safe inside graphs: the stable id is the identity, while each reference placement owns its local URL segment. Only direct links using the previous top-level segment start returning 404.
Lifecycle
The recommended flow is draft → review → publish → follow-up → republish in place:
- Draft — edit the body in the editor; learners see nothing until you publish.
- Review — use the preview before publishing, and avoid changing commercial rules at the same moment you deeply change the content.
- Publish — validates the recursive graph, copies the draft into
publishedDocument, recordspublishedAt, and writes the learner manifest plus graph projection. Reused content shows an impact warning. - Follow-up — see engagement and outcomes in Insights.
- Republish — repeat as many times as you need; learner progress is preserved.
Danger zone (deletion)
Deletion is restricted to the owning person or an organization owner/admin and has two safety locks:
- Referenced by other content — refused while another composition uses this content. Remove the references first, otherwise the graph would be left hanging.
- Already purchased — refused while any purchase exists. A purchase is a promise: unlist instead of deleting.
When deletion proceeds, enrollments, reviews, and quiz history are removed in cascade. Prefer taking it out of the catalog or halting new enrollments whenever there are still learners attached.