Type System
Status: Implemented Depends On: Page System, Layout System, Property System
Overview
Section titled “Overview”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.
Diagram
Section titled “Diagram”Architecture
Section titled “Architecture”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.
Key Design Decisions
Section titled “Key Design Decisions”1. System Types Are Immutable
Section titled “1. System Types Are Immutable”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.
2. Type Assignment Scoping
Section titled “2. Type Assignment Scoping”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_idfield 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).
3. Container Rule Inheritance
Section titled “3. Container Rule Inheritance”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.
4. Property Value Types
Section titled “4. Property Value Types”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.
5. System Properties
Section titled “5. System Properties”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.
6. Default Layout Association
Section titled “6. Default Layout Association”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.
7. Collection View Modes
Section titled “7. Collection View Modes”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.
8. Template Catalog
Section titled “8. Template Catalog”Types can be created from templates via a two-tier catalog system:
- Local templates — installed via
InstallTemplateUseCasefrom bundled template definitions. - Cloud templates — fetched from a remote catalog via
FetchCatalogUseCaseand installed viaInstallCloudTemplateUseCase. TheTemplateCatalogProvidertrait abstracts the remote source.
Domain Rules
Section titled “Domain Rules”| Rule | Enforcement |
|---|---|
| Type name non-empty, max 100 chars | TypeDefinition::validate_name() in domain |
| Type slug non-empty, max 100 chars, lowercase alphanumeric + hyphens only | TypeDefinition::validate_slug() in domain |
| System types cannot be renamed or deleted | TypeRepositoryError::SystemType in application |
| Property name non-empty, max 100 chars | PropertyDefinition::validate_name() in domain |
| Property slug same rules as type slug | PropertyDefinition::validate_slug() in domain |
Property value_type immutable after creation | Application layer validation |
| System properties cannot be deleted | Application layer validation |
Container rule depth must be DirectChildren or Recursive | ContainerRuleDepth::from_str() in domain |
Deleting a layout nullifies default_layout_id references | TypeRepository::clear_default_layout_references() |
Key Code Paths
Section titled “Key Code Paths”| Scenario | Entry Point |
|---|---|
| Create custom type | CreateTypeUseCase::execute() in crates/application/src/type_def/create.rs |
| Assign type to page | AssignTypeUseCase::execute() in crates/application/src/type_def/assign.rs |
| Auto-assign via container rule | SetContainerRuleUseCase::execute() in crates/application/src/container_rule/set_container_rule.rs |
| Browse pages by type | QueryPagesByTypeUseCase::execute() in crates/application/src/collection_view/query_pages_by_type.rs |
| Set property value on page | SetPropertyValueUseCase::execute() in crates/application/src/property/set_property_value.rs |
| Install cloud template | InstallCloudTemplateUseCase::execute() in crates/application/src/type_def/install_cloud_template.rs |
| Get applicable container rules | ContainerRuleRepository::get_applicable_rules() in crates/application/src/container_rule/services.rs |
Related
Section titled “Related”- Page System (
page-system): Types are assigned to pages; container rules apply during page creation - Layout System (
layout-system): Types link to default layouts viadefault_layout_id - Property System (
property-system): Inline property references and autocomplete for typed properties - Tag System (
tag-system): Thetagssystem 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?
Thanks for your feedback!