- API REST para gestion de facturas electronicas mexicanas (CFDI) - Laravel 9 con autenticacion OAuth 2.0 (Passport) - Integracion con Syntage, Clerk y Facturama - 30 modelos Eloquent, 39 controladores - Documentacion completa en /docs Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
435 lines
15 KiB
Markdown
435 lines
15 KiB
Markdown
# Arquitectura - Horux Backend
|
|
|
|
Documentacion de la arquitectura y diseno del sistema Horux.
|
|
|
|
## Vision General
|
|
|
|
Horux es una API REST que actua como intermediario entre aplicaciones cliente y servicios fiscales mexicanos. La arquitectura sigue el patron MVC de Laravel con una capa de servicios adicional.
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|
│ CLIENTES │
|
|
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
|
|
│ │ Web │ │ Mobile │ │ API │ │
|
|
│ │ App │ │ App │ │ Client │ │
|
|
│ └────┬────┘ └────┬────┘ └────┬────┘ │
|
|
└───────┼────────────┼────────────┼───────────────────────────────┘
|
|
│ │ │
|
|
└────────────┼────────────┘
|
|
│ HTTPS
|
|
▼
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|
│ HORUX BACKEND (Laravel) │
|
|
│ ┌─────────────────────────────────────────────────────────┐ │
|
|
│ │ MIDDLEWARE │ │
|
|
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
|
|
│ │ │ CORS │ │ Auth │ │ Throttle │ │ Custom │ │ │
|
|
│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │
|
|
│ └─────────────────────────────────────────────────────────┘ │
|
|
│ │ │
|
|
│ ┌─────────────────────────────────────────────────────────┐ │
|
|
│ │ CONTROLLERS │ │
|
|
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
|
|
│ │ │ Invoice │ │ Rfc │ │ Taxpayer │ │ │
|
|
│ │ │ Controller │ │ Controller │ │ Controller │ │ │
|
|
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
|
|
│ └─────────────────────────────────────────────────────────┘ │
|
|
│ │ │
|
|
│ ┌─────────────────────────────────────────────────────────┐ │
|
|
│ │ SERVICES │ │
|
|
│ │ ┌─────────────────┐ ┌─────────────────────────┐ │ │
|
|
│ │ │ SocialAccounts │ │ SocialUserResolver │ │ │
|
|
│ │ │ Service │ │ Service │ │ │
|
|
│ │ └─────────────────┘ └─────────────────────────┘ │ │
|
|
│ └─────────────────────────────────────────────────────────┘ │
|
|
│ │ │
|
|
│ ┌─────────────────────────────────────────────────────────┐ │
|
|
│ │ MODELS │ │
|
|
│ │ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ │ │
|
|
│ │ │ User │ │ Rfc │ │Invoice │ │Taxpayer│ ... │ │
|
|
│ │ └────────┘ └────────┘ └────────┘ └────────┘ │ │
|
|
│ └─────────────────────────────────────────────────────────┘ │
|
|
│ │ │
|
|
│ ┌─────────────────────────────────────────────────────────┐ │
|
|
│ │ DATABASE │ │
|
|
│ │ ┌──────────────┐ │ │
|
|
│ │ │ MySQL │ │ │
|
|
│ │ │ horux360bd │ │ │
|
|
│ │ └──────────────┘ │ │
|
|
│ └─────────────────────────────────────────────────────────┘ │
|
|
└─────────────────────────────────────────────────────────────────┘
|
|
│
|
|
│ HTTP Requests
|
|
▼
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|
│ SERVICIOS EXTERNOS │
|
|
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
|
│ │ Syntage │ │ Clerk │ │ Facturama │ │
|
|
│ │ API │ │ OAuth │ │ SDK │ │
|
|
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
|
└─────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## Capas de la Aplicacion
|
|
|
|
### 1. Capa de Routing
|
|
|
|
**Ubicacion:** `routes/`
|
|
|
|
Define los endpoints de la API y asocia rutas con controladores.
|
|
|
|
```php
|
|
// routes/api.php
|
|
Route::group(['middleware' => 'auth:api'], function() {
|
|
Route::get('/obtener-facturas', [InvoiceController::class, 'obtenerFacturas']);
|
|
});
|
|
```
|
|
|
|
**Grupos de rutas:**
|
|
- Rutas publicas (sin autenticacion)
|
|
- Rutas protegidas (requieren `auth:api`)
|
|
- Rutas con rate limiting (`throttle:custom-origin`)
|
|
|
|
---
|
|
|
|
### 2. Capa de Middleware
|
|
|
|
**Ubicacion:** `app/Http/Middleware/`
|
|
|
|
Procesa las solicitudes antes de llegar al controlador.
|
|
|
|
| Middleware | Proposito |
|
|
|------------|-----------|
|
|
| Authenticate | Verificar token OAuth |
|
|
| ThrottleEndpoint | Rate limiting personalizado |
|
|
| Cors | Manejo de CORS |
|
|
| EncryptCookies | Encriptar cookies |
|
|
| VerifyCsrfToken | Proteccion CSRF |
|
|
|
|
---
|
|
|
|
### 3. Capa de Controllers
|
|
|
|
**Ubicacion:** `app/Http/Controllers/`
|
|
|
|
Manejan la logica de las solicitudes HTTP.
|
|
|
|
**Patron utilizado:** Controller con logica de negocio embebida.
|
|
|
|
```php
|
|
class InvoiceController extends Controller
|
|
{
|
|
public function obtenerFacturas(Request $request)
|
|
{
|
|
// Validacion
|
|
// Logica de negocio
|
|
// Llamadas a APIs externas
|
|
// Persistencia
|
|
// Respuesta
|
|
}
|
|
}
|
|
```
|
|
|
|
**Controladores principales:**
|
|
- `InvoiceController` - Gestion de facturas (1811 lineas)
|
|
- `InvoicePaymentController` - Pagos de facturas
|
|
- `TaxpayerController` - Informacion de contribuyentes
|
|
- `RfcController` - Gestion de RFCs
|
|
|
|
---
|
|
|
|
### 4. Capa de Services
|
|
|
|
**Ubicacion:** `app/Services/`
|
|
|
|
Encapsula logica reutilizable.
|
|
|
|
```php
|
|
// app/Services/SocialAccountsService.php
|
|
class SocialAccountsService
|
|
{
|
|
public function findOrCreate($providerUser, $provider)
|
|
{
|
|
// Logica para manejar cuentas sociales
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### 5. Capa de Models
|
|
|
|
**Ubicacion:** `app/Models/`
|
|
|
|
Modelos Eloquent que representan las tablas de la base de datos.
|
|
|
|
```php
|
|
class Invoice extends Model
|
|
{
|
|
protected $fillable = ['uuid', 'serie', 'folio', ...];
|
|
|
|
public function rfc()
|
|
{
|
|
return $this->belongsTo(Rfc::class);
|
|
}
|
|
|
|
public function lines()
|
|
{
|
|
return $this->hasMany(InvoiceLine::class);
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### 6. Capa de Imports
|
|
|
|
**Ubicacion:** `app/Imports/`
|
|
|
|
Maneja la importacion de datos desde archivos Excel.
|
|
|
|
```php
|
|
class InvoicesImport implements ToModel, WithHeadingRow, WithChunkReading
|
|
{
|
|
public function model(array $row)
|
|
{
|
|
return new Invoice([...]);
|
|
}
|
|
|
|
public function chunkSize(): int
|
|
{
|
|
return 1000;
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Flujos de Datos
|
|
|
|
### Flujo de Autenticacion
|
|
|
|
```
|
|
1. Cliente -> POST /api/auth (code de Clerk)
|
|
2. Backend -> POST Clerk API (intercambio de codigo)
|
|
3. Clerk API -> access_token
|
|
4. Backend -> Crear/buscar usuario
|
|
5. Backend -> Generar token Passport
|
|
6. Backend -> Cliente (token Passport)
|
|
```
|
|
|
|
### Flujo de Obtencion de Facturas
|
|
|
|
```
|
|
1. Cliente -> GET /api/obtener-facturas (Bearer token)
|
|
2. Middleware -> Validar token
|
|
3. Controller -> Obtener RFC del usuario
|
|
4. Controller -> GET Syntage API (facturas)
|
|
5. Controller -> Procesar y guardar en BD
|
|
6. Controller -> Response JSON al cliente
|
|
```
|
|
|
|
### Flujo de Calculo de Metricas
|
|
|
|
```
|
|
1. Cliente -> GET /api/obtener-metricas
|
|
2. Controller -> Query facturas desde BD
|
|
3. Controller -> Calcular:
|
|
- Ingresos (tipo I)
|
|
- Egresos (tipo E)
|
|
- IVA trasladado/retenido
|
|
- ISR retenido
|
|
4. Controller -> Response con metricas
|
|
```
|
|
|
|
---
|
|
|
|
## Integraciones Externas
|
|
|
|
### Syntage API
|
|
|
|
**Proposito:** Obtener datos fiscales del SAT.
|
|
|
|
**Endpoints utilizados:**
|
|
- `/invoices` - Obtener facturas
|
|
- `/insights` - Metricas financieras
|
|
- `/taxpayer` - Informacion del contribuyente
|
|
- `/risks` - Riesgos fiscales
|
|
|
|
**Autenticacion:** API Key en header.
|
|
|
|
```php
|
|
$response = Http::withHeaders([
|
|
'Authorization' => 'Bearer ' . $apiKey
|
|
])->get('https://api.syntage.com/invoices', $params);
|
|
```
|
|
|
|
---
|
|
|
|
### Clerk OAuth
|
|
|
|
**Proposito:** Autenticacion de usuarios.
|
|
|
|
**Flujo:**
|
|
1. Usuario se autentica en Clerk (frontend)
|
|
2. Frontend obtiene authorization code
|
|
3. Backend intercambia code por access token
|
|
4. Backend crea sesion local
|
|
|
|
---
|
|
|
|
### Facturama SDK
|
|
|
|
**Proposito:** Generar y timbrar CFDIs.
|
|
|
|
```php
|
|
$facturama = new Facturama(['sandbox' => true]);
|
|
$cfdi = $facturama->post('Cfdi', $invoiceData);
|
|
```
|
|
|
|
---
|
|
|
|
## Patrones de Diseno
|
|
|
|
### Repository Pattern (Parcial)
|
|
|
|
Aunque no hay repositorios explicitos, los modelos Eloquent actuan como repositories.
|
|
|
|
### Service Pattern
|
|
|
|
Los servicios encapsulan logica de negocio reutilizable.
|
|
|
|
### Strategy Pattern (Imports)
|
|
|
|
Los importadores implementan interfaces de Maatwebsite Excel.
|
|
|
|
---
|
|
|
|
## Seguridad
|
|
|
|
### Autenticacion
|
|
|
|
- OAuth 2.0 con Laravel Passport
|
|
- Tokens de acceso con expiracion
|
|
- Refresh tokens para renovacion
|
|
|
|
### Autorizacion
|
|
|
|
- Middleware `auth:api` para rutas protegidas
|
|
- Validacion de pertenencia de RFCs a usuarios
|
|
|
|
### Protecciones
|
|
|
|
- CORS configurado
|
|
- Rate limiting con middleware personalizado
|
|
- Validacion de entrada en controllers
|
|
- Prepared statements (Eloquent ORM)
|
|
|
|
---
|
|
|
|
## Escalabilidad
|
|
|
|
### Actual
|
|
|
|
- Servidor unico
|
|
- Base de datos MySQL
|
|
- Cache en archivos
|
|
|
|
### Mejoras Recomendadas
|
|
|
|
```
|
|
┌─────────────┐
|
|
│ Load Balancer│
|
|
└──────┬──────┘
|
|
│
|
|
┌──────┴──────┐
|
|
│ │
|
|
▼ ▼
|
|
┌─────┐ ┌─────┐
|
|
│App 1│ │App 2│
|
|
└──┬──┘ └──┬──┘
|
|
│ │
|
|
└────┬─────┘
|
|
│
|
|
┌────┴────┐
|
|
│ Redis │ (Cache/Sessions)
|
|
└────┬────┘
|
|
│
|
|
┌────┴────┐
|
|
│ MySQL │ (Master-Slave)
|
|
└─────────┘
|
|
```
|
|
|
|
- Redis para cache y sesiones
|
|
- Queue workers para tareas pesadas
|
|
- Replica de base de datos
|
|
|
|
---
|
|
|
|
## Estructura de Directorios Detallada
|
|
|
|
```
|
|
app/
|
|
├── Console/
|
|
│ └── Kernel.php # Comandos programados
|
|
├── Exceptions/
|
|
│ └── Handler.php # Manejo global de excepciones
|
|
├── Http/
|
|
│ ├── Controllers/
|
|
│ │ ├── Controller.php # Base controller
|
|
│ │ ├── InvoiceController.php
|
|
│ │ ├── RfcController.php
|
|
│ │ └── ...
|
|
│ ├── Middleware/
|
|
│ │ ├── Authenticate.php
|
|
│ │ ├── ThrottleEndpoint.php
|
|
│ │ └── ...
|
|
│ └── Kernel.php # Registro de middleware
|
|
├── Imports/
|
|
│ ├── InvoicesImport.php
|
|
│ └── LineItemsImport.php
|
|
├── Models/
|
|
│ ├── Invoice.php
|
|
│ ├── User.php
|
|
│ └── ...
|
|
├── Providers/
|
|
│ ├── AppServiceProvider.php
|
|
│ ├── AuthServiceProvider.php
|
|
│ └── ...
|
|
└── Services/
|
|
├── SocialAccountsService.php
|
|
└── SocialUserResolver.php
|
|
```
|
|
|
|
---
|
|
|
|
## Consideraciones de Rendimiento
|
|
|
|
### Queries Optimizadas
|
|
|
|
```php
|
|
// Eager loading para evitar N+1
|
|
$invoices = Invoice::with(['lines', 'payments'])->get();
|
|
```
|
|
|
|
### Importacion en Chunks
|
|
|
|
```php
|
|
// Procesar Excel en lotes de 1000
|
|
public function chunkSize(): int
|
|
{
|
|
return 1000;
|
|
}
|
|
```
|
|
|
|
### Cache
|
|
|
|
```php
|
|
// Cachear catalogos estaticos
|
|
$regimes = Cache::remember('tax_regimes', 3600, function() {
|
|
return TaxRegime::all();
|
|
});
|
|
```
|