refactor: reorganizar openspec y planificacion con spec recaptcha

- renombrar openspec/ a _openspec/ (carpeta auxiliar)
- mover specs de features a changes/
- crear specs base: arquitectura-limpia, estandares-codigo, nomenclatura
- migrar _planificacion/ con design-system y roi-theme-template
- agregar especificacion recaptcha anti-spam (proposal, tasks, spec)
- corregir rutas y referencias en todas las specs

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
FrankZamora
2026-01-08 15:30:45 -06:00
parent 0d6b6db108
commit 0f6387ab46
58 changed files with 15364 additions and 1171 deletions

View File

@@ -0,0 +1,687 @@
# Especificacion de Nomenclatura - ROI Theme
## Purpose
Define las convenciones de nomenclatura para carpetas, archivos, clases, metodos, propiedades y variables en el tema ROI Theme (PHP 8.x / WordPress).
> **NOTA**: Para principios SOLID y estandares de codigo, ver `_openspec/specs/estandares-codigo.md`
> **NOTA**: Para arquitectura y modularidad, ver `_openspec/specs/arquitectura-limpia.md`
---
## Resumen de Nomenclaturas
| Elemento | Nomenclatura | Ejemplo |
|----------|-------------|---------|
| **Carpetas principales** | PascalCase | `Admin/`, `Public/`, `Shared/` |
| **Carpetas de contexto** | PascalCase | `Admin/`, `Public/` |
| **Carpetas de modulo** | PascalCase | `ContactForm/`, `FeaturedImage/` |
| **Carpetas de capa** | PascalCase | `Domain/`, `Application/`, `Infrastructure/` |
| **Carpetas auxiliares** | _minusculas | `_planificacion/`, `_arquitectura/` |
| **Archivos PHP de clase** | PascalCase.php | `ContactFormRenderer.php` |
| **Archivos PHP de interface** | PascalCaseInterface.php | `RendererInterface.php` |
| **Archivos JSON schema** | kebab-case.json | `contact-form.json` |
| **Namespaces** | PascalCase | `ROITheme\Public\ContactForm\Infrastructure\Ui` |
| **Clases** | PascalCase | `ContactFormRenderer` |
| **Interfaces** | PascalCase + Interface | `RendererInterface`, `CSSGeneratorInterface` |
| **Metodos** | camelCase | `render()`, `getVisibilityClass()` |
| **Propiedades** | camelCase | `$cssGenerator`, `$componentName` |
| **Variables locales** | $camelCase | `$showDesktop`, `$visibilityClass` |
| **Parametros** | $camelCase | `$component`, `$data` |
| **Campos privados** | $camelCase | `$cssGenerator` (con private) |
| **Constantes clase** | UPPER_SNAKE_CASE | `COMPONENT_NAME`, `MAX_ITEMS` |
| **Constantes globales** | UPPER_SNAKE_CASE | `ROI_THEME_VERSION` |
| **component_name** | kebab-case | `"contact-form"`, `"featured-image"` |
| **Hooks WordPress** | snake_case con prefijo | `roi_theme_after_render` |
---
## Requirements
### Requirement: Nomenclatura de Carpetas
Los nombres de carpetas siguen convenciones basadas en su proposito.
#### Scenario: Carpetas principales del tema
- **WHEN** se nombra una carpeta principal de codigo
- **THEN** DEBE usar PascalCase
- **AND** ejemplos correctos: `Admin/`, `Public/`, `Shared/`, `Schemas/`
- **AND** ejemplos incorrectos: `admin/`, `ADMIN/`, `shared_code/`
#### Scenario: Carpetas de contexto
- **WHEN** se nombra una carpeta que representa un contexto de la aplicacion
- **THEN** DEBE usar PascalCase
- **AND** carpetas permitidas:
- `Admin/` - Componentes del panel de administracion
- `Public/` - Componentes del frontend publico
- `Shared/` - Codigo compartido entre contextos
- **AND** ejemplos incorrectos: `backend/`, `frontend/`, `common/`
#### Scenario: Carpetas de modulo (componente)
- **WHEN** se nombra una carpeta que representa un modulo/componente
- **THEN** DEBE seguir PascalCase
- **AND** DEBE coincidir con component_name convertido de kebab-case
- **AND** ejemplos correctos:
- `ContactForm/` (de `contact-form`)
- `FeaturedImage/` (de `featured-image`)
- `TopNotificationBar/` (de `top-notification-bar`)
- `CtaBoxSidebar/` (de `cta-box-sidebar`)
- **AND** ejemplos incorrectos:
- `contact-form/` (kebab-case)
- `contactForm/` (camelCase)
- `CONTACT_FORM/` (UPPER_SNAKE)
#### Scenario: Carpetas de capa (Clean Architecture)
- **WHEN** se nombra una carpeta que representa una capa de arquitectura
- **THEN** DEBE usar PascalCase
- **AND** carpetas permitidas dentro de cada modulo:
- `Domain/` - Entidades, interfaces, value objects
- `Application/` - Casos de uso
- `Infrastructure/` - Implementaciones (Ui, Api, Persistence, Services)
- **AND** subcarpetas de Infrastructure permitidas:
- `Ui/` - Renderers, FormBuilders
- `Api/` - Handlers AJAX, REST endpoints
- `Persistence/` - Repositorios
- `Services/` - Servicios de infraestructura
- `WordPress/` - Integraciones especificas de WordPress
- **AND** ejemplos correctos: `Infrastructure/Ui/`, `Infrastructure/Api/WordPress/`
- **AND** ejemplos incorrectos: `infrastructure/`, `UI/`, `api/`
#### Scenario: Carpetas auxiliares (no codigo)
- **WHEN** se nombra una carpeta de documentacion, planificacion o configuracion
- **THEN** DEBE usar prefijo guion bajo + minusculas
- **AND** ejemplos correctos:
- `_planificacion/` - Documentos de planificacion
- `_arquitectura/` - Documentos de arquitectura
- **AND** nombres compuestos usan guion medio: `_pruebas-regresion/`
- **AND** el guion bajo indica carpetas auxiliares/no-codigo
#### Scenario: Carpetas de cambios (OpenSpec)
- **WHEN** se crea una carpeta para un cambio/feature en `_openspec/changes/`
- **THEN** DEBE usar nombre en kebab-case descriptivo
- **AND** maximo 1 nivel de carpeta despues de `changes/`
- **AND** ejemplos correctos:
- `anti-spam-validator/`
- `lazy-loading-images/`
- `improved-caching/`
- **AND** ejemplos incorrectos:
- `AntiSpam/` (PascalCase)
- `anti_spam/` (snake_case)
- `anti-spam/subfolder/` (anidamiento prohibido)
#### Scenario: Excepciones permitidas
- **WHEN** existen carpetas especiales del sistema
- **THEN** se permiten las siguientes excepciones:
- `.git/` - Control de versiones
- `.serena/` - Configuracion de Serena MCP
- `.claude/` - Configuracion de Claude Code
- `node_modules/` - Dependencias npm (si aplica)
- `vendor/` - Dependencias Composer (si aplica)
- `_openspec/` - Sistema de especificaciones (carpeta auxiliar)
---
### Requirement: Nomenclatura de Archivos PHP
Los archivos PHP DEBEN seguir convencion PascalCase.
#### Scenario: Archivos de clase
- **WHEN** se nombra un archivo que contiene una clase PHP
- **THEN** DEBE seguir PascalCase
- **AND** el nombre DEBE coincidir EXACTAMENTE con el nombre de la clase
- **AND** extension `.php`
- **AND** ejemplos correctos:
- `ContactFormRenderer.php` (contiene `class ContactFormRenderer`)
- `NewsletterAjaxHandler.php` (contiene `class NewsletterAjaxHandler`)
- `CSSGeneratorService.php` (contiene `class CSSGeneratorService`)
- **AND** ejemplos incorrectos:
- `contact-form-renderer.php` (kebab-case)
- `contactFormRenderer.php` (camelCase)
- `class_contact_form.php` (snake_case con prefijo)
#### Scenario: Archivos de interface
- **WHEN** se nombra un archivo que contiene una interface
- **THEN** DEBE seguir PascalCase con sufijo Interface
- **AND** extension `.php`
- **AND** ejemplos correctos:
- `RendererInterface.php`
- `CSSGeneratorInterface.php`
- `ComponentRepositoryInterface.php`
- **AND** ejemplos incorrectos:
- `IRenderer.php` (prefijo I estilo C#)
- `Renderer.php` (sin sufijo)
#### Scenario: Archivos de trait
- **WHEN** se nombra un archivo que contiene un trait PHP
- **THEN** DEBE seguir PascalCase con sufijo Trait
- **AND** extension `.php`
- **AND** ejemplos correctos:
- `VisibilityTrait.php`
- `CSSGeneratorTrait.php`
---
### Requirement: Nomenclatura de Archivos JSON (Schemas)
Los schemas JSON DEBEN usar kebab-case.
#### Scenario: Archivos de schema de componente
- **WHEN** se nombra un archivo JSON schema
- **THEN** DEBE usar kebab-case
- **AND** extension `.json`
- **AND** el nombre DEBE coincidir con el component_name
- **AND** ejemplos correctos:
- `contact-form.json` (component_name: "contact-form")
- `featured-image.json` (component_name: "featured-image")
- `top-notification-bar.json` (component_name: "top-notification-bar")
- `cta-box-sidebar.json` (component_name: "cta-box-sidebar")
- **AND** ejemplos incorrectos:
- `ContactForm.json` (PascalCase)
- `contact_form.json` (snake_case)
- `contactForm.json` (camelCase)
---
### Requirement: Nomenclatura de Namespaces
Los namespaces PHP DEBEN seguir convencion PascalCase jerarquica.
#### Scenario: Namespace raiz
- **WHEN** se define el namespace principal del tema
- **THEN** DEBE ser `ROITheme`
- **AND** ejemplo: `namespace ROITheme;`
#### Scenario: Namespaces de modulo publico
- **WHEN** se define un namespace para un componente en Public/
- **THEN** DEBE seguir `ROITheme\Public\[Componente]\[Capa][\Subcapa]`
- **AND** ejemplos correctos:
```php
// Renderers
namespace ROITheme\Public\ContactForm\Infrastructure\Ui;
namespace ROITheme\Public\FeaturedImage\Infrastructure\Ui;
namespace ROITheme\Public\TopNotificationBar\Infrastructure\Ui;
// AJAX Handlers
namespace ROITheme\Public\Footer\Infrastructure\Api\WordPress;
namespace ROITheme\Public\ContactForm\Infrastructure\Api\WordPress;
// Domain (si existe)
namespace ROITheme\Public\AdsensePlacement\Domain\ValueObjects;
namespace ROITheme\Public\AdsensePlacement\Domain\Contracts;
// Application (si existe)
namespace ROITheme\Public\CustomCSSManager\Application\UseCases;
```
#### Scenario: Namespaces de modulo admin
- **WHEN** se define un namespace para un componente en Admin/
- **THEN** DEBE seguir `ROITheme\Admin\[Componente]\[Capa][\Subcapa]`
- **AND** ejemplos correctos:
```php
// FormBuilders
namespace ROITheme\Admin\ContactForm\Infrastructure\Ui;
namespace ROITheme\Admin\FeaturedImage\Infrastructure\Ui;
// Shared de Admin
namespace ROITheme\Admin\Shared\Infrastructure\Ui;
```
#### Scenario: Namespaces de Shared
- **WHEN** se define un namespace para codigo compartido
- **THEN** DEBE seguir `ROITheme\Shared\[Capa][\Subcapa]`
- **AND** ejemplos correctos:
```php
// Domain
namespace ROITheme\Shared\Domain\Contracts;
namespace ROITheme\Shared\Domain\Entities;
namespace ROITheme\Shared\Domain\ValueObjects;
// Application
namespace ROITheme\Shared\Application\UseCases;
// Infrastructure
namespace ROITheme\Shared\Infrastructure\Services;
namespace ROITheme\Shared\Infrastructure\Persistence\WordPress;
```
---
### Requirement: Nomenclatura de Clases
Los nombres de clase DEBEN seguir convencion PascalCase.
#### Scenario: Clases regulares
- **WHEN** se define una clase en PHP
- **THEN** el nombre DEBE seguir PascalCase
- **AND** DEBE ser un sustantivo o frase sustantiva
- **AND** DEBE ser descriptivo de su responsabilidad
- **AND** ejemplos correctos:
```php
final class ContactFormRenderer
final class ComponentSettings
final class VisibilityChecker
```
- **AND** ejemplos incorrectos:
```php
final class contactFormRenderer // camelCase
final class contact_form_renderer // snake_case
final class Render // verbo, no sustantivo
```
#### Scenario: Clases Renderer
- **WHEN** se define una clase que renderiza HTML de un componente
- **THEN** DEBE usar sufijo `Renderer`
- **AND** DEBE implementar `RendererInterface`
- **AND** DEBE ser `final`
- **AND** ejemplos correctos:
```php
final class ContactFormRenderer implements RendererInterface
final class FeaturedImageRenderer implements RendererInterface
final class TopNotificationBarRenderer implements RendererInterface
```
#### Scenario: Clases FormBuilder
- **WHEN** se define una clase que genera formularios admin
- **THEN** DEBE usar sufijo `FormBuilder`
- **AND** DEBE ser `final`
- **AND** ejemplos correctos:
```php
final class ContactFormFormBuilder
final class FeaturedImageFormBuilder
final class TopNotificationBarFormBuilder
```
#### Scenario: Clases de caso de uso
- **WHEN** se define una clase UseCase en Application/
- **THEN** DEBE usar sufijo `UseCase`
- **AND** el nombre DEBE describir la accion
- **AND** ejemplos correctos:
```php
final class GetCriticalCSSUseCase
final class CheckAdsenseVisibilityUseCase
final class GetDeferredSnippetsUseCase
```
#### Scenario: Clases de servicio
- **WHEN** se define una clase que provee servicios en Infrastructure/
- **THEN** DEBE usar sufijo `Service`
- **AND** ejemplos correctos:
```php
final class CSSGeneratorService
final class AntiSpamValidatorService
final class CacheService
```
#### Scenario: Clases de repositorio
- **WHEN** se define una clase de acceso a datos
- **THEN** DEBE usar sufijo `Repository`
- **AND** ejemplos correctos:
```php
final class ComponentSettingsRepository
final class PageVisibilityRepository
```
#### Scenario: Clases Handler (AJAX/API)
- **WHEN** se define una clase que maneja peticiones AJAX o API
- **THEN** DEBE usar sufijo `Handler` o `Controller`
- **AND** ejemplos correctos:
```php
final class NewsletterAjaxHandler
final class ContactFormAjaxHandler
final class AdsenseVisibilityController
```
---
### Requirement: Nomenclatura de Interfaces
Los nombres de interface DEBEN seguir convencion PascalCase con sufijo.
#### Scenario: Interfaces
- **WHEN** se define una interface en PHP
- **THEN** el nombre DEBE terminar con `Interface`
- **AND** DEBE seguir PascalCase
- **AND** DEBE describir la capacidad o contrato
- **AND** ejemplos correctos:
```php
interface RendererInterface
interface CSSGeneratorInterface
interface ComponentRepositoryInterface
interface AjaxControllerInterface
```
- **AND** ejemplos incorrectos:
```php
interface IRenderer // prefijo I estilo C#
interface Renderer // sin sufijo
interface renderer_interface // snake_case
```
---
### Requirement: Nomenclatura de Metodos
Los nombres de metodo DEBEN seguir convencion camelCase.
#### Scenario: Metodos publicos
- **WHEN** se define un metodo publico
- **THEN** el nombre DEBE seguir camelCase
- **AND** DEBE comenzar con verbo que describe la accion
- **AND** ejemplos correctos:
```php
public function render(Component $component): string
public function getVisibilityClass(array $data): ?string
public function validateInput(string $input): bool
public function buildForm(string $componentId): string
```
- **AND** ejemplos incorrectos:
```php
public function Render() // PascalCase
public function get_visibility_class() // snake_case
public function visibility() // sin verbo
```
#### Scenario: Metodos privados
- **WHEN** se define un metodo privado
- **THEN** DEBE seguir camelCase (igual que publicos)
- **AND** ejemplos correctos:
```php
private function parseResponse(): array
private function validateInternal(): bool
private function generateCSS(array $data): string
```
#### Scenario: Metodos booleanos
- **WHEN** un metodo retorna un valor booleano
- **THEN** DEBE usar prefijo `is`, `has`, `can`, `should`
- **AND** ejemplos correctos:
```php
public function isEnabled(array $data): bool
public function hasPermission(string $capability): bool
public function canProcess(): bool
public function shouldShow(string $component): bool
```
- **AND** ejemplos incorrectos:
```php
public function enabled(): bool // sin prefijo
public function checkEnabled(): bool // check no es booleano
public function getIsEnabled(): bool // get redundante
```
#### Scenario: Metodos getter/setter
- **WHEN** se define un metodo de acceso
- **THEN** getters DEBEN usar prefijo `get`
- **AND** setters DEBEN usar prefijo `set`
- **AND** ejemplos correctos:
```php
public function getData(): array
public function setData(array $data): void
public function getComponentName(): string
```
---
### Requirement: Nomenclatura de Propiedades y Variables
Las propiedades y variables DEBEN seguir convencion camelCase.
#### Scenario: Propiedades de clase
- **WHEN** se declara una propiedad de clase
- **THEN** DEBE seguir camelCase
- **AND** DEBE tener visibilidad explicita (private, protected, public)
- **AND** ejemplos correctos:
```php
private CSSGeneratorInterface $cssGenerator;
private string $componentName;
protected array $settings;
```
- **AND** ejemplos incorrectos:
```php
private $CssGenerator; // PascalCase
private $css_generator; // snake_case
private $_cssGenerator; // prefijo _ (no necesario en PHP moderno)
```
#### Scenario: Propiedades booleanas
- **WHEN** se define una propiedad booleana
- **THEN** DEBE usar prefijo `is`, `has`, `can`
- **AND** ejemplos correctos:
```php
private bool $isEnabled;
private bool $hasChanges;
private bool $canEdit;
```
#### Scenario: Variables locales
- **WHEN** se declara una variable local
- **THEN** DEBE seguir $camelCase
- **AND** DEBE ser descriptiva
- **AND** ejemplos correctos:
```php
$showDesktop = $data['visibility']['show_on_desktop'] ?? true;
$visibilityClass = $this->getVisibilityClass($data);
$componentSettings = $this->repository->get($componentName);
```
- **AND** ejemplos incorrectos:
```php
$ShowDesktop // PascalCase
$show_desktop // snake_case
$sd // abreviatura
$strShowDesktop // notacion hungara
```
#### Scenario: Parametros de metodo
- **WHEN** se declara un parametro de metodo
- **THEN** DEBE seguir $camelCase
- **AND** ejemplos correctos:
```php
public function render(Component $component): string
public function validateField(string $fieldName, mixed $value): bool
```
#### Scenario: Variables de iteracion
- **WHEN** se usa una variable de iteracion en bucle
- **THEN** se permiten nombres cortos para indices: `$i`, `$j`, `$k`
- **AND** se prefiere nombre descriptivo para elementos
- **AND** ejemplos correctos:
```php
for ($i = 0; $i < count($items); $i++)
foreach ($components as $component)
foreach ($settings as $key => $value)
```
---
### Requirement: Nomenclatura de Constantes
Las constantes DEBEN seguir convencion UPPER_SNAKE_CASE.
#### Scenario: Constantes de clase
- **WHEN** se define una constante de clase
- **THEN** DEBE seguir UPPER_SNAKE_CASE
- **AND** ejemplos correctos:
```php
private const COMPONENT_NAME = 'contact-form';
public const MAX_RETRY_COUNT = 3;
protected const DEFAULT_TIMEOUT = 5000;
```
- **AND** ejemplos incorrectos:
```php
private const componentName = 'contact-form'; // camelCase
private const ComponentName = 'contact-form'; // PascalCase
```
#### Scenario: Constantes globales
- **WHEN** se define una constante global del tema
- **THEN** DEBE usar prefijo `ROI_THEME_`
- **AND** DEBE seguir UPPER_SNAKE_CASE
- **AND** ejemplos correctos:
```php
define('ROI_THEME_VERSION', '1.0.0');
define('ROI_THEME_PATH', get_template_directory());
```
---
### Requirement: Nomenclatura de component_name
El identificador de componente DEBE usar kebab-case.
#### Scenario: component_name en JSON
- **WHEN** se define component_name en un schema JSON
- **THEN** DEBE usar kebab-case
- **AND** DEBE coincidir con el nombre del archivo JSON
- **AND** ejemplos correctos:
```json
{
"component_name": "contact-form",
"component_name": "featured-image",
"component_name": "top-notification-bar",
"component_name": "cta-box-sidebar"
}
```
#### Scenario: component_name en BD
- **WHEN** se guarda component_name en base de datos
- **THEN** DEBE mantener kebab-case
- **AND** tabla: `wp_roi_theme_component_settings`
- **AND** columna: `component_name`
#### Scenario: component_name en codigo PHP
- **WHEN** se usa component_name en codigo PHP
- **THEN** DEBE mantenerse en kebab-case
- **AND** ejemplos correctos:
```php
private const COMPONENT_NAME = 'contact-form';
public function supports(string $componentType): bool
{
return $componentType === 'contact-form';
}
// En data-attribute
$html .= 'data-component="contact-form"';
```
#### Scenario: Conversion kebab-case a PascalCase
- **WHEN** se necesita convertir component_name a nombre de carpeta/clase
- **THEN** eliminar guiones y capitalizar cada palabra
- **AND** ejemplos de conversion:
| kebab-case | PascalCase |
|------------|------------|
| `contact-form` | `ContactForm` |
| `featured-image` | `FeaturedImage` |
| `top-notification-bar` | `TopNotificationBar` |
| `cta-box-sidebar` | `CtaBoxSidebar` |
| `cta-lets-talk` | `CtaLetsTalk` |
---
### Requirement: Nomenclatura de Hooks WordPress
Los hooks DEBEN usar snake_case con prefijo del tema.
#### Scenario: Actions del tema
- **WHEN** se define un action hook del tema
- **THEN** DEBE usar prefijo `roi_theme_`
- **AND** DEBE seguir snake_case
- **AND** ejemplos correctos:
```php
do_action('roi_theme_after_render', $component);
do_action('roi_theme_before_form_submit');
do_action('roi_theme_component_loaded', $componentName);
```
#### Scenario: Filters del tema
- **WHEN** se define un filter hook del tema
- **THEN** DEBE usar prefijo `roi_theme_filter_`
- **AND** DEBE seguir snake_case
- **AND** ejemplos correctos:
```php
$css = apply_filters('roi_theme_filter_component_css', $css, $component);
$html = apply_filters('roi_theme_filter_render_output', $html);
```
#### Scenario: Acciones AJAX
- **WHEN** se registra una accion AJAX
- **THEN** DEBE usar prefijo `roi_`
- **AND** DEBE seguir snake_case
- **AND** ejemplos correctos:
```php
add_action('wp_ajax_roi_newsletter_subscribe', [$this, 'handle']);
add_action('wp_ajax_nopriv_roi_contact_form_submit', [$this, 'handle']);
```
---
### Requirement: Prohibicion de Notacion Hungara
La notacion hungara esta PROHIBIDA.
#### Scenario: Prefijos de tipo prohibidos
- **WHEN** se nombra una variable, propiedad o parametro
- **THEN** NO DEBE usar prefijos de tipo
- **AND** prefijos prohibidos:
| Prefijo | Significado | Ejemplo Incorrecto |
|---------|-------------|-------------------|
| `str` | String | `$strNombre` |
| `int`, `i` | Integer | `$intContador`, `$iTotal` |
| `b`, `bln` | Boolean | `$bActivo`, `$blnValido` |
| `arr` | Array | `$arrItems` |
| `obj` | Object | `$objRenderer` |
#### Scenario: Nombres correctos sin notacion hungara
- **WHEN** se reemplaza notacion hungara
- **THEN** usar nombres descriptivos
| Incorrecto | Correcto |
|------------|----------|
| `$strNombre` | `$name` o `$customerName` |
| `$bActivo` | `$isActive` |
| `$arrItems` | `$items` |
| `$objRenderer` | `$renderer` |
| `$intCount` | `$count` o `$itemCount` |
---
### Requirement: Validacion Pre-Commit de Nomenclatura
Las convenciones DEBEN validarse antes del commit.
#### Scenario: Checklist de nomenclatura
- **WHEN** el codigo esta listo para commit
- **THEN** verificar:
- [ ] Carpetas de modulo en PascalCase
- [ ] Archivos PHP en PascalCase.php
- [ ] Archivos JSON schema en kebab-case.json
- [ ] Namespaces en PascalCase jerarquico
- [ ] Clases en PascalCase
- [ ] Interfaces con sufijo Interface
- [ ] Metodos en camelCase
- [ ] Propiedades en camelCase
- [ ] Variables locales en $camelCase
- [ ] Constantes en UPPER_SNAKE_CASE
- [ ] component_name en kebab-case
- [ ] Hooks con prefijo roi_theme_
- [ ] SIN notacion hungara
- [ ] Metodos booleanos con is/has/can/should
- [ ] Renderers con sufijo Renderer
- [ ] FormBuilders con sufijo FormBuilder
- [ ] UseCases con sufijo UseCase
- [ ] Services con sufijo Service
---
## Tabla de Conversion Rapida
| De | A | Ejemplo |
|----|---|---------|
| kebab-case | PascalCase | `contact-form` → `ContactForm` |
| PascalCase | kebab-case | `ContactForm` → `contact-form` |
| PascalCase | camelCase | `ContactForm` → `contactForm` |
| snake_case | PascalCase | `contact_form` → `ContactForm` |
| snake_case | camelCase | `contact_form` → `contactForm` |
---
**Última actualización:** 2026-01-08