arm-core/api/src/models/enums.py
Andrey Epifancev 9e53fc64be Схема БД конфигурируемая: настройка DB_SCHEMA вместо зашитой dkb (#38)
DB_SCHEMA (по умолчанию dkb, валидация идентификатора) читают models/base.py (SCHEMA), db/db.py (search_path),
alembic/env.py и миграции 0001-0005 (SCHEMA и строковые FK f"{SCHEMA}.x.id" вместо литералов). В контуре -
OPENBAO__APP__DB_SCHEMA. Офлайн-SQL `alembic upgrade head --sql` при значении по умолчанию совпадает побайтно.
Тесты: валидация настройки, миграции и сессия приложения в схеме dkb_alt; .env.example/.env.test/README/CLAUDE.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EAKRDNzXtRrwmWz9z6PZu3
2026-10-07 19:26:37 +04:00

357 lines
9.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Enum'ы модели данных DBML v5.17 (28 штук) и фабрика `pg_enum` для PostgreSQL-колонок.
Источник истины — docs/model/data-model-v5.17.dbml (блоки `Enum {}`). Значения — строки DBML буквально, в порядке
DBML (включая кириллические `"ЮЛ"`/`"ИП"` и значения в разном регистре); `notes` DBML значениями не являются.
Имя члена совпадает со значением (все значения DBML — валидные python-идентификаторы, кириллица допустима).
Классы — `enum.StrEnum` (подкласс `str`) — удобно для pydantic/JSON; `values_callable` в `pg_enum` в БД пишет `.value`.
"""
import enum
from sqlalchemy import Enum as SAEnum
from .base import SCHEMA
class EntityType(enum.StrEnum):
"""DBML `entity_type`."""
ЮЛ = "ЮЛ" # noqa: PLC2401 — значение DBML буквально
ИП = "ИП" # noqa: PLC2401 — значение DBML буквально
class RelatedGroupKind(enum.StrEnum):
"""DBML `related_group_kind`."""
gsk = "gsk"
gsz = "gsz"
class AccountKind(enum.StrEnum):
"""DBML `account_kind`."""
A = "A"
P = "P"
AP = "AP"
class AccountRowType(enum.StrEnum):
"""DBML `account_row_type`."""
account = "account"
subaccount = "subaccount"
analytic = "analytic"
class BusinessSegment(enum.StrEnum):
"""DBML `business_segment`."""
DKB = "DKB"
DMSB = "DMSB"
DM = "DM"
class DocumentType(enum.StrEnum):
"""DBML `document_type`."""
BALANCE = "BALANCE"
INCOME = "INCOME"
OSV = "OSV"
DISCLOSURE = "DISCLOSURE"
OTHER = "OTHER"
class FileType(enum.StrEnum):
"""DBML `file_type`."""
XLS = "XLS"
XLSX = "XLSX"
XLSB = "XLSB"
PDF = "PDF"
PNG = "PNG"
JPG = "JPG"
class RecognitionPipeline(enum.StrEnum):
"""DBML `recognition_pipeline`."""
tabular = "tabular"
image = "image"
class PeriodQuarter(enum.StrEnum):
"""DBML `period_quarter`."""
Q1 = "Q1"
Q2 = "Q2"
Q3 = "Q3"
Q4 = "Q4"
class FileStatus(enum.StrEnum):
"""DBML `file_status`."""
UPLOADED = "UPLOADED"
PROCESSING = "PROCESSING"
PROCESSED = "PROCESSED"
ERROR = "ERROR"
SUPERSEDED = "SUPERSEDED"
class DocumentStatus(enum.StrEnum):
"""DBML `document_status`."""
RECOGNIZED = "RECOGNIZED"
NEEDS_CHECK = "NEEDS_CHECK"
CONFIRMED = "CONFIRMED"
ERROR = "ERROR"
class S3BucketRole(enum.StrEnum):
"""DBML `s3_bucket_role`."""
uploads = "uploads"
results = "results"
exports = "exports"
archive = "archive"
class RecognitionStatus(enum.StrEnum):
"""DBML `recognition_status`."""
queued = "queued"
published = "published"
processing = "processing"
done = "done"
needs_check = "needs_check"
error = "error"
timeout = "timeout"
dlq = "dlq"
class StatementType(enum.StrEnum):
"""DBML `statement_type`."""
balance = "balance"
income = "income"
class OsvGroupType(enum.StrEnum):
"""DBML `osv_group_type`."""
ACCOUNT = "ACCOUNT"
DEPARTMENT = "DEPARTMENT"
COUNTERPARTY = "COUNTERPARTY"
CONTRACT = "CONTRACT"
OTHER = "OTHER"
class CounterpartyMatchKind(enum.StrEnum):
"""DBML `counterparty_match_kind` (v5.16): способ сопоставления контрагента строки ОСВ.
`INN` / `NAME` / `ALIAS` — шаг автоматического резолва при маппинге; `MANUAL` — ручное сопоставление;
`PROPAGATED` — автоприменение по имени в версии (DOC-221278 п. 12–13).
"""
INN = "INN"
NAME = "NAME"
ALIAS = "ALIAS"
MANUAL = "MANUAL"
PROPAGATED = "PROPAGATED"
class OsvDataType(enum.StrEnum):
"""DBML `osv_data_type`."""
BU = "BU"
NU = "NU"
CURRENCY = "CURRENCY"
QUANTITY = "QUANTITY"
SUM = "SUM"
class ConsolidationScenario(enum.StrEnum):
"""DBML `consolidation_scenario`."""
CREATE = "CREATE"
CONFIRM = "CONFIRM"
class ConsolidationApproach(enum.StrEnum):
"""DBML `consolidation_approach`."""
BASIC = "BASIC"
EXTENDED = "EXTENDED"
class ConsolidationStatus(enum.StrEnum):
"""DBML `consolidation_status`."""
INITIATED = "INITIATED"
DOCUMENTS_PROCESSING = "DOCUMENTS_PROCESSING"
DATA_CORRECTION = "DATA_CORRECTION"
CONSOLIDATION_RF = "CONSOLIDATION_RF"
ADJUSTMENT = "ADJUSTMENT"
VERIFICATION_RF = "VERIFICATION_RF"
CONSOLIDATION_GO = "CONSOLIDATION_GO"
VERIFICATION_GO = "VERIFICATION_GO"
VERIFIED = "VERIFIED"
CANCELLED = "CANCELLED"
REJECTED = "REJECTED"
ARCHIVED = "ARCHIVED"
class CorrectionStatus(enum.StrEnum):
"""DBML `correction_status`."""
DRAFT = "DRAFT"
APPLIED = "APPLIED"
REVOKED = "REVOKED"
class DocumentCheckResult(enum.StrEnum):
"""DBML `document_check_result`."""
MATCH = "MATCH"
MISMATCH = "MISMATCH"
UNKNOWN = "UNKNOWN"
class LeHistoryEvent(enum.StrEnum):
"""DBML `le_history_event`."""
CREATE = "CREATE"
UPDATE = "UPDATE"
MOVE_TO_GROUP = "MOVE_TO_GROUP"
CLOSE = "CLOSE"
REMOVE_FROM_GROUP = "REMOVE_FROM_GROUP"
class ExSnapshotStatus(enum.StrEnum):
"""DBML `ex_snapshot_status`."""
ACTUAL = "ACTUAL"
ARCHIVE = "ARCHIVE"
class PermissionObject(enum.StrEnum):
"""DBML `permission_object`."""
DIRECTORY = "DIRECTORY"
DOCUMENT = "DOCUMENT"
CONSOLIDATION = "CONSOLIDATION"
KFO = "KFO"
EX = "EX"
EXPORT = "EXPORT"
USERS = "USERS"
AUDIT = "AUDIT"
class PermissionAction(enum.StrEnum):
"""DBML `permission_action`."""
VIEW = "VIEW"
EDIT = "EDIT"
APPROVE = "APPROVE"
VERIFY = "VERIFY"
DELETE = "DELETE"
EXPORT = "EXPORT"
ADMIN = "ADMIN"
class AuditSection(enum.StrEnum):
"""DBML `audit_section`."""
DIRECTORIES = "DIRECTORIES"
CONSOLIDATION = "CONSOLIDATION"
PRIMARY_DOCUMENTS = "PRIMARY_DOCUMENTS"
RECOGNITION = "RECOGNITION"
KFO = "KFO"
EXPORT = "EXPORT"
ACCESS = "ACCESS"
SESSION = "SESSION"
USERS = "USERS"
class AuditAction(enum.StrEnum):
"""DBML `audit_action`."""
LOGIN = "LOGIN"
LOGIN_FAILED = "LOGIN_FAILED"
LOGOUT = "LOGOUT"
CONSOLIDATION_CREATE = "CONSOLIDATION_CREATE"
CONSOLIDATION_STATUS_CHANGE = "CONSOLIDATION_STATUS_CHANGE"
CONSOLIDATION_APPROVE = "CONSOLIDATION_APPROVE"
CONSOLIDATION_VERIFY = "CONSOLIDATION_VERIFY"
GROUP_CHANGE = "GROUP_CHANGE"
LEGAL_ENTITY_CHANGE = "LEGAL_ENTITY_CHANGE"
MEMBERSHIP_CHANGE = "MEMBERSHIP_CHANGE"
ASSIGNMENT_CHANGE = "ASSIGNMENT_CHANGE"
FILE_UPLOAD = "FILE_UPLOAD"
FILE_DELETE = "FILE_DELETE"
FILE_REPLACE = "FILE_REPLACE"
DOCUMENT_CONFIRM = "DOCUMENT_CONFIRM"
CONSOLIDATION_LOCK = "CONSOLIDATION_LOCK"
CONSOLIDATION_LOCK_TAKEOVER = "CONSOLIDATION_LOCK_TAKEOVER"
DISCLOSURE_EDIT = "DISCLOSURE_EDIT"
RECOGNIZED_DATA_EDIT = "RECOGNIZED_DATA_EDIT"
OSV_COUNTERPARTY_MAP = "OSV_COUNTERPARTY_MAP"
OSV_TYPE_OVERRIDE = "OSV_TYPE_OVERRIDE"
CORRECTION_CREATE = "CORRECTION_CREATE"
CORRECTION_EDIT = "CORRECTION_EDIT"
CORRECTION_REVOKE = "CORRECTION_REVOKE"
GOODWILL_EDIT = "GOODWILL_EDIT"
EXPORT = "EXPORT"
DIRECTORY_IMPORT = "DIRECTORY_IMPORT"
USER_ROLE_CHANGE = "USER_ROLE_CHANGE"
USER_CHANGE = "USER_CHANGE"
ROLE_PERMISSION_CHANGE = "ROLE_PERMISSION_CHANGE"
#: Реестр: имя enum в DBML (= имя типа в PostgreSQL) → класс.
ENUMS: dict[str, type[enum.Enum]] = {
"entity_type": EntityType,
"related_group_kind": RelatedGroupKind,
"account_kind": AccountKind,
"account_row_type": AccountRowType,
"business_segment": BusinessSegment,
"document_type": DocumentType,
"file_type": FileType,
"recognition_pipeline": RecognitionPipeline,
"period_quarter": PeriodQuarter,
"file_status": FileStatus,
"document_status": DocumentStatus,
"s3_bucket_role": S3BucketRole,
"recognition_status": RecognitionStatus,
"statement_type": StatementType,
"osv_group_type": OsvGroupType,
"counterparty_match_kind": CounterpartyMatchKind,
"osv_data_type": OsvDataType,
"consolidation_scenario": ConsolidationScenario,
"consolidation_approach": ConsolidationApproach,
"consolidation_status": ConsolidationStatus,
"correction_status": CorrectionStatus,
"document_check_result": DocumentCheckResult,
"le_history_event": LeHistoryEvent,
"ex_snapshot_status": ExSnapshotStatus,
"permission_object": PermissionObject,
"permission_action": PermissionAction,
"audit_section": AuditSection,
"audit_action": AuditAction,
}
def pg_enum(name: str) -> SAEnum:
"""Тип колонки для enum DBML `name`: нативный PG-enum `<схема>.<name>`, значения — `.value` членов.
Создание типа — поведение SQLAlchemy по умолчанию (`create_type=True`, `checkfirst`): `Base.metadata.create_all`
создаёт типы сам; миграция 0001 создаёт их явно.
"""
return SAEnum(
ENUMS[name],
name=name,
schema=SCHEMA,
native_enum=True,
values_callable=lambda e: [m.value for m in e],
)