Modelos de Base de Datos ======================== Este documento describe los modelos de Django que componen la base de datos de NoxPanel. Todos los modelos utilizan PostgreSQL 15 como motor y ``BigAutoField`` como campo de clave primaria por defecto (excepto donde se usa ``UUIDField``). App: accounts -------------- User ~~~~~ Modelo de usuario personalizado que extiende ``AbstractUser`` de Django. Implementa control de acceso basado en roles y permisos por módulo. .. list-table:: :header-rows: 1 :widths: 25 20 55 * - Campo - Tipo - Descripción * - ``email`` - EmailField (unique) - Dirección de email principal del usuario. * - ``role`` - CharField - Rol del usuario: ``admin`` o ``client``. * - ``is_verified`` - BooleanField - Indica si el email ha sido verificado. * - ``proxmox_username`` - CharField - Usuario asociado en Proxmox VE (opcional). * - ``can_manage_vms`` - BooleanField - Permiso para gestionar máquinas virtuales. * - ``vm_quota`` - IntegerField - Número máximo de VMs que puede crear (default: 5). * - ``can_access_vps`` - BooleanField - Acceso al módulo de VPS & VMs. * - ``can_access_hosting`` - BooleanField - Acceso al módulo de Hosting. * - ``can_access_billing`` - BooleanField - Acceso al módulo de Facturación. * - ``can_access_ticketing`` - BooleanField - Acceso al módulo de Tickets. * - ``phone`` - CharField - Teléfono de contacto (opcional). * - ``company`` - CharField - Nombre de la empresa (opcional). * - ``created_at`` - DateTimeField - Fecha de creación (automática). * - ``updated_at`` - DateTimeField - Última modificación (automática). **Tabla**: ``users`` **Índices**: ``email``, ``role`` **Métodos principales**: - ``is_admin`` / ``is_client``: Propiedades para verificar el rol. - ``has_admin_access()``: Verifica acceso admin (superuser o rol admin). - ``has_module_access(module_name)``: Verificación genérica de acceso a módulo. - ``can_create_vm()``: Verifica si la cuota de VMs permite crear más. App: hosting ------------- HostingPackage ~~~~~~~~~~~~~~~ Paquetes predefinidos de hosting (S, M, XL, XXL) que definen cuotas estándar. .. list-table:: :header-rows: 1 :widths: 25 20 55 * - Campo - Tipo - Descripción * - ``name`` - CharField (unique) - Nombre del paquete. * - ``slug`` - SlugField (unique) - Identificador URL-friendly. * - ``quota_sites`` - IntegerField - Máximo de sitios web (default: 5). * - ``quota_databases`` - IntegerField - Máximo de bases de datos (default: 3). * - ``quota_domains`` - IntegerField - Máximo de dominios (default: 5). * - ``quota_storage_gb`` - IntegerField - Almacenamiento máximo en GB (default: 5). * - ``quota_ftp_users`` - IntegerField - Máximo de cuentas FTP (default: 3). * - ``quota_mailboxes`` - IntegerField - Máximo de buzones de email (default: 5). * - ``quota_mail_aliases`` - IntegerField - Máximo de alias de email (default: 10). * - ``quota_shell_users`` - IntegerField - Máximo de usuarios shell (default: 1). * - ``price_monthly`` - DecimalField - Precio mensual (opcional). * - ``price_yearly`` - DecimalField - Precio anual (opcional). * - ``is_active`` - BooleanField - Paquete activo para nuevas asignaciones. * - ``is_featured`` - BooleanField - Paquete destacado en la interfaz. **Tabla**: ``hosting_packages`` HostingTenant ~~~~~~~~~~~~~~ Modelo central del sistema multi-tenant. Representa una organización que utiliza el panel de hosting con recursos y cuotas independientes. .. list-table:: :header-rows: 1 :widths: 25 20 55 * - Campo - Tipo - Descripción * - ``name`` - CharField (unique) - Nombre de la organización. * - ``slug`` - SlugField (unique) - Slug único para URLs y referencias internas. * - ``contact_email`` - EmailField - Email de contacto principal. * - ``is_active`` - BooleanField - Tenant activo o suspendido. * - ``package`` - FK → HostingPackage - Paquete de hosting asignado (opcional). * - ``quota_sites`` - IntegerField - Cuota de sitios web (default: 10). * - ``quota_databases`` - IntegerField - Cuota de bases de datos (default: 5). * - ``quota_domains`` - IntegerField - Cuota de dominios (default: 5). * - ``quota_storage_gb`` - IntegerField - Cuota de almacenamiento en GB (default: 10). * - ``quota_ftp_users`` - IntegerField - Cuota de cuentas FTP (default: 5). * - ``quota_mailboxes`` - IntegerField - Cuota de buzones (default: 10). * - ``quota_mail_aliases`` - IntegerField - Cuota de alias de email (default: 20). * - ``quota_shell_users`` - IntegerField - Cuota de usuarios shell (default: 1). * - ``created_by`` - FK → User - Usuario que creó el tenant. **Tabla**: ``hosting_tenants`` **Índices**: ``slug``, ``is_active`` **Métodos principales**: - ``can_create_site()`` / ``can_create_database()`` / ``can_create_domain()``: Verifican si la cuota permite crear más recursos. - ``apply_package_quotas()``: Copia las cuotas del paquete asignado al tenant. - ``get_sites_count()`` / ``get_databases_count()``: Conteo de recursos activos. TenantUser ~~~~~~~~~~~ Relación muchos-a-muchos entre usuarios y tenants con roles diferenciados. .. list-table:: :header-rows: 1 :widths: 25 20 55 * - Campo - Tipo - Descripción * - ``tenant`` - FK → HostingTenant - Tenant al que pertenece. * - ``user`` - FK → User - Usuario Django. * - ``role`` - CharField - Rol: ``admin``, ``member`` o ``viewer``. * - ``is_active`` - BooleanField - Membresía activa. **Tabla**: ``tenant_users`` | **Restricción**: ``unique_together = [tenant, user]`` HostingClient ~~~~~~~~~~~~~~ Mapeo entre un usuario Django/tenant y un cliente en el motor de hosting. .. list-table:: :header-rows: 1 :widths: 25 20 55 * - Campo - Tipo - Descripción * - ``tenant`` - FK → HostingTenant - Tenant asociado. * - ``user`` - OneToOne → User - Usuario Django asociado. * - ``hosting_client_id`` - IntegerField (unique) - ID del cliente en el motor de hosting. * - ``hosting_username`` - CharField - Nombre de usuario en el motor de hosting. * - ``hosting_password`` - CharField - Contraseña (encriptada) del cliente en el motor de hosting. * - ``last_sync`` - DateTimeField - Última sincronización con el motor de hosting. **Tabla**: ``hosting_clients`` HostingSite, HostingDatabase, HostingDomain ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Modelos que representan los recursos de hosting gestionados vía el motor de hosting. Todos comparten una estructura similar con los campos: - ``tenant`` (FK → HostingTenant): Tenant propietario. - ``hosting_client`` (FK → HostingClient): Cliente del motor de hosting asociado. - ``hosting_*_id`` (IntegerField): ID del recurso en el motor de hosting. - ``is_active`` (BooleanField): Estado del recurso (soft-delete). - ``created_at`` / ``updated_at``: Timestamps automáticos. **Campos específicos**: - **HostingSite** (``hosting_sites``): ``domain``, ``ip_address``, ``document_root``, ``ssl_enabled``. - **HostingDatabase** (``hosting_databases``): ``name``, ``db_user``, ``db_password`` (encriptada). - **HostingDomain** (``hosting_domains``): ``domain`` (unique), ``dns_enabled``. HostingFTPAccount, HostingMailbox, HostingMailAlias ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Recursos adicionales de hosting, todos vinculados a un tenant: - **HostingFTPAccount** (``hosting_ftp_accounts``): ``username``, ``password``, ``directory``, ``quota_mb``. FK → HostingSite. - **HostingMailbox** (``hosting_mailboxes``): ``email`` (unique), ``local_part``, ``quota_mb``, ``imap_enabled``, ``pop3_enabled``, ``smtp_enabled``. FK → HostingMailDomain. - **HostingMailAlias** (``hosting_mail_aliases``): ``source``, ``destination``. FK → HostingMailDomain. HostingDNSZone y HostingDNSRecord ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Gestión de DNS: - **HostingDNSZone** (``hosting_dns_zones``): ``origin`` (unique), ``ns_primary``, ``admin_email``, ``ttl``. FK → HostingTenant. - **HostingDNSRecord** (``hosting_dns_records``): ``record_type`` (A, AAAA, CNAME, MX, TXT, NS, SRV, CAA, PTR), ``name``, ``data``, ``priority``, ``ttl``. FK → HostingDNSZone. HostingShellUser y HostingSSLCertificate ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - **HostingShellUser** (``hosting_shell_users``): ``username``, ``shell`` (default: ``/bin/bash``), ``home_directory``. FK → HostingSite. - **HostingSSLCertificate** (``hosting_ssl_certificates``): ``cert_type`` (letsencrypt, custom, self_signed), ``domain``, ``expires_at``, ``certificate``, ``private_key``, ``ca_bundle``, ``auto_renew``. FK → HostingSite. App: billing ------------- BillingProfile ~~~~~~~~~~~~~~~ Datos fiscales de un tenant para facturación. .. list-table:: :header-rows: 1 :widths: 25 20 55 * - Campo - Tipo - Descripción * - ``tenant`` - OneToOne → HostingTenant - Tenant asociado. * - ``legal_name`` - CharField - Razón social. * - ``tax_id`` - CharField - NIF/CIF/VAT. * - ``address_line1/2`` - CharField - Dirección fiscal. * - ``city`` / ``state`` / ``postal_code`` / ``country`` - CharField - Ubicación (country: ISO 3166-1 alpha-2). * - ``billing_email`` - EmailField - Email para envío de facturas. * - ``stripe_customer_id`` - CharField - ID del cliente en Stripe. * - ``paypal_payer_id`` - CharField - ID del pagador en PayPal. * - ``currency`` - CharField - Moneda preferida (default: EUR). * - ``auto_pay`` - BooleanField - Cobro automático activado. **Tabla**: ``billing_profiles`` PricingPlan ~~~~~~~~~~~~ Planes de precios configurables por el administrador. - ``resource_type``: ``hosting``, ``vps``, ``addon``. - ``billing_period``: ``hourly``, ``daily``, ``monthly``, ``yearly``. - ``price``: Precio por periodo (DecimalField 10,4). - ``setup_fee``: Cuota de alta. - ``tax_rate``: Porcentaje de IVA (default: 21%). - ``hosting_package``: FK opcional → HostingPackage. **Tabla**: ``billing_pricing_plans`` Subscription ~~~~~~~~~~~~~ Suscripción activa que enlaza un tenant con un plan de precios. - ``id``: UUIDField (clave primaria). - ``status``: ``active``, ``paused``, ``cancelled``, ``past_due``, ``trial``. - ``custom_price``: Override de precio por cliente. - ``resource_type`` / ``resource_id`` / ``resource_name``: Recurso vinculado. - ``stripe_subscription_id`` / ``paypal_subscription_id``: IDs externos. - ``started_at`` / ``current_period_start`` / ``current_period_end``: Fechas. **Tabla**: ``billing_subscriptions`` Invoice e InvoiceItem ~~~~~~~~~~~~~~~~~~~~~~ Facturación: - **Invoice** (``billing_invoices``): ``number`` (INV-2026-0001), ``status`` (draft, pending, paid, overdue, cancelled, refunded), ``subtotal``, ``tax_rate``, ``tax_amount``, ``total``, ``currency``. Snapshot inmutable de datos fiscales (``billing_name``, ``billing_tax_id``, ``billing_address``). - **InvoiceItem** (``billing_invoice_items``): Líneas de factura con ``description``, ``quantity``, ``unit_price``, ``total``. Payment y PaymentMethod ~~~~~~~~~~~~~~~~~~~~~~~~ - **Payment** (``billing_payments``): ``gateway`` (stripe, paypal, bank_transfer, manual), ``status``, ``amount``, ``gateway_payment_id``, ``gateway_response`` (JSONField). - **PaymentMethod** (``billing_payment_methods``): ``method_type`` (card, sepa, paypal, bank_transfer), ``is_default``, ``stripe_payment_method_id``. UsageRecord ~~~~~~~~~~~~ Registros de consumo para facturación por horas o por uso. - ``subscription``: FK → Subscription. - ``resource_type`` / ``resource_id``: Recurso consumido. - ``quantity`` / ``unit`` / ``unit_price`` / ``total``: Datos de consumo. - ``invoiced``: Boolean para marcar si ya fue incluido en una factura. **Tabla**: ``billing_usage_records`` WebhookEvent ~~~~~~~~~~~~~~ Log de webhooks recibidos de Stripe y PayPal para auditoría y reprocesamiento: ``gateway``, ``event_id`` (unique), ``event_type``, ``payload`` (JSONField), ``processed``. **Tabla**: ``billing_webhook_events`` App: ticketing --------------- MailAccount ~~~~~~~~~~~~ Cuenta de email configurada para recibir y enviar tickets. .. list-table:: :header-rows: 1 :widths: 25 20 55 * - Campo - Tipo - Descripción * - ``email_address`` - EmailField (unique) - Dirección de email. * - ``protocol`` - CharField - Protocolo: ``imap``, ``pop3``, ``oauth2_microsoft``, ``oauth2_google``. * - ``incoming_server`` / ``incoming_port`` - CharField / IntegerField - Servidor y puerto de entrada (default: 993). * - ``outgoing_server`` / ``outgoing_port`` - CharField / IntegerField - Servidor SMTP y puerto (default: 587). * - ``password_encrypted`` - TextField - Contraseña cifrada con Fernet. * - ``oauth2_client_id`` / ``oauth2_client_secret_encrypted`` - CharField / TextField - Credenciales OAuth2 (cifradas). * - ``oauth2_tenant_id`` - CharField - Azure AD Tenant ID (para Microsoft 365). * - ``oauth2_access_token_encrypted`` / ``oauth2_refresh_token_encrypted`` - TextField - Tokens OAuth2 cifrados. * - ``default_department`` - FK → Department - Departamento por defecto para tickets nuevos. **Tabla**: ``ticketing_mail_accounts`` Department ~~~~~~~~~~~ Departamentos organizacionales: ``name``, ``slug``, ``email``, ``manager`` (FK → User). **Tabla**: ``ticketing_departments`` SLAPolicy ~~~~~~~~~~ Políticas de nivel de servicio por prioridad: - ``priority``: ``low``, ``medium``, ``high``, ``urgent``, ``critical`` (unique). - ``first_response_hours``: Horas máximas para primera respuesta. - ``resolution_hours``: Horas máximas para resolución completa. **Tabla**: ``ticketing_sla_policies`` Ticket ~~~~~~~ Modelo principal del sistema de tickets. - ``id``: UUIDField (clave primaria). - ``number``: Formato ``TK-000123`` (auto-generado, unique). - ``subject``: Asunto del ticket. - ``tenant``: FK → HostingTenant (opcional). - ``requester`` / ``requester_email`` / ``requester_name``: Solicitante. - ``assigned_to``: FK → User (agente asignado). - ``department``: FK → Department. - ``status``: ``new``, ``open``, ``pending``, ``on_hold``, ``resolved``, ``closed``. - ``priority``: ``low``, ``medium``, ``high``, ``urgent``, ``critical``. - ``source``: ``web``, ``email``, ``api``, ``phone``. - ``tags``: M2M → TicketTag. - ``sla_policy`` / ``sla_first_response_due`` / ``sla_resolution_due``: SLA. - ``email_message_id``: Message-ID del email original (para threading). **Tabla**: ``ticketing_tickets`` **Índices**: ``[status, priority]``, ``[assigned_to, status]``, ``[tenant, status]`` TicketMessage, TicketAttachment, CannedResponse ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - **TicketMessage** (``ticketing_messages``): ``ticket`` (FK), ``author``, ``message_type`` (reply, note, system), ``body`` / ``body_html``, ``is_from_agent``. - **TicketAttachment** (``ticketing_attachments``): ``file`` (FileField), ``filename``, ``content_type``, ``size_bytes``. - **CannedResponse** (``ticketing_canned_responses``): Respuestas predefinidas con ``title``, ``body``, ``department`` (FK opcional). Diagrama de Relaciones ----------------------- .. code-block:: text User ─────────────┬──── TenantUser ──── HostingTenant │ │ │ ┌────────────────┼────────────────┐ │ │ │ │ HostingClient │ HostingPackage BillingProfile │ │ │ ┌──────┼─────┐ │ Subscription │ │ │ │ │ HostingSite │ HostingDB HostingDomain Invoice ── InvoiceItem │ │ │ ┌────────┤ │ Payment │ │ │ FTPAccount │ HostingMailDomain ── HostingMailbox ShellUser │ HostingMailAlias SSLCert │ │ HostingDNSZone ── HostingDNSRecord Ticket ──── TicketMessage ──── TicketAttachment │ Department, SLAPolicy, TicketTag