> For the complete documentation index, see [llms.txt](https://senselab.gitbook.io/senselab-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://senselab.gitbook.io/senselab-docs/docs/guides/contributing.md).

# Guía de Contribución - Senselab Core API

¡Gracias por tu interés en contribuir al proyecto Senselab Core API desarrollado por **Senselab**!

## 🏢 Sobre Senselab

En SenseLab no vendemos software a la fuerza. Escuchamos, exploramos y luego construimos con sentido. Si busca un aliado tecnológico que entienda tanto de servidores como de píxeles, de bases de datos como de narrativa interactiva, hablemos.

**"No hacemos cualquier cosa. Hacemos cosas con sentido."** — *SenseLab, tecnología versátil con alma costarricense.*

* **Fundador**: Senselab Team
* **Desarrollador Principal**: Jeremy Arias Solano
* **Contacto**: <deadmooncr@gmail.com>

## 🤝 Cómo Contribuir

### 1. Fork del Repositorio

```bash
# Fork desde GitHub
git clone https://github.com/SenseLab-dev/Senselab_Core_API.git
cd Senselab_Core_API

# Agregar remote upstream
git remote add upstream https://github.com/SenseLab-dev/Senselab_Core_API.git
```

### 2. Crear una Rama de Feature

```bash
# Actualizar main
git checkout main
git pull upstream main

# Crear nueva rama
git checkout -b feature/nombre-descriptivo
# o
git checkout -b fix/descripcion-del-fix
```

### 3. Configurar Entorno de Desarrollo

```bash
# Instalar dependencias
composer install
pnpm install  # Usamos pnpm por seguridad (no npm)

# Copiar .env y configurar
cp .env.example .env
php artisan key:generate

# Configurar base de datos en .env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=senselab_core_api
DB_USERNAME=tu_usuario
DB_PASSWORD=tu_password

# Ejecutar migraciones y seeders (carga 112 registros)
php artisan migrate:fresh --seed

# Credenciales de prueba después de seeders:
# Email: admin@senselab.com
# Password: admin123
# Permisos: 68 (acceso total)
```

### 4. Realizar Cambios

Asegúrate de seguir nuestros estándares:

#### Estándares de Código

* **PSR-12**: Seguir estándar PSR-12 para código PHP
* **Nombres en Español**: Variables, métodos y clases en español
* **Comentarios**: Documentar funciones con PHPDoc
* **Testing**: Escribir tests para nuevas funcionalidades

#### Ejemplo de Código

```php
<?php

namespace App\Services;

/**
 * Servicio para gestión de facturación electrónica
 * 
 * @author Jeremy Arias Solano <deadmooncr@gmail.com>
 * @copyright 2025 Senselab
 */
class FacturacionElectronicaService
{
    /**
     * Genera una factura electrónica
     * 
     * @param array $datos Datos de la factura
     * @return array Factura generada
     * @throws \Exception Si hay error en la generación
     */
    public function generarFactura(array $datos): array
    {
        // Implementación
    }
}
```

### 4. Commit de Cambios

Usamos commits descriptivos en español:

```bash
git add .
git commit -m "feat: Agregar validación de identificación en clientes"
# o
git commit -m "fix: Corregir cálculo de impuestos en ventas"
# o
git commit -m "docs: Actualizar documentación de API"
```

**Prefijos de Commit:**

* `feat:` - Nueva funcionalidad
* `fix:` - Corrección de bug
* `docs:` - Cambios en documentación
* `style:` - Formato, espacios, etc.
* `refactor:` - Refactorización de código
* `test:` - Agregar o modificar tests
* `chore:` - Mantenimiento, dependencias

### 5. Ejecutar Tests

```bash
# Ejecutar todos los tests
php artisan test

# Con cobertura
php artisan test --coverage

# Tests específicos
php artisan test --filter NombreDelTest
```

### 6. Push y Pull Request

```bash
# Push a tu fork
git push origin feature/nombre-descriptivo
```

Luego crea un Pull Request en GitHub con:

**Título descriptivo:**

```
feat: Implementar módulo de facturación electrónica para DGT
```

**Descripción completa:**

```markdown
## Descripción
Implementa la integración completa con la API de DGT de Costa Rica para
emisión y recepción de comprobantes electrónicos.

## Cambios realizados
- [ ] Creación de servicios de facturación
- [ ] Integración con API de Hacienda
- [ ] Validación de certificados digitales
- [ ] Tests de integración

## Checklist
- [x] Código sigue PSR-12
- [x] Tests escritos y pasando
- [x] Documentación actualizada
- [x] Sin conflictos con main

## Screenshots (si aplica)
[Adjuntar capturas de pantalla]
```

## 📋 Checklist antes de PR

* [ ] El código sigue PSR-12
* [ ] Variables y métodos en español
* [ ] PHPDoc en funciones públicas
* [ ] Tests escritos y pasando
* [ ] Documentación actualizada
* [ ] Sin conflictos con main
* [ ] Commits descriptivos

## 🧪 Testing

Todos los PRs deben incluir tests:

### Ejecutar Tests

```bash
# Todos los tests
php artisan test

# Tests específicos
php artisan test --filter NombreDelTest

# Con cobertura
php artisan test --coverage
```

### Autenticación en Tests

Para tests que requieren autenticación:

```php
<?php

namespace Tests\Feature;

use App\Models\Usuario;
use App\Models\Rol;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class VentaControllerTest extends TestCase
{
    use RefreshDatabase;

    protected function setUp(): void
    {
        parent::setUp();
        
        // Ejecutar seeders para tener datos base
        $this->seed();
    }

    /** @test */
    public function usuario_autenticado_puede_crear_venta()
    {
        // Obtener usuario admin (creado por UsuarioAdminSeeder)
        $admin = Usuario::where('email', 'admin@senselab.com')->first();
        
        // Autenticar con Sanctum
        $token = $admin->createToken('test-token')->plainTextToken;
        
        // Hacer request con token
        $response = $this->withHeaders([
            'Authorization' => 'Bearer ' . $token,
            'Accept' => 'application/json',
        ])->postJson('/api/ventas', [
            'empresa_id' => 1,
            'sucursal_id' => 1,
            'cliente_id' => 1,
            // ... otros datos
        ]);
        
        $response->assertStatus(201);
    }

    /** @test */
    public function usuario_sin_permiso_no_puede_crear_venta()
    {
        // Crear usuario sin permisos
        $usuario = Usuario::factory()->create();
        $rolUsuario = Rol::where('nombre', 'Usuario')->first();
        $usuario->assignRoles(['Usuario']);
        
        $token = $usuario->createToken('test-token')->plainTextToken;
        
        $response = $this->withHeaders([
            'Authorization' => 'Bearer ' . $token,
            'Accept' => 'application/json',
        ])->postJson('/api/ventas', [
            'empresa_id' => 1,
            // ... datos
        ]);
        
        // Espera 403 Forbidden
        $response->assertStatus(403);
        $response->assertJson([
            'message' => 'No tienes permiso para realizar esta acción'
        ]);
    }
}
```

### Tests de RBAC

```php

use Tests\TestCase;

/**
 * Tests para módulo de facturación electrónica
 * 
 * @author Tu Nombre <tu@email.com>
 */
class FacturacionElectronicaTest extends TestCase
{
    /**
     * @test
     */
    public function puede_generar_factura_electronica(): void
    {
        // Arrange
        $datos = [...];
        
        // Act
        $response = $this->postJson('/api/facturas', $datos);
        
        // Assert
        $response->assertStatus(201);
        $this->assertDatabaseHas('facturas', [...]);
    }
}
```

## 📝 Documentación

Si tu cambio afecta la API, actualiza:

1. **API\_DOCUMENTATION.md** - Documentación de endpoints
2. **README.md** - Si cambia instalación o configuración
3. **MODELS\_RELATIONS.md** - Si agregas nuevos modelos
4. **Inline docs** - Comentarios PHPDoc

## 🐛 Reportar Bugs

Para reportar bugs:

1. **GitHub Issues**: [Crear issue](https://github.com/SenseLab-dev/Senselab_Core_API/issues)
2. **Email**: <deadmooncr@gmail.com>

**Template de Bug Report:**

```markdown
## Descripción del Bug
[Descripción clara del bug]

## Pasos para Reproducir
1. Ir a '...'
2. Hacer click en '...'
3. Ver error

## Comportamiento Esperado
[Qué debería pasar]

## Comportamiento Actual
[Qué pasa realmente]

## Screenshots
[Si aplica]

## Entorno
- OS: [ej. Ubuntu 22.04]
- PHP: [ej. 8.2.1]
- Laravel: [ej. 11.0]
- Navegador: [ej. Chrome 120]
```

## 💡 Solicitar Features

Para nuevas funcionalidades:

1. Crear issue con label "enhancement"
2. Describir el caso de uso
3. Esperar feedback del equipo

## 🎨 Estándares de Diseño

### Base de Datos

* **Tablas**: plural, snake\_case (ej: `ordenes_compra`)
* **Timestamps**: `creado_en`, `actualizado_en`
* **Soft Deletes**: `eliminado` (boolean)
* **Estado**: `activo` (boolean)

### API

* **Rutas**: plural, kebab-case (ej: `/api/ordenes-compra`)
* **Responses**: JSON estructurado
* **Errores**: HTTP status codes apropiados

### Código

* **Clases**: PascalCase (ej: `FacturaElectronica`)
* **Métodos**: camelCase (ej: `generarComprobante()`)
* **Variables**: camelCase (ej: `$numeroFactura`)

## 🔒 Seguridad

Si encuentras una vulnerabilidad de seguridad:

**NO CREAR ISSUE PÚBLICO**

Contactar directamente a:

* Email: <deadmooncr@gmail.com>
* Email corporativo: <deadmooncr@gmail.com>

## 📞 Contacto

**Senselab**

* **Email**: <deadmooncr@gmail.com>
* **Email Técnico**: <deadmooncr@gmail.com>
* **Web**: [senselab.com](https://senselab.com) | [senselab.com](https://senselab.com)
* **Repositorio**: [Senselab Reposit for Developers](https://sites.google.com/view/repdevsenselab/home/repositorio)
* **GitHub**: [github.com/SenseLab-dev](https://github.com/orgs/SenseLab-dev)

## 🙏 Agradecimientos

Agradecemos a todos los contribuidores que ayudan a mejorar este proyecto.

***

**"No hacemos cualquier cosa. Hacemos cosas con sentido."**\
\&#xNAN;*Costa Rica | Build with Sense*

© 2025 Senselab - Todos los derechos reservados


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://senselab.gitbook.io/senselab-docs/docs/guides/contributing.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
