Skip to content

[Feature Request]: Hierarchical Object Type System for AFFiNE #14123

Description

@vendelieu

Description

Summary

This request proposes an architectural evolution for AFFiNE, transitioning from a flat tagging system to a Hierarchical Object Type System. This system allows users to define custom object types with structured properties, inheritance, and bidirectional relational linking. The primary goal is to provide a powerful, schema-driven environment while maintaining full backward compatibility with existing tags.


1. Motivation

Current Limitations

AFFiNE’s current tagging system uses simple string-based metadata. This presents several challenges for power users:

  • Structural Deficit: Tags cannot represent complex entities (e.g., People, Projects, Meetings).
  • Static Metadata: No mechanism exists to add custom properties like "Due Date" or "Email" to a tag.
  • Unidirectional Data: Users cannot easily track relationships between different entities.
  • Redundant Workflow: Lack of inheritance forces users to recreate similar structures manually.

User Stories

Researcher: "I want to create a 'Paper' type with properties like Authors, Publication Date, and DOI, so I can organize my literature systematically."

Project Manager: "I want Meeting notes to automatically show which Projects they relate to, without manually maintaining both directions."


2. Goals & Non-Goals

Goals

  • G1: Define custom object types with typed properties.
  • G2: Support single inheritance between object types.
  • G3: Maintain 100% backward compatibility with existing tags.
  • G4: Provide reactive, two-way relational linking.

Non-Goals

  • NG1: Multi-inheritance (avoiding the "Diamond Problem" complexity).
  • NG2: Computed/formula-based properties (slated for Phase 2).
  • NG3: Type-level access control (relying on workspace-level permissions for now).

3. Architecture Overview

The system transitions the conceptual model from a flat "Tag" structure to a nested "Type" structure.

High-Level Approach

The core logic moves from Document → Tags to:

  1. Document → Is an instance of → Object Type.
  2. Object Type → Inherits from → Parent Type.
  3. Document → References → Other Objects (via typed properties).

4. Core Concepts

Inheritance Model

Types support single inheritance. Child types inherit all properties from the parent, can "shadow" (override) them, or extend the schema with new fields.

Should prevent circular references (for example through DAG).

Example Hierarchy:

┌─────────────────┐
│    Document     │  ← Base system type
│  • title        │
│  • createdAt    │
└────────┬────────┘
         │ inherits
    ┌────┴────┬───────────┐
    ▼         ▼           ▼
┌───────┐ ┌───────┐ ┌──────────┐
│Article│ │ Note  │ │ Meeting  │
│• author│ │• mood │ │• attendees│
│• date  │ │       │ │• agenda  │
└───┬────┘ └───────┘ └──────────┘
    │ inherits
    ▼
┌─────────┐
│BlogPost │  ← Inherits from Article
│• slug   │     (has title, createdAt, author, date)
│• tags   │
└─────────┘

Property Types

The system supports a wide range of data primitives to ensure data integrity

Two-Way Linking (Backlinks)

When a property references another object, the system maintains a virtual backlink index. This allows a "Company" object to automatically list all "Employee" objects that point to it without manual entry.


5. User Experience

The Object Studio

A dedicated interface for managing the workspace "DNA." Users can:

  1. Select a parent type (or start from a blank System Type).
  2. Define metadata (Icons, Colors, Descriptions).
  3. Add properties via a drag-and-drop schema builder.

Navigation Integration

The sidebar "Tags" section will be rebranded as Objects.

  • Hierarchical View: Types are nested visually.
  • Instance Counts: Real-time counters showing how many objects belong to a specific type.
  • Quick Add: Create new instances directly from the sidebar.
▾ Objects
  ▾ 🏷️ Tag                    (12)
      ├── Work
      ├── Personal
      └── ...
  ▾ 👤 Person                  (5)
      ├── Alice
      ├── Bob
      └── ...
  ▸ 📁 Project                 (3)
  ▸ 📅 Meeting                 (0)

6. Migration & Security

Backward Compatibility

To ensure a smooth transition:

  • System Tag Type: Existing tags are automatically mapped to a system:tag type.
  • Lazy Migration: We will not perform a bulk database migration. Instead, data is "upgraded" to the new schema only when a user interacts with it.

Permissions

  • Workspace Scope: Initially, all types are shared across the workspace.
  • System Protection: Core types (Document, Tag, Media) are "locked" to prevent accidental deletion of essential infrastructure.

7. Open Questions

  1. Versioning: How should we handle instances when a parent property is deleted? (Current plan: Keep data but hide from UI).
  2. Cross-Workspace: Should users be able to export "Type Templates" to other workspaces?
  3. Performance: How will the backlink index perform with >10,000 inter-connected objects?

Use case

No response

Anything else?

No response

Are you willing to submit a PR?

  • Yes I'd like to help by submitting a PR!

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

storyFeatures perceivable by end-users

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions