Pular para conteúdo

title: Conceito: Item description: O Item como unidade canônica de persistência flexível e modelo de dados central do framework.


Item

O Item é o conceito central de persistência do local_middag. Ele atua como um agregado genérico que sustenta múltiplos modelos de negócio sem exigir a criação de novas tabelas no banco de dados para cada funcionalidade.


O que é

Inspirado no conceito de post do WordPress, o Item é a unidade fundamental de informação do framework. Ele é definido por um discriminador chamado TYPE, que determina qual é a semântica de negócio do registro (ex: company, coursegroup, studyplan).

Um Item não é apenas uma linha em uma tabela, mas um objeto composto por: 1. Colunas Estruturais: Atributos fixos e essenciais (ID, TYPE, Status, Timestamps, GUID). 2. Metadados (Meta): Atributos dinâmicos armazenados em uma tabela satélite (EAV), permitindo extensibilidade ilimitada.

Por que existe

O Moodle possui um processo rígido para alteração de schema (install.xml e upgrade.php). Criar uma tabela para cada novo plugin ou funcionalidade gera: * Dificuldade de manutenção e migração. * Fragmentação de dados. * Rigidez para extensões que precisam adicionar campos "ao voo".

O Item resolve isso ao oferecer um Modelo Híbrido. O local_middag mantém a estrutura fixa (família de tabelas middag_items) e as Extensions utilizam essa estrutura para persistir seus dados específicos via TYPE e Metadados.

Esta escolha troca o "DDD clássico" (tabelas por Aggregate) por uma flexibilidade operacional superior dentro do ecossistema Moodle.

Como se relaciona com outros conceitos

O Item é o "sujeito" de quase todas as operações de persistência do framework, mas ele não deve ser confundido com seus registros satélites:

  • Item vs Revision: O Item representa o estado atual (o que é agora). A Revision é um snapshot histórico (como era em um momento X). Toda Revision aponta para um Item.
  • Item vs Audit: O Audit registra o evento (quem alterou o Item e por quê). O Item é o alvo da auditoria.
  • Item vs Entity: No código, o Item é mapeado para uma Entity de domínio imutável que utiliza o Wither Pattern para modificações.

Decisões de design

  • Imutabilidade e Wither Pattern: Para alterar um atributo de um Item, você não usa um setter. Você chama um método with_status(), que retorna uma nova instância do objeto com o valor alterado. Isso evita efeitos colaterais em cascata e facilita o rastreamento de mudanças.
  • Identidade Global (GUID): Cada Item possui um guid (UUID v7 na linhagem nova) que serve como referência estável para sistemas externos, independente dos IDs incrementais do banco de dados Moodle.
  • Hidratação por Type: O item_repository usa o campo TYPE para decidir qual classe de model instanciar, transformando um registro genérico de banco em um objeto rico de domínio.

O que não é

  • Não é uma Tabela SQL: Item é um conceito arquitetural. Ele é persistido em middag_items e middag_itemmeta, mas o código nunca deve acessar essas tabelas diretamente (use o item_repository).
  • Não é um Log: O Item deve ser mantido limpo, representando apenas o estado operacional. O histórico de "como chegamos aqui" pertence à família Revision.
  • Não é para Dados Transientes: O Item é para persistência duradoura. Para estados temporários de execução, use a família Job.

Perspectiva para builders de extensions

Como desenvolvedor de uma extension, você define o seu TYPE. Ao salvar dados: 1. Use as colunas estruturais para dados de busca e relacionamento (parent, status). 2. Use metadados para todo o restante. 3. O framework garante automaticamente que seu Item terá Auditoria e Revisão se você usar o item_repository padrão ou suas facades.

Exemplo ilustrativo

Trabalhando com um Item imutável via contrato de domínio:

// Representação de um Item no domínio
$company = $repository->find_by_id(45);

// Alterando o status usando Wither Pattern (gera nova instância)
$updated_company = $company->with_status('active');

// Persistindo a mudança
$repository->save($updated_company);

Comentário: Note que $company permanece inalterada. Isso é fundamental para a consistência do framework, permitindo que outros listeners consumam o estado anterior se necessário.

Referências