glam/.opencode/rules/type-naming-convention.md
kempersc f7bf1cc5ae Refactor schema slots and classes
- Deleted obsolete slot definitions: statement_summary, statement_text, statement_type, status_name, supersede_articles, supersede_condition, supersede_name, temporal_dynamics, total_amount, typical_contents, use_cases, was_acquired_through, was_fetched_at, was_retrieved_at.
- Updated existing slot definitions for states_or_stated to enhance clarity and structure.
- Introduced new classes: Article, ConditionofAccess, FinancialStatementType, MaximumQuantity, Series, Summary, Type, and their respective slots to improve schema organization and usability.
- Added new slots: changes_or_changed_through, has_or_had_condition_of_access, has_or_had_heritage_type, is_or_was_part_of_series, is_or_was_retrieved_at, maximum_of_maximum to capture additional metadata and relationships.
2026-01-30 00:29:31 +01:00

6.9 KiB

Rule: LinkML Type/Types File Naming Convention

Version: 1.0.0
Created: 2025-01-04
Status: Active
Applies to: schemas/20251121/linkml/modules/classes/


Rule Statement

When creating class hierarchies that replace enums in LinkML schemas, follow the Type/Types naming pattern to clearly distinguish abstract base classes from their concrete subclasses.


Pattern Definition

File Name Pattern Purpose Contains
[Entity]Type.yaml (singular) Abstract base class Single abstract class defining the type taxonomy
[Entity]Types.yaml (plural) Concrete subclasses All concrete subclasses inheriting from the base

Class Naming Convention

🚨 CRITICAL: Follow these naming rules for classes within the files:

  1. Abstract Base Class ([Entity]Type.yaml):

    • MUST end with Type suffix.
    • Example: DigitalPlatformType, WarehouseType.
  2. Concrete Subclasses ([Entity]Types.yaml):

    • MUST NOT end with Type suffix.
    • Use the natural entity name.
    • Example: DigitalLibrary (), CentralDepot ().
    • Incorrect: DigitalLibraryType (), CentralDepotType ().

Rationale: The file context (WarehouseTypes.yaml) already establishes these are types. Repeating "Type" in the class name is redundant and makes the class name less natural when used as an object instance (e.g., "This object is a CentralDepot").


Examples

Current Implementations

Base Class File Subclasses File Subclass Count Description
DigitalPlatformType.yaml DigitalPlatformTypes.yaml 69 Digital platform type taxonomy
WebPortalType.yaml WebPortalTypes.yaml ~15 Web portal type taxonomy
CustodianType.yaml CustodianTypes.yaml 19 Heritage custodian type taxonomy (GLAMORCUBESFIXPHDNT)
DataServiceEndpointType.yaml DataServiceEndpointTypes.yaml 7 API/data service endpoint types

File Structure Example

modules/classes/
├── DigitalPlatformType.yaml      # Abstract base class
├── DigitalPlatformTypes.yaml     # 69 concrete subclasses
├── WebPortalType.yaml            # Abstract base class
├── WebPortalTypes.yaml           # ~15 concrete subclasses
├── CustodianType.yaml            # Abstract base class
└── CustodianTypes.yaml           # 19 concrete subclasses

Import Pattern

The subclasses file MUST import the base class file:

# In DigitalPlatformTypes.yaml (subclasses file)
id: https://w3id.org/heritage-custodian/linkml/digital_platform_types
name: digital_platform_types

imports:
  - linkml:types
  - ./DigitalPlatformType  # Import base class (singular)

classes:
  DigitalLibrary:
    is_a: DigitalPlatformType  # Inherit from base
    description: >-
      A digital library platform providing access to digitized collections.      
    class_uri: schema:DigitalDocument
    
  DigitalArchive:
    is_a: DigitalPlatformType
    description: >-
      A digital archive for born-digital or digitized archival materials.      

Slot Range Pattern

When other classes reference the type taxonomy, use the base class (singular) as the range:

# In DigitalPlatform.yaml
imports:
  - ./DigitalPlatformType   # Import base class for range
  - ./DigitalPlatformTypes  # Import subclasses for validation

classes:
  DigitalPlatform:
    slots:
      - platform_type
    slot_usage:
      platform_type:
        range: DigitalPlatformType  # Use base class as range
        description: >-
          The type of digital platform. Value must be one of the
          concrete subclasses defined in DigitalPlatformTypes.          

Anti-Patterns

What NOT to Do

Anti-Pattern Why It's Wrong Correct Alternative
DigitalPlatformTypeBase.yaml "Base" suffix is redundant; singular "Type" already implies base class DigitalPlatformType.yaml
DigitalPlatformTypeClasses.yaml "Classes" is less intuitive than "Types" for a type taxonomy DigitalPlatformTypes.yaml
All types in single file Large files are hard to navigate; separation clarifies architecture Split into Type.yaml + Types.yaml
DigitalPlatformEnum.yaml Enums lack extensibility; class hierarchies are preferred Use class hierarchy pattern
CentralDepotType (Class Name) Redundant "Type" suffix on concrete subclass CentralDepot

Example of Incorrect Naming

# WRONG - Don't use "Base" suffix
# File: DigitalPlatformTypeBase.yaml
classes:
  DigitalPlatformTypeBase:  # Redundant "Base"
    abstract: true
# CORRECT - Use singular "Type"
# File: DigitalPlatformType.yaml
classes:
  DigitalPlatformType:  # Clean, clear naming
    abstract: true

Rationale

  1. Clarity: "Type" (singular) = one abstract concept; "Types" (plural) = many concrete implementations
  2. Discoverability: Related files appear adjacent in alphabetical directory listings
  3. Consistency: Follows established pattern across entire schema
  4. Semantics: Mirrors natural language ("a platform type" vs "the platform types")
  5. Scalability: Easy to add new types without modifying base class file

Migration Checklist

When renaming existing files to follow this convention:

Pre-Migration

  • Identify all files referencing the old name
  • Create backup or ensure version control is clean
  • Document the old → new name mapping

File Rename

  • Rename file: [Entity]TypeBase.yaml[Entity]Type.yaml
  • Update id: field in renamed file
  • Update name: field in renamed file
  • Update class name inside the file
  • Update all internal documentation references

Update References

  • Update imports in [Entity]Types.yaml (subclasses file)
  • Update is_a: in all subclasses
  • Update imports in consuming classes (e.g., DigitalPlatform.yaml)
  • Update range: in slot definitions
  • Update any slot_usage: references

Documentation

  • Update AGENTS.md if convention is documented there
  • Update any design documents
  • Add migration note to changelog

Verification

# Verify no references to old name remain
grep -r "OldClassName" schemas/20251121/linkml/

# Verify new file exists
ls -la schemas/20251121/linkml/modules/classes/NewClassName.yaml

# Verify old file is removed
ls -la schemas/20251121/linkml/modules/classes/OldClassName.yaml  # Should fail

# Validate schema
linkml-validate schemas/20251121/linkml/01_custodian_name.yaml

  • Rule 0: LinkML Schemas Are the Single Source of Truth
  • Rule 9: Enum-to-Class Promotion - Single Source of Truth

Changelog

Date Version Change
2025-01-04 1.0.0 Initial rule created after DigitalPlatformType refactoring