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étodowith_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_repositoryusa o campoTYPEpara 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_itemsemiddag_itemmeta, mas o código nunca deve acessar essas tabelas diretamente (use oitem_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.