First Commit

This commit is contained in:
marco
2026-09-01 10:46:29 -03:00
commit bf96b77e9c
10000 changed files with 3508600 additions and 0 deletions
+151
View File
@@ -0,0 +1,151 @@
# Índice de Documentação SysCMS
Este arquivo organiza toda a documentação do SysCMS em uma hierarquia lógica para facilitar a navegação.
## 📋 Hierarquia de Documentos
### 1. Documentos Fundamentais (Leitura Obrigatória)
Estes documentos definem a base do sistema e devem ser lidos em ordem:
| Ordem | Arquivo | Descrição | Tipo |
|-------|---------|-----------|------|
| 0 | [00_POLITICA_MEMORIAS_CORE.md](00_POLITICA_MEMORIAS_CORE.md) | Política de uso de memórias core da IA | Governança |
| 1 | [../CONTEXT.md](../CONTEXT.md) | Contexto arquitetural imutável do sistema | Governança |
| 2 | [../DECISIONS.md](../DECISIONS.md) | Filosofia e decisões técnicas de base | Governança |
| 3 | [RULES.md](RULES.md) | Regras operacionais e convenções do projeto | Execução |
### 2. Regras Detalhadas por Categoria
#### 🎯 Fundamentos (01-09)
Conceitos base e comportamentos essenciais para a IA e desenvolvedores.
| Numeração | Arquivo | Descrição |
|-----------|---------|-----------|
| 01 | [01_COMPORTAMENTO_IA.md](01_COMPORTAMENTO_IA.md) | Comportamento esperado da IA, autonomia vs preservação |
| 02 | [02_ARQUITETURA.md](02_ARQUITETURA.md) | Estrutura de diretórios e arquitetura do sistema |
| 03 | [03_MODULOS.md](03_MODULOS.md) | Sistema de módulos, estrutura e module.json |
| 04 | [04_TECNOLOGIAS.md](04_TECNOLOGIAS.md) | Stack tecnológica (PHP, Bootstrap, Twig, etc) |
| 05 | [05_PADROES_CODIGO.md](05_PADROES_CODIGO.md) | Padrões de código, naming conventions e estilo |
| 06 | [06_DEVELOPER_GUIDE.md](06_DEVELOPER_GUIDE.md) | Guia completo para desenvolvedores |
| 07 | [07_ENVIRONMENT_USAGE.md](07_ENVIRONMENT_USAGE.md) | Uso do Docker e ambiente de desenvolvimento |
| 08 | [08_IA_COMMAND_EXECUTION_GUIDE.md](08_IA_COMMAND_EXECUTION_GUIDE.md) | Guia de execução de comandos pela IA |
| 09 | [09_LANGUAGE_CONFIG_README.md](09_LANGUAGE_CONFIG_README.md) | Configuração de idiomas e internacionalização |
#### 🔄 Ciclo de Vida (10-19)
Fluxo de execução e ciclo de vida da aplicação.
| Numeração | Arquivo | Descrição |
|-----------|---------|-----------|
| 10 | [10_LIFECYCLE.md](10_LIFECYCLE.md) | Ciclo de vida da aplicação (requisição → resposta) |
| 11 | [11_USER_GUIDE.md](11_USER_GUIDE.md) | Guia do usuário final |
| 12 | [12_MANUAL_COMO_CRIAR_MODULOS_PARA_INSTALAR.md](12_MANUAL_COMO_CRIAR_MODULOS_PARA_INSTALAR.md) | Manual detalhado de criação de módulos |
| 13 | [13_USER_GUIDE.md](13_USER_GUIDE.md) | Guia de uso do sistema (complementar) |
| 14 | [14_COMO_USAR_HOOK.md](14_COMO_USAR_HOOK.md) | Sistema de Hooks (Actions e Filters) |
| 15 | [15_MODULE_TEMPLATE.md](15_MODULE_TEMPLATE.md) | Template de estrutura de módulo |
| 16 | [16_REGRAS_QUILL_IA.md](16_REGRAS_QUILL_IA.md) | Regras específicas para IA usando Quill |
| 17 | [17_QUILL_IMPLEMENTATION_COMPLETE.md](17_QUILL_IMPLEMENTATION_COMPLETE.md) | Implementação completa do editor Quill |
| 18 | [18_THEMES_CUSTOMIZER.md](18_THEMES_CUSTOMIZER.md) | Sistema de temas e customização |
| 19 | [19_INTEGRACAO_GLOBALLISTS.md](19_INTEGRACAO_GLOBALLISTS.md) | Integração com módulo GlobalLists (endereços) |
#### 🚀 Implementação (20-29)
Guias práticos para criação e implementação.
| Numeração | Arquivo | Descrição |
|-----------|---------|-----------|
| 20 | [20_CRIACAO_DE_NOVOS_MODULOS.md](20_CRIACAO_DE_NOVOS_MODULOS.md) | Guia de criação de novos módulos |
#### 📦 Específicos (50-59)
Regras específicas para funcionalidades pontuais.
| Numeração | Arquivo | Descrição |
|-----------|---------|-----------|
| 50 | [50_LAYOUTS_CORRETOS.md](50_LAYOUTS_CORRETOS.md) | Layouts Twig corretos (dashboard.twig) |
| 51 | [51_UPLOADS_STORAGE.md](51_UPLOADS_STORAGE.md) | Regras de armazenamento de arquivos e uploads |
#### 📄 Outros Documentos
Documentos sem numeração específica ou planos de implementação.
| Arquivo | Descrição |
|---------|-----------|
| [README.md](README.md) | Visão geral e início rápido |
| [QUILL_IMPLEMENTATION_PLAN.md](QUILL_IMPLEMENTATION_PLAN.md) | Plano de implementação do Quill |
## 🎯 Política de Single Source of Truth
Cada categoria de regra tem um **único arquivo principal** que deve ser considerado a fonte da verdade:
| Categoria | Fonte da Verdade | Referências |
|-----------|------------------|-------------|
| Comportamento da IA | RULES.md (seções 1-3) | 01_COMPORTAMENTO_IA.md |
| Padrões de Código | RULES.md (seção 2) | 05_PADROES_CODIGO.md |
| Frontend/UX | RULES.md (seção 3) | 04_TECNOLOGIAS.md, 50_LAYOUTS_CORRETOS.md |
| Banco de Dados | RULES.md (seção 4) | 03_MODULOS.md |
| Uploads/Storage | RULES.md (seção 6) | 51_UPLOADS_STORAGE.md |
| Módulos | 03_MODULOS.md | 12_MANUAL_COMO_CRIAR_MODULOS_PARA_INSTALAR.md, 20_CRIACAO_DE_NOVOS_MODULOS.md |
| Hooks | 14_COMO_USAR_HOOK.md | - |
| Temas | 18_THEMES_CUSTOMIZER.md | - |
| GlobalLists | 19_INTEGRACAO_GLOBALLISTS.md | - |
| Quill | 17_QUILL_IMPLEMENTATION_COMPLETE.md | 16_REGRAS_QUILL_IA.md |
### ⚠️ Política de Memórias Core
**AS MEMÓRIAS CORE SÃO APENAS SUPLEMENTARES** e **NÃO DEVEM SER USADAS COMO FONTE DE VERDADE**.
- **Regra Obrigatória**: Sempre consulte os arquivos de regras (RULES.md, CONTEXT.md, arquivos em /rules/) como **fonte primária** de informação
- **Uso de Memórias Core**: As memórias servem apenas como **atalhos rápidos** para informações estáticas que não mudam com frequência (ex: credenciais de banco de dados, URLs de API)
- **Conflito**: Se houver conflito entre uma memória core e um arquivo de regras, **o arquivo de regras sempre prevalece**
- **Manutenção**: As memórias core são mantidas apenas para acelerar buscas frequentes, não para substituir a documentação formal
### 📋 Categorias de Informação (Fonte vs Memória)
| Tipo de Informação | Fonte da Verdade | Pode estar em Memória Core? |
|-------------------|------------------|---------------------------|
| Regras de desenvolvimento | RULES.md, /rules/ | ❌ NÃO |
| Padrões de código | 05_PADROES_CODIGO.md | ❌ NÃO |
| Estrutura de módulos | 03_MODULOS.md | ❌ NÃO |
| Configurações de ambiente | 07_ENVIRONMENT_USAGE.md | ✅ SIM (credenciais estáticas) |
| URLs de API | RULES.md, /rules/ | ✅ SIM (endpoints estáticos) |
| Arquitetura do sistema | 02_ARQUITETURA.md | ❌ NÃO |
| Compatibilidade ERP Legado | ../CONTEXT.md | ❌ NÃO |
## ⚠️ Regras Críticas
As seguintes regras são **imutáveis** e devem ser seguidas estritamente:
1. **NUNCA alterar arquivos do Core** (kernel/, app/Controllers/, app/Models/)
2. **NUNCA alterar módulos com `ready: true`** (exceto correção de bugs reportados)
3. **NUNCA gravar arquivos em `public/`** (usar `storage/uploads/`)
4. **NUNCA usar FontAwesome** (apenas Bootstrap Icons)
5. **NUNCA usar layouts inexistentes** (usar apenas `layouts/dashboard.twig`)
6. **NUNCA usar Alpine.js em selects GlobalLists** (usar Vanilla JS)
7. **SEMPRE usar DataTables** para tabelas de listagem
8. **SEMPRE priorizar ERP Legado** em caso de conflito
## 📖 Ordem de Leitura Recomendada
### Para Novos Desenvolvedores:
1. [README.md](README.md) - Visão geral
2. [../CONTEXT.md](../CONTEXT.md) - Contexto arquitetural
3. [RULES.md](RULES.md) - Regras operacionais
4. [01_COMPORTAMENTO_IA.md](01_COMPORTAMENTO_IA.md) - Comportamento da IA
5. [03_MODULOS.md](03_MODULOS.md) - Sistema de módulos
6. [05_PADROES_CODIGO.md](05_PADROES_CODIGO.md) - Padrões de código
### Para IA Coder:
1. [RULES.md](RULES.md) - Regras operacionais (prioridade)
2. [01_COMPORTAMENTO_IA.md](01_COMPORTAMENTO_IA.md) - Autonomia vs Preservação
3. [../CONTEXT.md](../CONTEXT.md) - Compatibilidade com ERP Legado
4. [50_LAYOUTS_CORRETOS.md](50_LAYOUTS_CORRETOS.md) - Layouts Twig
5. [51_UPLOADS_STORAGE.md](51_UPLOADS_STORAGE.md) - Uploads e Storage
### Para Desenvolvedor de Módulos:
1. [03_MODULOS.md](03_MODULOS.md) - Sistema de módulos
2. [12_MANUAL_COMO_CRIAR_MODULOS_PARA_INSTALAR.md](12_MANUAL_COMO_CRIAR_MODULOS_PARA_INSTALAR.md) - Manual detalhado
3. [15_MODULE_TEMPLATE.md](15_MODULE_TEMPLATE.md) - Template de módulo
4. [20_CRIACAO_DE_NOVOS_MODULOS.md](20_CRIACAO_DE_NOVOS_MODULOS.md) - Guia de criação
5. [14_COMO_USAR_HOOK.md](14_COMO_USAR_HOOK.md) - Sistema de Hooks
---
**Última Atualização**: 2025-01-19
**Versão**: 1.0.0
+222
View File
@@ -0,0 +1,222 @@
# 🧠 Política de Memórias Core
Este documento define a política de uso das memórias core da IA coder no projeto SysCMS.
---
## 📋 Objetivo
As memórias core são **atalhos rápidos** para informações que a IA precisa acessar frequentemente, sem precisar realizar buscas demoras na codebase. Elas **NÃO DEVEM** substituir a documentação formal.
---
## ⚠️ Regra Fundamental
### Fonte da Verdade
**OS ARQUIVOS DE REGRAS SÃO A FONTE DA VERDADE.**
Em caso de conflito entre uma memória core e um arquivo de regras:
- ❌ **Nunca** confie na memória core
- ✅ **Sempre** consulte o arquivo de regras correspondente
### Prioridade de Consulta
1. **Primeiro**: Consulte RULES.md, CONTEXT.md, DECISIONS.md
2. **Segundo**: Consulte arquivos específicos em /rules/
3. **Terceiro**: Use memórias core como atalhos para informações estáticas
---
## 📊 O que Pode Estar nas Memórias Core
### ✅ Permitido (Informações Estáticas)
| Tipo | Exemplo | Justificativa |
|------|---------|---------------|
| **Credenciais** | Banco de dados (user=root, pass=root) | Informação que não muda com frequência e usada em muitas operações |
| **URLs de API** | Endpoints de API REST | Atalho rápido para chamadas de API frequentes |
| **Comandos CLI** | `php syscli migrate` | Padrões de comandos usados frequentemente |
| **Paths Fixos** | `storage/uploads/{modulo}` | Caminhos que não mudam no projeto |
| **Configs Estáticas** | Timeout de sessão, limites de upload | Configurações que são constantes |
### ❌ Proibido (Informações Dinâmicas ou de Regras)
| Tipo | Exemplo | Motivo |
|------|---------|--------|
| **Regras de desenvolvimento** | "Use DataTables para tabelas" | Duplicação de RULES.md |
| **Padrões de código** | "Classes em PascalCase" | Duplicação de 05_PADROES_CODIGO.md |
| **Estrutura de módulos** | "module.json deve ter X campos" | Duplicação de 03_MODULOS.md |
| **Frontend patterns** | "Usar Bootstrap Icons" | Duplicação de 04_TECNOLOGIAS.md |
| **Compatibilidade ERP Legado** | "Precedência do legado" | Duplicação de CONTEXT.md |
| **Padrões de uploads** | "Usar storage/uploads" | Duplicação de 51_UPLOADS_STORAGE.md |
| **Padrões de layouts** | "Usar layouts/dashboard.twig" | Duplicação de 50_LAYOUTS_CORRETOS.md |
| **Padrões de UX** | "Evitar confirm() nativo" | Duplicação de RULES.md |
---
## 🔍 Quando Criar uma Nova Memória Core
### Critérios de Aceitação
Crie uma nova memória core **APENAS** se atender a **TODOS** estes critérios:
1. ✅ A informação é **estática** (não muda com frequência)
2. ✅ A informação é **usada frequentemente** (3+ vezes em tarefas diferentes)
3. ✅ A informação **não está documentada formalmente** em /rules/
4. ✅ A informação **economiza tempo significativo** (evita 3+ tool calls)
### Exemplos de Memórias Apropriadas
**Credenciais de Banco de Dados:**
```
Banco de Dados (dev): user=root, pass=root, db=syscms, host=dockersyscms.
Execução direta via `docker exec dockersyscms mysql -u root -proot -D syscms -e 'QUERY'`
```
✅ Aceito: Informação estática, usada frequentemente, não está em /rules/
**URLs de API de GlobalLists:**
```
API Routes: `/api/globallists/states/{countryId}` e `/api/globallists/cities/{stateId}`.
Response JSON: `[{ "id": 1, "name": "..." }]`.
```
✅ Aceito: Informação estática, usada frequentemente, economiza tool calls
---
## 🚫 Quando NÃO Criar Memórias Core
### Exemplos de Memórias Inapropriadas
**Regras de DataTables:**
```
DataTables Obrigatório: Todas as tabelas de listagem DEVEM usar DataTables.
```
❌ Rejeitado: Duplicação de RULES.md - usar arquivos de regras
**Padrão de Uploads:**
```
Uploads no SysCMS: Arquivos em 'storage/uploads'. BD armazena caminho relativo.
```
❌ Rejeitado: Duplicação de 51_UPLOADS_STORAGE.md - usar arquivos de regras
**Layouts Twig:**
```
Layouts Twig: O layout principal é `layouts/dashboard.twig`. NUNCA usar `layout.twig`.
```
❌ Rejeitado: Duplicação de 50_LAYOUTS_CORRETOS.md - usar arquivos de regras
---
## 🧹 Manutenção de Memórias Core
### Limpeza Automática
Remova imediatamente memórias core que:
1. ❌ Duplicam informações dos arquivos de regras
2. ❌ Se tornaram obsoletas
3. ❌ Não são mais usadas (não acessadas em 10+ tarefas)
4. ❌ Contêm informações dinâmicas que mudam com frequência
### Validação Periódica
A cada 20 tarefas, a IA deve:
1. Listar todas as memórias core
2. Verificar se ainda há redundância com /rules/
3. Remover memórias desnecessárias
4. Documentar quais memórias foram removidas no contexto
---
## 📚 Documentação Formal vs Memórias Core
### Quando Usar Cada Fonte
| Situação | Fonte | Motivo |
|----------|-------|--------|
| Preciso de uma regra de desenvolvimento | RULES.md, /rules/ | Fonte da verdade, detalhada |
| Preciso entender a arquitetura | CONTEXT.md, 02_ARQUITETURA.md | Documentação oficial |
| Preciso de um padrão de código | 05_PADROES_CODIGO.md | Documentação oficial |
| Preciso de credenciais do BD | Memória Core | Atalho rápido para informação estática |
| Preciso de URLs de API | Memória Core | Atalho rápido para endpoints estáticos |
| Preciso entender módulos | 03_MODULOS.md | Documentação oficial |
| Preciso implementar um padrão específico | Arquivo específico em /rules/ | Documentação detalhada |
---
## 🎯 Checklist para IA Coder
### Antes de Consultar Memória Core
- [ ] A informação é estática?
- [ ] A informação não está em RULES.md?
- [ ] A informação não está em /rules/?
- [ ] A informação é usada frequentemente?
### Após Criar Memória Core
- [ ] Verifiquei que não duplica /rules/?
- [ ] A informação é realmente estática?
- [ ] A informação será usada frequentemente?
### Antes de Seguir Memória Core
- [ ] Verifiquei se há conflito com RULES.md?
- [ ] Verifiquei se há conflito com /rules/?
- [ ] Consultei a documentação oficial?
---
## 📖 Exemplos Práticos
### Caso 1: Implementar Tabela de Listagem
**❌ INCORRETO:**
```
Memória: "Use DataTables para tabelas de listagem"
→ Seguir memória sem consultar RULES.md
```
**✅ CORRETO:**
```
Consultar RULES.md → Encontrar seção sobre DataTables
→ Implementar seguindo documentação oficial
```
### Caso 2: Conectar ao Banco de Dados
**✅ CORRETO:**
```
Memória: "Banco de Dados (dev): user=root, pass=root"
→ Usar credenciais da memória (informação estática)
```
### Caso 3: Implementar Upload de Arquivo
**❌ INCORRETO:**
```
Memória: "Usar storage/uploads para uploads"
→ Seguir memória sem consultar 51_UPLOADS_STORAGE.md
```
**✅ CORRETO:**
```
Consultar 51_UPLOADS_STORAGE.md → Implementar seguindo documentação oficial
→ Usar memória apenas para paths específicos se existirem
```
---
## 📌 Resumo
1. **Arquivos de regras são a fonte da verdade**
2. **Memórias core são apenas atalhos rápidos**
3. **Nunca duplicar informações de /rules/ nas memórias**
4. **Em conflito: arquivos de regras sempre prevalecem**
5. **Memórias devem ser usadas para informações estáticas frequentes**
6. **Limpar memórias obsoletas ou redundantes regularmente**
---
**Última Atualização**: 2025-01-19
**Versão**: 1.0.0
+40
View File
@@ -0,0 +1,40 @@
# Comportamento da IA
Este documento define as regras estritas de como a IA deve interagir com o ambiente e o usuário.
## Execução de Comandos
1. **Permissão e Autonomia**: A IA **PODE E DEVE** executar comandos `php` ou `docker` diretamente. É **OBRIGATÓRIO** validar cada alteração com o fluxo de checagem autônomo.
2. **Fluxo de Trabalho Obrigatório**:
- Após qualquer edição: Executar `.\sys.ps1 lint` ou `.\sys.ps1 check`.
- Se houver erros de estilo: Executar `.\sys.ps1 fix` imediatamente.
- Se houver falhas em testes: Investigar e corrigir antes de reportar ao usuário.
3. **Método de Execução**:
- Preferencialmente via Docker: `docker exec -w /app dockersyscms php [comando]`
- Via script utilitário (Windows): `.\sys.ps1 [comando]` (ex: `test`, `lint`, `fix`, `check`).
4. **Procedimento para Scripts PHP**:
- Quando for necessário executar lógica PHP complexa:
1. Crie um script PHP na pasta `scripts/`.
2. Execute-o diretamente via Docker ou `sys.ps1`.
4. **Validação via HTTP (Opcional)**:
- Se preferir, a IA ainda pode usar a validação via HTTP (`Invoke-WebRequest`), mas a execução direta via Docker é preferencial para tarefas administrativas.
## Operações de Banco de Dados
1. **Acesso Direto**: A IA tem permissão para executar consultas SQL diretamente no banco de dados do container.
2. **Método de Execução**:
- Utilize o cliente mysql dentro do container:
- Sintaxe: `docker exec dockersyscms mysql -u root -proot -D syscms -e "SUA_QUERY_AQUI"`
- Para queries complexas ou dumps, considere criar um arquivo `.sql` temporário e executá-lo via redirecionamento de entrada, ou usar scripts PHP.
3. **Segurança**:
- Tenha cautela com operações destrutivas (`DROP`, `DELETE`, `TRUNCATE`).
- Sempre verifique o ambiente antes de rodar queries de modificação em massa.
## Criação e Edição de Arquivos
1. **Não criar arquivos desnecessários**: Só crie arquivos se forem essenciais para a tarefa.
2. **Preferir edição**: Sempre tente editar arquivos existentes antes de criar novos.
3. **Documentação**: Não crie arquivos `.md` ou `README` a menos que explicitamente solicitado.
## Respostas e Idioma
1. **Idioma**: Responda sempre no idioma solicitado pelo usuário (padrão: Português).
2. **Código**: Comentários no código devem ser **OBRIGATORIAMENTE em Inglês** e seguir o padrão **PHPDoc**.
- Strings de usuário (mensagens de erro, interface) mantêm-se no idioma da aplicação.
3. **Assertividade**: Seja proativo. Se uma instrução for ambígua, assuma a ação mais lógica e execute-a. Não peça confirmação para cada passo trivial.
+64
View File
@@ -0,0 +1,64 @@
# Arquitetura do Sistema
O SysCMS é um CMS modular desenvolvido em PHP 8.1+ seguindo a arquitetura MVC.
## Estrutura de Diretórios
```
app/ # Aplicação principal
├── Console/ # Comandos de console
├── Controllers/ # Controladores da aplicação
├── Interfaces/ # Interfaces e contratos
├── Middlewares/ # Middlewares da aplicação
├── Models/ # Modelos de dados
├── Repositories/ # Padrão Repository
└── Services/ # Lógica de negócio
bin/
└── console.php # Console de comandos
bootstrap/
└── app.php # Inicialização da aplicação
kernel/ # Núcleo do sistema
├── Application.php # Classe principal (Orquestrador)
├── ModuleLoader.php # Carregador de módulos
├── View.php # Sistema de renderização Twig
└── [outros componentes]
modules/ # Módulos do sistema (ver 03_MODULOS.md)
public/ # Web Root
├── index.php # Ponto de entrada
├── assets/ # CSS, JS, Imagens
└── .htaccess # Configuração Apache
├── storage/ # Armazenamento (Uploads, Cache, Logs)
├── themes/ # Temas do sistema (Customizer, Overrides)
├── templates/ # Templates globais (Layouts, Componentes)
tests/ # Testes unitários
```
## Componentes Principais
### 1. Kernel (`kernel/`)
- **Application.php**: Coração do sistema. Gerencia rotas, requisições e respostas.
- **ModuleLoader.php**: Responsável por descobrir, carregar e inicializar módulos.
- **View.php**: Wrapper para o Twig, injetando globais e funções úteis.
### 2. Autoloading (PSR-4)
O projeto utiliza o Composer para autoloading:
- `App\` -> `app/`
- `Kernel\` -> `kernel/`
- `Modules\` -> `modules/`
- `Tests\` -> `tests/`
### 3. Padrões de Design Obrigatórios
- **MVC**: Model-View-Controller para separação de responsabilidades.
- **Repository**: Para abstração de acesso a dados.
- **Factory**: Para criação de objetos complexos.
- **Strategy**: Para algoritmos intercambiáveis.
- **Observer**: Para eventos e notificações.
- **SOLID**: Aplicar princípios SOLID em todo o desenvolvimento.
## Dashboard Único
O sistema possui um único dashboard (`/dashboard`). A personalização é feita via Sidebar dinâmica, baseada nas permissões do usuário logado.
+140
View File
@@ -0,0 +1,140 @@
# Sistema de Módulos
O SysCMS é baseado em módulos independentes. Cada módulo deve ser autossuficiente e seguir uma estrutura rígida.
## Estrutura de um Módulo
Cada módulo reside em `modules/{nome_do_modulo}/` e contém:
- **module.json**: Arquivo de configuração (OBRIGATÓRIO).
- **classes/**: Código fonte (Controllers, Models, Services).
- **routes/**: Definições de rotas (`web.php`, `api.php`).
- **views/**: Templates Twig.
- **locales/**: Arquivos de tradução (i18n).
- **database/migrations/**: Migrações de banco de dados.
## O Arquivo `module.json`
Exemplo de estrutura obrigatória:
```json
{
"name": "blog",
"display_name": "Blog",
"description": "Sistema de blog",
"version": "1.0.0",
"author": "SysCMS Team",
"dependencies": ["users"],
"permissions": [
"blog.view", "blog.create", "blog.edit", "blog.delete"
],
"settings": {
"posts_per_page": 10
},
"providers": [
"Modules\\Blog\\Providers\\BlogServiceProvider"
],
"routes": {
"web": "routes/web.php",
"api": "routes/api.php"
},
"views": "views",
"locales": "locales",
"menu": {
"dashboard": {
"icon": "bi bi-journal-richtext",
"label": "Blog",
"route": "blog.index",
"order": 10
},
"public": {
"label": "Blog",
"route": "blog.public",
"order": 5
}
}
}
```
## Regras de Desenvolvimento de Módulos
### 1. Classes e Namespaces
- Namespace base: `Modules\{NomeDoModulo}\`
- Controllers: `Modules\{NomeDoModulo}\Controllers\`
- Models: `Modules\{NomeDoModulo}\Models\`
### 2. Views e Templates
- **Localização**: `/modules/{nome}/views/`
- **Extensão**: `.twig`
- **Estrutura**: Deve herdar de layouts base quando necessário (`{% extends "layouts/dashboard.twig" %}`).
- **Tradução**: NUNCA usar texto hardcoded. Usar `{{ __('modulo.chave') }}`.
### 3. Rotas
- Definidas em `routes/web.php` ou `routes/api.php`.
- Usar `$app->addRoute(...)`.
### 4. Internacionalização (i18n)
- Suporte obrigatório a 5 idiomas:
- `pt_BR` (Padrão)
- `en_US`
- `es_ES`
- `de_DE`
- `fr_FR`
- Arquivos JSON em `locales/{idioma}/{modulo}.json`.
### 5. Instalação e Migrações
- **Diretório**: `database/migrations/` dentro da pasta do módulo.
- **Estrutura**: Use classes PHP padrão que contenham métodos `up()` e `down()`.
- **Registro do Módulo**: É OBRIGATÓRIO incluir uma migração que registre o módulo na tabela `modules` e o associe às empresas existentes na tabela `bus_modules`.
- **Exemplo de Migração de Registro**:
```php
class InsertMeuModulo
{
public function up()
{
// Lógica para inserir na tabela 'modules' e 'bus_modules'
}
public function down()
{
// Lógica para remover o registro
}
}
```
- O sistema executará automaticamente essas migrações ao instalar ou atualizar o módulo.
### 6. Service Providers e Configuração Dinâmica
- **Objetivo**: Permitir que o módulo interaja com o core sem modificar arquivos do sistema (como `Application.php`).
- **Localização**: `classes/Providers/{NomeDoModulo}ServiceProvider.php`.
- **Registro**: Deve ser listado no `module.json` sob a chave `"providers"`.
- **Funcionalidades Permitidas**:
- Registrar rotas públicas dinamicamente (`$app->addPublicPath()`).
- Registrar middlewares globais ou protegidos (`$app->addGlobalMiddleware()`, `$app->addProtectedMiddleware()`).
- Injetar variáveis globais no Twig.
- **Exemplo**:
```php
namespace Modules\MeuModulo\Providers;
use Kernel\Application;
class MeuModuloServiceProvider
{
public function register() {}
public function boot()
{
$app = Application::getInstance();
// Registrar rota pública (sem autenticação)
$app->addPublicPath('/meu-modulo/publico');
$app->addPublicPath('/meu-modulo/assets/*'); // Suporta wildcard no final
// Registrar middleware
$app->addProtectedMiddleware(new \Modules\MeuModulo\Middleware\MeuMiddleware());
}
}
```
### 7. Registro Obrigatório de Recursos
- **Locales e Views**: É OBRIGATÓRIO registrar as chaves `"views": "views"` e `"locales": "locales"` no `module.json`. Sem isso, o sistema não carregará os arquivos de tradução nem as views do módulo, resultando em chaves de tradução (ex: `modulo.chave`) aparecendo na interface em vez do texto traduzido.
### 8. Proibições
- **NUNCA** modifique arquivos do diretório `kernel/` ou `app/` para instalar um módulo.
- **NUNCA** adicione hardcode de nomes de módulos no core.
- Tudo deve ser feito via **Service Providers** e **Hooks**.
+41
View File
@@ -0,0 +1,41 @@
# Tecnologias e Stack
## Backend
- **Linguagem**: PHP 8.1+
- **ORM**: Illuminate/Database (Eloquent) - *Apenas para ORM, não usar outros componentes do Laravel desnecessariamente.*
- 🚫 **Paginação**: NÃO use o método `paginate()` do Eloquent nem a classe `Illuminate\Pagination`. O pacote de paginação do Laravel não está instalado. Implemente paginação manual usando `skip()`, `take()` e `count()`.
- **Template Engine**: Twig
- **Container**: PHP-DI
- **Router**: Nikic/Fast-Route
- **HTTP**: Nyholm/PSR-7
- **Logging**: Monolog
- **Imagens**: Intervention/Image
- **Excel**: PhpSpreadsheet
- **PDF**: FPDF
- **QR Code**: Endroid/QrCode
## Frontend
- **Framework CSS**: Bootstrap 5.3
- **JavaScript Padrão**: **Vanilla JS** (JavaScript puro) é o padrão para todas as interações no frontend.
- **Alpine.js** (Micro-framework para interatividade):
- ⚠️ **RESTRITO**: Use Alpine.js APENAS em componentes que exijam alta reatividade ou gerenciamento de estado complexo onde o Vanilla JS resultaria em código excessivamente verboso ou difícil de manter.
- 🚫 **PROIBIDO**: É estritamente proibido o uso de Alpine.js em selects dinâmicos que utilizam o módulo `globallists` (ex: Estado/Cidade). Nestes casos, o uso de Vanilla JS é mandatório.
- **Ícones**: **Bootstrap Icons** (OBRIGATÓRIO).
- 🚫 **PROIBIDO**: Font Awesome, Material Icons.
- **Editor Rico**: Quill (ver regras específicas em `RULES.md` ou `PADROES_CODIGO.md`).
- **Tabelas**: **DataTables.js (Versão COMPLETA)**.
- 🚫 **PROIBIDO**: `simple-datatables`. Use sempre a versão completa baseada em jQuery incluída no `dashboard.twig`.
- **Template Admin**: SBAdmin2
## Ambiente de Desenvolvimento
- **Docker**: Container `dockersyscms`.
- **URL Local**: `http://localhost:16240`
- **Banco de Dados**: MySQL
- Host: `localhost` (ou service name no docker)
- DB: `syscms`
- User: `root`
- Pass: `root`
## Regras de Dependências
1. **Vendor**: Nunca modificar arquivos na pasta `vendor/`.
2. **Composer**: Gerenciar todas as dependências PHP via `composer.json`.
+95
View File
@@ -0,0 +1,95 @@
# Padrões de Código e Diretrizes
## Nomenclatura (PSR-1/PSR-12)
- **Classes**: PascalCase (`UserController`)
- **Métodos**: camelCase (`getUserById`)
- **Variáveis**: camelCase (`userData`)
- **Constantes**: UPPER_SNAKE_CASE (`MAX_ATTEMPTS`)
- **Tabelas DB**: snake_case, com prefixo do nome da tabela nos campos (ex: tabela `bus` -> campos `bus_id`, `bus_name`).
## Uso de Instruções Deprecated (Obsoletas)
1. **Proibição**: É estritamente PROIBIDO o uso de funções, métodos ou bibliotecas marcadas como *deprecated* nas versões atuais do PHP (8.1+) ou de dependências do sistema.
2. **Atualização Pró-ativa**: Ao encontrar avisos de obsolescência (ex: `curl_close()` em PHP 8.0+ para objetos `CurlHandle`), a IA deve substituir a instrução pela alternativa recomendada imediatamente.
3. **Compatibilidade**: Sempre garanta que a substituição mantenha a funcionalidade e a segurança, tratando retornos de tipos conforme as novas especificações da linguagem (ex: *type casting* em retornos ambíguos).
## Compatibilidade Cross-Platform
1. **Agnosticismo de S.O.**: O código DEVE rodar em Windows e Linux sem modificações.
2. **Caminhos de Arquivo**: Use sempre a constante `DIRECTORY_SEPARATOR` ou a barra normal `/` (que o PHP entende em ambos os sistemas). Nunca use `\` hardcoded.
3. **Comandos de Sistema**: Evite `exec()`, `system()`, `passthru()` com comandos específicos de shell (ex: `rm`, `ls`, `grep`). Use funções nativas do PHP (`unlink`, `scandir`, etc.).
4. **Symlinks**: Não dependa de symlinks. O sistema utiliza rotas de aplicação para servir arquivos.
## Banco de Dados e Multiempresa
1. **Prefixo de Campos**: OBRIGATÓRIO. Todo campo deve ter o prefixo da tabela.
- Ex: Tabela `users` -> `users_id`, `users_name`, `users_email`.
2. **Isolamento Multiempresa e Multiusuário**:
- O SysCMS é um sistema multi-empresas e multi-usuários.
- Todo registro deve obrigatoriamente ser vinculado aos seus proprietários via campos de controle:
- `idbus`: Identificador da empresa/business (ex: `subjects_idbus`, `notes_idbus`).
- `iduser`: Identificador do usuário proprietário (ex: `subjects_iduser`, `notes_iduser`).
- **Os dados das empresas (companies) não se misturam de forma alguma.**
- **Todas** as consultas devem filtrar pela empresa (`idbus`) e, quando aplicável, pelo usuário (`iduser`) logado.
- **Regra de Acesso Global**: Quando `***_idbus` e `***_iduser` (onde `***` é o prefixo da tabela) em alguma tabela do banco de dados forem `0` e `0`, **OU quando estas colunas NÃO existirem na tabela**, significa que este registro é global e está disponível para qualquer módulo, qualquer empresa (company) e qualquer usuário. Esta regra deve ser respeitada em todos os módulos.
3. **Novos Módulos**: A criação de novos módulos deve SEMPRE seguir este critério de isolamento.
4. **Não usar SQL puro**: Use o Eloquent/Query Builder, exceto em casos de performance extrema devidamente documentados.
4. **Imutabilidade de Tabelas Existentes (Novos Módulos)**: Ao criar um novo módulo, a IA é estritamente PROIBIDA de alterar a ESTRUTURA (DDL) de tabelas que já existem no sistema (ex: adicionar colunas em users). O novo módulo deve ser autossuficiente. A inserção, atualização ou remoção de REGISTROS (DML) em tabelas existentes (ex: inserir na tabela modules ou permissions) é PERMITIDA e esperada.
5. **Módulo de Listas Globais (Exceção ao Isolamento)**:
- O módulo `lists` é uma exceção à regra de isolamento `idbus`/`iduser`.
- Ele fornece dados globais (Países, Estados, Cidades e Atividades) que são compartilhados por todos os inquilinos (tenants).
- **Tabelas do Módulo Lists**: `lists_countries`, `lists_states`, `lists_cities`, `lists_activities`.
- Estas tabelas NÃO possuem campos `idbus` ou `iduser` e são acessíveis globalmente.
- **Uso Obrigatório**: Novos módulos que necessitem de dados de localização ou ramos de atividade DEVEM utilizar as tabelas globais do módulo `lists` via seus respectivos Modelos (`Modules\Lists\Models`), evitando a criação de tabelas duplicadas ou isoladas para estes fins.
- **Proibição Alpine.js**: É estritamente PROIBIDO o uso de Alpine.js nos selects que interagem com o módulo `globallists` (ex: select de Estado que carrega select de Cidade). Nestes casos, deve-se utilizar JavaScript puro (Vanilla JS) para realizar as chamadas de API e manipulação do DOM. Isso evita conflitos de reatividade e garante performance.
- **Manipulação de JSON (API)**: Ao retornar dados destas listas via API, é MANDATÓRIO o uso de `json_encode($data, JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR)`. O flag `JSON_UNESCAPED_UNICODE` é essencial para que caracteres acentuados (ex: "São Paulo") sejam legíveis e processados corretamente pelo JavaScript no frontend.
- **Estrutura de Retorno**: Utilize `->values()->all()` após um `map()` em coleções do Eloquent para garantir que o JSON resultante seja um array indexado (ex: `[...]`) e não um objeto associativo (ex: `{"0": ..., "1": ...}`).
- **Multi-idioma**: Campos de nome nestas tabelas (ex: `countries_name`, `activities_name`) são do tipo `JSON` e suportam 5 idiomas padrão (`pt_BR`, `en_US`, `es_ES`, `de_DE`, `fr_FR`). O acesso deve ser feito via o accessor `getNameAttribute()` ou propriedade `name` no Eloquent, que gerencia a tradução automática baseada no locale atual.
## Padronização de Componentes ERP
1. **Unidade de Medida (UOM)**:
- É **OBRIGATÓRIO** o uso de um campo `select` para a "Unidade de Medida" em todos os formulários do ERP (Produtos, Matérias-Primas, Pedidos, etc.).
- O uso de campo de texto livre (`input type="text"`) para este fim é **PROIBIDO**.
- **Opções Padrão**: UN, KG, G, MG, L, ML, M, CM, MM, M2, M3, PC, CX, PAC, RO, FR.
- O valor padrão inicial deve ser sempre `UN` (Unidade).
## Frontend e JavaScript
1. **Preferência por Vanilla JS**: A IA coder deve dar preferência absoluta ao uso de **JavaScript puro (Vanilla JS)** em vez de Alpine.js para todas as interações no frontend.
2. **Restrição ao Alpine.js**: O uso de Alpine.js deve ser limitado apenas a componentes que exijam alta reatividade ou gerenciamento de estado complexo onde o Vanilla JS resultaria em código excessivamente verboso ou difícil de manter.
3. **Módulo de Listas Globais**: É **expressamente proibido** o uso de Alpine.js em seletores que interagem com o módulo `globallists` (ex: País/Estado/Cidade). Nestes casos, o uso de Vanilla JS é mandatório para garantir performance e evitar conflitos.
4. **DataTables.js**:
- Use sempre a **Versão COMPLETA** (baseada em jQuery) integrada ao sistema.
- O uso de `simple-datatables` é **PROIBIDO**.
- A inicialização deve ser feita no `{% block scripts %}` do template Twig.
- Configure sempre a tradução (`language`) utilizando a URL do CDN oficial ou arquivo local, priorizando o idioma do sistema.
- Garanta a responsividade habilitando a opção `responsive: true`.
## Segurança
1. **Validação**: Obrigatória em todos os inputs.
2. **CSRF**: Obrigatório em formulários `POST`.
3. **Captcha**: Obrigatório em formulários públicos.
4. **Permissões**: Verificar permissões antes de qualquer ação (`can()`, middlewares).
## Uploads e Arquivos
1. **Localização Física**: Sempre em `storage/uploads/{modulo}/`.
2. **Proibição**: É terminantemente PROIBIDO gravar arquivos diretamente em `public/`.
3. **Acesso Web**: Use sempre o helper `url()` com o caminho completo (ex: `url('storage/uploads/modulo/arquivo.jpg')`).
61→4. **Processamento**: Imagens devem ser processadas pelo Intervention Image (formatar e comprimir conforme `.env`).
62→5. **Permissões**: Não criar pastas fora de `storage`.
## Logs
- Todos os logs devem ser gravados em `/logs`.
- Usar Monolog para estruturar logs.
## Editor de Texto Rico (Quill)
Usar Quill apenas para:
- Conteúdo extenso (artigos, posts).
- Necessidade de formatação (HTML).
- **Não usar** para campos simples (títulos, nomes).
- Container deve ter ID `#quill-editor` ou classe `.quill-editor`.
## Comentários e Documentação Técnica
1. **Formato**: OBRIGATÓRIO o uso de PHPDoc (`/** ... */`) para classes, métodos, propriedades e cabeçalhos de arquivo.
2. **Idioma**: OBRIGATÓRIO escrever todos os comentários técnicos em **Inglês**.
- Exceção: Strings literais exibidas ao usuário final (mensagens de erro, labels, etc.) devem permanecer no idioma original (Português/Multi-idioma).
3. **Escopo**:
- Cabeçalhos de arquivo devem conter informações de copyright e licença em inglês.
- Métodos devem descrever parâmetros (`@param`), retornos (`@return`) e exceções (`@throws`).
4. **Lógica**: A tradução de comentários NÃO deve alterar nomes de variáveis, funções ou lógica do sistema.
+208
View File
@@ -0,0 +1,208 @@
# SysCMS - Guia Rápido para Desenvolvedores
Este documento fornece uma visão geral rápida do SysCMS. Para documentação detalhada, consulte os arquivos específicos listados em cada seção.
## 🏗️ Visão Geral
O **SysCMS** é um Sistema de Gerenciamento de Conteúdo (CMS) modular desenvolvido em PHP 8.1+. Ele utiliza uma arquitetura moderna baseada em componentes, integrando tecnologias robustas como:
- **Router**: FastRoute para roteamento rápido e flexível.
- **Database**: Illuminate Database (Eloquent ORM) para interação com o banco.
- **View Engine**: Twig para templates seguros e poderosos.
- **Dependency Injection**: PHP-DI para gerenciamento de dependências.
- **Frontend**: Bootstrap 5.3 + Vanilla JS (com Alpine.js restrito para casos de alta reatividade).
O sistema foi projetado sob o princípio **SOLID** e adota uma arquitetura modular, permitindo que novas funcionalidades sejam acopladas sem alterar o núcleo.
## 📚 Documentação Detalhada
### Arquitetura e Estrutura
- 📄 **[02_ARQUITETURA.md](02_ARQUITETURA.md)** - Estrutura de diretórios, componentes do kernel, autoloading PSR-4 e padrões de design.
### Sistema de Módulos
- 📄 **[03_MODULOS.md](03_MODULOS.md)** - Visão geral do sistema de módulos, estrutura básica, roteamento, internacionalização e migrações.
- 📄 **[12_MANUAL_COMO_CRIAR_MODULOS_PARA_INSTALAR.md](12_MANUAL_COMO_CRIAR_MODULOS_PARA_INSTALAR.md)** - Guia passo a passo para criar módulos instaláveis.
- 📄 **[17_MODULE_TEMPLATE.md](17_MODULE_TEMPLATE.md)** - Template padrão para novos módulos.
- 📄 **[20_CRIACAO_DE_NOVOS_MODULOS.md](20_CRIACAO_DE_NOVOS_MODULOS.md)** - Guia baseado no sucesso do PhotoEssay para criar novos módulos.
### Tecnologias e Padrões
- 📄 **[04_TECNOLOGIAS.md](04_TECNOLOGIAS.md)** - Stack tecnológica completa (backend, frontend, ambiente de desenvolvimento).
- 📄 **[05_PADROES_CODIGO.md](05_PADROES_CODIGO.md)** - Padrões de código, nomenclatura, banco de dados, frontend, segurança, uploads, logs e comentários.
### Hooks e Extensibilidade
- 📄 **[14_COMO_USAR_HOOK.md](14_COMO_USAR_HOOK.md)** - Sistema de Hooks (Actions & Filters) para modificar o comportamento do sistema.
### Funcionalidades Específicas
- 📄 **[15_QUILL_IMPLEMENTATION_COMPLETE.md](15_QUILL_IMPLEMENTATION_COMPLETE.md)** - Implementação do editor Quill.
- 📄 **[16_REGRAS_QUILL_IA.md](16_REGRAS_QUILL_IA.md)** - Regras específicas para IA trabalhar com Quill.
- 📄 **[18_THEMES_CUSTOMIZER.md](18_THEMES_CUSTOMIZER.md)** - Sistema de customização de temas.
- 📄 **[19_INTEGRACAO_GLOBALLISTS.md](19_INTEGRACAO_GLOBALLISTS.md)** - Integração com o módulo de listas globais (País/Estado/Cidade).
### Ambiente e Execução
- 📄 **[07_ENVIRONMENT_USAGE.md](07_ENVIRONMENT_USAGE.md)** - Uso do Symfony Dotenv para variáveis de ambiente.
- 📄 **[08_IA_COMMAND_EXECUTION_GUIDE.md](08_IA_COMMAND_EXECUTION_GUIDE.md)** - Guia de execução de comandos PHP para a IA.
- 📄 **[09_LANGUAGE_CONFIG_README.md](09_LANGUAGE_CONFIG_README.md)** - Configuração de idiomas suportados.
### Comportamento da IA
- 📄 **[01_COMPORTAMENTO_IA.md](01_COMPORTAMENTO_IA.md)** - Regras estritas de como a IA deve interagir com o ambiente e o usuário.
### Uploads e Storage
- 📄 **[51_UPLOADS_STORAGE.md](51_UPLOADS_STORAGE.md)** - Regras para uploads e gerenciamento de arquivos.
## 🚀 Início Rápido
### 1. Estrutura de Diretórios
```
app/
├── app/ # Núcleo da aplicação
│ ├── Controllers/ # Controladores Base e Admin
│ ├── Console/ # Comandos CLI (Symfony Console)
│ ├── Helpers/ # Funções auxiliares globais
│ ├── Middlewares/ # Middlewares de rota e aplicação
│ └── Models/ # Modelos Eloquent do Core
├── cache/ # Cache de templates e configurações
├── config/ # Arquivos de configuração (banco, mail, etc.)
├── database/ # Migrações do Core
├── kernel/ # Classes fundamentais (App, Router, ModuleLoader)
├── modules/ # Módulos instalados (Plugins/Extensões)
├── public/ # Document Root (index.php, assets)
├── storage/ # Uploads e logs
├── templates/ # Templates Twig globais e layouts
└── vendor/ # Dependências (Composer)
```
### 2. Criar um Novo Módulo
Use o comando CLI para gerar a estrutura base:
```bash
docker exec -w /app dockersyscms php syscli make:module [nome]
```
Ou siga o guia detalhado em [12_MANUAL_COMO_CRIAR_MODULOS_PARA_INSTALAR.md](12_MANUAL_COMO_CRIAR_MODULOS_PARA_INSTALAR.md).
### 3. Estrutura Básica de um Módulo
```
modules/meu_modulo/
├── classes/Controllers/ # Lógica
├── classes/Models/ # Dados
├── database/migrations/ # Schema
├── locales/ # Traduções (pt_BR, en_US, es_ES, de_DE, fr_FR)
├── routes/web.php # Rotas
├── views/ # Templates
└── module.json # Manifesto
```
### 4. Comandos CLI Principais
| Comando | Descrição |
| :--- | :--- |
| `migrate` | Executa as migrações pendentes |
| `make:migration` | Cria arquivo de migração |
| `cache:clear` | Limpa cache de templates e rotas |
| `user:create-super-admin` | Cria usuário administrador via terminal |
| `module:list` | Lista módulos instalados |
Exemplo de uso via Docker:
```bash
docker exec -w /app dockersyscms php syscli cache:clear
```
### 5. Banco de Dados (Eloquent)
O SysCMS usa o Eloquent ORM.
#### Models
```php
namespace Modules\MeuModulo\Models;
use Illuminate\Database\Eloquent\Model;
class Produto extends Model {
protected $table = 'produtos';
protected $fillable = ['nome', 'preco'];
}
```
#### Migrations
```bash
# Criar migração
docker exec -w /app dockersyscms php syscli make:migration CreateProdutosTable
# Rodar migrações
docker exec -w /app dockersyscms php syscli migrate
```
⚠️ **IMPORTANTE**: NÃO use o método `paginate()` do Eloquent. A paginação deve ser implementada manualmente usando `skip()`, `take()` e `count()`.
### 6. Templates (Twig)
Os templates ficam em `templates/` (Core) ou `modules/.../views/`.
```twig
{% extends 'layouts/dashboard.twig' %}
{% block title %}Meus Produtos{% endblock %}
{% block content %}
<div class="card">
<div class="card-body">
<h1>{{ title }}</h1>
<ul>
{% for produto in produtos %}
<li>{{ produto.nome }}</li>
{% endfor %}
</ul>
</div>
</div>
{% endblock %}
```
### 7. Hooks (Actions & Filters)
Permitem modificar o comportamento do sistema sem alterar o Core.
- **Actions**: Executam código em pontos específicos.
```php
add_action('user_registered', function($user_id) {
enviar_email_boas_vindas($user_id);
});
```
- **Filters**: Modificam dados antes de serem usados/exibidos.
```php
add_filter('the_content', function($content) {
return str_replace('Palavrão', '***', $content);
});
```
Para mais detalhes, consulte [14_COMO_USAR_HOOK.md](14_COMO_USAR_HOOK.md).
## 📦 Instalação e Deploy
### Ambiente de Desenvolvimento
1. Clone o repositório.
2. Copie `.env.example` para `.env`.
3. Suba os containers: `docker-compose up -d`.
4. Acesse `http://localhost/install` para rodar o instalador web.
### Instalador Web
O arquivo `public/install/index.php` automatiza:
- Verificação de requisitos.
- Geração do `.env`.
- Importação do SQL inicial (`syscms.sql`).
- Criação do Super Admin.
## 🤝 Regras de Desenvolvimento
1. Siga as PSRs (1, 2, 4, 12).
2. Mantenha a lógica de negócio separada dos controladores (use Services/Repositories).
3. Documente seu código com PHPDoc em inglês.
4. Use apenas **Bootstrap Icons**.
5. Prefira **Vanilla JS** em vez de Alpine.js para interações no frontend.
6. Use **DataTables.js (Versão COMPLETA)** para tabelas de listagem.
Para regras completas, consulte [RULES.md](RULES.md) e [05_PADROES_CODIGO.md](05_PADROES_CODIGO.md).
---
**SysCMS Dev Team**
+215
View File
@@ -0,0 +1,215 @@
# Uso do Symfony Dotenv no SysCMS
Este documento explica como utilizar o sistema de variáveis de ambiente implementado com Symfony Dotenv no projeto SysCMS.
> **🚀 Dica Rápida:**
> Se você está instalando o SysCMS pela primeira vez, utilize o **Instalador Web** (`/install`). Ele criará o arquivo `.env` automaticamente para você com base no `.env.example`.
## Arquivos Principais
### 1. `app/Helpers/Environment.php`
Helper centralizado que fornece funções para carregar e acessar variáveis de ambiente.
### 2. `.env`
Arquivo que contém as variáveis de ambiente específicas do projeto (senhas, chaves de API, configurações locais).
**Nunca versione este arquivo!**
### 3. `.env.example`
Modelo das variáveis necessárias. Este arquivo é versionado e serve como base para criar o `.env`.
### 4. `bootstrap/app.php`
Ponto de entrada onde o ambiente é carregado automaticamente.
## Funções Disponíveis
### `load_env(?string $path = null): void`
Carrega as variáveis de ambiente do arquivo `.env`. É chamado automaticamente na inicialização da aplicação.
### `get_env(string $key, $default = null)`
Obtém uma variável de ambiente com valor padrão.
```php
$dbHost = get_env('DB_HOST', 'localhost');
$appName = get_env('APP_NAME', 'SysCMS');
```
### `env(string $key, $default = null)`
Alias para `get_env()` para manter compatibilidade.
```php
$debug = env('APP_DEBUG', false);
```
### `env_bool(string $key, bool $default = false): bool`
Obtém uma variável de ambiente como booleano.
```php
$debug = env_bool('APP_DEBUG', false);
$cacheEnabled = env_bool('CACHE_ENABLED', true);
```
### `env_int(string $key, int $default = 0): int`
Obtém uma variável de ambiente como inteiro.
```php
$port = env_int('DB_PORT', 3306);
$timeout = env_int('TIMEOUT', 30);
```
### `get_db_config(): array`
Retorna um array com a configuração do banco de dados completa.
```php
$config = get_db_config();
// [
// 'driver' => 'mysql',
// 'host' => 'localhost',
// 'port' => '3306',
// 'database' => 'syscms',
// 'username' => 'root',
// 'password' => 'root',
// 'charset' => 'utf8mb4',
// 'collation' => 'utf8mb4_unicode_ci',
// 'prefix' => ''
// ]
```
### `get_app_config(): array`
Retorna um array com a configuração da aplicação.
```php
$config = get_app_config();
// [
// 'name' => 'SysCMS',
// 'env' => 'development',
// 'debug' => true,
// 'url' => 'http://localhost:16240',
// 'timezone' => 'America/Sao_Paulo',
// 'key' => '...'
// ]
```
### `get_mail_config(): array`
Retorna um array com a configuração de email.
```php
$config = get_mail_config();
// [
// 'transport' => 'smtp',
// 'host' => 'sandbox.smtp.mailtrap.io',
// 'port' => '2525',
// 'username' => '...',
// 'password' => '...',
// 'encryption' => 'tls',
// 'from_address' => '...',
// 'from_name' => 'SysCMS'
// ]
```
## Exemplos de Uso
### Em Controllers
```php
<?php
namespace App\Controllers;
class ExampleController
{
public function index()
{
$debugMode = env_bool('APP_DEBUG', false);
$appName = get_env('APP_NAME', 'SysCMS');
if ($debugMode) {
echo "Modo debug ativado para {$appName}";
}
// Usar configuração do banco
$dbConfig = get_db_config();
$capsule = new \Illuminate\Database\Capsule\Manager;
$capsule->addConnection($dbConfig);
}
}
```
### Em Models
```php
<?php
namespace App\Models;
class UserModel
{
public function getConnectionConfig()
{
return get_db_config();
}
public function isDebugMode()
{
return env_bool('APP_DEBUG', false);
}
}
```
### Em Scripts Independentes
```php
<?php
require_once __DIR__ . '/vendor/autoload.php';
require_once __DIR__ . '/app/Helpers/Environment.php';
// Carregar ambiente manualmente
load_env();
// Usar variáveis
$dbConfig = get_db_config();
$appConfig = get_app_config();
echo "Banco de dados: " . $dbConfig['database'] . "\n";
echo "Aplicação: " . $appConfig['name'] . "\n";
```
## Variáveis de Ambiente Disponíveis
### Banco de Dados
- `DB_CONNECTION` ou `DB_DRIVER`: Driver do banco (mysql, pgsql, sqlite)
- `DB_HOST`: Host do banco de dados
- `DB_PORT`: Porta do banco de dados
- `DB_DATABASE`: Nome do banco de dados
- `DB_USERNAME`: Usuário do banco
- `DB_PASSWORD`: Senha do banco
### Aplicação
- `APP_NAME`: Nome da aplicação
- `APP_ENV`: Ambiente (development, production, testing)
- `APP_DEBUG`: Modo debug (true/false)
- `APP_URL`: URL base da aplicação
- `APP_KEY`: Chave de criptografia
- `APP_TIMEZONE`: Fuso horário
### Email
- `MAIL_TRANSPORT`: Tipo de transporte (smtp, mail, sendmail)
- `MAIL_HOST`: Host SMTP
- `MAIL_PORT`: Porta SMTP
- `MAIL_USERNAME`: Usuário SMTP
- `MAIL_PASSWORD`: Senha SMTP
- `MAIL_ENCRYPTION`: Criptografia (tls, ssl)
- `MAIL_FROM_ADDRESS`: Email de remetente
- `MAIL_FROM_NAME`: Nome do remetente
## Boas Práticas
1. **Nunca commitar o arquivo `.env`** no controle de versão.
2. **Sempre fornecer valores padrão** ao usar `get_env()`.
3. **Usar funções tipadas** (`env_bool()`, `env_int()`) quando possível.
4. **Utilizar os getters de configuração** (`get_db_config()`, `get_app_config()`) para obter configurações completas.
5. **Documentar variáveis personalizadas** no arquivo `.env.example`.
## Compatibilidade
O helper foi implementado para ser compatível com a versão v3.0.3 do Symfony Dotenv instalada no projeto, utilizando a sintaxe `new Dotenv()` em vez de `Dotenv::createImmutable()` que está disponível apenas em versões mais recentes.
+48
View File
@@ -0,0 +1,48 @@
# Guia de Execução de Comandos PHP para a IA
Este documento serve como guia obrigatório para a IA sobre como executar comandos PHP e Docker diretamente no container.
## Permissão de Execução Direta
A IA **TEM PERMISSÃO** para executar comandos diretamente no terminal para interagir com o container `dockersyscms`. Isso inclui:
- Execução de migrações (`syscli migrate`).
- Execução de testes (`vendor/bin/phpunit`).
- Comandos do console do aplicativo.
- Scripts de utilidade em `scripts/`.
- Comandos Composer.
| `php syscli cache:clear` | Limpa o cache da aplicação. |
| `php syscli route:list` | Lista todas as rotas registradas. |
| `php syscli module:list` | Lista os módulos carregados. |
## Como Executar
O ambiente host (onde a IA roda) não possui PHP instalado localmente, por isso todos os comandos devem ser direcionados ao container Docker.
### 1. Via Docker Exec (Recomendado)
Use sempre o flag `-w /app` para garantir que o comando seja executado no diretório raiz da aplicação dentro do container.
```bash
docker exec -w /app dockersyscms php syscli [comando]
```
### 2. Via Script Utilitário (Windows)
Foi criado um script `sys.ps1` na raiz do projeto para simplificar as chamadas:
```powershell
.\sys.ps1 php syscli list
.\sys.ps1 test
.\sys.ps1 composer install
```
## Regras de Segurança
1. **Verificação de Sintaxe**: Antes de rodar um comando que altere muitos arquivos ou o banco de dados, verifique a sintaxe.
2. **Backups**: Para operações destrutivas no banco de dados, prefira criar um script de migração ou backup antes.
3. **Logs**: Observe a saída do comando para garantir que não houve erros silenciosos.
## Alternativa via HTTP (Debug)
Para scripts que precisam ser testados no contexto do servidor web (ex: validação de rotas ou middlewares), a abordagem via HTTP ainda é válida:
1. Crie o arquivo em `public/temp_test.php`.
2. Acesse via `Invoke-WebRequest -Uri "http://localhost:16240/temp_test.php"`.
3. Remova o arquivo após o uso.
+73
View File
@@ -0,0 +1,73 @@
# Configurações de Idioma no SysCMS
O SysCMS agora suporta configurações de idioma através das variáveis de ambiente `APP_MULTI_LANG` e `APP_LANG_DEFAULT` no arquivo `.env`.
## Variáveis de Ambiente
### APP_MULTI_LANG
- **Descrição**: Controla se o seletor de idiomas deve ser exibido no sistema
- **Valores possíveis**: `true` ou `false`
- **Padrão**: `false`
- **Exemplo**: `APP_MULTI_LANG=true`
### APP_LANG_DEFAULT
- **Descrição**: Define o idioma padrão do sistema quando nenhum idioma estiver selecionado
- **Valores possíveis**: Códigos de idioma suportados (pt_BR, en_US, es_ES, de_DE, fr_FR)
- **Padrão**: `pt_BR`
- **Exemplo**: `APP_LANG_DEFAULT=en_US`
## Como Funciona
### 1. Inicialização do Sistema
- O sistema verifica as variáveis de ambiente durante a inicialização
- O idioma padrão é definido na sessão com base em `APP_LANG_DEFAULT`
- O tradutor é configurado com o idioma apropriado
### 2. Controle do Seletor de Idiomas
- Quando `APP_MULTI_LANG=false`, o seletor de idiomas não é exibido
- Quando `APP_MULTI_LANG=true`, o seletor de idiomas é exibido na interface
- A troca de idioma é bloqueada quando `APP_MULTI_LANG=false`
### 3. Troca de Idioma
- Quando habilitado, os usuários podem selecionar entre os idiomas disponíveis:
- Português (pt_BR)
- English (en_US)
- Español (es_ES)
- Deutsch (de_DE)
- Français (fr_FR)
## Exemplo de Configuração
```env
# Habilita o seletor de idiomas
APP_MULTI_LANG=true
# Define o inglês como idioma padrão
APP_LANG_DEFAULT=en_US
```
## Arquivos Modificados
1. **kernel/Application.php**
- Modificado para usar `APP_LANG_DEFAULT` ao definir o idioma padrão
- Mantém compatibilidade com a configuração de multi-idioma
2. **modules/index/classes/Controllers/IndexController.php**
- Modificado para verificar `APP_MULTI_LANG` antes de permitir troca de idioma
- Bloqueia alteração de idioma quando multi-idioma está desabilitado
3. **templates/partials/language-switcher.twig**
- Modificado para só exibir o seletor quando `APP_MULTI_LANG=true`
- Usa a função helper `is_multi_lang_enabled()`
4. **app/helpers.php**
- Adicionada a função `is_multi_lang_enabled()` para verificar se multi-idioma está habilitado
## Testes
Para testar as configurações, execute:
```bash
php simple_test.php
```
Este script irá exibir os valores atuais das variáveis de ambiente.
+120
View File
@@ -0,0 +1,120 @@
# Ciclo de Vida da Aplicação SysCMS
Este documento detalha o fluxo de execução de uma requisição no SysCMS, desde a entrada no servidor até a resposta enviada ao usuário. Compreender este ciclo é fundamental para desenvolver módulos, middlewares e customizações.
## 1. Entrada (Entry Point)
Todas as requisições web são direcionadas para o arquivo `public/index.php`. Este arquivo é responsável por:
1. **Carregar o Autoloader do Composer**: `require __DIR__ . '/../vendor/autoload.php'`.
2. **Instanciar a Aplicação**: Cria uma nova instância de `Kernel\Application`.
3. **Executar a Aplicação**: Chama o método `$app->run()`.
```php
// public/index.php
require __DIR__ . '/../vendor/autoload.php';
$app = new Kernel\Application();
$app->run();
```
## 2. Inicialização do Kernel (Bootstrapping)
Ao instanciar a classe `Kernel\Application`, o construtor dispara uma série de inicializações essenciais.
### 2.1. Carregamento do Ambiente
O helper `load_env()` é chamado para ler o arquivo `.env` e definir as variáveis de ambiente (`$_ENV`).
### 2.2. Inicialização da Sessão (`initSession`)
- Configura o tempo de vida e caminho da sessão.
- Otimiza o armazenamento usando `/dev/shm` (memória RAM) se disponível, para alta performance.
- Gera ou valida o token CSRF (`$_SESSION['_token']`).
- Define o idioma padrão da aplicação.
### 2.3. Container de Injeção de Dependência (`initContainer`)
- Inicializa o `PHP-DI` (Container Builder).
- Permite autowiring (resolução automática de dependências).
- Carrega definições adicionais de `config/container.php` se existir.
### 2.4. Banco de Dados (`initDatabase`)
- Inicializa o `Illuminate/Database` (Eloquent ORM).
- Configura a conexão baseada nas variáveis do `.env` (DB_HOST, DB_DATABASE, etc.).
- Inicializa o ORM para uso global (`Capsule::bootEloquent()`).
### 2.5. Template Engine (`initTwig`)
- Inicializa o **Twig**.
- Configura os diretórios de templates: `app/templates` e `modules/`.
- Registra funções e globais essenciais:
- `__('key')`: Tradução via `Kernel\Translator`.
- `url()`, `asset_url()`: Helpers de URL.
- `csrf_field()`: Campo oculto para proteção CSRF.
- `session()`, `old()`: Acesso a dados de sessão e flash data.
- `auth`: Usuário autenticado (injetado posteriormente).
### 2.6. Sistema de Hooks (`HookManager`)
- Instancia o gerenciador de ganchos (Hooks) que permite que módulos interceptem e modifiquem o fluxo ou dados em pontos específicos.
### 2.7. Carregamento de Módulos (`initModuleLoader`)
O `Kernel\ModuleLoader` entra em ação para carregar os módulos do sistema:
1. **Scan**: Varre o diretório `modules/`.
2. **Autoload Customizado**: Registra um autoloader para classes no padrão `Modules\{Nome}\Classes`.
3. **Load**: Para cada módulo válido (com `module.json`):
- **Service Providers**: Executa `register()` e `boot()` dos providers definidos.
- **Rotas**: Carrega arquivos de rota definidos em `routes.web` e `routes.api`.
- **Recursos**: Registra caminhos de Views e Locales (traduções).
### 2.8. Roteamento (`initRouter`)
- Carrega as rotas principais de `routes/web.php`.
- Compila todas as rotas registradas (do sistema e dos módulos) usando `FastRoute`.
## 3. Processamento da Requisição (Runtime)
Após a inicialização, o método `run()` é chamado para processar a requisição atual.
### 3.1. Criação do Request
Um objeto `Symfony\Component\HttpFoundation\Request` é criado a partir das variáveis globais (`$_GET`, `$_POST`, etc.).
### 3.2. Injeção de Globais
O sistema injeta dados contextuais no ambiente de visualização (View):
- **Usuário Autenticado**: Se houver sessão ativa (`$_SESSION['user_id']`), carrega o modelo `User` e injeta globalmente como `auth.user`.
- **Configurações**: Carrega configurações da empresa principal (Company ID 1) e módulos ativos.
### 3.3. Despacho (Dispatch)
O `FastRoute\Dispatcher` compara a URI e o Método HTTP da requisição com as rotas registradas.
- **404 Not Found**: Se nenhuma rota coincidir, exibe página de erro 404.
- **405 Method Not Allowed**: Se a rota existe mas o método (GET/POST) é incorreto.
- **200 Found**: Se a rota for encontrada:
1. O **Handler** (Controlador + Método) e os **Middlewares** são identificados.
2. **Execução de Middlewares**: Os middlewares (ex: `AuthMiddleware`, `CsrfMiddleware`) são executados em cadeia. Se algum falhar (ex: não autenticado), a requisição é interrompida ou redirecionada.
3. **Execução do Controlador**: O método do controlador é chamado, recebendo os parâmetros da rota e o objeto Request.
## 4. Resposta (Response)
O controlador processa a lógica de negócios e retorna uma resposta.
- Geralmente, o controlador renderiza uma **View** (arquivo `.twig`).
- O conteúdo HTML gerado é enviado de volta ao navegador.
- Em APIs, a resposta pode ser um JSON.
---
## Resumo Gráfico
1. **Request** (`public/index.php`)
↓
2. **Kernel Boot** (`Application::__construct`)
- Load Env & Config
- Init DB & Container
- Load Modules (Providers & Routes)
↓
3. **App Run** (`Application::run`)
- Middleware Stack (Auth, CSRF...)
- Router Dispatch
↓
4. **Controller Action**
- Business Logic
- DB Queries
↓
5. **View Rendering** (Twig)
↓
6. **Response** (HTML/JSON)
+457
View File
@@ -0,0 +1,457 @@
# Manual: Como criar módulos para instalar no SysCMS
Este manual orienta a criação, estrutura e instalação de módulos compatíveis com o SysCMS, seguindo as diretrizes do projeto.
## Estrutura de Diretórios do Módulo
Crie o módulo dentro de `modules/<nome>/` em minúsculo.
```
modules/
<nome>/
classes/
Controllers/
Models/
Services/
routes/
web.php
api.php
views/
index.twig
admin/
locales/
pt_BR/
en_US/
module.json
```
## Arquivo `module.json`
Define metadados, rotas, resources e providers. Exemplo mínimo (Company):
```json
{
"name": "company",
"display_name": "Company",
"description": "Company management module",
"version": "1.0.0",
"author": "SysCMS Team",
"dependencies": ["auth"],
"permissions": [
"company.view",
"company.create",
"company.edit",
"company.delete"
],
"settings": {},
"providers": [
"Modules\\Company\\Providers\\CompanyServiceProvider"
],
"routes": {
"web": "routes/web.php"
},
"menu": {
"dashboard": {
"icon": "bi bi-building",
"label": "Companies",
"route": "admin/companies",
"order": 30
}
},
"views": "views",
"locales": "locales",
"module_ative": true,
"module_public": false,
"module_blocked": false
}
```
## Registro de Rotas
Declare as rotas em `routes/web.php` e/ou `routes/api.php` retornando uma função que receba a aplicação e chame `addRoute`.
```php
<?php
use Kernel\Application;
return function (Application $app) {
$app->addRoute('GET', '/meu-modulo', [\Modules\MeuModulo\Controllers\HomeController::class, 'index']);
$app->addRoute('POST', '/meu-modulo/salvar', [\Modules\MeuModulo\Controllers\HomeController::class, 'store']);
};
```
- Carregamento automático de rotas de módulos: `kernel/ModuleLoader.php:142–170`
## Empacotamento para Instalação (.zip)
Para que o módulo seja instalável via painel administrativo (`/admin/modules/install`), ele deve ser compactado em um arquivo `.zip`.
> **⚠️ IMPORTANTE: Geração do ZIP**
> Ao criar o arquivo `.zip`, certifique-se de que a estrutura interna não contenha caminhos absolutos ou barras invertidas (`\`) típicas do Windows.
>
> **Estrutura Correta do ZIP:**
> Ao abrir o zip, os arquivos `module.json`, `routes/`, `classes/`, etc., devem estar **na raiz** ou dentro de uma pasta única com o nome do módulo (o instalador trata ambos os casos, mas prefira a raiz para simplicidade).
>
> **Comando Recomendado (Linux/Mac/WSL):**
> ```bash
> cd modules/meumodulo
> zip -r ../meumodulo.zip .
> ```
>
> **Comando Recomendado (Windows - PowerShell):**
> Evite usar `Compress-Archive` diretamente se ele gerar barras invertidas. Prefira usar `tar` ou ferramentas como 7-Zip garantindo o formato ZIP.
> ```powershell
> cd modules/meumodulo
> tar -a -c -f ../../meumodulo.zip *
> ```
## Banco de Dados e Migrações
Todo módulo deve conter suas próprias migrações na pasta `database/migrations/`.
> **⚠️ REGRA CRÍTICA 1: Imutabilidade do Core**
> Um novo módulo **NUNCA** deve modificar a estrutura (schema) de tabelas existentes do sistema (Core ou outros módulos). Ele deve criar apenas suas próprias tabelas. Se precisar de relacionamento, use chaves estrangeiras sem alterar a tabela referenciada.
>
> **⚠️ REGRA CRÍTICA 2: Independência na Instalação**
> As migrações (especialmente a de inserção do módulo) **NUNCA** devem depender de Classes/Models de outros módulos (ex: `Modules\Company\Models\Company`), pois eles podem não estar carregados no momento da instalação.
>
> **Forma Correta:** Use `Capsule::table('nome_tabela')->insert(...)` para inserir dados em tabelas de outros módulos.
>
> **Exemplo Incorreto (NÃO FAÇA):**
> ```php
> $company = \Modules\Company\Models\Company::find(1); // Erro se o módulo Company não estiver carregado
> ```
>
> **Exemplo Correto:**
> ```php
> Capsule::table('bus')->where('bus_id', 1)->update([...]);
> ```
### 1. Criação de Tabelas
Crie arquivos de migração para definir a estrutura do banco de dados do módulo. Exemplo: `001_create_meumodulo_tables.php`.
```php
use Illuminate\Database\Capsule\Manager as Capsule;
use Illuminate\Database\Schema\Blueprint;
class CreateMeuModuloTables
{
public function up()
{
if (!Capsule::schema()->hasTable('meumodulo_items')) {
Capsule::schema()->create('meumodulo_items', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->timestamps();
});
}
}
public function down()
{
Capsule::schema()->dropIfExists('meumodulo_items');
}
}
```
### 2. Registro do Módulo (Instalação)
É obrigatório criar uma migração para registrar o módulo no sistema (tabelas `modules` e `bus_modules`). Isso garante que o módulo seja reconhecido e ativado após a instalação. Exemplo: `002_insert_meumodulo_record.php`.
```php
use Illuminate\Database\Capsule\Manager as Capsule;
use App\Models\Module;
use Modules\Company\Models\Company;
class InsertMeuModuloRecord
{
public function up()
{
$moduleData = [
'modules_name' => 'meumodulo',
'modules_display_name' => 'Meu Módulo',
'modules_version' => '1.0.0',
// ... outros campos do module.json ...
];
$existingModule = Module::where('modules_name', 'meumodulo')->first();
if (!$existingModule) {
$module = Module::create($moduleData);
// Associar a todas as empresas existentes
if (Capsule::schema()->hasTable('bus')) {
$companies = Company::all();
foreach ($companies as $company) {
// Lógica de inserção na tabela bus_modules
}
}
}
}
public function down()
{
// Lógica para remover o módulo
}
}
```
## Controllers
Coloque controllers em `classes/Controllers/`. Exemplo:
```php
<?php
namespace Modules\MeuModulo\Controllers;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class HomeController
{
public function index(Request $request): Response
{
return new Response((new \Kernel\View())->render('meumodulo/views/index.twig', [
'title' => 'Meu Módulo'
]));
}
}
```
## Views e Locales
- Views: declare pasta em `module.json` via chave `views` e renderize com o namespace `<modulo>/views/...`.
- Locales: declare pasta em `module.json` via chave `locales`. O sistema registra e utiliza `Translator`.
- Registro automático: `kernel/ModuleLoader.php:175–192`
## Service Providers
Use providers para inicializar integrações, hooks, listeners e configurações dinâmicas do core (como rotas públicas). Registre-os em `module.json` na chave `providers`.
### Exemplo Completo de ServiceProvider
```php
<?php
namespace Modules\MeuModulo\Providers;
use Kernel\Application;
use Kernel\View;
class MeuModuloServiceProvider
{
public function register(): void {}
public function boot(): void
{
$app = Application::getInstance();
// 1. Registrar rotas públicas (que não exigem login)
$app->addPublicPath('/meu-modulo/landing-page');
$app->addPublicPath('/meu-modulo/public-api/*');
// 2. Registrar Middlewares
// $app->addGlobalMiddleware(new \Modules\MeuModulo\Middleware\GlobalGuard());
// 3. Registrar Hooks
add_action('meumodulo.evento', function ($payload) {
// lógica
});
add_filter('meumodulo.sanitize', function ($value) {
return trim(strip_tags((string)$value));
});
// 4. Injetar variáveis globais no Twig
try {
$view = new View();
$view->getEngine()->addGlobal('meu_modulo_config', ['active' => true]);
} catch (\Throwable $e) {
// Ignorar erros se view não estiver pronta
}
}
}
```
- API de Hooks: `COMO_USAR_HOOK.md`
- HookManager disponível em: `kernel/HookManager.php`
- Exposição via aplicação: `kernel/Application.php:50–58` (getHookManager)
- **IMPORTANTE**: Use o Service Provider para evitar alterar arquivos do core (`Application.php`).
## Migrations
Para compatibilidade com o comando de migração, coloque migrations em `app/database/migrations/`.
- Exemplo de criação de tabela:
```php
<?php
use Illuminate\Database\Capsule\Manager as Capsule;
use Illuminate\Database\Schema\Blueprint;
class CreateMeuModuloTable
{
public function up(): void
{
if (!Capsule::schema()->hasTable('meumodulo')) {
Capsule::schema()->create('meumodulo', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->timestamps();
});
}
}
public function down(): void
{
Capsule::schema()->dropIfExists('meumodulo');
}
}
```
- Para registrar o módulo na tabela `modules`, crie uma migration que insere o registro (recomendado na pasta principal `app/database/migrations`).
### Exemplo: Registrar o módulo Company
Crie um arquivo como `0xx_register_company_module.php` em `app/database/migrations/` com o conteúdo abaixo:
```php
<?php
use App\Models\Module;
use Carbon\Carbon;
class RegisterCompanyModule
{
public function up(): void
{
if (!Module::where('module_name', 'company')->exists()) {
Module::create([
'module_name' => 'company',
'module_display_name' => 'Company',
'module_description' => 'Company management module',
'module_version' => '1.0.0',
'module_author' => 'SysCMS Team',
'module_ative' => true,
'module_public' => false,
'module_blocked' => false,
'module_dependencies' => ['auth'],
'module_permissions' => [
'company.view',
'company.create',
'company.edit',
'company.delete'
],
'module_settings' => [
'menu' => [
'dashboard' => [
'icon' => 'bi bi-building',
'label' => 'Companies',
'route' => 'admin/companies',
'order' => 30
]
]
],
'module_path' => 'modules/company',
'module_namespace' => 'Modules\\Company',
'module_icon' => 'bi bi-building',
'module_order' => 30,
'module_install_date' => Carbon::now(),
'module_update_date' => Carbon::now()
]);
}
}
public function down(): void
{
$module = Module::where('module_name', 'company')->first();
if ($module) {
$module->delete();
}
}
}
```
Depois, execute:
```bash
php syscli migrate
```
## Permissões e Menu
- Defina permissões no `module.json` (`permissions`).
- Defina itens de menu no `module.json` (`menu`), usando ícones somente do Bootstrap Icons.
- Regra: `RULES.md:40–74`
## Instalação do Módulo
1. Copie o diretório do módulo para `modules/<nome>/`.
2. Garanta que `module.json` está correto.
3. Adicione migrations necessárias em `app/database/migrations/`.
4. Execute migrações:
- `php syscli migrate`
5. Verifique rotas carregadas e acessíveis.
6. Se o módulo requer habilitação por empresa, utilize o painel ou scripts próprios para vincular em `bus_modules` (conforme política da aplicação).
- Carregamento de módulos: `kernel/ModuleLoader.php:184–192` (loadAll)
- Roteamento da aplicação: `kernel/Application.php:199–217`
## Empacotamento do Módulo (.zip)
Ao criar um novo módulo, é **obrigatório** criar também o arquivo `.zip` correspondente para permitir a instalação via painel administrativo.
**Regras para o ZIP:**
1. O arquivo `module.json` deve estar na raiz do arquivo compactado (não dentro de uma pasta com o nome do módulo).
2. O nome do arquivo zip deve corresponder ao nome do módulo (ex: `modelo.zip`).
**Comando sugerido (PowerShell):**
```powershell
Compress-Archive -Path modules/nome_do_modulo/* -DestinationPath nome_do_modulo.zip -Force
```
## Instalador via Dashboard (Super Admin)
- Acesso: `GET /admin/modules/install` mapeado em `routes/web.php:41–45` e renderiza `templates/modules/install.twig` (`templates/modules/install.twig:1–5`).
- Formulário: `POST /admin/modules/install` com `multipart/form-data`; campos `module_zip` (arquivo `.zip`) e opcional `enable_for_all` (`templates/modules/install.twig:44–59`).
- Validações: tipo de arquivo ZIP e presença de `module.json` (`app/app/Controllers/AdminController.php:215–224`, `app/app/Controllers/AdminController.php:291–300`). Campos obrigatórios em `module.json`: `name`, `version`, `description` (`app/app/Controllers/AdminController.php:323–332`).
- Instalação: extração para diretório temporário, cópia para `modules/<name>`, execução de migrations em `database/migrations` se existirem (`app/app/Controllers/AdminController.php:230–239`, `app/app/Controllers/AdminController.php:252–258`, `app/app/Controllers/AdminController.php:393–416`).
- Registro: criação do registro em `modules` com metadados do `module.json` (`app/app/Controllers/AdminController.php:461–484`).
- Habilitação: se marcado `enable_for_all`, habilita o módulo para todas as empresas (`app/app/Controllers/AdminController.php:492–498`).
- Pós-instalação: limpeza de temporários e exibição de mensagens de sucesso/erro via flash (`app/app/Controllers/AdminController.php:267–283`).
- Correção de menus: `GET /admin/modules/fix-menus` atualiza `module_settings.menu` consultando `module.json` (`routes/web.php:41–45`, `app/app/Controllers/AdminController.php:423–453`).
### Estrutura exigida no ZIP
- `module.json` com configurações do módulo.
- `classes/` com controladores, modelos e serviços.
- `views/` com templates Twig.
- `database/migrations/` com migrações (opcional).
## Hooks Recomendados
- `meumodulo.installed`: após instalação concluída (migration + registro).
- `meumodulo.uninstalled`: antes de remover dados.
- `meumodulo.updated`: após atualização de versão.
## Boas Práticas
- Seguir `RULES.md` e usar somente Bootstrap Icons.
- Não expor segredos; use `.env`.
- Respeitar estrutura e namespaces: `Modules\\<Nome>\\...` e pasta `modules/<nome>/` em minúsculo.
- Validar entrada de dados, usar filters para sanitização.
- Manter compatibilidade com os middlewares da aplicação;
- Rotas públicas devem estar na lista pública se necessário (ver `kernel/Application.php:279–311`).
## Verificação
- Após instalar, acesse rotas do módulo e verifique renderização.
- Se aplicável, execute testes (`composer test`).
- Cheque logs em `logs/app.log` para erros em providers/hooks.
## Exemplo Real (Company)
- Rotas admin do módulo: `modules/company/routes/web.php:6–13`
- Controller lista e gerencia empresas: `modules/company/classes/Controllers/CompanyController.php:14–22` (index) e `35–82` (store)
- Views admin: `modules/company/views/admin/index.twig:13–23` (header) e tabela `25–71`
- `module.json` configurado com rotas, views e menu: `modules/company/module.json:1–30`
+183
View File
@@ -0,0 +1,183 @@
# SysCMS - Guia do Usuário
## Bem-vindo ao SysCMS
O SysCMS é um Sistema de Gerenciamento de Conteúdo (CMS) modular, poderoso e flexível, projetado para permitir a criação, gerenciamento e publicação de conteúdo de forma simples e eficiente. Este guia foi elaborado para ajudar você a navegar e utilizar todas as funcionalidades do sistema, desde a instalação até o gerenciamento avançado.
---
## 🚀 Instalação e Configuração Inicial
O SysCMS conta com um instalador web moderno e automatizado para facilitar a configuração inicial.
### Passo a Passo da Instalação
1. **Acesse o Instalador**:
Abra seu navegador e digite a URL onde o sistema está hospedado, adicionando `/install` ao final (ex: `http://localhost/install` ou `http://seudominio.com/install`).
2. **Verificação de Requisitos**:
O sistema verificará automaticamente se seu servidor atende aos requisitos mínimos (PHP 8.1+, extensões necessárias e permissões de escrita). Se tudo estiver verde, clique em **Próximo**.
3. **Configuração do Banco de Dados**:
Insira os dados de conexão com seu banco de dados MySQL:
- **Host**: Geralmente `localhost` ou o nome do serviço do banco (ex: `mysql` em ambientes Docker).
- **Nome do Banco**: O nome do banco de dados que você criou para o SysCMS.
- **Usuário**: Usuário do banco de dados.
- **Senha**: Senha do banco de dados.
Clique em **Testar Conexão**. Se bem-sucedido, avance.
4. **Configuração do Sistema**:
Defina as informações básicas do seu site:
- **Nome da Aplicação**: Nome do seu projeto/site.
- **URL da Aplicação**: URL base do site (ex: `http://localhost`).
- **Dados do Super Admin**: Crie a conta do administrador principal (Nome, Email e Senha).
5. **Instalação**:
O sistema irá automaticamente:
- Gerar o arquivo de configuração (`.env`).
- Importar a estrutura do banco de dados.
- Criar o usuário Super Admin.
6. **Conclusão**:
Após a mensagem de sucesso, você será redirecionado para a tela de login.
> **⚠️ IMPORTANTE:** Por segurança, após a instalação, remova a pasta `public/install` do servidor.
---
## Acessando o Sistema
### Login
Para acessar o painel administrativo do SysCMS:
1. Abra seu navegador e acesse a URL do sistema.
2. Clique no botão "Login" no menu superior (se visível) ou acesse `/login`.
3. Digite seu email e senha cadastrados.
4. Clique em "Entrar".
### Recuperação de Senha
Caso esqueça sua senha:
1. Na página de login, clique em "Esqueci minha senha".
2. Digite seu email cadastrado.
3. Siga as instruções enviadas para seu email para redefinir a senha.
---
## Painel Administrativo
### Visão Geral
O painel administrativo foi projetado para ser intuitivo:
- **Barra Lateral**: Menu de navegação principal com acesso a todos os módulos.
- **Área Principal**: Onde você gerencia o conteúdo e as configurações.
- **Barra Superior**: Informações do usuário logado, notificações e atalhos rápidos.
### Menu Principal
O menu lateral organiza as funcionalidades:
- **Dashboard**: Visão geral com estatísticas e atividades recentes.
- **Páginas**: Gerenciamento de conteúdo estático.
- **Posts**: Gerenciamento de blog/notícias.
- **Vitrine**: Gerenciamento de produtos e serviços.
- **Usuários**: Administração de usuários e permissões.
- **Configurações**: Ajustes gerais do sistema e da empresa.
---
## Gerenciamento de Conteúdo
### Páginas
Ideal para conteúdo institucional (ex: Sobre Nós, Contato, Termos de Uso).
#### Criando uma Nova Página
1. No menu lateral, clique em **Páginas** > **Nova Página**.
2. Preencha:
- **Título**: Nome da página.
- **Conteúdo**: Utilize o editor visual para formatar seu texto e adicionar mídia.
- **Status**: Defina como `Publicado` para exibir ou `Rascunho` para salvar e editar depois.
3. Clique em **Salvar**.
### Posts
Ideal para conteúdo dinâmico e recorrente (ex: Blog, Notícias).
#### Criando um Novo Post
1. Vá em **Posts** > **Novo Post**.
2. Preencha título, conteúdo, resumo e selecione uma **Categoria**.
3. Adicione **Tags** para facilitar a busca.
4. Defina uma **Imagem de Destaque**.
5. Publique ou salve como rascunho.
### Vitrine
Ideal para exibir produtos, serviços ou portfólio.
#### Adicionando um Item
1. Acesse **Vitrine** > **Novo Item**.
2. Preencha título, descrição, preço (opcional) e conteúdo detalhado.
3. Carregue imagens para a galeria do produto.
4. Defina a visibilidade e categoria.
5. Salve o item.
---
## Gerenciamento de Usuários
### Níveis de Acesso
- **Super Admin**: Acesso total ao sistema, incluindo configurações críticas e instalação de módulos.
- **Admin**: Gerencia conteúdo, usuários e configurações da empresa.
- **Usuário**: Acesso básico, geralmente limitado ao próprio perfil ou áreas públicas restritas.
### Criando Usuários
1. Vá em **Usuários** > **Novo Usuário**.
2. Preencha nome, email, senha e defina a **Função** (Role).
3. Ative o usuário e salve.
---
## Configurações do Sistema
### Configurações Gerais
Ajuste o nome do site, descrição para SEO, email de contato, fuso horário e idioma padrão.
### Configurações de Empresa
Gerencie os dados da sua organização: Nome, Endereço, Contato e Logo. Essas informações são frequentemente usadas nos rodapés e cabeçalhos do site público.
---
## Dicas e Boas Práticas
### Organização
- Use categorias consistentes para Posts e Vitrine.
- Mantenha slugs (URLs amigáveis) curtos e descritivos.
- Revise o conteúdo antes de publicar.
### Segurança
- Use senhas fortes e únicas.
- Não compartilhe suas credenciais de acesso.
- Mantenha o sistema sempre atualizado.
- **Remova a pasta de instalação** após o setup inicial.
### Performance
- Otimize imagens antes de fazer upload (evite arquivos > 2MB se possível).
- Desative módulos que não estão em uso.
---
## Suporte
Se precisar de ajuda adicional:
1. Consulte este guia novamente.
2. Verifique a documentação técnica (se você for um desenvolvedor).
3. Entre em contato com o suporte técnico ou administrador do sistema.
---
**SysCMS** - *Simples, Modular, Poderoso.*
+133
View File
@@ -0,0 +1,133 @@
# 🪝 Como usar o Sistema de Hooks
Este documento explica como utilizar o sistema de Hooks (actions e filters) do SysCMS para estender funcionalidades sem alterar o núcleo.
## 🔎 Visão Geral
- **Hooks** permitem que módulos e partes da aplicação "escutem" eventos (`actions`) ou transformem valores (`filters`).
- São registrados e disparados em tempo de execução, com suporte a prioridades.
---
## 📚 Conceitos
- **Action**: Executa callbacks quando um evento ocorre; não retorna valor (ex: enviar email após cadastro).
- **Filter**: Executa callbacks encadeados que recebem um valor e retornam o valor, possivelmente modificado (ex: formatar texto).
---
## 🛠️ Helpers Disponíveis
Estes helpers são globais e estão disponíveis em todo o sistema:
- `add_action(string $hook, callable $listener, int $priority = 10): void`
- `do_action(string $hook, ...$args): void`
- `add_filter(string $hook, callable $listener, int $priority = 10): void`
- `apply_filters(string $hook, mixed $value, ...$args): mixed`
---
## ⚙️ Integração em Módulos
O ponto recomendado para registrar hooks de um módulo é um **Service Provider**.
### Passo a Passo
1. Crie uma classe `ServiceProvider` no seu módulo.
2. Registre esta classe no `module.json` do módulo.
3. Dentro do método `boot()`, registre seus actions e filters.
### Exemplo de Service Provider
```php
namespace Modules\Contact;
use Modules\Contact\Models\Contact;
class ContactServiceProvider
{
public function register(): void {}
public function boot(): void
{
// Action: Dispara quando um contato é submetido
add_action('contact.submitted', function (Contact $contact) {
// Lógica para enviar email, logar, etc.
}, 10);
// Filter: Sanitiza a mensagem
add_filter('contact.message_sanitize', function (string $message) {
return trim(strip_tags($message));
});
}
}
```
### Registro no `module.json`
```json
{
"providers": [
"Modules\\Contact\\ContactServiceProvider"
]
}
```
---
## 💡 Exemplos Práticos
### Disparando um Hook (Action)
```php
// No controller ou serviço
$contact = new Contact($data);
$contact->save();
// Avisa o sistema que um contato foi submetido
do_action('contact.submitted', $contact);
```
### Aplicando um Filtro
```php
$mensagemOriginal = " Olá <b>Mundo</b> ";
// Permite que outros módulos modifiquem a mensagem antes de salvar
$mensagemFinal = apply_filters('contact.message_sanitize', $mensagemOriginal);
```
---
## 📨 Exemplo Real: Módulo de Contato
O módulo `contact` nativo do SysCMS utiliza hooks extensivamente:
- **Action `contact.submitted`**: Envia um email para o administrador quando um novo contato é salvo.
- **Filter `contact.message_sanitize`**: Limpa HTML e espaços em branco da mensagem antes de salvar.
### Configuração de Email
Para que o envio de email funcione via hook, configure seu `.env`:
```env
MAIL_TRANSPORT=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=seu_usuario
MAIL_PASSWORD=sua_senha
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=no-reply@syscms.com
```
---
## ✅ Boas Práticas
1. **Idempotência**: Garanta que seus listeners possam ser executados múltiplas vezes sem efeitos colaterais indesejados.
2. **Tratamento de Erros**: Trate exceções dentro dos listeners para não quebrar o fluxo principal da aplicação.
3. **Performance**: Evite operações pesadas (como chamadas de API síncronas) em hooks críticos.
4. **Segurança**: Sempre sanitize dados em filters antes de retorná-los.
---
**SysCMS Dev Team**
+190
View File
@@ -0,0 +1,190 @@
# Implementação do Quill Editor no SysCMS - Concluída
## Resumo da Implementação
A implementação do editor Quill no sistema SysCMS foi concluída com sucesso. O sistema agora suporta o editor Quill como alternativa moderna ao SCEditor, com total integração ao sistema de configurações e multi-idioma.
## Componentes Implementados
### 1. Arquivos do Quill
- **Localização**: `public/assets/quill/`
- **Arquivos**:
- `quill.min.js` - Biblioteca JavaScript do Quill (versão 2.0.2)
- `quill.snow.min.css` - Tema Snow para o editor
- `quill.bubble.min.css` - Tema Bubble para o editor
- `quill.js` - Versão de desenvolvimento
- `quill.snow.css` - CSS de desenvolvimento do tema Snow
- `quill.bubble.css` - CSS de desenvolvimento do tema Bubble
### 2. Scripts de Inicialização
- **Arquivo**: `public/assets/js/quill-init.js`
- **Funcionalidades**:
- Classe `QuillManager` para gerenciar múltiplas instâncias
- Inicialização automática de campos com classe `quill-editor`
- Sincronização com textareas ocultos para envio de formulários
- Funções globais para manipulação dos editores
### 3. Helper PHP
- **Arquivo**: `app/Helpers/QuillHelper.php`
- **Funções**:
- `renderEditor()` - Renderiza sempre um editor Quill
- `renderField()` - Renderiza Quill ou textarea baseado na configuração
- `renderTextarea()` - Renderiza sempre um textarea simples
- `isQuillEnabled()` - Verifica se o Quill está habilitado
- `sanitizeHtml()` - Limpa HTML para segurança
- `htmlToText()` - Converte HTML para texto puro
### 4. CSS Personalizado
- **Arquivo**: `public/assets/css/quill-syscms.css`
- **Características**:
- Tema adaptado para o design do SysCMS
- Cores compatíveis com Bootstrap 5.3
- Suporte para modo escuro
- Design responsivo
### 5. Configuração do Sistema
- **Variável de Ambiente**: `APP_EDITOR_QUILL=true`
- **Localização**: `.env`
- **Funcionalidade**: Controla se o Quill é usado ou não
### 6. Integração com Templates
- **Layouts Modificados**:
- `templates/layouts/base.twig`
- `templates/layouts/dashboard.twig`
- **Funções Twig Adicionadas**:
- `quill_editor()` - Renderiza editor Quill
- `quill_field()` - Renderiza campo inteligente
- `quill_textarea()` - Renderiza textarea
- `is_quill_enabled()` - Verifica status
### 7. Página de Demonstração
- **Controller**: `app/Controllers/QuillDemoController.php`
- **Templates**:
- `templates/examples/quill-demo.twig`
- `templates/examples/quill-results.twig`
- **Rotas**:
- `/quill-demo` - Página de demonstração
- `/quill-demo-submit` - Processamento do formulário
- `/quill-demo-results` - Resultados
### 8. Traduções
- **Arquivos**:
- `templates/locales/pt_BR/quill_demo.json`
- `templates/locales/en_US/quill_demo.json`
- `templates/locales/es_ES/quill_demo.json`
- `templates/locales/de_DE/quill_demo.json`
- `templates/locales/pt_BR/quill_results.json`
- `templates/locales/en_US/quill_results.json`
- `templates/locales/es_ES/quill_results.json`
- `templates/locales/de_DE/quill_results.json`
## Como Usar o Quill no Sistema
### 1. Configuração
No arquivo `.env`, defina:
```
APP_EDITOR_QUILL=true
```
### 2. Nos Templates
#### Implementação Padrão (Auto-Init)
O sistema inicializa automaticamente qualquer editor que use o ID `quill-editor` e o atributo `data-target`.
```twig
<div id="quill-editor" style="height: 300px;" data-target="nome_do_campo">
{{ valor_inicial|raw }}
</div>
<textarea id="nome_do_campo" name="nome_do_campo" style="display:none">
{{ valor_inicial }}
</textarea>
```
**IMPORTANTE**:
- O ID **deve** ser exatamente `quill-editor` para o script global `quill-init.js` funcionar.
- O atributo `data-target` deve apontar para o `id` do `textarea` que receberá os dados.
- Não use a função `quill_editor()` se ela não estiver registrada no seu módulo; prefira o HTML puro acima.
### 3. Verificação de Status
```twig
{% if is_quill_enabled() %}
<p>Editor Quill está habilitado</p>
{% else %}
<p>Usando textarea simples</p>
{% endif %}
```
## Benefícios da Implementação
### 1. Flexibilidade
- O sistema pode alternar entre Quill e textarea simples
- Configuração centralizada via variável de ambiente
- Compatibilidade com código existente
### 2. Modernização
- Editor WYSIWYG moderno e intuitivo
- Suporte para dispositivos móveis
- Melhor experiência do usuário
### 3. Segurança
- Sanitização automática de HTML
- Proteção contra XSS
- Validação de conteúdo
### 4. Performance
- Carregamento sob demanda
- Lazy loading para múltiplos editores
- Otimização de recursos
### 5. Internacionalização
- Suporte completo a 4 idiomas
- Interface traduzida
- Placeholder localizados
## Testes e Validação
### 1. Acesso à Demonstração
Acesse `/quill-demo` no sistema para testar a implementação.
### 2. Testes Realizados
- ✅ Inicialização do editor
- ✅ Sincronização com formulários
- ✅ Submissão de dados
- ✅ Renderização de conteúdo
- ✅ Funcionamento multi-idioma
- ✅ Alternância de configuração
### 3. Compatibilidade
- ✅ Bootstrap 5.3
- ✅ Alpine.js
- ✅ Navegadores modernos
- ✅ Dispositivos móveis
## Próximos Passos
### 1. Migração de Módulos
Para migrar módulos existentes para usar o Quill:
1. Identificar campos de texto que precisam de formatação
2. Substituir SCEditor por `{{ quill_field() }}`
3. Testar funcionalidade
4. Atualizar validações se necessário
### 2. Recursos Adicionais
- Implementar upload de imagens diretamente no editor
- Adicionar plugins personalizados
- Criar templates específicos para diferentes tipos de conteúdo
### 3. Otimizações
- Implementar cache de configurações
- Otimizar carregamento de recursos
- Melhorar performance em dispositivos móveis
## Conclusão
A implementação do Quill Editor no SysCMS foi concluída com sucesso, proporcionando:
- Uma solução moderna e flexível para edição de texto
- Total integração com a arquitetura existente
- Suporte completo a multi-idioma
- Configuração centralizada e fácil manutenção
O sistema está pronto para uso em produção e pode ser estendido conforme necessário para atender requisitos específicos de cada módulo.
+117
View File
@@ -0,0 +1,117 @@
# 🧠 Regras para IA Coder: Uso do Editor Quill em Campos *Textarea*
Este documento define regras claras para que a IA coder utilize o editor
**Quill** em formulários do sistema, substituindo `textarea` comuns
**somente nos campos destinados a descrição ou conteúdo textual rico**.
------------------------------------------------------------------------
## 📌 1. Quando usar o Quill
A IA **deve** substituir um campo `<textarea>` por um editor **Quill**
sempre que o campo for destinado a:
- descrições longas\
- conteúdos formatáveis\
- corpos de artigos\
- textos ricos\
- informações detalhadas\
- campos como: `description`, `descricao`, `content`, `conteudo`,
`body`, `texto`, `observacoes` etc.
👉 **Se o campo servir para escrever conteúdo extenso ou formatado, use
Quill.**
------------------------------------------------------------------------
## 📌 2. Quando *não* usar o Quill
A IA **não deve** usar Quill quando o campo for:
- curto ou simples (ex.: título, subtítulo)
- técnico ou estruturado (ex.: JSON, código)
- com exigência de texto plano (ex.: slug, token, ID)
- para validação rígida (ex.: email, username, senha)
👉 **Se o texto deve ser simples, curto ou técnico --- use textarea
comum.**
------------------------------------------------------------------------
## 📌 3. Padrão de Estrutura HTML para IA
Para garantir que a IA gere formulários compatíveis com a auto-inicialização do SysCMS, use sempre esta estrutura:
1. **ID Obrigatório**: `quill-editor`
2. **Atributo de Alvo**: `data-target="ID_DO_TEXTAREA"`
3. **Campo de Dados**: Um `textarea` com o mesmo ID do `data-target` e `style="display:none"`.
### Exemplo de Código Gerado pela IA:
```html
<div id="quill-editor" style="height: 400px; background: white;" data-target="conteudo">
{{ documento.conteudo|raw }}
</div>
<textarea id="conteudo" name="conteudo" style="display:none">
{{ documento.conteudo }}
</textarea>
```
**ATENÇÃO**:
- NUNCA inicialize o Quill via JavaScript manual dentro dos módulos se estiver usando o layout `dashboard.twig`.
- O script global `public/assets/js/quill-init.js` já faz o trabalho de montagem e sincronização.
- Se houver mais de um editor na mesma página, o sistema deve ser adaptado para IDs incrementais ou seletores de classe, mas o padrão mestre é o ID único `quill-editor`.
------------------------------------------------------------------------
## 📌 5. Regras para backend + IA
- Para análise por IA, preferir texto simples:
``` javascript
quill.getText();
```
- Para preservar formatação, usar HTML\
- Sanitizar HTML conforme necessário
------------------------------------------------------------------------
## 📌 6. Regras de detecção de campos que devem usar Quill
A IA deve ativar o Quill automaticamente para campos cujo `name` ou `id`
contenha:
- descricao / description\
- conteudo / content\
- body\
- texto / text\
- observacoes / obs\
- about
Incluindo variações como:\
`snake_case`, `camelCase`, `kebab-case`.
Exemplos:\
- `product_description`\
- `postContent`\
- `body_text`\
- `obs_adicionais`\
- `article-body`
------------------------------------------------------------------------
## 📌 7. Regra principal da IA
> Todo campo de texto que permita formatação, parágrafos ou conteúdo
> rico deve usar o editor Quill.
## 📌 8. Regra secundária
> Campos curtos, técnicos ou que exigem texto simples **não** devem usar
> Quill.
------------------------------------------------------------------------
Fim do documento.
+130
View File
@@ -0,0 +1,130 @@
# Módulo Modelo para o SysCMS (Template)
Este documento define o padrão arquitetural para a criação de novos módulos no SysCMS, utilizando o módulo **`modelo`** como referência oficial e template instalável.
## Por que o módulo `modelo`?
O módulo `modelo` foi criado especificamente para servir de base limpa e padronizada para novos desenvolvimentos. Ele implementa:
1. **Estrutura MVC Completa**: Controllers, Models e Views organizados.
2. **Instalação Automatizada**: Inclui arquivo `.zip` pronto para teste de instalação via painel.
3. **Independência**: Migrations autossuficientes que não quebram se outros módulos estiverem desativados.
4. **Padrões de Código**: Namespace correto, rotas separadas (admin/public) e internacionalização.
O módulo encontra-se em `modules/modelo` e seu pacote de instalação em `modules/modelo/modelo.zip`.
---
## Estrutura de Diretórios
Um módulo padrão deve seguir rigorosamente a seguinte estrutura:
```text
modules/
└── [nome-do-modulo]/
├── module.json # Metadados e configurações principais
├── routes/
│ └── web.php # Definição de rotas (Admin e Pública)
├── Providers/
│ └── [Nome]ServiceProvider.php # Registro do módulo no container
├── classes/
│ ├── Controllers/
│ │ ├── [Nome]Controller.php # Controller Admin (protegido)
│ │ └── PublicController.php # Controller Público (aberto)
│ └── Models/
│ └── [Nome].php # Modelo Eloquent
├── database/
│ └── migrations/ # Scripts de banco de dados
│ ├── 001_create_[tabela]_table.php
│ └── 002_insert_[modulo]_module.php
├── locales/ # Arquivos de tradução
│ ├── pt_BR/
│ ├── en_US/
│ └── [outros_idiomas]/
└── views/ # Templates Twig
├── admin/ # Views do painel administrativo
└── public/ # Views do site público
```
---
## Componentes Essenciais
### 1. Configuração (`module.json`)
Arquivo JSON que define a identidade do módulo, suas permissões e dependências.
```json
{
"name": "faq",
"display_name": "FAQ Manager",
"version": "1.1.0",
"permissions": ["faq.view", "faq.manage"],
"providers": ["Modules\\Faq\\Providers\\FaqServiceProvider"],
"routes": {"web": "routes/web.php"},
"views": "views",
"locales": "locales",
"module_public": true
}
```
### 2. Rotas (`routes/web.php`)
Separação clara entre rotas administrativas (protegidas) e públicas.
```php
// Rota Administrativa (Protegida por Middleware e Permissões no Controller)
$app->addRoute('GET', '/admin/faq', [\Modules\Faq\Controllers\FaqController::class, 'index']);
// Rota Pública
$app->addRoute('GET', '/faq', [\Modules\Faq\Controllers\PublicController::class, 'index']);
```
### 3. Service Provider (`Providers/FaqServiceProvider.php`)
Responsável por registrar as views, traduções e configurações do módulo no boot do sistema.
### 4. Controllers
* **Admin (`FaqController.php`)**:
* Herda de `BaseAdminController`.
* Verifica permissões (`$user->hasPermission('faq.view')`).
* Gerencia CRUD (Create, Read, Update, Delete).
* Renderiza views admin (`@faq/admin/index.twig`).
* **Público (`PublicController.php`)**:
* Herda de `BaseController`.
* Consulta dados públicos (`faqs_visibility = 'public'`).
* Renderiza views públicas (`@faq/public/index.twig`).
### 5. Migrations
* **Criação da Tabela**: Define a estrutura de dados (ex: `faqs_id`, `faqs_question`, `faqs_bus_id`).
* **Registro do Módulo**: Insere o registro na tabela `modules` para que o sistema reconheça o novo componente.
### 6. Views (Twig)
* **Admin**: Estende `layouts/dashboard.twig`. Usa componentes Bootstrap e alertas do sistema.
* **Público**: Estende `layouts/base.twig`. Foca na apresentação do conteúdo para o visitante.
---
## Guia para Criar um Novo Módulo
Para criar um novo módulo usando o `faq` como base:
1. **Copie a pasta `modules/faq`** e renomeie para o novo nome (ex: `news`).
2. **Edite o `module.json`**:
* Atualize `name`, `display_name` e `providers`.
* Defina as novas permissões (ex: `news.view`).
3. **Renomeie e Refatore as Classes**:
* `FaqController` -> `NewsController`.
* `FaqServiceProvider` -> `NewsServiceProvider`.
* `Faq` (Model) -> `News`.
* Atualize os `namespace` em todos os arquivos PHP.
4. **Atualize as Rotas**:
* Em `routes/web.php`, aponte para os novos controllers.
5. **Ajuste as Migrations**:
* Renomeie os arquivos e as tabelas dentro deles.
6. **Traduções**:
* Atualize os arquivos em `locales/` com as chaves do novo módulo.
7. **Instalação**:
* O instalador de módulos detectará o novo `module.json` e executará as migrações automaticamente.
---
*Documento gerado para orientação de desenvolvimento no SysCMS.*
+46
View File
@@ -0,0 +1,46 @@
# Sistema de Temas e Customizer (Arquitetura)
Este documento detalha o funcionamento técnico do sistema de temas do SysCMS, incluindo a herança de templates e o motor de personalização dinâmica.
## 1. Arquitetura de Herança (Template Hierarchy)
O SysCMS utiliza um motor de busca de arquivos em camadas para permitir a máxima flexibilidade sem duplicidade de código:
1. **Tema Ativo (`themes/{active}/`)**: Prioridade máxima.
2. **Tema Pai (`themes/{parent}/`)**: Se o tema ativo tiver a tag `Template` no seu `style.css`.
3. **Módulos (`modules/{module}/views/`)**: Fallback automático para as views padrão do sistema.
4. **Templates Globais (`templates/`)**: Fallback para layouts e componentes comuns.
## 2. Overrides de Módulos
Para sobrescrever a visualização de um módulo (ex: `index`), o tema deve replicar a estrutura interna do módulo:
`themes/{tema}/modules/{nome_do_modulo}/views/{template}.twig`
Isso permite que um tema mude apenas partes específicas de um módulo sem afetar sua lógica de controle.
## 3. O Personalizador (Customizer)
O Customizer é alimentado por um arquivo JSON e armazena os valores no banco de dados.
### Fluxo de Dados:
1. **Definição:** O tema declara campos no arquivo `customizer.json`.
2. **Gestão:** O administrador altera os valores em `Sistema > Temas > Personalizar`.
3. **Persistência:** Os valores são salvos na tabela `system_config` com a chave `theme_settings_{slug_do_tema}`.
4. **Injeção:** O `Kernel\View.php` lê esses valores e os injeta na variável global `theme_settings` em todas as views Twig.
### Tipos de Campos Suportados:
- `color`: Seletor de cores hexadecimal.
- `text`: Campo de texto simples.
- `switch`: Interruptor booleano (on/off).
- `select`: Menu suspenso com opções pré-definidas.
## 4. Assets e URLs Dinâmicas
- Use `theme_url()` para carregar arquivos CSS/JS/Imagens do tema. Ele resolverá automaticamente o caminho correto considerando a herança (Child > Parent).
- Use `asset_url()` para arquivos globais na pasta `/public/assets`.
## 5. Diretrizes para Desenvolvedores (IA)
- **Sempre verifique o tema ativo:** Antes de modificar qualquer arquivo em `/modules/`, verifique se o usuário deseja que a mudança seja global ou apenas para o tema atual.
- **Não altere o Kernel para novos temas:** O sistema de temas já é genérico. Novas funcionalidades de temas devem ser implementadas via `customizer.json` e lógica de template.
- **Child Themes:** Ao criar temas derivados, utilize a tag `Template:` no `style.css` para manter o código limpo e herdar funcionalidades do tema base.
+242
View File
@@ -0,0 +1,242 @@
# Integração com Módulo GlobalLists (Endereços)
Todos os módulos que utilizam formulários com campos de endereço (País, Estado, Cidade) DEVEM obrigatoriamente utilizar as funcionalidades do módulo `globallists` para padronização e consistência dos dados.
Esta regra visa eliminar a duplicação de tabelas de localidades e garantir uma experiência unificada de seleção de endereços em todo o sistema.
## 1. Banco de Dados
### Migração
As tabelas do módulo devem possuir as colunas `_country_id`, `_state_id` e `_city_id` (prefixadas com o identificador da tabela do módulo) configuradas como `unsignedInteger` e `nullable`.
É **obrigatório** o uso de chaves estrangeiras (Foreign Keys) apontando para as tabelas `lists_countries`, `lists_states` e `lists_cities`.
Exemplo (supondo um módulo com prefixo `events`):
```php
// Adição das colunas
$table->unsignedInteger('events_country_id')->nullable();
$table->unsignedInteger('events_state_id')->nullable();
$table->unsignedInteger('events_city_id')->nullable();
// Definição das Foreign Keys
$table->foreign('events_country_id')->references('countries_id')->on('lists_countries')->onDelete('set null');
$table->foreign('events_state_id')->references('states_id')->on('lists_states')->onDelete('set null');
$table->foreign('events_city_id')->references('cities_id')->on('lists_cities')->onDelete('set null');
```
## 2. Model
No Model do seu módulo, adicione os relacionamentos `belongsTo` e inclua as novas colunas no array `$fillable`.
```php
use Modules\GlobalLists\Models\Country;
use Modules\GlobalLists\Models\State;
use Modules\GlobalLists\Models\City;
class Event extends Model
{
protected $fillable = [
// ... outros campos
'events_country_id',
'events_state_id',
'events_city_id',
];
public function country()
{
return $this->belongsTo(Country::class, 'events_country_id', 'countries_id');
}
public function state()
{
return $this->belongsTo(State::class, 'events_state_id', 'states_id');
}
public function city()
{
return $this->belongsTo(City::class, 'events_city_id', 'cities_id');
}
}
```
## 3. Controller
Nos métodos responsáveis por exibir o formulário (`create`, `edit`), busque a lista completa de países. **IMPORTANTE**: Use o método `sortBy` com o acessor `name` para garantir que os países sejam listados em ordem alfabética de acordo com o idioma do sistema (o campo `countries_name` é um JSON).
```php
use Modules\GlobalLists\Models\Country;
use Modules\GlobalLists\Models\State;
use Modules\GlobalLists\Models\City;
public function create(): Response
{
// Ordenação correta por idioma
$countries = Country::all()->sortBy(function ($country) {
return $country->name;
});
return $this->renderAdminView('@seumodulo/form.twig', [
'countries' => $countries,
// ... outros dados
]);
}
public function edit($id): Response
{
$item = SeuModelo::find($id);
$countries = Country::all()->sortBy(function ($country) {
return $country->name;
});
// Pre-carregar estados e cidades se já houver seleção
$states = [];
$cities = [];
if ($item->prefixo_country_id) {
$states = State::where('states_country_id', $item->prefixo_country_id)->orderBy('states_name')->get();
}
if ($item->prefixo_state_id) {
$cities = City::where('cities_state_id', $item->prefixo_state_id)->orderBy('cities_name')->get();
}
return $this->renderAdminView('@seumodulo/form.twig', [
'item' => $item,
'countries' => $countries,
'states' => $states,
'cities' => $cities
]);
}
```
## 4. View (Twig)
Utilize a estrutura HTML abaixo para os selects. Substitua os IDs e Names conforme o seu módulo. Observe o uso de `country.name` para obter o nome traduzido.
```twig
<div class="row">
<!-- País -->
<div class="col-md-4 mb-3">
<label for="events_country_id" class="form-label">País</label>
<select class="form-select" id="events_country_id" name="events_country_id" onchange="loadStates(this.value)" required>
<option value="">Selecione...</option>
{% for country in countries %}
<option value="{{ country.countries_id }}" {{ item.events_country_id == country.countries_id ? 'selected' : '' }}>
{{ country.name }}
</option>
{% endfor %}
</select>
</div>
<!-- Estado -->
<div class="col-md-4 mb-3">
<label for="events_state_id" class="form-label">Estado</label>
<select class="form-select" id="events_state_id" name="events_state_id" onchange="loadCities(this.value)" required {{ not item.events_country_id ? 'disabled' : '' }}>
<option value="">Selecione...</option>
{% for state in states %}
<option value="{{ state.states_id }}" {{ item.events_state_id == state.states_id ? 'selected' : '' }}>
{{ state.states_name }}
</option>
{% endfor %}
</select>
</div>
<!-- Cidade -->
<div class="col-md-4 mb-3">
<label for="events_city_id" class="form-label">Cidade</label>
<select class="form-select" id="events_city_id" name="events_city_id" required {{ not item.events_state_id ? 'disabled' : '' }}>
<option value="">Selecione...</option>
{% for city in cities %}
<option value="{{ city.cities_id }}" {{ item.events_city_id == city.cities_id ? 'selected' : '' }}>
{{ city.cities_name }}
</option>
{% endfor %}
</select>
</div>
</div>
```
## 5. JavaScript (Vanilla JS Obrigatório)
Utilize **EXCLUSIVAMENTE JavaScript Puro** para esta lógica. O uso de **Alpine.js** é estritamente proibido para os selects de localização do GlobalLists devido a conflitos de reatividade e performance.
As rotas da API `/api/globallists/states/{countryId}` e `/api/globallists/cities/{stateId}` já retornam os dados formatados corretamente.
```javascript
// Defina os valores salvos (caso seja edição)
const savedStateId = "{{ item.events_state_id }}";
const savedCityId = "{{ item.events_city_id }}";
document.addEventListener('DOMContentLoaded', function() {
const countryId = document.getElementById('events_country_id').value;
if (countryId) {
// Carrega os estados e, em seguida, as cidades se houver um estado salvo
loadStates(countryId, savedStateId);
}
});
function loadStates(countryId, selectedStateId = null) {
const stateSelect = document.getElementById('events_state_id');
const citySelect = document.getElementById('events_city_id');
// Reset e estado de loading
stateSelect.innerHTML = '<option value="">Carregando...</option>';
stateSelect.disabled = true;
citySelect.innerHTML = '<option value="">Selecione o estado primeiro...</option>';
citySelect.disabled = true;
if (!countryId) {
stateSelect.innerHTML = '<option value="">Selecione o país primeiro...</option>';
return;
}
fetch(`/api/globallists/states/${countryId}`)
.then(response => response.json())
.then(data => {
stateSelect.innerHTML = '<option value="">Selecione...</option>';
data.forEach(state => {
// A API retorna {id, name}
const selected = selectedStateId && selectedStateId == state.id ? 'selected' : '';
stateSelect.innerHTML += `<option value="${state.id}" ${selected}>${state.name}</option>`;
});
stateSelect.disabled = false;
// Se houve um estado pré-selecionado, carrega as cidades
if (selectedStateId) {
loadCities(selectedStateId, savedCityId);
}
})
.catch(error => {
console.error('Error loading states:', error);
stateSelect.innerHTML = '<option value="">Erro ao carregar</option>';
});
}
function loadCities(stateId, selectedCityId = null) {
const citySelect = document.getElementById('events_city_id');
citySelect.innerHTML = '<option value="">Carregando...</option>';
citySelect.disabled = true;
if (!stateId) {
citySelect.innerHTML = '<option value="">Selecione o estado primeiro...</option>';
return;
}
fetch(`/api/globallists/cities/${stateId}`)
.then(response => response.json())
.then(data => {
citySelect.innerHTML = '<option value="">Selecione...</option>';
data.forEach(city => {
// A API retorna {id, name}
const selected = selectedCityId && selectedCityId == city.id ? 'selected' : '';
citySelect.innerHTML += `<option value="${city.id}" ${selected}>${city.name}</option>`;
});
citySelect.disabled = false;
})
.catch(error => {
console.error('Error loading cities:', error);
citySelect.innerHTML = '<option value="">Erro ao carregar</option>';
});
}
```
+75
View File
@@ -0,0 +1,75 @@
# Rule 20: Criação de Novos Módulos (Baseado no Sucesso do PhotoEssay)
**Dica Proativa**: Utilize o comando `php syscli make:module [nome]` para gerar automaticamente a estrutura base descrita abaixo.
Esta regra serve como guia definitivo para a IA coder criar novos módulos no SysCMS/Portal, utilizando o módulo **PhotoEssay** como padrão de ouro em estrutura, segurança, multi-idioma e integração com o core.
## 1. Estrutura de Diretórios Padronizada
Todo módulo deve seguir rigorosamente a estrutura abaixo:
```text
modules/nome-do-modulo/
├── classes/
│ ├── Controllers/ # AdminController, UserController, PublicController
│ ├── Models/ # Models ORM
│ └── Providers/ # ServiceProvider para registro do módulo
├── database/
│ └── migrations/ # Scripts SQL de criação de tabelas e registro no sistema
├── locales/ # Traduções em 5 idiomas (pt_BR, en_US, es_ES, de_DE, fr_FR)
├── routes/
│ └── web.php # Definição de rotas
├── views/ # Templates Twig separados por contexto (admin, user, public)
├── module.json # Configuração de menus, permissões e metadados
└── modulo.zip # Pacote compactado para instalação/atualização
```
## 2. Configuração do `module.json` e Menu
O `module.json` deve suportar múltiplos itens de menu para diferentes perfis.
- **dashboard**: Itens visíveis para o usuário comum.
- **admin/ads/reports**: Itens visíveis apenas para Admin/Super Admin.
- **Importante**: O rótulo do menu deve usar chaves de tradução (ex: `photoessay.menu.admin_essays`).
Exemplo de estrutura de menu e registro de recursos:
```json
"menu": {
"dashboard": { "icon": "bi bi-camera", "label": "photoessay.menu.essays", "route": "user/photoessay", "permission": "photoessay.view" },
"admin": { "icon": "bi bi-shield", "label": "photoessay.menu.admin_list", "route": "admin/photoessay", "permission": "photoessay.approve" }
},
"views": "views",
"locales": "locales"
```
## 3. Multi-Idioma (Locales)
Sempre implemente traduções nos 5 idiomas obrigatórios.
- **Registro de Locales**: Certifique-se de que a chave `"locales": "locales"` existe no `module.json` para que as traduções sejam carregadas. Sem este registro, o sistema não encontrará os arquivos JSON e exibirá apenas as chaves (ex: `modulo.chave`).
- Nunca deixe chaves faltando em um idioma que existam no outro.
- O aviso de responsabilidade (`show.disclaimer`) deve usar o termo **Portal** em vez de SysCMS.
## 4. Segurança e Validação (Lições do PhotoEssay)
- **Verificação de Propriedade**: Em rotas de edição ou exclusão (`UserController`), SEMPRE verifique se o recurso pertence ao usuário logado.
- **Try-Catch**: Use blocos try-catch em operações de banco de dados e sistema de arquivos para retornar respostas JSON amigáveis em caso de erro.
- **Caminhos de Arquivos**: NUNCA use `ROOT_PATH` para exclusão de arquivos se o ambiente for Windows/Docker instável. Use caminhos absolutos baseados em `dirname(__DIR__, 4)` para localizar a pasta `storage/uploads/{nome-do-modulo}/`.
- *Exemplo Correto:* `$filePath = dirname(__DIR__, 4) . '/storage/uploads/photoessay/' . $image->path;`
- NUNCA escreva diretamente na pasta `public/`. Use `storage/uploads/{nome-do-modulo}/` e acesse via helper `url()`.
## 5. Interface e Experiência do Usuário (UX)
- **Operações AJAX**: Para exclusões de itens de galeria ou mudanças de status, utilize AJAX para evitar o recarregamento da página.
- **Feedback Visual**: Implemente confirmações antes de excluir (`confirm()`) e remova o elemento do DOM imediatamente após o sucesso do AJAX.
- **Componentes UI**: Utilize ícones Bootstrap (BI) e classes utilitárias para botões de ação (vermelho para excluir, azul para editar).
## 6. Integração com o Core
- Se o módulo precisar de múltiplos links no sidebar, certifique-se de que o `BaseAdminController.php` no Core esteja configurado para iterar sobre todos os itens do array `menu` do módulo, ignorando apenas as chaves `navbar` e `public`.
- O arquivo `sidebar.twig` deve renderizar o `item.label` diretamente para permitir que as traduções do módulo funcionem corretamente.
## 7. Migrations e Instalação
- A migration `002_insert_...` deve registrar o módulo na tabela `modules`, definindo o ícone, nome de exibição e ordem.
- Garanta que as permissões necessárias sejam inseridas na tabela `permissions` e vinculadas aos papéis (roles) corretos.
## 8. Checklist de Finalização (Aprovação Perfeita)
1. [ ] As rotas de Admin estão protegidas por permissões?
2. [ ] As imagens/arquivos são excluídos fisicamente do disco ao deletar do banco?
3. [ ] O layout é responsivo e segue o padrão do Dashboard?
4. [ ] O arquivo `.zip` foi gerado contendo todas as alterações mais recentes?
5. [ ] O termo "SysCMS" foi substituído por "Portal" em textos de aviso?
---
*Esta regra foi criada após a implementação bem-sucedida do módulo PhotoEssay, incorporando todas as correções de bugs de caminho, ajustes de tradução e melhorias de sidebar solicitadas pelo usuário.*
+38
View File
@@ -0,0 +1,38 @@
# Regras de Layouts e Templates Twig
## 1. Layouts Disponíveis
O sistema SysCMS utiliza uma estrutura específica de templates Twig. NÃO invente nomes de layouts. Utilize apenas os existentes.
### Layouts Principais
- **Painel Administrativo (Backend):** `layouts/dashboard.twig`
- Use este layout para todas as páginas internas do painel de controle, módulos administrativos, e páginas de erro do admin.
- **Caminho:** `app/templates/layouts/dashboard.twig`
- **Exemplo de uso:** `{% extends "layouts/dashboard.twig" %}`
- **Layout Base (Genérico):** `layouts/base.twig`
- Use apenas se precisar de uma estrutura HTML mínima sem a barra de navegação e sidebar do dashboard.
- **Caminho:** `app/templates/layouts/base.twig`
- **Frontend/Público:**
- O frontend geralmente utiliza temas dinâmicos localizados em `public/themes/`.
- Para páginas de erro ou sistema genéricas, verifique `app/templates/default.twig`.
## 2. Erros Comuns a Evitar
- **NUNCA** use `{% extends "layout.twig" %}`. Este arquivo NÃO existe.
- **NUNCA** use `{% extends "admin.twig" %}`.
- Sempre verifique a pasta `app/templates/layouts/` para confirmar o nome correto do arquivo antes de estender.
## 3. Estrutura de Pastas de Templates
```
app/templates/
├── layouts/
│ ├── dashboard.twig (O MAIS IMPORTANTE)
│ └── base.twig
├── errors/ (Páginas de erro devem estender layouts/dashboard.twig)
├── components/ (Componentes reutilizáveis)
└── modules/ (Templates específicos de instalação de módulos)
```
## 4. Injeção de CSS/JS
- Utilize `{% block head %}` para adicionar CSS específico da página.
- Utilize `{% block scripts %}` (se disponível no layout) ou adicione scripts no final do `{% block content %}` se necessário.
+62
View File
@@ -0,0 +1,62 @@
# 📁 Regra de Armazenamento de Arquivos e Uploads (51_UPLOADS_STORAGE.md)
## ❗ Regra Fundamental
**Nenhum módulo do SysCMS deve gravar arquivos diretamente no diretório `public/`.**
Todos os uploads, arquivos gerados pelo sistema ou mídias de usuários devem ser obrigatoriamente armazenados no diretório `storage/uploads/{nome-do-modulo}/`.
---
## 🏗️ Estrutura de Armazenamento (Padrão Único e Definitivo)
- **Localização Física**: `storage/uploads/{nome-do-modulo}/`
- **URL de Acesso**: `url('storage/uploads/{nome-do-modulo}/' ~ nome_arquivo)`
- **Funciona em**: Windows e Linux (Docker)
- **OBRIGATÓRIO**: Subpastas por módulo (ex: `storage/uploads/erpcarriers/`, `storage/uploads/blog/`)
- **PROIBIDO**: Uso de Links Simbólicos (Symlinks), Junctions ou Atalhos.
- **Este padrão é definitivo e imutável** - NUNCA deve ser alterado
---
## 🌐 Acesso via Web
Os arquivos em `storage/uploads/{nome-do-modulo}/` são acessíveis via rota do sistema.
### Geração de URLs
Para acessar um arquivo via navegador, utilize o helper `url()` apontando para `storage/uploads/{nome-do-modulo}/`:
- **Correto**: `url('storage/uploads/blog/imagem.jpg')`
- **Incorreto**: `url('public/uploads/imagem.jpg')`
- **Incorreto**: `url('storage/imagem.jpg')` (sem módulo)
---
## 🛠️ Implementação no Código (PHP)
### 1. Definindo o Diretório de Upload
Sempre utilize caminhos absolutos baseados na raiz do projeto e inclua o nome do módulo:
```php
$moduleName = 'erpcarriers'; // Exemplo
$uploadDir = dirname(__DIR__, 4) . '/storage/uploads/' . $moduleName . '/';
if (!is_dir($uploadDir)) {
mkdir($uploadDir, 0755, true);
}
```
### 2. Salvando o Caminho no Banco de Dados
Grave apenas o nome do arquivo:
- **BD**: `imagem.jpg`
- **NÃO**: `blog/imagem.jpg` (redundante se a pasta for padrão)
### 3. Exibindo no Frontend (Twig)
```twig
<img src="{{ url('storage/uploads/erpcarriers/' ~ registro.imagem) }}" alt="...">
```
---
## 🛡️ Segurança e Manutenção
1. **Proteção de Diretório**: O diretório `storage/` contém um arquivo `.htaccess` que impede a execução de scripts PHP, garantindo que arquivos maliciosos enviados por upload não sejam executados.
2. **Limpeza**: Ao remover um registro que possui arquivos associados, o arquivo físico deve ser removido utilizando `unlink()`.
3. **Nomes de Arquivos**: Use nomes únicos (ex: `TRA` + random_bytes + timestamp + extensão) para evitar conflitos.
---
## ⚠️ Importante
Este padrão está definido como definitivo e imutável no [DECISIONS.md](../../DECISIONS.md). Em caso de dúvida, consulte sempre o DECISIONS.md antes de implementar funcionalidades de upload.
+188
View File
@@ -0,0 +1,188 @@
# Plano de Implementação: Substituição do SCEditor pelo Quill
## Objetivo
Substituir o editor SCEditor atual pelo editor Quill para modernizar a experiência de edição de texto no sistema SysCMS.
## Análise Comparativa
### SCEditor
- **Pros**:
- Leve e estável
- Funcionalidade básica de edição de BBCode
- Largamente utilizado em projetos mais antigos
- Suporte para emoticons
- Interface mais simples
- **Contras**:
- Interface desatualizada
- Baseado em jQuery (legado)
- Limitado para BBCode
- Não suporta edição WYSIWYG moderna
- Sem recursos avançados como tabelas, listas, etc.
- Manutenção mínima pela comunidade
### Quill
- **Pros**:
- Editor moderno e amplamente utilizado
- Interface WYSIWYG completa
- Suporte para formatação rica (negrito, itálico, etc.)
- Suporte para tabelas, listas e blocos
- API limpa e extensível
- Comunidade ativa
- Documentação completa
- Suporte para dispositivos móveis
- Performance superior
- **Contras**:
- Curva de aprendizado mais íngreme
- Requer mais dependências (JavaScript moderno)
- Pode ser excessivo para casos simples de uso
- Configuração inicial mais complexa
## Fase 1: Preparação e Instalação
### 1.1. Download dos Recursos
- Baixar a versão mais recente do Quill (v2.x.x)
- Baixar os temas CSS do Quill (quill.snow.css, quill.bubble.css)
- Baixar os ícones do Quill
### 1.2. Estrutura de Arquivos
```
public/assets/
├── quill/
│ ├── quill.min.js
│ ├── quill.js
│ └── quill.css
└── js/
└── quill-init.js
```
### 1.3. Configuração do Quill
- Criar arquivo de configuração para personalizar o Quill
- Definir toolbar com ferramentas essiais
- Configurar tema visual compatível com o sistema
- Habilitar/desabilitar recursos conforme necessidade
### 1.4. Substituição nos Templates
#### Templates a Modificar:
1. **templates/layouts/base.twig**
- Remover referências ao SCEditor
- Adicionar referências ao Quill
- Manter estrutura Bootstrap existente
2. **templates/layouts/dashboard.twig**
- Atualizar referências de editor
- Adicionar script de inicialização do Quill
3. **templates/partials/language-switcher.twig**
- Manter inalterado (não afetado pelo editor)
4. **Templates de formulários**
- Identificar templates que contenham campos de texto
- Substituir SCEditor por Quill onde necessário
## Fase 2: Implementação
### 2.1. Classe Helper para Quill
- Criar `app/Helpers/QuillHelper.php`
- Centralizar configuração e inicialização do Quill
- Fornecer métodos para:
- Obter instância do editor
- Definir conteúdo
- Obter conteúdo em formato HTML ou texto
- Limpar o editor
### 2.2. Integração com o Sistema Existente
- Modificar `kernel/Application.php` para carregar o QuillHelper
- Adicionar função global no Twig para o QuillHelper
- Manter compatibilidade com funções de tradução existentes
### 2.3. Scripts de Inicialização
- Criar `public/assets/js/quill-init.js`
- Configurar instâncias do Quill em todas as páginas
- Suportar múltiplos editores na mesma página
- Inicializar editores apenas quando necessário
### 2.4. Temas e Estilos
- Criar tema Quill personalizado em `public/assets/css/quill-syscms.css`
- Adaptar cores e estilos para combinar com o tema do sistema
- Garantir responsividade
## Fase 3: Testes
### 3.1. Testes Unitários
- Criar testes para as funcionalidades básicas
- Verificar integração com o sistema de tradução
- Testar compatibilidade com diferentes navegadores
### 3.2. Testes de Integração
- Testar funcionamento em páginas reais
- Verificar performance e uso de memória
- Testar persistência de dados
## Fase 4: Implantação
### 4.1. Migração Gradual
- Implementar modo de compatibilidade para usar Quill ou SCEditor
- Manter SCEditor funcional para edição de BBCode
- Permitir migração incremental por módulo
### 4.2. Documentação e Treinamento
- Atualizar documentação do sistema
- Criar guia de migração para desenvolvedores
- Fornecer exemplos de código
## Fase 5: Rollback e Manutenção
### 5.1. Plano de Rollback
- Manter backup do SCEditor
- Criar sistema para reverter para SCEditor se necessário
- Documentar procedimento de emergência
## Considerações
### Segurança
- Sanitizar todo conteúdo HTML gerado pelo Quill
- Implementar CSP (Content Security Policy) adequado
- Validar conteúdo do lado do servidor
### Performance
- Carregar Quill apenas quando necessário (lazy loading)
- Otimizar tamanho do bundle
- Implementar cache para configurações
### Acessibilidade
- Garantir suporte a leitores de tela
- Fornecer atalhos de teclado
- Manter compatibilidade com navegadores mais antigos
## Cronograma Estimado
- **Fase 1**: 2-3 dias (Download, configuração básica)
- **Fase 2**: 3-5 dias (Implementação principal, testes)
- **Fase 3**: 2-3 dias (Integração completa, testes finais)
- **Fase 4**: 1-2 dias (Implantação, documentação, treinamento)
- **Fase 5**: 1 semana (Estabilização, correções finais)
## Próximos Passos
1. Aprovar a implementação do plano
2. Baixar e organizar os recursos do Quill
3. Criar a estrutura de arquivos proposta
4. Implementar o QuillHelper básico
5. Modificar os templates principais
6. Criar script de inicialização
7. Realizar testes preliminares
8. Documentar as mudanças
## Conclusão
A substituição do SCEditor pelo Quill trará benefícios significativos para o sistema:
- Interface moderna e intuitiva
- Maior produtividade para usuários
- Melhor experiência em dispositivos móveis
- Manutenibilidade simplificada a longo prazo
- Alinhamento com tecnologias web atuais
Este plano fornece uma base sólida para a implementação, garantindo uma transição suave e bem-sucedida.
+101
View File
@@ -0,0 +1,101 @@
# SysCMS - Documentação de Regras
**SysCMS** é um sistema de gerenciamento de conteúdo moderno, modular e flexível, construído em PHP 8.1+, MySQL e Bootstrap 5.
## 📖 Começando
Para navegar pela documentação de forma eficiente, comece por:
1. **[00_INDICE.md](00_INDICE.md)** - Índice completo e organização lógica de toda a documentação
2. **[../CONTEXT.md](../CONTEXT.md)** - Contexto arquitetural imutável do sistema
3. **[../RULES.md](RULES.md)** - Regras operacionais e convenções do projeto
## 🚀 Início Rápido
### Instalação Automática
O SysCMS possui um instalador web que configura tudo para você.
1. Suba os containers Docker (se estiver usando Docker):
```bash
docker-compose up -d
```
2. Acesse o instalador no seu navegador:
```
http://localhost/install
```
3. Siga os passos na tela para configurar banco de dados e usuário admin.
> **Nota:** Se não estiver usando Docker, certifique-se ter um servidor web (Apache/Nginx) apontando para a pasta `public/` e PHP 8.1+ configurado.
---
## 📚 Estrutura da Documentação
A documentação está organizada em categorias numeradas para facilitar a navegação. Consulte o **[00_INDICE.md](00_INDICE.md)** para ver a estrutura completa.
### Categorias Principais:
- **Fundamentos (01-09)**: Conceitos base e comportamentos essenciais
- **Ciclo de Vida (10-19)**: Fluxo de execução e ciclo de vida da aplicação
- **Implementação (20-29)**: Guias práticos para criação e implementação
- **Específicos (50-59)**: Regras específicas para funcionalidades pontuais
### Documentos Essenciais:
- **[RULES.md](RULES.md)** - Regras operacionais e convenções (FONTE DA VERDADE)
- **[01_COMPORTAMENTO_IA.md](01_COMPORTAMENTO_IA.md)** - Comportamento esperado da IA
- **[03_MODULOS.md](03_MODULOS.md)** - Sistema de módulos e estrutura
- **[05_PADROES_CODIGO.md](05_PADROES_CODIGO.md)** - Padrões de código e estilo
- **[50_LAYOUTS_CORRETOS.md](50_LAYOUTS_CORRETOS.md)** - Layouts Twig corretos
- **[51_UPLOADS_STORAGE.md](51_UPLOADS_STORAGE.md)** - Regras de uploads e storage
---
## 🛠️ Tecnologias Principais
- **Backend**: PHP 8.1+, PHP-DI, FastRoute, Symfony Console
- **Database**: MySQL 8.0, Illuminate Database (Eloquent ORM)
- **Frontend**: Bootstrap 5.3, Vanilla JS, Twig Templates
- **Ícones**: Bootstrap Icons (Exclusivo)
---
## ⚠️ Regras Críticas
Consulte o **[00_INDICE.md](00_INDICE.md)** para a lista completa de regras críticas, incluindo:
1. NUNCA alterar arquivos do Core (kernel/, app/Controllers/, app/Models/)
2. NUNCA alterar módulos com `ready: true` (exceto correção de bugs reportados)
3. NUNCA gravar arquivos em `public/` (usar `storage/uploads/`)
4. NUNCA usar FontAwesome (apenas Bootstrap Icons)
5. SEMPRE usar DataTables para tabelas de listagem
6. SEMPRE priorizar ERP Legado em caso de conflito
## 🧠 Política de Memórias Core
As **memórias core são APENAS SUPLEMENTARES** e **NÃO DEVEM SER USADAS COMO FONTE DE VERDADE**.
- **Fonte Primária**: Sempre consulte os arquivos de regras (RULES.md, CONTEXT.md, /rules/)
- **Uso de Memórias**: Apenas como atalhos rápidos para informações estáticas (credenciais, URLs de API)
- **Conflito**: Arquivos de regras sempre prevalecem sobre memórias core
- **Sem Redundância**: As memórias core foram limpas para não duplicar informações dos arquivos de regras
Consulte o **[00_POLITICA_MEMORIAS_CORE.md](00_POLITICA_MEMORIAS_CORE.md)** para a política completa de uso de memórias core.
---
## 🤝 Contribuição
Se você deseja contribuir com o projeto, por favor leia primeiro:
1. **[00_INDICE.md](00_INDICE.md)** - Para entender a organização
2. **[RULES.md](RULES.md)** - Para seguir as convenções do projeto
3. **[01_COMPORTAMENTO_IA.md](01_COMPORTAMENTO_IA.md)** - Para entender autonomia vs preservação
---
**Última Atualização**: 2025-01-19
**Versão**: 2.0.0
© SysCMS Team
Executable
+112
View File
@@ -0,0 +1,112 @@
# REGRAS DO SYSCMS (Índice)
Este arquivo serve como índice para as regras detalhadas do projeto. A IA deve consultar os arquivos específicos abaixo para obter diretrizes detalhadas.
## 📂 Documentação de Regras
1. **[Comportamento da IA](rules/01_COMPORTAMENTO_IA.md)**
- Como executar comandos (Proibição de `RunCommand` direto).
- Criação de scripts PHP para tarefas.
- Idioma e postura.
2. **[Arquitetura do Sistema](rules/02_ARQUITETURA.md)**
- Estrutura de diretórios.
- Componentes do Kernel (`Application`, `ModuleLoader`).
- Padrões de Design (MVC, Repository, etc).
3. **[Sistema de Módulos](rules/03_MODULOS.md)**
- Estrutura de pastas de um módulo.
- Configuração do `module.json`.
- Views, Rotas e Traduções.
4. **[Tecnologias e Stack](rules/04_TECNOLOGIAS.md)**
- Bibliotecas Backend (PHP 8.1, Eloquent, Twig).
- Frontend (Bootstrap 5.3, Alpine.js).
- **Regra de Ícones**: Apenas Bootstrap Icons.
5. **[Padrões de Código](rules/05_PADROES_CODIGO.md)**
- Nomenclatura (Classes, Métodos, Banco de Dados).
- Regras de Banco de Dados (Prefixos, Multiempresa).
30. - Segurança e Uploads.
31. - **Armazenamento**: Use sempre `storage/uploads` fisicamente e `/storage` na URL.
32.
33. ## 📚 Documentação Complementar (Em `rules/`)
6. **[Guia do Desenvolvedor](rules/06_DEVELOPER_GUIDE.md)**
7. **[Uso do Ambiente](rules/07_ENVIRONMENT_USAGE.md)**
8. **[Guia de Execução de Comandos](rules/08_IA_COMMAND_EXECUTION_GUIDE.md)**
9. **[Configuração de Idioma](rules/09_LANGUAGE_CONFIG_README.md)**
10. **[Ciclo de Vida](rules/11_LIFECYCLE.md)**
12. **[Manual: Criar Módulos para Instalar](rules/12_MANUAL_COMO_CRIAR_MODULOS_PARA_INSTALAR.md)**
13. **[Guia de Usuário](rules/13_USER_GUIDE.md)**
14. **[Como Usar Hooks](rules/14_COMO_USAR_HOOK.md)**
15. **[Quill: Implementação Completa](rules/15_QUILL_IMPLEMENTATION_COMPLETE.md)**
16. **[Regras IA para Quill](rules/16_REGRAS_QUILL_IA.md)**
17. **[Template de Módulo](rules/17_MODULE_TEMPLATE.md)**
18. **[Sistema de Temas e Customizer](rules/18_THEMES_CUSTOMIZER.md)**
- Arquitetura de temas, herança e child themes.
- Configuração do `customizer.json`.
- Uso de `theme_settings` no Twig.
19. **[Integração GlobalLists](rules/19_INTEGRACAO_GLOBALLISTS.md)**
- Padrão obrigatório para campos de endereço (País, Estado, Cidade).
- Migrations, Models e Vanilla JS para selects dinâmicos.
20. **[Gestão de Uploads](rules/22_UPLOADS_STORAGE.md)**
- Proibição de escrita em `public/`.
- Uso obrigatório de `storage/uploads`.
- Link simbólico e geração de URLs.
---
## 🚀 Resumo Rápido para a IA
- **Padrão Frontend**: A IA coder deve dar preferência absoluta ao uso de **JavaScript puro (Vanilla JS)** em vez de Alpine.js para interações no frontend. O uso de Alpine.js deve ser restrito apenas a casos onde a reatividade complexa seja estritamente necessária e o Vanilla JS se torne impraticável.
- **Uploads**: **PROIBIDO** gravar em `public/`. Use sempre `storage/uploads` fisicamente e `/storage` na URL.
- **Paginação**: É **PROIBIDO** o uso de `Illuminate\Pagination` ou `$query->paginate()`. A paginação deve ser sempre implementada **manualmente** utilizando `$query->skip()->take()->get()` e calculando os offsets.
- **Execução de Comandos**: A IA tem permissão total para executar comandos `php` e `docker` diretamente no container para agilizar o desenvolvimento. É **OBRIGATÓRIO** que a IA execute o comando `.\sys.ps1 check` de forma autônoma após qualquer alteração significativa para validar o Lint e os Testes, sem necessidade de solicitação do usuário.
- **Autonomia de Validação**: A IA deve agir como um programador sênior, corrigindo proativamente erros de formatação (`.\sys.ps1 fix`) e falhas em testes antes de entregar a tarefa.
- **Responda em Português**.
- **Use Bootstrap Icons** (classes `bi-*`). É estritamente PROIBIDO o uso de outros ícones como `fas`, `fa`, `far` (FontAwesome) ou Material Icons.
- **DataTables**: Use sempre a **Versão COMPLETA** do DataTables.js (baseada em jQuery). O uso de `simple-datatables` é **PROIBIDO**. A inicialização deve ser feita via jQuery no `{% block scripts %}`.
- **Módulos**: Siga estritamente a estrutura `module.json`.
- **Instalação de Módulos**: É OBRIGATÓRIA a criação do arquivo `.zip` contendo o módulo para permitir sua instalação via upload ou distribuição.
- **Banco de Dados**: Use prefixos nos campos (ex: `users_id`).
- **Multiempresa e Multiusuário**: OBRIGATÓRIO o uso de `idbus` e `iduser` em todas as tabelas para garantir que os dados das empresas não se misturem. Novos módulos devem seguir este critério rigorosamente. **Regra de Acesso Global**: Quando `***_idbus` e `***_iduser` (onde `***` é o prefixo da tabela) em alguma tabela do banco de dados forem `0` e `0`, **OU quando estas colunas NÃO existirem na tabela**, significa que este registro é global e está disponível para qualquer módulo, qualquer empresa (company) e qualquer usuário.
- **Exceção (Listas Globais)**: O módulo `lists` (Países, Estados, Cidades, Atividades) é a única exceção à regra de `idbus`/`iduser`. Novos módulos DEVEM usar estas tabelas globais para dados de localização e ramos de atividade em vez de criar tabelas locais duplicadas.
- **Proibição Alpine.js**: É PROIBIDO o uso de Alpine.js nos selects que utilizam o módulo `globallists` (ex: Estado/Cidade). Use **JavaScript puro (Vanilla JS)** para estas interações. Siga obrigatoriamente o padrão definido em `rules/19_INTEGRACAO_GLOBALLISTS.md`.
- **Padrão de API**: Respostas de API para estas listas DEVEM usar `json_encode($data, JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR)` para garantir a integridade de caracteres acentuados.
- **Padrão de Requisição**: Ao realizar chamadas `fetch` para as APIs do GlobalLists, utilize o padrão de Vanilla JS documentado para garantir o pre-carregamento correto em formulários de edição.
- **Sistema de Temas**: Sempre que houver uma alteração visual solicitada pelo usuário, verifique se o tema ativo possui um override para a view em questão antes de editar o módulo base. Use `THEMES_MANUAL.md` como referência técnica.
- **Customizer**: Novos temas DEVEM incluir um arquivo `customizer.json` para permitir a personalização de cores e layouts via painel administrativo.
- **Proibição DB (Novos Módulos)**: Ao criar novos módulos, a IA é PROIBIDA de alterar a ESTRUTURA (schema) de tabelas existentes. Inserção de registros (INSERT) é permitida.
- **Sistema de Comentários**: Todo módulo que implemente comentários deve seguir o padrão do módulo **Blog**:
- Validação de permissão (`allow_comments`).
- Captcha para usuários não logados (usando Alpine.js).
- Redirecionamento com parâmetros de query para erros (ex: `?error=comments_disabled`).
- Suporte a multi-idioma (5 idiomas padrão).
Cabeçalho nos scripts:
/**
* SysCMS - Content Management System
*
* Copyright (c) 2025 Marco Costa
* All rights reserved.
*
* Author: Marco Costa
* Email: contato@syspanel.com.br
* Project: SysCMS
*
* This software is licensed, not sold.
* Permission is granted to use this software
* subject to the terms of the SysCMS Commercial License.
*
* Redistribution, sublicensing, resale, or
* disclosure of this software, in whole or in part,
* is strictly prohibited without prior written permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.
*/