feat(enterprise): add custom branding system — logo, accent color, company name

- Add branding_logo_url, branding_primary_color, branding_company_name columns to Account model
- Add Alembic migration (58e3f27f3e8f) for branding and SSO columns
- Add GET/PATCH /accounts/me/branding endpoints (owner-only for PATCH)
- Add BrandingSettingsPage with logo URL input, color picker, preview section
- Add /account/branding route (ProtectedRoute owner) in router.tsx
- Add Branding link card in AccountSettingsPage

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-19 20:35:35 +00:00
parent 1f4a8a6389
commit 2f56327f81
6 changed files with 504 additions and 2 deletions

View File

@@ -3,7 +3,7 @@ from datetime import datetime, timezone
from typing import Optional, TYPE_CHECKING
from sqlalchemy import String, DateTime, ForeignKey, Boolean, Integer
from sqlalchemy.orm import Mapped, mapped_column, relationship
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.dialects.postgresql import UUID, JSONB
from app.core.database import Base
if TYPE_CHECKING:
@@ -44,6 +44,16 @@ class Account(Base):
Integer, nullable=True, default=100, server_default="100"
)
# Custom branding (Task 9)
branding_logo_url: Mapped[Optional[str]] = mapped_column(String(500), nullable=True)
branding_primary_color: Mapped[Optional[str]] = mapped_column(String(7), nullable=True) # hex like #06b6d4
branding_company_name: Mapped[Optional[str]] = mapped_column(String(200), nullable=True)
# SSO / SAML groundwork (Task 11)
sso_enabled: Mapped[bool] = mapped_column(Boolean, default=False, server_default="false")
sso_provider: Mapped[Optional[str]] = mapped_column(String(20), nullable=True) # "saml" | "oidc"
sso_config: Mapped[Optional[dict]] = mapped_column(JSONB, nullable=True)
# Relationships
owner: Mapped["User"] = relationship("User", foreign_keys=[owner_id], back_populates="owned_account")
users: Mapped[list["User"]] = relationship("User", foreign_keys="[User.account_id]", back_populates="account")