Files
chatballs/apps/backend/hub_platform/support/errors.py
T
Andrey 092553941f feat(support): verify product support token and start session
SPEC-HUB-0011 §12 (алгоритм start) + §14 (error model).

- token.py: HS256 JWT verify через stdlib (hmac/hashlib/base64), envelope claims
  (iss/aud/contract/iat/exp/jti/data). RS256/EdDSA — TODO.
- jsonpath.py: ограниченный JSONPath-subset ($.field, $.a.b, $.arr[0].field).
- session.py: verify_and_resolve (channel policy → token → contract → schema →
  identity/operator/ai/search extraction) + start_support_session (snapshot upsert,
  create-or-continue conversation, audit success/denied). Raw token не сохраняется
  и не логируется — только хэш jti.
- errors.py: машинные коды (TOKEN_*, CONTRACT_*, PAYLOAD_SCHEMA_INVALID, ...) +
  SupportSessionError; публичное сообщение безопасное.
- services.py: register_contract / set_contract_status (зеркало products).
- selectors.py / serializers.py / views.py / urls.py: CRUD контрактов (IsOwner),
  POST /api/v1/support/sessions/ (AllowAny, продукт→Hub), snapshot-by-subject.
- Публичный error envelope {error, message} для start (как OrderIngestView).
2026-07-09 00:55:03 +03:00

41 lines
1.8 KiB
Python

"""Машинные коды ошибок support-сессии (SPEC-HUB-0011 §14).
Публичный ответ widget всегда безопасный: {"error":"support_unavailable","message":...}.
Внутренний machine code пишется в audit payload и не раскрывается пользователю.
"""
from __future__ import annotations
# Публичное сообщение для всех категорий отказа — без технических деталей.
PUBLIC_SUPPORT_UNAVAILABLE = (
"Поддержка временно недоступна. Обновите страницу или обратитесь позже."
)
# Внутренние machine codes для audit/debug.
TOKEN_MISSING = "TOKEN_MISSING"
TOKEN_SIGNATURE_INVALID = "TOKEN_SIGNATURE_INVALID"
TOKEN_EXPIRED = "TOKEN_EXPIRED"
TOKEN_AUDIENCE_INVALID = "TOKEN_AUDIENCE_INVALID"
TOKEN_ISSUER_INVALID = "TOKEN_ISSUER_INVALID"
CONTRACT_NOT_FOUND = "CONTRACT_NOT_FOUND"
CONTRACT_DISABLED = "CONTRACT_DISABLED"
CONTRACT_CHANNEL_NOT_ALLOWED = "CONTRACT_CHANNEL_NOT_ALLOWED"
PAYLOAD_SCHEMA_INVALID = "PAYLOAD_SCHEMA_INVALID"
SUBJECT_MAPPING_EMPTY = "SUBJECT_MAPPING_EMPTY"
CHANNEL_NOT_SUPPORT = "CHANNEL_NOT_SUPPORT"
CHANNEL_PRODUCT_MISMATCH = "CHANNEL_PRODUCT_MISMATCH"
ANONYMOUS_NOT_ALLOWED = "ANONYMOUS_NOT_ALLOWED"
class SupportSessionError(Exception):
"""Отказ старта support-сессии с машинным кодом причины.
code — внутренний machine code (для audit); пользователю отдаётся только
безопасное публичное сообщение без раскрытия деталей проверки.
"""
def __init__(self, code: str, message: str = PUBLIC_SUPPORT_UNAVAILABLE) -> None:
super().__init__(message)
self.code = code