mirror of
https://github.com/dartdavros/chatballs.git
synced 2026-10-05 17:14:59 +03:00
Тарифы, подписки, entitlements, quotas и managed AI удалены целиком: - приложение subscriptions снесено (12 таблиц дропаются в tenancy/0020); - CustoAI и credential_mode удалены (ai/0016): AI только через BYOK-провайдера организации; активация агента требует настроенного провайдера; - вычищены все quota/entitlement-гейты: диалоги, порталы, интеграции, продукты, звонки (p2p-слоты), storage (остаётся технический учёт без лимитов); - provisioning без плана/подписки; приглашение владельца без активации тарифа; - эндпоинт и раздел «Тариф и оплата» удалены (фронт + бэк), HasEntitlement снят; - уведомление LIMIT_REACHED удалено (notifications/0009); - заодно: чек-лист запуска /company/launch-checklist/ (SPEC-HUB-0031 §5) и фикс сохранения provider_integration при обновлении агента. Backend 550 тестов OK (докер, миграции с нуля), frontend tsc + vitest 67 OK. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
33 lines
984 B
Python
33 lines
984 B
Python
from typing import Any
|
|
|
|
from rest_framework import status
|
|
from rest_framework.response import Response
|
|
from rest_framework.views import exception_handler as drf_exception_handler
|
|
|
|
|
|
|
|
def _flatten(data: Any) -> str:
|
|
if isinstance(data, str):
|
|
return data
|
|
if isinstance(data, dict):
|
|
return "; ".join(_flatten(value) for value in data.values())
|
|
if isinstance(data, (list, tuple)):
|
|
return "; ".join(_flatten(item) for item in data)
|
|
return str(data)
|
|
|
|
|
|
def api_exception_handler(exc: Exception, context: dict[str, Any]):
|
|
"""Normalize every DRF error body to the SPA contract: {"detail": "<text>"}."""
|
|
response = drf_exception_handler(exc, context)
|
|
if response is None:
|
|
return None
|
|
data = response.data
|
|
if (
|
|
isinstance(data, dict)
|
|
and list(data.keys()) == ["detail"]
|
|
and isinstance(data["detail"], str)
|
|
):
|
|
return response
|
|
response.data = {"detail": _flatten(data)}
|
|
return response
|