feat(l1): add accounts.enabled_l1_categories with default allowlist
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,35 @@
|
|||||||
|
"""add enabled_l1_categories to accounts
|
||||||
|
|
||||||
|
Revision ID: cb9e282267d2
|
||||||
|
Revises: beca7464b6b4
|
||||||
|
Create Date: 2026-05-29 18:48:27.155183
|
||||||
|
|
||||||
|
"""
|
||||||
|
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 = 'cb9e282267d2'
|
||||||
|
down_revision: Union[str, None] = 'beca7464b6b4'
|
||||||
|
branch_labels: Union[str, Sequence[str], None] = None
|
||||||
|
depends_on: Union[str, Sequence[str], None] = None
|
||||||
|
|
||||||
|
|
||||||
|
_DEFAULT = ('["password_reset","account_lockout","printer","email_outlook_client",'
|
||||||
|
'"wifi_network_basics","vpn_connect","teams_zoom_av","browser_cache_cookies",'
|
||||||
|
'"peripheral_reconnect","os_restart_update"]')
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade() -> None:
|
||||||
|
op.add_column("accounts", sa.Column(
|
||||||
|
"enabled_l1_categories", postgresql.JSONB(), nullable=False,
|
||||||
|
server_default=sa.text(f"'{_DEFAULT}'::jsonb"),
|
||||||
|
))
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade() -> None:
|
||||||
|
op.drop_column("accounts", "enabled_l1_categories")
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import uuid
|
import uuid
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
from typing import Optional, TYPE_CHECKING
|
from typing import Optional, TYPE_CHECKING
|
||||||
from sqlalchemy import String, DateTime, ForeignKey, Boolean, Integer
|
from sqlalchemy import String, DateTime, ForeignKey, Boolean, Integer, text as sa_text
|
||||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||||
from sqlalchemy.dialects.postgresql import UUID, JSONB
|
from sqlalchemy.dialects.postgresql import UUID, JSONB
|
||||||
from app.core.database import Base
|
from app.core.database import Base
|
||||||
@@ -67,6 +67,17 @@ class Account(Base):
|
|||||||
sso_provider: Mapped[Optional[str]] = mapped_column(String(20), nullable=True) # "saml" | "oidc"
|
sso_provider: Mapped[Optional[str]] = mapped_column(String(20), nullable=True) # "saml" | "oidc"
|
||||||
sso_config: Mapped[Optional[dict]] = mapped_column(JSONB, nullable=True)
|
sso_config: Mapped[Optional[dict]] = mapped_column(JSONB, nullable=True)
|
||||||
|
|
||||||
|
# L1 AI tree builder — per-account allowlist of problem categories
|
||||||
|
enabled_l1_categories: Mapped[list[str]] = mapped_column(
|
||||||
|
JSONB(), nullable=False,
|
||||||
|
server_default=sa_text(
|
||||||
|
"'[\"password_reset\",\"account_lockout\",\"printer\","
|
||||||
|
"\"email_outlook_client\",\"wifi_network_basics\",\"vpn_connect\","
|
||||||
|
"\"teams_zoom_av\",\"browser_cache_cookies\",\"peripheral_reconnect\","
|
||||||
|
"\"os_restart_update\"]'::jsonb"
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
# Relationships
|
# Relationships
|
||||||
owner: Mapped["User"] = relationship("User", foreign_keys=[owner_id], back_populates="owned_account")
|
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")
|
users: Mapped[list["User"]] = relationship("User", foreign_keys="[User.account_id]", back_populates="account")
|
||||||
|
|||||||
7
backend/tests/test_account_l1_categories_column.py
Normal file
7
backend/tests/test_account_l1_categories_column.py
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
from app.models.account import Account
|
||||||
|
|
||||||
|
|
||||||
|
def test_account_has_enabled_l1_categories_default():
|
||||||
|
a = Account(name="Acme", display_code="ABC12345")
|
||||||
|
# Column default is applied at flush; attribute may be None pre-flush.
|
||||||
|
assert hasattr(a, "enabled_l1_categories")
|
||||||
Reference in New Issue
Block a user