Manuals — Models¶
Overview¶
The manuals app defines a structured content model for building rich, ordered manuals.
The model layer is responsible for:
- content structure
- relationships
- ordering rules
- validation constraints
- data integrity
It does not handle:
- workflow logic
- request handling
- serialization
- side effects
High-level structure¶
Manual content is hierarchical, but also partially stream-based.
Hierarchy:
- Organization
- Manual
- Chapter
- Sections / Notes / StepGroups / Media / Callouts
Display:
- ChapterItem defines the ordered stream inside a chapter
Model relationships (high-level)¶
flowchart TD
Org --> Manual
Manual --> Chapter
Chapter --> Section
Chapter --> SectionNote
Chapter --> StepGroup
StepGroup --> ManualStep
Manual --> Callout
Chapter --> Callout
Section --> Callout
StepGroup --> Callout
ManualStep --> Callout
Manual --> ManualMedia
Chapter --> ManualMedia
Section --> ManualMedia
StepGroup --> ManualMedia
ManualStep --> ManualMedia
Chapter --> ChapterItem
ChapterItem --> Section
ChapterItem --> SectionNote
ChapterItem --> Callout
ChapterItem --> StepGroup
Taxonomy models¶
Category¶
Represents a high-level grouping for manuals.
Fields:
- org
- name
- slug
Constraints:
- unique (org, slug)
Notes:
- org-scoped
- used for filtering and organization
Topic¶
Secondary taxonomy layer.
Fields:
- org
- name
- slug
- color
Constraints:
- unique (org, slug)
Notes:
- adds visual metadata (color)
- more flexible than category
Core content models¶
Manual¶
Top-level content container.
Fields:
- org
- title
- description
- cover_image
- category
- topic
- is_public_external
- published_at
- order
Indexes:
- (org, order, id)
- (org, published_at, id)
Notes:
- belongs to exactly one org
- contains ordered chapters
- can be externally published
Chapter¶
Second-level container inside a manual.
Fields:
- manual
- order
- title
- description
- cover_image
Constraints:
- unique (manual, order)
Indexes:
- (manual, order)
Notes:
- defines logical grouping of content
- owns the display stream via ChapterItem
Content block models¶
Section¶
Rich content block.
Fields:
- chapter
- order
- title
- description
- description_json
Indexes:
- (chapter, order)
Notes:
- description_json is the primary rich content source
- supports inline media references
SectionNote¶
Lightweight note block.
Fields:
- chapter
- order
- title
- body
Indexes:
- (chapter, order)
Notes:
- simpler than section
- useful for quick annotations
StepGroup¶
Container for ordered steps.
Fields:
- chapter
- order
- title
Indexes:
- (chapter, order)
ManualStep¶
Individual step inside a step group.
Fields:
- step_group
- order
- title
- body_text
Constraints:
- unique (step_group, order)
Indexes:
- (step_group, order)
Notes:
- represents procedural instructions
Callout models¶
CalloutPreset¶
Reusable callout style.
Fields:
- org
- name
- slug
- icon
- color
- is_active
- order
Constraints:
- unique (org, slug)
Notes:
- centralizes styling
- enables consistent UI
Callout¶
Contextual highlight block.
Fields:
- manual (optional)
- chapter (optional)
- section (optional)
- step_group (optional)
- step (optional)
- order
- name
- description
- preset
- icon
- color
Indexes:
- per-parent (parent, order)
Callout validation¶
A callout must be attached to exactly one parent.
flowchart TD
Start --> CountParents
CountParents -->|0| ErrorNone
CountParents -->|>1| ErrorMultiple
CountParents -->|1| Valid
Callout parent rules¶
Rules:
- zero parents → invalid
- multiple parents → invalid
- exactly one → valid
Resolved fields¶
Callout resolves display properties:
- icon_resolved
- color_resolved
Resolution order:
- explicit value on callout
- value from preset
- empty string
Media model¶
ManualMedia¶
Represents media attached to content.
Fields:
- manual (optional)
- chapter (optional)
- section (optional)
- step_group (optional)
- step (optional)
- order
- file
- caption
- type (image, video, file)
Indexes:
- per-parent
(parent, order)
Media attachment rule¶
Media must belong to exactly one parent.
This is enforced at serializer/service level.
ChapterItem (display stream)¶
Purpose¶
Defines the ordered rendering stream of a chapter.
Separates:
- storage models
- display order
Fields¶
- manual
- chapter
- order
- kind
Targets:
- section
- note
- callout
- step_group
Supported kinds¶
- section
- note
- callout
- step_group
- media_grid
Validation rules¶
flowchart TD
Start --> CheckKind
CheckKind --> SectionCheck
CheckKind --> NoteCheck
CheckKind --> CalloutCheck
CheckKind --> StepGroupCheck
CheckKind --> MediaGridCheck
SectionCheck --> RequireSection
NoteCheck --> RequireNote
CalloutCheck --> RequireCallout
StepGroupCheck --> RequireStepGroup
MediaGridCheck --> NoTarget
RequireSection --> Valid
RequireNote --> Valid
RequireCallout --> Valid
RequireStepGroup --> Valid
NoTarget --> Valid
Rules¶
- each kind requires exactly one matching target
- media_grid requires no target
- mismatches raise validation errors
Additional constraints¶
- callout must belong to same chapter
- step_group must belong to same chapter
Ordering strategy¶
Ordering is enforced via:
- order fields on all content models
- unique constraints where necessary
- explicit ordering in Meta
Important:
- ChapterItem.order defines actual display order
- other order fields define internal ordering
Data integrity principles¶
Single parent rule¶
Applies to:
- Callout
- ManualMedia
Ensures:
- no ambiguous ownership
- predictable queries
Chapter-local consistency¶
Some objects must belong to the same chapter:
- callout in ChapterItem
- step_group in ChapterItem
Org scoping¶
Manual is org-scoped.
All related data inherits org through:
- manual → chapter → content
Design decisions¶
Split storage vs display¶
Content models store data.
ChapterItem controls display order.
This allows:
- reordering without rewriting content
- flexible layouts
Rich content via JSON¶
Sections use structured JSON instead of HTML.
Benefits:
- safer editing
- easier transformation
- better frontend integration
Flexible attachment model¶
Callouts and media attach to multiple levels.
This enables:
- global manual highlights
- chapter-level context
- step-level detail
Summary¶
The models layer defines:
- hierarchical structure (manual → chapter → content)
- flexible attachment system (media, callouts)
- ordered rendering (ChapterItem)
- org-scoped ownership
- strong validation rules
It is the foundation for:
- serializers (data shape)
- services (workflow)
- views (API exposure)
Key idea¶
store content once, control presentation separately, enforce strict structure.