Skip to content
Documentation GitHub
Content

Type System

Status: Implemented Depends On: Page System, Layout System, Property System


The Type System provides workspace-scoped custom page type definitions. A TypeDefinition describes a category of page (e.g., “Character”, “Location”, “Quest”) with associated properties, an optional default layout, and display metadata (icon, color, sort order). Pages are linked to types via TypeAssignment records, which track how the assignment originated (system, container rule, or manual).

Four domain entities collaborate to form the complete type system:

  • TypeDefinition — the type itself (name, slug, icon, properties, default layout).
  • PropertyDefinition — a reusable property schema (value type, config, options) that can be attached to one or more types.
  • ContainerRule — a rule on a folder that auto-assigns a type to child pages created within it.
  • CollectionView — saved view preferences (table/list/gallery) for browsing pages of a given type.

Only two system types ship with the application: Page and Folder (deterministic UUIDs ...0001 and ...0002). All other types are user-created. Worldbuilding-specific defaults (Character, Location, etc.) are not shipped — users create custom types themselves, optionally from the template catalog.



Framework (Tauri)
└── Tauri commands apps/desktop/src-tauri/src/commands/
type_def: create, get, list, update, delete, assign, remove_type,
add_property, remove_property, get_page_types,
install_template, fetch_catalog, install_cloud_template
property: create, update, delete, list, get_page_properties, set_property_value
container_rule: set, get, remove
collection_view: query_pages_by_type, get_view, save_view
Application
├── Type use cases crates/application/src/type_def/
│ CreateTypeUseCase, GetTypeUseCase, ListTypesUseCase,
│ UpdateTypeUseCase, DeleteTypeUseCase, AssignTypeUseCase,
│ RemoveTypeUseCase, GetPageTypesUseCase,
│ AddPropertyToTypeUseCase, RemovePropertyFromTypeUseCase,
│ InstallTemplateUseCase, FetchCatalogUseCase, InstallCloudTemplateUseCase
├── Property use cases crates/application/src/property/
│ CreatePropertyUseCase, UpdatePropertyUseCase, DeletePropertyUseCase,
│ ListPropertiesUseCase, GetPagePropertiesUseCase, SetPropertyValueUseCase
├── Container rule use cases crates/application/src/container_rule/
│ SetContainerRuleUseCase, GetContainerRulesUseCase, RemoveContainerRuleUseCase
├── Collection view use cases crates/application/src/collection_view/
│ QueryPagesByTypeUseCase, GetCollectionViewUseCase, SaveCollectionViewUseCase
├── TypeRepository (trait) crates/application/src/type_def/services.rs
├── PropertyRepository (trait) crates/application/src/property/services.rs
├── ContainerRuleRepository (trait) crates/application/src/container_rule/services.rs
└── CollectionViewRepository (trait)crates/application/src/collection_view/services.rs
Domain
├── TypeDefinition crates/domain/src/type_definition.rs
├── TypeAssignment + AssignmentScope
├── PropertyDefinition crates/domain/src/property_definition.rs
│ PropertyValueType, PropertyConfig, SelectOption
├── ContainerRule crates/domain/src/container_rule.rs
│ ContainerRuleDepth (DirectChildren | Recursive)
└── CollectionView crates/domain/src/collection_view.rs
ViewMode (Table | List | Gallery), ColumnConfig, CollectionViewRow
Infrastructure
└── SQLite implementations crates/infrastructure/sqlite/src/workspace/

Dependencies flow inward: Framework -> Infrastructure -> Application -> Domain.


The two system types (Page, Folder) have deterministic UUIDs and is_system = true. They cannot be renamed, deleted, or have their slugs changed. The TypeRepository::seed_system_types() method ensures they exist on workspace initialization.

Each TypeAssignment carries an AssignmentScope that records its origin:

  • System — auto-assigned by the system (e.g., every page gets the “Page” type).
  • Container — auto-assigned by a container rule on the parent folder. The source_id field stores the rule’s UUID.
  • Manual — explicitly assigned by the user.

The UI uses scope to prevent users from removing system-scoped assignments. A page can hold multiple simultaneous type assignments (one per distinct type_id).

Container rules attached to a folder can apply at two depths:

  • DirectChildren — only immediate children of the folder.
  • Recursive — all descendants at any depth.

The ContainerRuleRepository::get_applicable_rules() method walks the page tree to find all rules that apply at a given parent: direct-depth rules on the parent, plus recursive-depth rules on any ancestor.

Properties support seven value types: Text, Number, Boolean, Date, Select, MultiSelect, and Relation. The value_type is immutable after creation. Select and MultiSelect properties carry a PropertyConfig with predefined options (label + optional color). Relation properties reference a target TypeDefinition by UUID.

Four system properties ship with deterministic UUIDs: summary (...0011), cover_image (...0012), tags (...0013), and aliases (...0014). System properties cannot be deleted. The tags property bridges to the Tag System via Tauri command routing.

Each TypeDefinition has an optional default_layout_id linking to a LayoutDefinition. When a type with a default layout is assigned to a page:

  • If the page has no layout, the frontend auto-applies it.
  • If the page already has a layout, the frontend prompts the user via LayoutConflictDialog.

When a layout is deleted, TypeRepository::clear_default_layout_references() nullifies any dangling references.

Collection views support three display modes: Table (configurable columns with per-column width and visibility), List (compact single-column), and Gallery (card grid for cover-image-heavy types). One view config is stored per type, keyed by type_slug. The CollectionViewRow query returns page metadata alongside a HashMap<String, serde_json::Value> of property values for frontend rendering.

Types can be created from templates via a two-tier catalog system:

  • Local templates — installed via InstallTemplateUseCase from bundled template definitions.
  • Cloud templates — fetched from a remote catalog via FetchCatalogUseCase and installed via InstallCloudTemplateUseCase. The TemplateCatalogProvider trait abstracts the remote source.

RuleEnforcement
Type name non-empty, max 100 charsTypeDefinition::validate_name() in domain
Type slug non-empty, max 100 chars, lowercase alphanumeric + hyphens onlyTypeDefinition::validate_slug() in domain
System types cannot be renamed or deletedTypeRepositoryError::SystemType in application
Property name non-empty, max 100 charsPropertyDefinition::validate_name() in domain
Property slug same rules as type slugPropertyDefinition::validate_slug() in domain
Property value_type immutable after creationApplication layer validation
System properties cannot be deletedApplication layer validation
Container rule depth must be DirectChildren or RecursiveContainerRuleDepth::from_str() in domain
Deleting a layout nullifies default_layout_id referencesTypeRepository::clear_default_layout_references()

ScenarioEntry Point
Create custom typeCreateTypeUseCase::execute() in crates/application/src/type_def/create.rs
Assign type to pageAssignTypeUseCase::execute() in crates/application/src/type_def/assign.rs
Auto-assign via container ruleSetContainerRuleUseCase::execute() in crates/application/src/container_rule/set_container_rule.rs
Browse pages by typeQueryPagesByTypeUseCase::execute() in crates/application/src/collection_view/query_pages_by_type.rs
Set property value on pageSetPropertyValueUseCase::execute() in crates/application/src/property/set_property_value.rs
Install cloud templateInstallCloudTemplateUseCase::execute() in crates/application/src/type_def/install_cloud_template.rs
Get applicable container rulesContainerRuleRepository::get_applicable_rules() in crates/application/src/container_rule/services.rs

  • Page System (page-system): Types are assigned to pages; container rules apply during page creation
  • Layout System (layout-system): Types link to default layouts via default_layout_id
  • Property System (property-system): Inline property references and autocomplete for typed properties
  • Tag System (tag-system): The tags system property bridges to the tag system

Provides workspace-scoped page typing with properties, container rules, and collection views. See also: Layout System, Tag System.

Was this page helpful?