# SWMVC Framework — Manual Técnico da Arquitetura & Guia Extensível (Humanos & IA)

O **SWMVC** é um microframework autoral em PHP 8.3 + MySQL 8.0, desenvolvido pela Sanweb para servir como base de código (starter kit / boilerplate) para aplicações web, sites institucionais, blogs, plataformas e e-commerces.

Este manual foi desenhado para ser **compreendido perfeitamente tanto por desenvolvedores humanos quanto por Inteligências Artificiais / Agentes**, garantindo que qualquer nova I.A. possa ler este documento e continuar desenvolvendo módulos no admin ou no site público com 100% de consistência.

---

## 🏛️ 1. Filosofia & Recursos Nativos (O que o SWMVC faz)

O framework resolve de forma nativa e encapsulada os principais pilares de uma aplicação web:

1. **Roteamento Dinâmico (`sis/Core/Router.php`)**:
   - Suporte a verbos HTTP (`get`, `post`, `put`, `delete`).
   - Agrupamento de rotas (`Router::grupo('/admin', ...)`).
   - Middlewares dinâmicos (`['auth']`, `['admin']`).
   - Parâmetros命名ados na URL (`/:id`, `/:slug`).
2. **Camada de Visão & Layouts (`sis/Core/View.php`)**:
   - Motor de templates PHP nativo ultraveloz.
   - Herança de layout principal via `View::layout('admin/layouts/app', [...])`.
   - Escape de variáveis contra XSS via `View::e()`.
   - Helper de formação de datas via `View::data()`.
3. **QueryBuilder Flutuante (`sis/Core/QueryBuilder.php`)**:
   - Interface fluente contra SQL Injection (`QB::tabela('users')->where('status', 'A')->buscar()`).
   - Suporte nativo a paginação (`paginar(15)`).
   - Suporte a Soft-Deletes (`whereNull('deleted_at')`, `whereNotNull('deleted_at')`).
4. **Matriz Dinâmica de Permissões (RBAC) (`sis/Auth/RBAC.php`)**:
   - 4 papéis nativos: `admin`, `gerente`, `editor`, `usuario`.
   - Verificação em 2 níveis: `RBAC::pode('modulo.acao')` no controller/view e `RBAC::ehNivel('admin')`.
   - Tabela `permissoes_papeis` editável via painel `/admin/permissoes`.
5. **Galeria Central de Mídias & Uploads (`sis/Utils/Upload.php`)**:
   - Processamento de imagens em WebP + pipeline obrigatório de thumbnails.
   - Organização relacional polimórfica via tabela `imgs` (`ref_id`, `local`, `tipo`).
6. **Sistema de Log & Observabilidade (`sis/Utils/Logger.php`)**:
   - Registro estruturado em banco de dados (`logs`) com níveis (info, erro, alerta, debug) e dados em JSON.

---

## 📁 2. Árvore de Diretórios Canonical

```
swmvc/
├── app/                        # Regras de Negócio e Aplicação
│   ├── Controllers/
│   │   ├── Admin/              # Controladores do Painel Administrativo
│   │   └── Site/               # Controladores da Área Pública / Front-end
│   ├── Database/
│   │   └── schema_completo.sql # Banco de dados unificado completo (Tabelas + Seeds)
│   ├── Models/                 # Entidades e regras de banco (Product, Post, User, etc.)
│   ├── Routes/
│   │   ├── admin.php           # Definição das rotas /admin
│   │   └── web.php             # Definição das rotas públicas /site
│   └── Views/
│       ├── admin/              # Views do Painel (layouts, partials, módulos)
│       └── site/               # Views públicas do site
├── sis/                        # Núcleo / Core do Framework (Router, View, QB, Auth, RBAC)
├── public/                     # DocumentRoot (index.php, CSS, JS, uploads)
│   ├── assets/
│   │   ├── css/pages/          # CSS específico por módulo (ex: permissoes.css, posts.css)
│   │   └── js/pages/           # JS específico por módulo (ex: permissoes.js, dashboard.js)
│   └── storage/uploads/        # Imagens e arquivos enviados pelos usuários
├── .env                        # Configurações de ambiente e credenciais de banco
├── install.php                 # Instalador e inicializador automatizado CLI
└── DOCUMENTACAO_MODULOS.md     # Este manual técnico
```

---

## 🚀 3. Guia de Instalação e Inicialização Rápida

Para subir o projeto em um novo ambiente ou criar uma nova instância:

1. Edite as credenciais do MySQL no arquivo `.env`:
   ```env
   DB_HOST=127.0.0.1
   DB_PORT=3306
   DB_NAME=meu_novo_banco
   DB_USER=root
   DB_PASS=minha_senha
   ```
2. Execute o instalador CLI no terminal:
   ```bash
   php install.php
   ```
   *O `install.php` criará o banco MySQL, importará o `schema_completo.sql`, criará o usuário admin padrão (`admin@admin.com` / `Admin2026!`) e preparará todas as pastas de upload.*

---

## 🛠️ 4. Guia Passo a Passo: Como Criar Novas Áreas no ADMIN (Para Humanos & IA)

Sempre que precisar adicionar uma nova funcionalidade no Painel Administrativo (exemplo: **Banners**):

### Passo 1: Criar a Tabela no Banco (`app/Database/schema_completo.sql`)
```sql
CREATE TABLE IF NOT EXISTS banners (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    titulo VARCHAR(150) NOT NULL,
    img VARCHAR(255) NOT NULL,
    status CHAR(1) NOT NULL DEFAULT 'A',
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    deleted_at DATETIME DEFAULT NULL,
    INDEX idx_status (status),
    INDEX idx_deleted (deleted_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
```

### Passo 2: Criar o Model (`app/Models/Banner.php`)
```php
<?php
namespace App\Models;

use SW\Core\QueryBuilder as QB;

class Banner
{
    public static function listarAtivos(): array
    {
        return QB::tabela('banners')
            ->whereNull('deleted_at')
            ->where('status', 'A')
            ->orderBy('id', 'DESC')
            ->buscar();
    }
}
```

### Passo 3: Criar o Controller (`app/Controllers/Admin/BannerController.php`)
> **Regra Obrigatória**: Todo controller do admin DEVE chamar `RBAC::requerPermissao('modulo.acao')` no início dos seus métodos.

```php
<?php
namespace App\Controllers\Admin;

use SW\Core\Controller;
use SW\Core\View;
use SW\Auth\RBAC;
use App\Models\Banner;

class BannerController extends Controller
{
    public function index(): void
    {
        RBAC::requerPermissao('banners.ver');
        $banners = Banner::listarAtivos();
        
        View::renderizar('admin/banners/index', [
            'banners' => $banners
        ]);
    }
}
```

### Passo 4: Registrar as Rotas (`app/Routes/admin.php`)
```php
Router::grupo('/banners', function () {
    Router::get('', 'Admin\BannerController@index');
    Router::post('', 'Admin\BannerController@salvar');
}, ['auth']);
```

### Passo 5: Criar a View (`app/Views/admin/banners/index.php`)
> **Regra de Design System**: Siga o padrão do cabeçalho admin (`page-header-admin`, `page-title`, `page-subtitle`).

```php
<?php
use SW\Core\View;
View::layout('admin/layouts/app', ['titulo' => 'Gerenciar Banners']);
?>
<link rel="stylesheet" href="/assets/css/pages/banners.css">

<div class="flx alc j-sb mb-m page-header-admin">
    <div>
        <h1 class="page-title">Banners</h1>
        <p class="page-subtitle">Gerencie os destaques visuais do site</p>
    </div>
</div>

<div sw-card>
    <!-- Tabela ou Conteúdo -->
</div>
```

### Passo 6: Registrar no Menu Lateral (`app/Views/admin/_partials/sidebar.php`)
```php
<?php if (RBAC::pode('banners.ver')): ?>
<a sw-sidebar-it <?= navActive('/admin/banners', $uri) ? 'act' : '' ?> href="/admin/banners">
    <i class="swi-image"></i>
    <span sw-sidebar-lbl>Banners</span>
</a>
<?php endif; ?>
```

---

## 🌐 5. Guia Passo a Passo: Como Criar Novas Áreas no SITE PÚBLICO (Front-End)

Para criar uma nova página pública no site (ex: página `/sobre` ou `/catalogo`):

### Passo 1: Criar o Controller (`app/Controllers/Site/SobreController.php`)
```php
<?php
namespace App\Controllers\Site;

use SW\Core\Controller;
use SW\Core\View;
use App\Models\Config;

class SobreController extends Controller
{
    public function index(): void
    {
        $configs = Config::todas();
        
        View::renderizar('site/sobre/index', [
            'titulo'  => 'Sobre Nós — ' . ($configs['site_titulo'] ?? 'SWMVC'),
            'configs' => $configs
        ]);
    }
}
```

### Passo 2: Registrar a Rota Pública (`app/Routes/web.php`)
```php
Router::get('/sobre', 'Site\SobreController@index');
```

### Passo 3: Criar a View Pública (`app/Views/site/sobre/index.php`)
```php
<?php
use SW\Core\View;
View::layout('site/layouts/app', ['titulo' => $titulo]);
?>

<section class="container py-g">
    <h1>Sobre a Empresa</h1>
    <p><?= View::e($configs['empresa_nome'] ?? '') ?></p>
</section>
```

---

## 🎨 6. Diretrizes Obrigatórias de Estilo e UX (SW Design System)

1. **Variáveis CSS de Tema**: Utilize sempre as variáveis de cor globais `--sw-pri` (primária), `--sw-sec` (secundária), `--sw-txt-bas` (texto principal), `--sw-txt-mut` (texto escuro/suave), `--sw-bg-sec` (fundo de cartões/tabelas) e `--sw-bor` (bordas).
2. **Cabeçalho Único**: Nenhuma página deve ter títulos em tamanhos desproporcionais. Use a classe `.page-title` (2rem, font-weight 800).
3. **Sem Paginação Forçada em Tabelas Pequenas**: Se a tabela for de configuração ou matriz fixa, use o atributo `data-pagination-disabled` na tag `<table>` para evitar que o JS global adicione barra de paginação indesejada.
