Initial commit: Horux Backend API
- 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>
This commit is contained in:
434
docs/ARCHITECTURE.md
Normal file
434
docs/ARCHITECTURE.md
Normal file
@@ -0,0 +1,434 @@
|
||||
# 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();
|
||||
});
|
||||
```
|
||||
Reference in New Issue
Block a user