# Instalação — Professor API

Guia para colocar o projeto rodando em uma máquina nova, a partir do `git clone`.

## 1. Pré-requisitos

- PHP 8.3+ com extensões: `pdo_pgsql`, `pgsql`, `mbstring`, `ctype`, `openssl`, `tokenizer`, `xml`, `bcmath`
- Composer 2.x
- Node.js 18+ e npm
- PostgreSQL 13+ (dois bancos: um central e um por tenant)
- Git

## 2. Clonar o repositório

```bash
git clone <url-do-repositorio>
cd laravel-multitenant-api
```

## 3. Instalar dependências PHP

```bash
composer install
```

## 4. Configurar o ambiente

```bash
cp .env.example .env
php artisan key:generate
```

Edite o `.env` e ajuste pelo menos:

- `APP_URL`
- `DB_CENTRAL_HOST`, `DB_CENTRAL_PORT`, `DB_CENTRAL_DATABASE`, `DB_CENTRAL_USERNAME`, `DB_CENTRAL_PASSWORD` (banco central/landlord)
- `DB_HOST`, `DB_PORT`, `DB_DATABASE`, `DB_USERNAME`, `DB_PASSWORD` (conexão padrão de tenant, usada como template)

## 5. Criar os bancos de dados no PostgreSQL

O projeto força charset **Latin-1 (ISO-8859-1)** em todas as conexões (`config/database.php` e `config/multitenancy.php`). O PostgreSQL só permite criar um banco em Latin-1 a partir do `template0`, com locale compatível (`C`). Crie o banco central e o(s) banco(s) de tenant assim:

```bash
createdb --encoding=LATIN1 --template=template0 --lc-collate=C --lc-ctype=C central_db
createdb --encoding=LATIN1 --template=template0 --lc-collate=C --lc-ctype=C forge   # ou o nome definido em DB_DATABASE
```

Ajuste usuário/host conforme necessário (`-U`, `-h`, `-p`).

## 6. Rodar as migrations

Central e tenant têm pastas de migrations **separadas** (`database/central/migrations` e `database/tenant/migrations`) e vivem em bancos diferentes. Sempre informe `--database` **e** `--path` — sem `--path` o Artisan também tentaria carregar `database/migrations` (vazio) e migrations de pacotes vendor publicadas nesse caminho, o que pode gerar erros de tabela duplicada.

```bash
# Banco central (tabela de tenants)
php artisan migrate --database=central --path=database/central/migrations --force

# Banco de tenant "template" (definido no .env)
php artisan migrate --database=tenant --path=database/tenant/migrations --force
```

> Alternativamente, `composer run setup` executa em sequência: `composer install`, cópia do `.env`, `key:generate` e as duas migrations acima.

Outros comandos úteis (sempre com `--database` e `--path`):

```bash
# Ver quais migrations já rodaram / faltam rodar
php artisan migrate:status --database=tenant --path=database/tenant/migrations
php artisan migrate:status --database=central --path=database/central/migrations

# Desfazer o último lote de migrations
php artisan migrate:rollback --database=tenant --path=database/tenant/migrations
php artisan migrate:rollback --database=central --path=database/central/migrations
```

O nome da tabela de controle de migrations é `api_migrations` (configurado em `config/database.php`), não a `migrations` padrão do Laravel — isso é o esperado nesse projeto.

## 7. Novo cliente:
Após adiciona uma nova cidade na tabela `tenants` do banco `central` executar o comando para executar as migrations:

```bash
php artisan tenants:migrate {id_do_tenant}
```

## 8. Instalar dependências JS e compilar assets

```bash
npm install
npm run build
```

## 9. Cadastrar um tenant

Não há endpoint de cadastro de tenant; a tabela `tenants` (banco central) precisa ser populada manualmente, por exemplo via Tinker:

```bash
php artisan tinker
```

```php
App\Models\Central\Tenant::on('central')->create([
    'id' => 'cliente1',
    'name' => 'Cliente 1',
    'domain' => 'cliente1.localhost',
    'db_host' => '127.0.0.1',
    'db_port' => 5432,
    'db_database' => 'cliente1_db',
    'db_username' => 'postgres',
    'db_password' => 'secret',
]);
```

Crie o banco de dados correspondente (`cliente1_db`, mesmo procedimento do passo 5) e depois rode as migrations de todos os tenants cadastrados (o comando `tenants:migrate` não existe; o pacote `spatie/laravel-multitenancy` expõe `tenants:artisan` para rodar qualquer comando artisan em todos os tenants):

```bash
php artisan tenants:artisan "migrate --database=tenant --path=database/tenant/migrations --force"
```

## 10. Subir a aplicação

```bash
composer run dev
```

Isso inicia em paralelo: `php artisan serve`, `queue:listen`, `php artisan pail` (logs) e `vite` (assets).

Ou, individualmente:

```bash
php artisan serve
```

## 11. Verificar a instalação

```bash
curl http://localhost:8080/up
```

As rotas de autenticação exigem o header de identificação do tenant:

```bash
curl -X POST http://localhost:8080/api/v1/login \
  -H "X-Tenant-ID: cliente1" \
  -H "Content-Type: application/json" \
  -d '{"login":"teste","senha":"password"}'
```

## 12. Troubleshooting

**`SQLSTATE[42P07]: Duplicate table: ... relation "personal_access_tokens" already exists`**

Ocorre ao rodar `migrate --database=tenant` num tenant que já possui essa tabela (por exemplo, bancos provisionados a partir de um template/dump que já incluía o schema do Sanctum). A migration `database/tenant/migrations/*_create_personal_access_tokens_table.php` já verifica `Schema::connection('tenant')->hasTable(...)` antes de criar, então basta rodar a migration novamente — ela vai pular a criação e apenas registrar o migration como executado em `api_migrations`.

**Erro genérico ao rodar qualquer comando `artisan`**

Se o erro apontar para `app/Providers/AppServiceProvider.php`, o `boot()` desse provider roda em toda invocação do Artisan — um método inexistente ou mal chamado ali quebra `migrate`, `tinker`, `serve`, etc. simultaneamente. Confira esse arquivo primeiro.
