class MigrationBusinessModule:
    __slots__: typing.Sequence[str] = (
        "_module",
        "_upgrade_process",
        "_downgrade_process",
    )
    def __init__(self, module: types.ModuleType, /) -> None:
        self._module = module
        self._upgrade_process = self._get_business_process("upgrade")
        self._downgrade_process = self._get_business_process("downgrade")
    @property
    def location(self) -> str:
        return self._module.__file__ or ""
    @property
    def description(self) -> str:
        return self._module.__doc__ or ""
    @property
    def version(self) -> int:
        return typing.cast(int, self._module.version)
    @property
    def upgrade_process(self) -> domain_migration.MigrationProcess:
        return self._upgrade_process
    @property
    def downgrade_process(self) -> domain_migration.MigrationProcess:
        return self._downgrade_process
    def get_name(self) -> str:
        *_, migration_name = self._module.__name__.split(".")
        return migration_name.strip()
    def _get_business_process(self, process_name: str, /) -> domain_migration.MigrationProcess:
        process = getattr(self._module, process_name, None)
        if process is None:
            raise ValueError(
                f"Can't find {process_name!r} process in {self.get_name()!r} migration."
            )
        return process