# HostControl API - Design Specification

## Visão Geral

Sistema de gerenciamento de assinaturas de hospedagem para aplicações Laravel/Filament. Uma API central cadastra clientes, aplicações e assinaturas. Cada aplicação Filament consome a API via HTTP para exibir débitos e permitir pagamentos.

**Objetivo:** Controle de mensalidades de hospedagem dos clientes que utilizam o servidor.

---

## Stack

- **Backend:** Laravel 10 + PHP 8.1+
- **Autenticação:** Laravel Sanctum (API Keys)
- **Banco:** MySQL 8+ ou MariaDB
- **HTTP Client:** Guzzle (para consumidores da API)

---

## Estrutura de Pastas

```
hostcontrol/
├── app/
│   ├── Http/
│   │   ├── Controllers/
│   │   │   └── Api/
│   │   │       ├── ClientController.php
│   │   │       ├── ApplicationController.php
│   │   │       ├── SubscriptionController.php
│   │   │       ├── PaymentController.php
│   │   │       └── HeartbeatController.php
│   │   ├── Middleware/
│   │   │   └── AuthenticateApiKey.php
│   │   └── Requests/
│   │       ├── StoreClientRequest.php
│   │       ├── StoreSubscriptionRequest.php
│   │       └── ...
│   ├── Models/
│   │   ├── Client.php
│   │   ├── Application.php
│   │   ├── Subscription.php
│   │   ├── Payment.php
│   │   └── Heartbeat.php
│   └── Services/
│       └── PaymentGatewayInterface.php
├── database/
│   └── migrations/
├── routes/
│   └── api.php
└── config/
    └── hostcontrol.php
```

---

## Database Schema

### clients

| Coluna     | Tipo         | Descrição                    |
|------------|--------------|------------------------------|
| id         | bigint (pk)  | Auto increment               |
| name       | string       | Nome do cliente              |
| email      | string       | Email único                  |
| phone      | string       | Telefone (nullable)          |
| document   | string       | CPF/CNPJ (nullable)          |
| created_at | timestamp    |                              |
| updated_at | timestamp    |                              |

### applications

| Coluna      | Tipo         | Descrição                    |
|-------------|--------------|------------------------------|
| id          | bigint (pk)  | Auto increment               |
| client_id   | foreign key  | references clients.id        |
| name        | string       | Nome da aplicação            |
| domain      | string       | Domínio da aplicação         |
| repository  | string       | Repositório git (nullable)   |
| server      | string       | Servidor (nullable)          |
| status      | enum         | active, inactive             |
| created_at  | timestamp    |                              |
| updated_at  | timestamp    |                              |

### subscriptions

| Coluna        | Tipo         | Descrição                    |
|---------------|--------------|------------------------------|
| id            | bigint (pk)  | Auto increment               |
| client_id     | foreign key  | references clients.id        |
| application_id| foreign key  | references applications.id   |
| status        | enum         | active, inactive, suspended, cancelled |
| monthly_price | decimal(10,2)| Preço mensal                 |
| paid_until    | date         | Pago até (data)              |
| next_due      | date         | Próximo vencimento           |
| license_key   | string       | Chave de licença única (gerada pelo sistema) |
| grace_until   | date         | Período de carência (nullable)|
| created_at    | timestamp    |                              |
| updated_at    | timestamp    |                              |

### payments

| Coluna         | Tipo         | Descrição                    |
|----------------|--------------|------------------------------|
| id             | bigint (pk)  | Auto increment               |
| subscription_id| foreign key  | references subscriptions.id  |
| value          | decimal(10,2)| Valor pago                   |
| paid_at        | datetime     | Data do pagamento (nullable) |
| status         | enum         | pending, paid, failed, refunded |
| gateway_id     | string       | ID no gateway (nullable)     |
| gateway_data   | json         | Dados extras do gateway (nullable) |
| created_at     | timestamp    |                              |
| updated_at     | timestamp    |                              |

### heartbeats

| Coluna         | Tipo         | Descrição                    |
|----------------|--------------|------------------------------|
| id             | bigint (pk)  | Auto increment               |
| subscription_id| foreign key  | references subscriptions.id  |
| ip_address     | string       | IP de onde veio o ping       |
| pinged_at      | datetime     | Data/hora do ping            |

> **Nota:** Heartbeats não usa timestamps do Laravel ($timestamps = false).

---

## Autenticação

> **Revisão (2026-08-26):** a autenticação de aplicações clientes migrou de `clients.api_key` (escopo por cliente) para `subscriptions.license_key` (escopo por assinatura). Cada aplicação cliente possui uma subscription e autentica com a própria license_key.

### Geração de License Key

Quando uma subscription é criada, uma `license_key` é gerada automaticamente:

```php
$subscription->license_key = 'hcl_' . bin2hex(random_bytes(32));
```

- Única (unique index) e sempre visível nas respostas da API (store e show).
- Não é aceita como input no create/update — apenas o sistema gera.

### Middleware `AuthenticateLicenseKey`

O middleware verifica o header `X-License-Key`:

```php
// Request header esperado:
// X-License-Key: hcl_xxxxx...
```

**Fluxo:**
1. Busca a Subscription pela `license_key` fornecida
2. Se não encontrar → retorna 401 Unauthorized
3. Se encontrar → injeta a Subscription no request como `$request->subscription`
4. Todos os endpoints de escopo cliente operam sobre essa subscription (payments/me, heartbeats, etc.)

### Rotas Protegidas

As rotas de escopo de aplicação usam o middleware `license_key`; rotas administrativas usam `admin_token` (header `X-Admin-Token`).

---

## Endpoints da API

Base URL: `https://sua-api.com/api/v1`

### Clients

| Método  | Endpoint           | Descrição                  |
|---------|--------------------|-----------------------------|
| GET     | /clients           | Listar clientes             |
| POST    | /clients           | Criar cliente               |
| GET     | /clients/{id}      | Detalhes do cliente         |
| PUT     | /clients/{id}      | Atualizar cliente           |
| DELETE  | /clients/{id}      | Remover cliente             |

### Applications

| Método  | Endpoint                      | Descrição                  |
|---------|-------------------------------|-----------------------------|
| GET     | /applications                 | Listar aplicações           |
| POST    | /applications                 | Criar aplicação             |
| GET     | /applications/{id}            | Detalhes da aplicação       |
| PUT     | /applications/{id}            | Atualizar aplicação         |
| DELETE  | /applications/{id}            | Remover aplicação           |

### Subscriptions

| Método  | Endpoint                          | Descrição                  |
|---------|-----------------------------------|-----------------------------|
| GET     | /subscriptions                    | Listar assinaturas          |
| POST    | /subscriptions                    | Criar assinatura            |
| GET     | /subscriptions/{id}               | Detalhes da assinatura      |
| PUT     | /subscriptions/{id}               | Atualizar assinatura        |
| DELETE  | /subscriptions/{id}               | Remover assinatura          |
| GET     | /subscriptions/{id}/payments      | Pagamentos da assinatura    |

### Payments

| Método  | Endpoint               | Descrição                  |
|---------|------------------------|-----------------------------|
| GET     | /payments              | Listar pagamentos           |
| POST    | /payments              | Criar registro de pagamento |
| GET     | /payments/{id}         | Detalhes do pagamento       |

### Heartbeats

| Método  | Endpoint               | Descrição                  |
|---------|------------------------|-----------------------------|
| POST    | /heartbeats            | Registrar heartbeat (ping)  |

---

## Exemplos de Request/Response

### POST /api/v1/clients

**Request:**
```json
{
    "name": "João da Silva",
    "email": "joao@exemplo.com",
    "phone": "(11) 99999-9999",
    "document": "123.456.789-00"
}
```

**Response (201):**
```json
{
    "data": {
        "id": 1,
        "name": "João da Silva",
        "email": "joao@exemplo.com",
        "phone": "(11) 99999-9999",
        "document": "123.456.789-00",
        "created_at": "2026-08-24T10:00:00Z"
    }
}
```

### GET /api/v1/subscriptions?client_id=1

**Response (200):**
```json
{
    "data": [
        {
            "id": 1,
            "client_id": 1,
            "application_id": 1,
            "status": "active",
            "monthly_price": 150.00,
            "paid_until": "2026-09-24",
            "next_due": "2026-10-24",
            "application": {
                "id": 1,
                "name": "Sistema de Pedidos",
                "domain": "pedidos.cliente.com"
            }
        }
    ]
}
```

---

## Endpoints para Consumidores (Lado Filament)

Para a aplicação Filament do cliente consumir a API, são necessários estes endpoints (já inclusos acima):

1. **Listar assinaturas do cliente** → `GET /subscriptions?client_id={id}`
2. **Listar pagamentos** → `GET /payments?subscription_id={id}`
3. **Verificar status** → `GET /subscriptions/{id}`

### Exemplo de Consumo via Guzzle (no lado Filament)

```php
use Illuminate\Support\Facades\Http;

$response = Http::withHeaders([
    'X-License-Key' => config('hostcontrol.license_key'),
    'Accept' => 'application/json',
])->get(config('hostcontrol.api_url') . '/api/v1/subscriptions');

$subscription = $response->json('data');
```

---

## Configuração

Arquivo `config/hostcontrol.php`:

```php
return [
    'api_url' => env('HOSTCONTROL_API_URL', 'http://localhost:8000/api/v1'),
    'license_key' => env('HOSTCONTROL_LICENSE_KEY', ''),
];
```

---

## Webhooks de Pagamento

### Endpoint para Webhook

| Método | Endpoint              | Descrição                    |
|--------|-----------------------|------------------------------|
| POST   | /webhooks/payment     | Receber notificação gateway  |

O webhook deve:
1. Validar a assinatura do gateway (segurança)
2. Atualizar o status do pagamento
3. Atualizar `paid_until` da assinatura se pago

> **Nota:** A implementação específica do gateway fica para quando integrar os serviços de pagamento.

---

## Módulos de Implementação (Ordem Sugerida)

### Módulo 1: Setup Inicial
- Criar projeto Laravel 10
- Instalar Sanctum
- Configurar migrations
- Configurar `.env`

### Módulo 2: Clients
- Model Client
- Migration clients
- Controller + Rotas CRUD
- Middleware de autenticação
- Seeders de teste

### Módulo 3: Applications
- Model Application
- Migration applications
- Controller + Rotas CRUD
- Relacionamento com Client

### Módulo 4: Subscriptions
- Model Subscription
- Migration subscriptions
- Controller + Rotas CRUD
- Relacionamento com Client e Application

### Módulo 5: Payments
- Model Payment
- Migration payments
- Controller + Rotas CRUD
- Relacionamento com Subscription

### Módulo 6: Heartbeats
- Model Heartbeat
- Migration heartbeats
- Controller para registrar ping

### Módulo 7: Webhooks
- Endpoint para receber webhook de pagamento
- Validação de assinatura
- Atualização de status

### Módulo 8: Documentação
- README com instruções de instalação
- Exemplos de uso da API
- Configuração para consumidores Filament

---

## Regras de Negócio

1. Uma assinatura pertence a um cliente e uma aplicação
2. Uma aplicação pode ter múltiplas assinaturas (ex: planos diferentes)
3. O `paid_until` é atualizado quando um pagamento é confirmado
4. O `grace_until` define um período de tolerância após o vencimento
5. Heartbeats são pings periódicos das aplicações para verificar se estão ativas
6. A `license_key` é única, intransferível e gerada apenas pelo sistema (nunca via input)

---

## Prioridades

- **P0 (Must Have):** Clients, Subscriptions, Payments, Autenticação
- **P1 (Should Have):** Applications, Heartbeats
- **P2 (Nice to Have):** Webhooks, Relatórios

---

## Fora do Escopo (por enquanto)

- Interface de administração web (Filament) para o hostcontrol
- Integração com gateways de pagamento específicos
- Sistema de notificações por email
- Dashboard com métricas
