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

@@ -0,0 +1,38 @@
"""add branding and SSO columns to accounts
Revision ID: 58e3f27f3e8f
Revises: 9094262a4be3
Create Date: 2026-03-19 20:25:03.423778
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql
# revision identifiers, used by Alembic.
revision: str = '58e3f27f3e8f'
down_revision: Union[str, None] = '9094262a4be3'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
# Custom branding columns (Task 9)
op.add_column('accounts', sa.Column('branding_logo_url', sa.String(length=500), nullable=True))
op.add_column('accounts', sa.Column('branding_primary_color', sa.String(length=7), nullable=True))
op.add_column('accounts', sa.Column('branding_company_name', sa.String(length=200), nullable=True))
# SSO / SAML groundwork columns (Task 11)
op.add_column('accounts', sa.Column('sso_enabled', sa.Boolean(), server_default='false', nullable=False))
op.add_column('accounts', sa.Column('sso_provider', sa.String(length=20), nullable=True))
op.add_column('accounts', sa.Column('sso_config', postgresql.JSONB(astext_type=sa.Text()), nullable=True))
def downgrade() -> None:
op.drop_column('accounts', 'sso_config')
op.drop_column('accounts', 'sso_provider')
op.drop_column('accounts', 'sso_enabled')
op.drop_column('accounts', 'branding_company_name')
op.drop_column('accounts', 'branding_primary_color')
op.drop_column('accounts', 'branding_logo_url')