Files
leocrm/app/models/system_settings.py
T
Agent Zero 5ec1fc9b05 Phase 1: Fix all critical release blockers (B1-B10)
B1: Remove duplicate get_redis() — singleton no longer overwritten
B2: Plugin routes now enforce activation status via require_active_plugin()
B3: Fix UploadFile ForwardRef error — remove functools.wraps from wrap_plugin_route
B4: DMS upload uses true streaming via save_stream() instead of RAM accumulation
B5: Worker on_startup registers plugin event handlers + webhook dispatcher
B6: Implement send_password_reset_email job, remove raw token logging
B7: Webhook SSRF protection (IP validation, no redirects), secret removed from response
B8: RLS repair migration 0044 + separate crm_runtime DB user (NOSUPERUSER, NOBYPASSRLS)
B9: Fix .env.docker.example AUTH_SECRET → SECRET_KEY
B10: Remove Redis default password, remove exposed DB/Redis ports

Also: add frontend_url to config, add SMTP settings to .env.docker.example,
update prestart.sh to use MIGRATION_DATABASE_URL for alembic.
2026-07-26 20:45:42 +02:00

56 lines
2.9 KiB
Python

"""System settings model — singleton company master data per tenant."""
from __future__ import annotations
import uuid
from datetime import datetime
from sqlalchemy import DateTime, ForeignKey, Index, Integer, String
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.dialects.postgresql import UUID as PGUUID
from sqlalchemy.orm import Mapped, mapped_column
from app.core.db import Base, TenantMixin
class SystemSettings(Base, TenantMixin):
"""Singleton system settings per tenant — company master data for invoices/quotes."""
__tablename__ = "system_settings"
__table_args__ = (
Index("ix_system_settings_tenant", "tenant_id"),
)
id: Mapped[uuid.UUID] = mapped_column(
PGUUID(as_uuid=True), primary_key=True, default=uuid.uuid4
)
company_name: Mapped[str] = mapped_column(String(200), nullable=False)
company_legal_form: Mapped[str | None] = mapped_column(String(50), nullable=True)
company_street: Mapped[str] = mapped_column(String(255), nullable=False)
company_city: Mapped[str] = mapped_column(String(100), nullable=False)
company_zip: Mapped[str] = mapped_column(String(20), nullable=False)
company_country: Mapped[str] = mapped_column(String(2), nullable=False)
tax_number: Mapped[str | None] = mapped_column(String(50), nullable=True)
vat_id: Mapped[str | None] = mapped_column(String(50), nullable=True)
iban: Mapped[str | None] = mapped_column(String(34), nullable=True)
bic: Mapped[str | None] = mapped_column(String(11), nullable=True)
bank_name: Mapped[str | None] = mapped_column(String(100), nullable=True)
ceo: Mapped[str | None] = mapped_column(String(100), nullable=True)
trade_register: Mapped[str | None] = mapped_column(String(100), nullable=True)
default_currency_id: Mapped[uuid.UUID | None] = mapped_column(
PGUUID(as_uuid=True), ForeignKey("currencies.id", ondelete="SET NULL"), nullable=True
)
default_tax_id: Mapped[uuid.UUID | None] = mapped_column(
PGUUID(as_uuid=True), ForeignKey("tax_rates.id", ondelete="SET NULL"), nullable=True
)
invoice_prefix: Mapped[str] = mapped_column(String(20), nullable=False, default="RE-")
quote_prefix: Mapped[str] = mapped_column(String(20), nullable=False, default="AN-")
payment_terms_days: Mapped[int] = mapped_column(Integer, nullable=False, default=14)
# Theme customization
theme_primary_color: Mapped[str] = mapped_column(String(20), nullable=False, default="#2563eb")
theme_accent_color: Mapped[str] = mapped_column(String(20), nullable=False, default="#d946ef")
theme_font_family: Mapped[str] = mapped_column(String(100), nullable=False, default="Inter")
theme_border_radius: Mapped[str] = mapped_column(String(20), nullable=False, default="0.5rem")
# Automation plugin settings (JSONB)
automation_config: Mapped[dict | None] = mapped_column(JSONB, nullable=True)