@startuml "NTR Text Fragmentation Architecture"

' Использование CSS-стилей вместо skinparams
<style>  
  .concrete {
    BackgroundColor #FFFFFF
    BorderColor #795548
  }
  
  .models {
    BackgroundColor #E8F5E9
    BorderColor #4CAF50
  }
  
  .strategies {
    BackgroundColor #E1F5FE
    BorderColor #03A9F4
  }
  
  .core {
    BackgroundColor #FFEBEE
    BorderColor #F44336
  }
  
  note {
    BackgroundColor #FFF9C4
    BorderColor #FFD54F
    FontSize 10
  }
</style>

' Легенда
legend
  <b>Легенда</b>
  
  | Цвет | Описание |
  | <back:#E8F5E9>Зеленый</back> | Модели данных |
  | <back:#E1F5FE>Голубой</back> | Стратегии чанкинга |
  | <back:#FFEBEE>Красный</back> | Основные компоненты |
endlegend

' Разделение на пакеты

package "models" {
  class LinkerEntity <<models>> {
    + id: UUID
    + name: str
    + text: str
    + in_search_text: str | None
    + metadata: dict
    + source_id: UUID | None
    + target_id: UUID | None
    + number_in_relation: int | None
    + type: str
    + serialize(): LinkerEntity
    + {abstract} deserialize(data: LinkerEntity): Self
  }
    
  class Chunk <<models>> extends LinkerEntity {
    + chunk_index: int | None
  }
    
  class DocumentAsEntity <<models>> extends LinkerEntity {
  }

  note right of LinkerEntity
    Базовая сущность для всех элементов системы.
    in_search_text определяет текст, используемый
    при поиске, если None - данная сущность не должна попасть
    в поиск и используется только для вспомогательных целей.
  end note
}

package "chunking_strategies" as chunking_strategies {
  abstract class ChunkingStrategy <<abstract>> {
    + {abstract} chunk(document: ParsedDocument, doc_entity: DocumentAsEntity): list[LinkerEntity]
    + dechunk(entities: list[LinkerEntity], links: list[LinkerEntity]): str
  }
  
  package "specific_strategies" {
    class FixedSizeChunkingStrategy <<strategies>> extends chunking_strategies.ChunkingStrategy {
      + chunk(document: ParsedDocument, doc_entity: DocumentAsEntity): list[LinkerEntity]
      + dechunk(entities: list[LinkerEntity], links: list[LinkerEntity]): str
    }
    
    class SentenceChunkingStrategy <<strategies>> extends chunking_strategies.ChunkingStrategy {
      + chunk(document: ParsedDocument, doc_entity: DocumentAsEntity): list[LinkerEntity]
      + dechunk(entities: list[LinkerEntity], links: list[LinkerEntity]): str
    }
    
    class NumberedItemsChunkingStrategy <<strategies>> extends chunking_strategies.ChunkingStrategy {
      + chunk(document: ParsedDocument, doc_entity: DocumentAsEntity): list[LinkerEntity]
      + dechunk(entities: list[LinkerEntity], links: list[LinkerEntity]): str
    }
  }
  
  note right of ChunkingStrategy
    Базовая реализация dechunk сортирует чанки по chunk_index.
    Стратегии могут переопределить, если им нужна
    специфическая логика сборки
  end note
}

package "core" {
  class Destructurer <<core>> {
    + __init__(document: ParsedDocument, strategy_name: str)
    + configure(strategy_name: str, **kwargs)
    + destructure(): list[LinkerEntity]
  }
  
  class InjectionBuilder <<core>> {
    + __init__(entities: list[LinkerEntity], config: dict)
    + register_strategy(doc_type: str, strategy: ChunkingStrategy)
    + build(filtered_entities: list[LinkerEntity]): str
    - _group_chunks_by_document(chunks, links): dict
  }

  note right of Destructurer
    Основной класс библиотеки, используется для разбиения 
    документа на чанки и вспомогательные сущности. В 
    полученной конфигурации содержатся in_search сущности 
    и множество вспомогательных сущностей. Предполагается, 
    что первые будут отфильтрованы векторным или иным поиском, 
    а вторые можно будет использовать для обогащения и сборки 
    итоговой инъекции в промпт.
  end note

  note right of InjectionBuilder
    Класс-единая точка входа для сборки итоговой инъекции 
    в промпт. Принимает в себя все сущности и конфигурацию 
    в конструкторе, а в методе build принимает отфильтрованные 
    сущности. Может частично делегировать сборку стратегиям для 
    специфических типов чанкинга.
  end note

}

' Композиционные отношения
core.Destructurer --> chunking_strategies.ChunkingStrategy
core.InjectionBuilder --> chunking_strategies.ChunkingStrategy

' Отношения между компонентами
chunking_strategies.ChunkingStrategy ..> models

' Дополнительные отношения
core.InjectionBuilder ..> models.LinkerEntity
core.Destructurer ..> models.LinkerEntity

@enduml