15.4 Documentação
O que é
Tipos de documentação:
1. Code comments (comentários no código)
2. API documentation (Swagger/OpenAPI)
3. README (visão geral do projeto)
4. Technical documentation (arquitetura)
5. User documentation (para usuários)Comentários no código
Quando comentar:
✅ BOM: explicar o "porquê"
// Hash MD5 por compatibilidade com a API legacy
// TODO: migrar para bcrypt na v2.0
$hash = md5($password);
// Workaround para bug no PHP 8.0 (https://bugs.php.net/bug.php?id=12345)
if (version_compare(PHP_VERSION, '8.0', '>=')) {
// código alternativo
}
// Regra de negócio: 10% de desconto para clientes VIP em pedidos > R$ 100
if ($user->isVip() && $order->total > 100) {
$discount = 0.10;
}❌ RUIM: comentar o óbvio
// Buscar o usuário pelo ID
$user = User::find($id);
// Definir o nome
$user->name = $name;
// Salvar o usuário
$user->save();✅ MELHOR: código autoexplicativo
function applyVipDiscount(Order $order, User $user): void
{
if ($user->isVip() && $order->exceedsMinimumForDiscount()) {
$order->applyDiscount(self::VIP_DISCOUNT_PERCENTAGE);
}
}PHPDoc
Para classes:
/**
* Service para processar pagamentos de usuários
*
* Processa pagamento em vários gateways
* (Stripe, PayPal), com retry automático e detecção de fraude.
*
* @package App\Services
* @author John Doe <john@example.com>
*/
class PaymentService
{
// ...
}Para métodos:
/**
* Processa o pagamento de um pedido
*
* Cobra o meio de pagamento do cliente e cria o registro
* no banco. Se falhar, tenta de novo até 3 vezes com exponential backoff.
*
* @param Order $order Pedido a ser cobrado
* @param PaymentMethod $method Meio de pagamento do cliente
* @return Payment Registro do pagamento criado
*
* @throws PaymentFailedException Se o pagamento falhar depois de todas as tentativas
* @throws InsufficientFundsException Se o cliente não tiver saldo
*
* @example
* $payment = $paymentService->processPayment($order, $card);
*/
public function processPayment(Order $order, PaymentMethod $method): Payment
{
// ...
}Para parâmetros complexos:
/**
* Cria um usuário com dados extras
*
* @param array $data Dados do usuário
* @param array $data['name'] string Nome completo
* @param array $data['email'] string Email do usuário
* @param array $data['roles'] array<string> Array opcional de nomes de role
* @param array $data['profile'] array Dados opcionais de perfil
* @param array $data['profile']['avatar'] string URL opcional do avatar
*
* @return User
*/
public function createUser(array $data): User
{
// ...
}Documentação de API
OpenAPI (Swagger):
/**
* @OA\Get(
* path="/api/users/{id}",
* summary="Buscar usuário por ID",
* tags={"Users"},
* @OA\Parameter(
* name="id",
* in="path",
* required=true,
* @OA\Schema(type="integer")
* ),
* @OA\Response(
* response=200,
* description="Sucesso",
* @OA\JsonContent(ref="#/components/schemas/User")
* ),
* @OA\Response(
* response=404,
* description="Usuário não encontrado"
* )
* )
*/
public function show(int $id)
{
return User::findOrFail($id);
}Laravel API Resources (alternativa):
// app/Http/Resources/UserResource.php
/**
* Representação do resource de usuário
*
* @property int $id ID do usuário
* @property string $name Nome completo
* @property string $email Email do usuário
* @property Carbon $created_at Data de criação da conta
*/
class UserResource extends JsonResource
{
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
'created_at' => $this->created_at->toIso8601String(),
];
}
}README.md
Estrutura:
# Nome do projeto
Descrição curta do que o projeto faz.
## Features
- Autenticação de usuários
- Processamento de pagamentos
- Notificações em tempo real
- Dashboard admin
## Requirements
- PHP 8.2+
- MySQL 8.0+
- Redis 6.0+
- Node.js 18+
## Installation
```bash
# Clonar o repositório
git clone https://github.com/user/project.git
cd project
# Instalar dependências
composer install
npm install
# Configurar o ambiente
cp .env.example .env
php artisan key:generate
# Configurar o banco
php artisan migrate --seed
# Build dos assets
npm run buildConfiguration
Database
Edite o .env:
DB_HOST=localhost
DB_DATABASE=myapp
DB_USERNAME=root
DB_PASSWORD=secretQueue
php artisan queue:workUsage
Rodar local
php artisan serve
npm run devAcesse http://localhost:8000
Rodar testes
php artisan testAPI Documentation
Docs da API em: http://localhost:8000/api/documentation
Contributing
- Faça fork do repositório
- Crie a feature branch (
git checkout -b feature/amazing) - Faça commit (
git commit -m 'Adiciona feature incrível') - Dê push na branch (
git push origin feature/amazing) - Abra o Pull Request
License
MIT License
---
## Documentação técnica
**Visão da arquitetura:**
```markdown
# Architecture
## Overview
A app segue uma arquitetura em camadas:┌─────────────────────────────────┐ │ Controllers │ ├─────────────────────────────────┤ │ Services │ ├─────────────────────────────────┤ │ Repositories │ ├─────────────────────────────────┤ │ Models │ └─────────────────────────────────┘
## Layers
### Controllers
Recebem o HTTP request, validam o input, devolvem o response.
Fica em: `app/Http/Controllers`
### Services
Guardam a regra de negócio, orquestram as operações.
Fica em: `app/Services`
### Repositories
Abstraem o acesso ao banco, implementam as queries.
Fica em: `app/Repositories`
### Models
Models Eloquent que representam as tabelas.
Fica em: `app/Models`
## Key Components
### Payment Processing
Fica no `PaymentService`, que cobre:
- Integração Stripe
- Integração PayPal
- Retry (3 tentativas)
- Tratamento de webhook
### Notification System
Usa Laravel Notifications com os canais:
- Email (via queue)
- SMS (via Twilio)
- Push notifications (via FCM)
### Caching Strategy
- Dados do usuário: 1 hora
- Catálogo de produtos: 24 horas
- Configuração: até o deploySchema do banco
Documentando migrations:
/**
* Cria a tabela users
*
* Guarda conta do usuário: credenciais de autenticação
* e dados de perfil. Tabelas relacionadas: orders, posts, comments.
*/
class CreateUsersTable extends Migration
{
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique(); // Usado no login
$table->timestamp('email_verified_at')->nullable(); // Confirmação de email
$table->string('password'); // Hash com bcrypt
$table->enum('role', ['user', 'admin'])->default('user'); // Controle de acesso
$table->rememberToken(); // Funcionalidade "lembrar de mim"
$table->timestamps();
$table->softDeletes(); // Suporte a soft delete
// Indexes
$table->index('email'); // Acelera as queries de login
$table->index(['role', 'created_at']); // Filtros do admin
});
}
}ADR (Architecture Decision Records)
Formato:
# ADR-001: Usar Redis para session storage
## Status
Accepted
## Context
Precisamos escalar na horizontal com vários app servers.
Sessão em arquivo não funciona entre servers.
## Decision
Usar Redis para session storage.
## Consequences
### Positive
- Sessão compartilhada entre todos os servers
- Leitura e escrita rápidas
- Dá para persistir a sessão
### Negative
- Dependência a mais (Redis)
- Setup um pouco mais complexo
- Precisa monitorar se o Redis está no ar
## Alternatives Considered
1. **Database sessions**
- Pros: o banco já existe
- Cons: mais lento que Redis
2. **Sticky sessions**
- Pros: não muda nada
- Cons: carga desigual
## Implementation
```php
// config/session.php
'driver' => 'redis',
'connection' => 'session',Date
2024-01-15
---
## Changelog
**Formato:**
```markdown
# Changelog
Todas as mudanças relevantes deste projeto ficam neste arquivo.
## [1.2.0] - 2024-01-15
### Added
- Autenticação em dois fatores para usuários
- Exportar pedidos para CSV
- Tema dark mode
### Changed
- Pagamento passou a usar Stripe API v2
- Dashboard carrega 5x mais rápido
### Fixed
- Memory leak no queue worker
- XSS no sistema de comentários
### Security
- Dependências atualizadas com patches de segurança
## [1.1.0] - 2023-12-20
### Added
- Notificações por email quando o status do pedido muda
### Fixed
- Bug no fluxo de reset de senhaDicas práticas
Para que NÃO serve comentário:
// ❌ Repetir o código
// Buscar todos os usuários
$users = User::all();
// ❌ Código comentado
// $oldImplementation = doSomething();
$newImplementation = doSomethingBetter();
// ❌ Óbvio
// Percorrer os usuários
foreach ($users as $user) {
// ...
}Onde o comentário faz falta:
// ✅ Lógica não óbvia
// Imposto: 20% na UE, 0% fora da UE
$vat = $country->isEU() ? 0.20 : 0.00;
// ✅ TODO/FIXME
// TODO: refatorar para o pattern Strategy
// FIXME: memory leak ao processar arquivos grandes
// ✅ Workarounds
// Hack: o Safari não suporta essa propriedade CSS
// Usa polyfill no lugar
// ✅ Regex complexa
// Casa email: user@domain.com, user+tag@domain.co.uk
$pattern = '/^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$/i';Ferramentas
Gerando a documentação:
# PHPDoc
composer require --dev phpdocumentor/phpdocumentor
vendor/bin/phpdoc -d src -t docs
# API docs (Swagger)
composer require darkaonline/l5-swagger
php artisan l5-swagger:generate
# Database schema
composer require --dev beyondcode/laravel-er-diagram-generator
php artisan generate:erdNa entrevista
"Documentação: code comments para o 'porquê', não para o 'o quê'. PHPDoc em classes e métodos com @param, @return, @throws. API documentation com OpenAPI/Swagger ou Laravel API Resources. README com instalação, configuração e exemplos. Documentação de arquitetura descreve camadas e componentes. ADR para decisões de arquitetura. Changelog para versões. Ferramentas: phpdocumentor, l5-swagger. Código autoexplicativo vale mais que comentário."
Parte do PHP/Laravel Interview Handbook | Feito com ❤️ pela equipe CodeMate