From f58e48a0e33126b8563c40a78c77b180ab33e8cb Mon Sep 17 00:00:00 2001 From: ivan-borovets <130386813+ivan-borovets@users.noreply.github.com> Date: Fri, 17 Apr 2026 23:14:21 +0300 Subject: [PATCH 1/2] Infrastructure -> Outbound --- alembic.ini | 2 +- pyproject.toml | 14 +++++----- src/app/main/config/settings.py | 2 +- src/app/main/ioc/core.py | 18 ++++++------ .../ioc/{infrastructure.py => outbound.py} | 28 +++++++++---------- src/app/main/ioc/provider_registry.py | 4 +-- src/app/main/run.py | 2 +- .../{infrastructure => outbound}/__init__.py | 0 .../adapters/__init__.py | 0 .../adapters/auth_session_access_revoker.py | 2 +- .../auth_session_identity_provider.py | 2 +- .../adapters/bcrypt_password_hasher.py | 2 +- .../adapters/exceptions.py | 0 .../adapters/sqla_flusher.py | 4 +-- .../adapters/sqla_transaction_manager.py | 2 +- .../adapters/sqla_user_reader.py | 4 +-- .../adapters/sqla_user_tx_storage.py | 2 +- .../adapters/system_utc_timer.py | 0 .../auth_ctx/__init__.py | 0 .../auth_ctx/cookie_manager.py | 0 .../auth_ctx/exceptions.py | 0 .../auth_ctx/handlers/__init__.py | 0 .../auth_ctx/handlers/change_password.py | 2 +- .../auth_ctx/handlers/log_in.py | 6 ++-- .../auth_ctx/handlers/log_out.py | 2 +- .../auth_ctx/handlers/sign_up.py | 4 +-- .../auth_ctx/id_factory.py | 2 +- .../auth_ctx/jwt_processor.py | 4 +-- .../auth_ctx/jwt_types.py | 0 .../auth_ctx/model.py | 2 +- .../auth_ctx/service.py | 16 +++++------ .../auth_ctx/sqla_transaction_manager.py | 4 +-- .../auth_ctx/sqla_tx_storage.py | 8 +++--- .../auth_ctx/sqla_user_tx_storage.py | 4 +-- .../auth_ctx/types_.py | 0 .../auth_ctx/utc_timer.py | 2 +- .../exceptions.py | 0 .../persistence_sqla/__init__.py | 0 .../persistence_sqla/alembic/README | 0 .../persistence_sqla/alembic/__init__.py | 0 .../persistence_sqla/alembic/env.py | 4 +-- .../persistence_sqla/alembic/script.py.mako | 0 .../versions/2026-04-01_222815_users.py | 11 ++++---- .../2026-04-01_223011_auth_sessions.py | 11 ++++---- .../alembic/versions/__init__.py | 0 .../persistence_sqla/constraint_names.py | 0 .../persistence_sqla/mappings/__init__.py | 0 .../persistence_sqla/mappings/all.py | 6 ++-- .../persistence_sqla/mappings/auth_session.py | 4 +-- .../persistence_sqla/mappings/user.py | 2 +- .../persistence_sqla/registry.py | 0 .../http/account/change_password.py | 8 +++--- src/app/presentation/http/account/log_in.py | 8 +++--- src/app/presentation/http/account/log_out.py | 6 ++-- src/app/presentation/http/account/sign_up.py | 8 +++--- .../http/auth_cookie_middleware.py | 2 +- .../presentation/http/users/activate_user.py | 4 +-- .../presentation/http/users/create_user.py | 6 ++-- .../http/users/deactivate_user.py | 4 +-- .../presentation/http/users/grant_admin.py | 4 +-- src/app/presentation/http/users/list_users.py | 4 +-- .../presentation/http/users/revoke_admin.py | 4 +-- .../http/users/set_user_password.py | 6 ++-- .../with_infra/account/test_sign_up.py | 2 +- tests/integration/with_infra/conftest.py | 2 +- .../profile_bcrypt_password_hasher.py | 2 +- .../{infrastructure => outbound}/__init__.py | 0 .../{infrastructure => outbound}/conftest.py | 2 +- .../test_bcrypt_password_hasher.py | 2 +- 69 files changed, 127 insertions(+), 129 deletions(-) rename src/app/main/ioc/{infrastructure.py => outbound.py} (83%) rename src/app/{infrastructure => outbound}/__init__.py (100%) rename src/app/{infrastructure => outbound}/adapters/__init__.py (100%) rename src/app/{infrastructure => outbound}/adapters/auth_session_access_revoker.py (86%) rename src/app/{infrastructure => outbound}/adapters/auth_session_identity_provider.py (86%) rename src/app/{infrastructure => outbound}/adapters/bcrypt_password_hasher.py (97%) rename src/app/{infrastructure => outbound}/adapters/exceptions.py (100%) rename src/app/{infrastructure => outbound}/adapters/sqla_flusher.py (91%) rename src/app/{infrastructure => outbound}/adapters/sqla_transaction_manager.py (92%) rename src/app/{infrastructure => outbound}/adapters/sqla_user_reader.py (95%) rename src/app/{infrastructure => outbound}/adapters/sqla_user_tx_storage.py (94%) rename src/app/{infrastructure => outbound}/adapters/system_utc_timer.py (100%) rename src/app/{infrastructure => outbound}/auth_ctx/__init__.py (100%) rename src/app/{infrastructure => outbound}/auth_ctx/cookie_manager.py (100%) rename src/app/{infrastructure => outbound}/auth_ctx/exceptions.py (100%) rename src/app/{infrastructure => outbound}/auth_ctx/handlers/__init__.py (100%) rename src/app/{infrastructure => outbound}/auth_ctx/handlers/change_password.py (97%) rename src/app/{infrastructure => outbound}/auth_ctx/handlers/log_in.py (92%) rename src/app/{infrastructure => outbound}/auth_ctx/handlers/log_out.py (92%) rename src/app/{infrastructure => outbound}/auth_ctx/handlers/sign_up.py (94%) rename src/app/{infrastructure => outbound}/auth_ctx/id_factory.py (74%) rename src/app/{infrastructure => outbound}/auth_ctx/jwt_processor.py (88%) rename src/app/{infrastructure => outbound}/auth_ctx/jwt_types.py (100%) rename src/app/{infrastructure => outbound}/auth_ctx/model.py (87%) rename src/app/{infrastructure => outbound}/auth_ctx/service.py (80%) rename src/app/{infrastructure => outbound}/auth_ctx/sqla_transaction_manager.py (82%) rename src/app/{infrastructure => outbound}/auth_ctx/sqla_tx_storage.py (85%) rename src/app/{infrastructure => outbound}/auth_ctx/sqla_user_tx_storage.py (88%) rename src/app/{infrastructure => outbound}/auth_ctx/types_.py (100%) rename src/app/{infrastructure => outbound}/auth_ctx/utc_timer.py (93%) rename src/app/{infrastructure => outbound}/exceptions.py (100%) rename src/app/{infrastructure => outbound}/persistence_sqla/__init__.py (100%) rename src/app/{infrastructure => outbound}/persistence_sqla/alembic/README (100%) rename src/app/{infrastructure => outbound}/persistence_sqla/alembic/__init__.py (100%) rename src/app/{infrastructure => outbound}/persistence_sqla/alembic/env.py (94%) rename src/app/{infrastructure => outbound}/persistence_sqla/alembic/script.py.mako (100%) rename src/app/{infrastructure => outbound}/persistence_sqla/alembic/versions/2026-04-01_222815_users.py (84%) rename src/app/{infrastructure => outbound}/persistence_sqla/alembic/versions/2026-04-01_223011_auth_sessions.py (80%) rename src/app/{infrastructure => outbound}/persistence_sqla/alembic/versions/__init__.py (100%) rename src/app/{infrastructure => outbound}/persistence_sqla/constraint_names.py (100%) rename src/app/{infrastructure => outbound}/persistence_sqla/mappings/__init__.py (100%) rename src/app/{infrastructure => outbound}/persistence_sqla/mappings/all.py (81%) rename src/app/{infrastructure => outbound}/persistence_sqla/mappings/auth_session.py (87%) rename src/app/{infrastructure => outbound}/persistence_sqla/mappings/user.py (96%) rename src/app/{infrastructure => outbound}/persistence_sqla/registry.py (100%) rename tests/unit/{infrastructure => outbound}/__init__.py (100%) rename tests/unit/{infrastructure => outbound}/conftest.py (94%) rename tests/unit/{infrastructure => outbound}/test_bcrypt_password_hasher.py (96%) diff --git a/alembic.ini b/alembic.ini index 5fa0c360..5f398355 100644 --- a/alembic.ini +++ b/alembic.ini @@ -5,7 +5,7 @@ # this is typically a path given in POSIX (e.g. forward slashes) # format, relative to the token %(here)s which refers to the location of this # ini file -script_location = src/app/infrastructure/persistence_sqla/alembic +script_location = src/app/outbound/persistence_sqla/alembic # template used to generate migration file names; The default value is %%(rev)s_%%(slug)s # Uncomment the line below if you want the files to be prepended with date and time diff --git a/pyproject.toml b/pyproject.toml index 20bfda2a..fedc6f39 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -97,12 +97,12 @@ containers = ["app"] layers = [ "(main)", "presentation", - "infrastructure", + "outbound", "core", ] ignore_imports = [ - "app.infrastructure.persistence_sqla.alembic.env -> app.main.config.loader", - "app.infrastructure.persistence_sqla.alembic.env -> app.main.config.settings", + "app.outbound.persistence_sqla.alembic.env -> app.main.config.loader", + "app.outbound.persistence_sqla.alembic.env -> app.main.config.settings", ] [[tool.importlinter.contracts]] @@ -137,8 +137,8 @@ forbidden_modules = ["app.core.commands"] id = "auth-ctx" name = "auth-ctx must use its own adapters" type = "forbidden" -source_modules = ["app.infrastructure.auth_ctx"] -forbidden_modules = ["app.infrastructure.adapters"] +source_modules = ["app.outbound.auth_ctx"] +forbidden_modules = ["app.outbound.adapters"] [tool.mypy] mypy_path = ["src"] @@ -247,7 +247,7 @@ split-on-trailing-comma = true [tool.ruff.lint.per-file-ignores] "scripts/dishka/plot_dependencies_data.py" = ["T201"] # print -"src/app/infrastructure/persistence_sqla/alembic/**" = ["ALL"] +"src/app/outbound/persistence_sqla/alembic/**" = ["ALL"] "tests/**" = [ "ARG002", # unused-method-argument "PLC2801", # unnecessary-dunder-call @@ -263,7 +263,7 @@ split-on-trailing-comma = true [tool.slotscheck] strict-imports = true exclude-modules = ''' -^app\.infrastructure\.persistence_sqla\.alembic +^app\.outbound\.persistence_sqla\.alembic ''' [tool.typos.files] diff --git a/src/app/main/config/settings.py b/src/app/main/config/settings.py index b3a7a308..7c0531fd 100644 --- a/src/app/main/config/settings.py +++ b/src/app/main/config/settings.py @@ -3,8 +3,8 @@ from pydantic import BaseModel, Field, PostgresDsn -from app.infrastructure.auth_ctx.jwt_types import JwtAlgorithm from app.main.config.logging_ import LoggingLevel +from app.outbound.auth_ctx.jwt_types import JwtAlgorithm class AppSettings(BaseModel): diff --git a/src/app/main/ioc/core.py b/src/app/main/ioc/core.py index 56f6cda0..47e2f8f0 100644 --- a/src/app/main/ioc/core.py +++ b/src/app/main/ioc/core.py @@ -18,19 +18,19 @@ from app.core.common.services.user import UserService from app.core.queries.list_users import ListUsers from app.core.queries.ports.user_reader import UserReader -from app.infrastructure.adapters.auth_session_access_revoker import AuthSessionAccessRevoker -from app.infrastructure.adapters.auth_session_identity_provider import AuthSessionIdentityProvider -from app.infrastructure.adapters.bcrypt_password_hasher import ( +from app.main.config.settings import PasswordHasherSettings +from app.outbound.adapters.auth_session_access_revoker import AuthSessionAccessRevoker +from app.outbound.adapters.auth_session_identity_provider import AuthSessionIdentityProvider +from app.outbound.adapters.bcrypt_password_hasher import ( BcryptPasswordHasher, HasherSemaphore, HasherThreadPoolExecutor, ) -from app.infrastructure.adapters.sqla_flusher import SqlaFlusher -from app.infrastructure.adapters.sqla_transaction_manager import SqlaTransactionManager -from app.infrastructure.adapters.sqla_user_reader import SqlaUserReader -from app.infrastructure.adapters.sqla_user_tx_storage import SqlaUserTxStorage -from app.infrastructure.adapters.system_utc_timer import SystemUtcTimer -from app.main.config.settings import PasswordHasherSettings +from app.outbound.adapters.sqla_flusher import SqlaFlusher +from app.outbound.adapters.sqla_transaction_manager import SqlaTransactionManager +from app.outbound.adapters.sqla_user_reader import SqlaUserReader +from app.outbound.adapters.sqla_user_tx_storage import SqlaUserTxStorage +from app.outbound.adapters.system_utc_timer import SystemUtcTimer class CoreProvider(Provider): diff --git a/src/app/main/ioc/infrastructure.py b/src/app/main/ioc/outbound.py similarity index 83% rename from src/app/main/ioc/infrastructure.py rename to src/app/main/ioc/outbound.py index 75c69179..b7128eaf 100644 --- a/src/app/main/ioc/infrastructure.py +++ b/src/app/main/ioc/outbound.py @@ -8,19 +8,6 @@ from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession, async_sessionmaker, create_async_engine from starlette.requests import Request -from app.infrastructure.adapters.bcrypt_password_hasher import HasherSemaphore, HasherThreadPoolExecutor -from app.infrastructure.auth_ctx.cookie_manager import CookieManager, CookieName -from app.infrastructure.auth_ctx.handlers.change_password import ChangePassword -from app.infrastructure.auth_ctx.handlers.log_in import LogIn -from app.infrastructure.auth_ctx.handlers.log_out import LogOut -from app.infrastructure.auth_ctx.handlers.sign_up import SignUp -from app.infrastructure.auth_ctx.jwt_processor import JwtProcessor -from app.infrastructure.auth_ctx.service import AuthService -from app.infrastructure.auth_ctx.sqla_transaction_manager import AuthSqlaTransactionManager -from app.infrastructure.auth_ctx.sqla_tx_storage import AuthSessionSqlaTxStorage -from app.infrastructure.auth_ctx.sqla_user_tx_storage import AuthSqlaUserTxStorage -from app.infrastructure.auth_ctx.types_ import AuthAsyncSession -from app.infrastructure.auth_ctx.utc_timer import AuthSessionUtcTimer from app.main.config.settings import ( CookieSettings, JwtSettings, @@ -29,6 +16,19 @@ SessionSettings, SqlaSettings, ) +from app.outbound.adapters.bcrypt_password_hasher import HasherSemaphore, HasherThreadPoolExecutor +from app.outbound.auth_ctx.cookie_manager import CookieManager, CookieName +from app.outbound.auth_ctx.handlers.change_password import ChangePassword +from app.outbound.auth_ctx.handlers.log_in import LogIn +from app.outbound.auth_ctx.handlers.log_out import LogOut +from app.outbound.auth_ctx.handlers.sign_up import SignUp +from app.outbound.auth_ctx.jwt_processor import JwtProcessor +from app.outbound.auth_ctx.service import AuthService +from app.outbound.auth_ctx.sqla_transaction_manager import AuthSqlaTransactionManager +from app.outbound.auth_ctx.sqla_tx_storage import AuthSessionSqlaTxStorage +from app.outbound.auth_ctx.sqla_user_tx_storage import AuthSqlaUserTxStorage +from app.outbound.auth_ctx.types_ import AuthAsyncSession +from app.outbound.auth_ctx.utc_timer import AuthSessionUtcTimer logger = logging.getLogger(__name__) @@ -168,7 +168,7 @@ class RequestProvider(Provider): request = from_context(provides=Request, scope=Scope.REQUEST) -def infrastructure_providers() -> tuple[Provider, ...]: +def outbound_providers() -> tuple[Provider, ...]: return ( HasherThreadPoolProvider(), PersistenceSqlaProvider(), diff --git a/src/app/main/ioc/provider_registry.py b/src/app/main/ioc/provider_registry.py index 8ca138b9..86d13e3d 100644 --- a/src/app/main/ioc/provider_registry.py +++ b/src/app/main/ioc/provider_registry.py @@ -3,11 +3,11 @@ from dishka import Provider from app.main.ioc.core import CoreProvider -from app.main.ioc.infrastructure import infrastructure_providers +from app.main.ioc.outbound import outbound_providers def get_providers() -> Iterable[Provider]: return ( CoreProvider(), - *infrastructure_providers(), + *outbound_providers(), ) diff --git a/src/app/main/run.py b/src/app/main/run.py index 9d52d1b4..5581045b 100644 --- a/src/app/main/run.py +++ b/src/app/main/run.py @@ -5,7 +5,6 @@ from dishka.integrations.fastapi import setup_dishka from fastapi import FastAPI -from app.infrastructure.persistence_sqla.mappings.all import map_tables from app.main.config.loader import ( load_app_settings, load_cookie_settings, @@ -26,6 +25,7 @@ ) from app.main.ioc.provider_registry import get_providers from app.main.setup import setup_global_exception_handlers, setup_logging, setup_middlewares +from app.outbound.persistence_sqla.mappings.all import map_tables from app.presentation.http.root_router import make_fastapi_root_router diff --git a/src/app/infrastructure/__init__.py b/src/app/outbound/__init__.py similarity index 100% rename from src/app/infrastructure/__init__.py rename to src/app/outbound/__init__.py diff --git a/src/app/infrastructure/adapters/__init__.py b/src/app/outbound/adapters/__init__.py similarity index 100% rename from src/app/infrastructure/adapters/__init__.py rename to src/app/outbound/adapters/__init__.py diff --git a/src/app/infrastructure/adapters/auth_session_access_revoker.py b/src/app/outbound/adapters/auth_session_access_revoker.py similarity index 86% rename from src/app/infrastructure/adapters/auth_session_access_revoker.py rename to src/app/outbound/adapters/auth_session_access_revoker.py index 2fa0fbc3..85266286 100644 --- a/src/app/infrastructure/adapters/auth_session_access_revoker.py +++ b/src/app/outbound/adapters/auth_session_access_revoker.py @@ -1,6 +1,6 @@ from app.core.common.entities.types_ import UserId from app.core.common.ports.access_revoker import AccessRevoker -from app.infrastructure.auth_ctx.service import AuthService +from app.outbound.auth_ctx.service import AuthService class AuthSessionAccessRevoker(AccessRevoker): diff --git a/src/app/infrastructure/adapters/auth_session_identity_provider.py b/src/app/outbound/adapters/auth_session_identity_provider.py similarity index 86% rename from src/app/infrastructure/adapters/auth_session_identity_provider.py rename to src/app/outbound/adapters/auth_session_identity_provider.py index 239fb3eb..eb9bd364 100644 --- a/src/app/infrastructure/adapters/auth_session_identity_provider.py +++ b/src/app/outbound/adapters/auth_session_identity_provider.py @@ -1,6 +1,6 @@ from app.core.common.entities.types_ import UserId from app.core.common.ports.identity_provider import IdentityProvider -from app.infrastructure.auth_ctx.service import AuthService +from app.outbound.auth_ctx.service import AuthService class AuthSessionIdentityProvider(IdentityProvider): diff --git a/src/app/infrastructure/adapters/bcrypt_password_hasher.py b/src/app/outbound/adapters/bcrypt_password_hasher.py similarity index 97% rename from src/app/infrastructure/adapters/bcrypt_password_hasher.py rename to src/app/outbound/adapters/bcrypt_password_hasher.py index 8a9ed29f..547df028 100644 --- a/src/app/infrastructure/adapters/bcrypt_password_hasher.py +++ b/src/app/outbound/adapters/bcrypt_password_hasher.py @@ -12,7 +12,7 @@ from app.core.common.entities.types_ import UserPasswordHash from app.core.common.ports.password_hasher import PasswordHasher from app.core.common.value_objects.raw_password import RawPassword -from app.infrastructure.adapters.exceptions import PasswordHasherBusyError +from app.outbound.adapters.exceptions import PasswordHasherBusyError HasherThreadPoolExecutor = NewType("HasherThreadPoolExecutor", ThreadPoolExecutor) HasherSemaphore = NewType("HasherSemaphore", asyncio.Semaphore) diff --git a/src/app/infrastructure/adapters/exceptions.py b/src/app/outbound/adapters/exceptions.py similarity index 100% rename from src/app/infrastructure/adapters/exceptions.py rename to src/app/outbound/adapters/exceptions.py diff --git a/src/app/infrastructure/adapters/sqla_flusher.py b/src/app/outbound/adapters/sqla_flusher.py similarity index 91% rename from src/app/infrastructure/adapters/sqla_flusher.py rename to src/app/outbound/adapters/sqla_flusher.py index 743f8fee..f9656ff2 100644 --- a/src/app/infrastructure/adapters/sqla_flusher.py +++ b/src/app/outbound/adapters/sqla_flusher.py @@ -7,8 +7,8 @@ from app.core.commands.exceptions import UsernameAlreadyExistsError from app.core.commands.ports.flusher import Flusher -from app.infrastructure.exceptions import StorageError -from app.infrastructure.persistence_sqla import constraint_names as cn +from app.outbound.exceptions import StorageError +from app.outbound.persistence_sqla import constraint_names as cn logger = logging.getLogger(__name__) diff --git a/src/app/infrastructure/adapters/sqla_transaction_manager.py b/src/app/outbound/adapters/sqla_transaction_manager.py similarity index 92% rename from src/app/infrastructure/adapters/sqla_transaction_manager.py rename to src/app/outbound/adapters/sqla_transaction_manager.py index f84273d4..7cc7ca44 100644 --- a/src/app/infrastructure/adapters/sqla_transaction_manager.py +++ b/src/app/outbound/adapters/sqla_transaction_manager.py @@ -5,7 +5,7 @@ from sqlalchemy.ext.asyncio import AsyncSession from app.core.commands.ports.transaction_manager import TransactionManager -from app.infrastructure.exceptions import StorageError +from app.outbound.exceptions import StorageError DB_COMMIT_DONE: Final[str] = "Commit was done." DB_COMMIT_FAILED: Final[str] = "Commit failed." diff --git a/src/app/infrastructure/adapters/sqla_user_reader.py b/src/app/outbound/adapters/sqla_user_reader.py similarity index 95% rename from src/app/infrastructure/adapters/sqla_user_reader.py rename to src/app/outbound/adapters/sqla_user_reader.py index e41eab8c..69188c88 100644 --- a/src/app/infrastructure/adapters/sqla_user_reader.py +++ b/src/app/outbound/adapters/sqla_user_reader.py @@ -7,8 +7,8 @@ from app.core.queries.query_support.exceptions import SortingError from app.core.queries.query_support.offset_pagination import OffsetPaginationParams from app.core.queries.query_support.sorting import SortingOrder, SortingParams -from app.infrastructure.exceptions import ReaderError -from app.infrastructure.persistence_sqla.mappings.user import users_table +from app.outbound.exceptions import ReaderError +from app.outbound.persistence_sqla.mappings.user import users_table class SqlaUserReader(UserReader): diff --git a/src/app/infrastructure/adapters/sqla_user_tx_storage.py b/src/app/outbound/adapters/sqla_user_tx_storage.py similarity index 94% rename from src/app/infrastructure/adapters/sqla_user_tx_storage.py rename to src/app/outbound/adapters/sqla_user_tx_storage.py index a1fbf865..7e55ae8d 100644 --- a/src/app/infrastructure/adapters/sqla_user_tx_storage.py +++ b/src/app/outbound/adapters/sqla_user_tx_storage.py @@ -5,7 +5,7 @@ from app.core.common.authorization.ports import AuthzUserFinder from app.core.common.entities.types_ import UserId from app.core.common.entities.user import User -from app.infrastructure.exceptions import StorageError +from app.outbound.exceptions import StorageError class SqlaUserTxStorage(UserTxStorage, AuthzUserFinder): diff --git a/src/app/infrastructure/adapters/system_utc_timer.py b/src/app/outbound/adapters/system_utc_timer.py similarity index 100% rename from src/app/infrastructure/adapters/system_utc_timer.py rename to src/app/outbound/adapters/system_utc_timer.py diff --git a/src/app/infrastructure/auth_ctx/__init__.py b/src/app/outbound/auth_ctx/__init__.py similarity index 100% rename from src/app/infrastructure/auth_ctx/__init__.py rename to src/app/outbound/auth_ctx/__init__.py diff --git a/src/app/infrastructure/auth_ctx/cookie_manager.py b/src/app/outbound/auth_ctx/cookie_manager.py similarity index 100% rename from src/app/infrastructure/auth_ctx/cookie_manager.py rename to src/app/outbound/auth_ctx/cookie_manager.py diff --git a/src/app/infrastructure/auth_ctx/exceptions.py b/src/app/outbound/auth_ctx/exceptions.py similarity index 100% rename from src/app/infrastructure/auth_ctx/exceptions.py rename to src/app/outbound/auth_ctx/exceptions.py diff --git a/src/app/infrastructure/auth_ctx/handlers/__init__.py b/src/app/outbound/auth_ctx/handlers/__init__.py similarity index 100% rename from src/app/infrastructure/auth_ctx/handlers/__init__.py rename to src/app/outbound/auth_ctx/handlers/__init__.py diff --git a/src/app/infrastructure/auth_ctx/handlers/change_password.py b/src/app/outbound/auth_ctx/handlers/change_password.py similarity index 97% rename from src/app/infrastructure/auth_ctx/handlers/change_password.py rename to src/app/outbound/auth_ctx/handlers/change_password.py index 43c25165..829931fb 100644 --- a/src/app/infrastructure/auth_ctx/handlers/change_password.py +++ b/src/app/outbound/auth_ctx/handlers/change_password.py @@ -6,7 +6,7 @@ from app.core.common.authorization.current_user_service import CurrentUserService from app.core.common.services.user import UserService from app.core.common.value_objects.raw_password import RawPassword -from app.infrastructure.auth_ctx.exceptions import ( +from app.outbound.auth_ctx.exceptions import ( AuthenticationChangeError, ReAuthenticationError, ) diff --git a/src/app/infrastructure/auth_ctx/handlers/log_in.py b/src/app/outbound/auth_ctx/handlers/log_in.py similarity index 92% rename from src/app/infrastructure/auth_ctx/handlers/log_in.py rename to src/app/outbound/auth_ctx/handlers/log_in.py index 72f330e4..370e6e65 100644 --- a/src/app/infrastructure/auth_ctx/handlers/log_in.py +++ b/src/app/outbound/auth_ctx/handlers/log_in.py @@ -6,12 +6,12 @@ from app.core.common.services.user import UserService from app.core.common.value_objects.raw_password import RawPassword from app.core.common.value_objects.username import Username -from app.infrastructure.auth_ctx.exceptions import ( +from app.outbound.auth_ctx.exceptions import ( AlreadyAuthenticatedError, AuthenticationError, ) -from app.infrastructure.auth_ctx.service import AuthService -from app.infrastructure.auth_ctx.sqla_user_tx_storage import AuthSqlaUserTxStorage +from app.outbound.auth_ctx.service import AuthService +from app.outbound.auth_ctx.sqla_user_tx_storage import AuthSqlaUserTxStorage AUTH_ACCOUNT_INACTIVE: Final[str] = "Your account is inactive. Please contact support." diff --git a/src/app/infrastructure/auth_ctx/handlers/log_out.py b/src/app/outbound/auth_ctx/handlers/log_out.py similarity index 92% rename from src/app/infrastructure/auth_ctx/handlers/log_out.py rename to src/app/outbound/auth_ctx/handlers/log_out.py index 3b141afd..98fd392c 100644 --- a/src/app/infrastructure/auth_ctx/handlers/log_out.py +++ b/src/app/outbound/auth_ctx/handlers/log_out.py @@ -1,7 +1,7 @@ import logging from app.core.common.authorization.current_user_service import CurrentUserService -from app.infrastructure.auth_ctx.service import AuthService +from app.outbound.auth_ctx.service import AuthService logger = logging.getLogger(__name__) diff --git a/src/app/infrastructure/auth_ctx/handlers/sign_up.py b/src/app/outbound/auth_ctx/handlers/sign_up.py similarity index 94% rename from src/app/infrastructure/auth_ctx/handlers/sign_up.py rename to src/app/outbound/auth_ctx/handlers/sign_up.py index 8a21a1c1..a3ceaf94 100644 --- a/src/app/infrastructure/auth_ctx/handlers/sign_up.py +++ b/src/app/outbound/auth_ctx/handlers/sign_up.py @@ -10,11 +10,11 @@ from app.core.common.services.user import UserService from app.core.common.value_objects.raw_password import RawPassword from app.core.common.value_objects.username import Username -from app.infrastructure.auth_ctx.exceptions import ( +from app.outbound.auth_ctx.exceptions import ( AlreadyAuthenticatedError, AuthenticationError, ) -from app.infrastructure.auth_ctx.sqla_user_tx_storage import AuthSqlaUserTxStorage +from app.outbound.auth_ctx.sqla_user_tx_storage import AuthSqlaUserTxStorage logger = logging.getLogger(__name__) diff --git a/src/app/infrastructure/auth_ctx/id_factory.py b/src/app/outbound/auth_ctx/id_factory.py similarity index 74% rename from src/app/infrastructure/auth_ctx/id_factory.py rename to src/app/outbound/auth_ctx/id_factory.py index b936c7f9..e30bd459 100644 --- a/src/app/infrastructure/auth_ctx/id_factory.py +++ b/src/app/outbound/auth_ctx/id_factory.py @@ -1,6 +1,6 @@ import secrets -from app.infrastructure.auth_ctx.model import SessionId +from app.outbound.auth_ctx.model import SessionId def create_session_id(value: str | None = None) -> SessionId: diff --git a/src/app/infrastructure/auth_ctx/jwt_processor.py b/src/app/outbound/auth_ctx/jwt_processor.py similarity index 88% rename from src/app/infrastructure/auth_ctx/jwt_processor.py rename to src/app/outbound/auth_ctx/jwt_processor.py index 340da028..c7177543 100644 --- a/src/app/infrastructure/auth_ctx/jwt_processor.py +++ b/src/app/outbound/auth_ctx/jwt_processor.py @@ -2,8 +2,8 @@ import jwt -from app.infrastructure.auth_ctx.jwt_types import JwtAlgorithm -from app.infrastructure.auth_ctx.model import AuthSession, SessionId +from app.outbound.auth_ctx.jwt_types import JwtAlgorithm +from app.outbound.auth_ctx.model import AuthSession, SessionId class JwtProcessor: diff --git a/src/app/infrastructure/auth_ctx/jwt_types.py b/src/app/outbound/auth_ctx/jwt_types.py similarity index 100% rename from src/app/infrastructure/auth_ctx/jwt_types.py rename to src/app/outbound/auth_ctx/jwt_types.py diff --git a/src/app/infrastructure/auth_ctx/model.py b/src/app/outbound/auth_ctx/model.py similarity index 87% rename from src/app/infrastructure/auth_ctx/model.py rename to src/app/outbound/auth_ctx/model.py index 26212ff9..c7fdd474 100644 --- a/src/app/infrastructure/auth_ctx/model.py +++ b/src/app/outbound/auth_ctx/model.py @@ -12,7 +12,7 @@ class AuthSession: """ This class can become a domain entity in a new bounded context, enabling a monolithic architecture to become modular, while the other classes working - with it are likely to become application and infrastructure layer components. + with it are likely to become core and outbound layer components. For example, `LogIn` can become an interactor. """ diff --git a/src/app/infrastructure/auth_ctx/service.py b/src/app/outbound/auth_ctx/service.py similarity index 80% rename from src/app/infrastructure/auth_ctx/service.py rename to src/app/outbound/auth_ctx/service.py index 59d8f04f..aa52aaf3 100644 --- a/src/app/infrastructure/auth_ctx/service.py +++ b/src/app/outbound/auth_ctx/service.py @@ -1,12 +1,12 @@ from app.core.common.entities.types_ import UserId -from app.infrastructure.auth_ctx.cookie_manager import CookieManager -from app.infrastructure.auth_ctx.exceptions import AuthenticationError -from app.infrastructure.auth_ctx.id_factory import create_session_id -from app.infrastructure.auth_ctx.jwt_processor import JwtProcessor -from app.infrastructure.auth_ctx.model import AuthSession, SessionId -from app.infrastructure.auth_ctx.sqla_transaction_manager import AuthSqlaTransactionManager -from app.infrastructure.auth_ctx.sqla_tx_storage import AuthSessionSqlaTxStorage -from app.infrastructure.auth_ctx.utc_timer import AuthSessionUtcTimer +from app.outbound.auth_ctx.cookie_manager import CookieManager +from app.outbound.auth_ctx.exceptions import AuthenticationError +from app.outbound.auth_ctx.id_factory import create_session_id +from app.outbound.auth_ctx.jwt_processor import JwtProcessor +from app.outbound.auth_ctx.model import AuthSession, SessionId +from app.outbound.auth_ctx.sqla_transaction_manager import AuthSqlaTransactionManager +from app.outbound.auth_ctx.sqla_tx_storage import AuthSessionSqlaTxStorage +from app.outbound.auth_ctx.utc_timer import AuthSessionUtcTimer class AuthService: diff --git a/src/app/infrastructure/auth_ctx/sqla_transaction_manager.py b/src/app/outbound/auth_ctx/sqla_transaction_manager.py similarity index 82% rename from src/app/infrastructure/auth_ctx/sqla_transaction_manager.py rename to src/app/outbound/auth_ctx/sqla_transaction_manager.py index 8cec23df..471bc146 100644 --- a/src/app/infrastructure/auth_ctx/sqla_transaction_manager.py +++ b/src/app/outbound/auth_ctx/sqla_transaction_manager.py @@ -3,8 +3,8 @@ from sqlalchemy.exc import SQLAlchemyError -from app.infrastructure.auth_ctx.types_ import AuthAsyncSession -from app.infrastructure.exceptions import StorageError +from app.outbound.auth_ctx.types_ import AuthAsyncSession +from app.outbound.exceptions import StorageError DB_COMMIT_DONE: Final[str] = "Commit was done." DB_COMMIT_FAILED: Final[str] = "Commit failed." diff --git a/src/app/infrastructure/auth_ctx/sqla_tx_storage.py b/src/app/outbound/auth_ctx/sqla_tx_storage.py similarity index 85% rename from src/app/infrastructure/auth_ctx/sqla_tx_storage.py rename to src/app/outbound/auth_ctx/sqla_tx_storage.py index 77dab19b..f1cf0d04 100644 --- a/src/app/infrastructure/auth_ctx/sqla_tx_storage.py +++ b/src/app/outbound/auth_ctx/sqla_tx_storage.py @@ -2,10 +2,10 @@ from sqlalchemy.exc import SQLAlchemyError from app.core.common.entities.types_ import UserId -from app.infrastructure.auth_ctx.model import AuthSession, SessionId -from app.infrastructure.auth_ctx.types_ import AuthAsyncSession -from app.infrastructure.exceptions import StorageError -from app.infrastructure.persistence_sqla.mappings.auth_session import auth_sessions_table +from app.outbound.auth_ctx.model import AuthSession, SessionId +from app.outbound.auth_ctx.types_ import AuthAsyncSession +from app.outbound.exceptions import StorageError +from app.outbound.persistence_sqla.mappings.auth_session import auth_sessions_table class AuthSessionSqlaTxStorage: diff --git a/src/app/infrastructure/auth_ctx/sqla_user_tx_storage.py b/src/app/outbound/auth_ctx/sqla_user_tx_storage.py similarity index 88% rename from src/app/infrastructure/auth_ctx/sqla_user_tx_storage.py rename to src/app/outbound/auth_ctx/sqla_user_tx_storage.py index 17bf092a..cc692960 100644 --- a/src/app/infrastructure/auth_ctx/sqla_user_tx_storage.py +++ b/src/app/outbound/auth_ctx/sqla_user_tx_storage.py @@ -4,8 +4,8 @@ from app.core.common.entities.user import User from app.core.common.value_objects.username import Username -from app.infrastructure.exceptions import StorageError -from app.infrastructure.persistence_sqla.mappings.user import users_table +from app.outbound.exceptions import StorageError +from app.outbound.persistence_sqla.mappings.user import users_table class AuthSqlaUserTxStorage: diff --git a/src/app/infrastructure/auth_ctx/types_.py b/src/app/outbound/auth_ctx/types_.py similarity index 100% rename from src/app/infrastructure/auth_ctx/types_.py rename to src/app/outbound/auth_ctx/types_.py diff --git a/src/app/infrastructure/auth_ctx/utc_timer.py b/src/app/outbound/auth_ctx/utc_timer.py similarity index 93% rename from src/app/infrastructure/auth_ctx/utc_timer.py rename to src/app/outbound/auth_ctx/utc_timer.py index 9cbe3a9f..41244f49 100644 --- a/src/app/infrastructure/auth_ctx/utc_timer.py +++ b/src/app/outbound/auth_ctx/utc_timer.py @@ -1,7 +1,7 @@ from datetime import UTC, datetime, timedelta from app.core.common.value_objects.utc_datetime import UtcDatetime -from app.infrastructure.auth_ctx.model import AuthSession +from app.outbound.auth_ctx.model import AuthSession class AuthSessionUtcTimer: diff --git a/src/app/infrastructure/exceptions.py b/src/app/outbound/exceptions.py similarity index 100% rename from src/app/infrastructure/exceptions.py rename to src/app/outbound/exceptions.py diff --git a/src/app/infrastructure/persistence_sqla/__init__.py b/src/app/outbound/persistence_sqla/__init__.py similarity index 100% rename from src/app/infrastructure/persistence_sqla/__init__.py rename to src/app/outbound/persistence_sqla/__init__.py diff --git a/src/app/infrastructure/persistence_sqla/alembic/README b/src/app/outbound/persistence_sqla/alembic/README similarity index 100% rename from src/app/infrastructure/persistence_sqla/alembic/README rename to src/app/outbound/persistence_sqla/alembic/README diff --git a/src/app/infrastructure/persistence_sqla/alembic/__init__.py b/src/app/outbound/persistence_sqla/alembic/__init__.py similarity index 100% rename from src/app/infrastructure/persistence_sqla/alembic/__init__.py rename to src/app/outbound/persistence_sqla/alembic/__init__.py diff --git a/src/app/infrastructure/persistence_sqla/alembic/env.py b/src/app/outbound/persistence_sqla/alembic/env.py similarity index 94% rename from src/app/infrastructure/persistence_sqla/alembic/env.py rename to src/app/outbound/persistence_sqla/alembic/env.py index ff9d8db4..35b1fdae 100644 --- a/src/app/infrastructure/persistence_sqla/alembic/env.py +++ b/src/app/outbound/persistence_sqla/alembic/env.py @@ -8,8 +8,8 @@ from app.main.config.loader import load_postgres_settings from app.main.config.settings import PostgresSettings -from app.infrastructure.persistence_sqla.mappings.all import map_tables -from app.infrastructure.persistence_sqla.registry import mapper_registry +from app.outbound.persistence_sqla.mappings.all import map_tables +from app.outbound.persistence_sqla.registry import mapper_registry # this is the Alembic Config object, which provides # access to the values within the .ini file in use. diff --git a/src/app/infrastructure/persistence_sqla/alembic/script.py.mako b/src/app/outbound/persistence_sqla/alembic/script.py.mako similarity index 100% rename from src/app/infrastructure/persistence_sqla/alembic/script.py.mako rename to src/app/outbound/persistence_sqla/alembic/script.py.mako diff --git a/src/app/infrastructure/persistence_sqla/alembic/versions/2026-04-01_222815_users.py b/src/app/outbound/persistence_sqla/alembic/versions/2026-04-01_222815_users.py similarity index 84% rename from src/app/infrastructure/persistence_sqla/alembic/versions/2026-04-01_222815_users.py rename to src/app/outbound/persistence_sqla/alembic/versions/2026-04-01_222815_users.py index 71d951bb..3654eabe 100644 --- a/src/app/infrastructure/persistence_sqla/alembic/versions/2026-04-01_222815_users.py +++ b/src/app/outbound/persistence_sqla/alembic/versions/2026-04-01_222815_users.py @@ -6,17 +6,16 @@ """ -from typing import Sequence, Union +from collections.abc import Sequence -from alembic import op import sqlalchemy as sa - +from alembic import op # revision identifiers, used by Alembic. revision: str = "0e6c649ac887" -down_revision: Union[str, Sequence[str], None] = None -branch_labels: Union[str, Sequence[str], None] = None -depends_on: Union[str, Sequence[str], None] = None +down_revision: str | Sequence[str] | None = None +branch_labels: str | Sequence[str] | None = None +depends_on: str | Sequence[str] | None = None def upgrade() -> None: diff --git a/src/app/infrastructure/persistence_sqla/alembic/versions/2026-04-01_223011_auth_sessions.py b/src/app/outbound/persistence_sqla/alembic/versions/2026-04-01_223011_auth_sessions.py similarity index 80% rename from src/app/infrastructure/persistence_sqla/alembic/versions/2026-04-01_223011_auth_sessions.py rename to src/app/outbound/persistence_sqla/alembic/versions/2026-04-01_223011_auth_sessions.py index 751e05d3..2559c82c 100644 --- a/src/app/infrastructure/persistence_sqla/alembic/versions/2026-04-01_223011_auth_sessions.py +++ b/src/app/outbound/persistence_sqla/alembic/versions/2026-04-01_223011_auth_sessions.py @@ -6,17 +6,16 @@ """ -from typing import Sequence, Union +from collections.abc import Sequence -from alembic import op import sqlalchemy as sa - +from alembic import op # revision identifiers, used by Alembic. revision: str = "c025baa8044e" -down_revision: Union[str, Sequence[str], None] = "0e6c649ac887" -branch_labels: Union[str, Sequence[str], None] = None -depends_on: Union[str, Sequence[str], None] = None +down_revision: str | Sequence[str] | None = "0e6c649ac887" +branch_labels: str | Sequence[str] | None = None +depends_on: str | Sequence[str] | None = None def upgrade() -> None: diff --git a/src/app/infrastructure/persistence_sqla/alembic/versions/__init__.py b/src/app/outbound/persistence_sqla/alembic/versions/__init__.py similarity index 100% rename from src/app/infrastructure/persistence_sqla/alembic/versions/__init__.py rename to src/app/outbound/persistence_sqla/alembic/versions/__init__.py diff --git a/src/app/infrastructure/persistence_sqla/constraint_names.py b/src/app/outbound/persistence_sqla/constraint_names.py similarity index 100% rename from src/app/infrastructure/persistence_sqla/constraint_names.py rename to src/app/outbound/persistence_sqla/constraint_names.py diff --git a/src/app/infrastructure/persistence_sqla/mappings/__init__.py b/src/app/outbound/persistence_sqla/mappings/__init__.py similarity index 100% rename from src/app/infrastructure/persistence_sqla/mappings/__init__.py rename to src/app/outbound/persistence_sqla/mappings/__init__.py diff --git a/src/app/infrastructure/persistence_sqla/mappings/all.py b/src/app/outbound/persistence_sqla/mappings/all.py similarity index 81% rename from src/app/infrastructure/persistence_sqla/mappings/all.py rename to src/app/outbound/persistence_sqla/mappings/all.py index 78bd6435..51f76a6c 100644 --- a/src/app/infrastructure/persistence_sqla/mappings/all.py +++ b/src/app/outbound/persistence_sqla/mappings/all.py @@ -21,9 +21,9 @@ during database migrations. """ -from app.infrastructure.persistence_sqla.mappings.auth_session import map_auth_sessions_table -from app.infrastructure.persistence_sqla.mappings.user import map_users_table -from app.infrastructure.persistence_sqla.registry import mapper_registry +from app.outbound.persistence_sqla.mappings.auth_session import map_auth_sessions_table +from app.outbound.persistence_sqla.mappings.user import map_users_table +from app.outbound.persistence_sqla.registry import mapper_registry def map_tables() -> None: diff --git a/src/app/infrastructure/persistence_sqla/mappings/auth_session.py b/src/app/outbound/persistence_sqla/mappings/auth_session.py similarity index 87% rename from src/app/infrastructure/persistence_sqla/mappings/auth_session.py rename to src/app/outbound/persistence_sqla/mappings/auth_session.py index f41c4343..55d32e48 100644 --- a/src/app/infrastructure/persistence_sqla/mappings/auth_session.py +++ b/src/app/outbound/persistence_sqla/mappings/auth_session.py @@ -2,8 +2,8 @@ from sqlalchemy.orm import composite from app.core.common.value_objects.utc_datetime import UtcDatetime -from app.infrastructure.auth_ctx.model import AuthSession -from app.infrastructure.persistence_sqla.registry import mapper_registry +from app.outbound.auth_ctx.model import AuthSession +from app.outbound.persistence_sqla.registry import mapper_registry auth_sessions_table = Table( "auth_sessions", diff --git a/src/app/infrastructure/persistence_sqla/mappings/user.py b/src/app/outbound/persistence_sqla/mappings/user.py similarity index 96% rename from src/app/infrastructure/persistence_sqla/mappings/user.py rename to src/app/outbound/persistence_sqla/mappings/user.py index d723a566..387db38c 100644 --- a/src/app/infrastructure/persistence_sqla/mappings/user.py +++ b/src/app/outbound/persistence_sqla/mappings/user.py @@ -7,7 +7,7 @@ from app.core.common.entities.user import User from app.core.common.value_objects.username import Username from app.core.common.value_objects.utc_datetime import UtcDatetime -from app.infrastructure.persistence_sqla.registry import mapper_registry +from app.outbound.persistence_sqla.registry import mapper_registry def get_strenum_values(enum_cls: type[StrEnum]) -> list[str]: diff --git a/src/app/infrastructure/persistence_sqla/registry.py b/src/app/outbound/persistence_sqla/registry.py similarity index 100% rename from src/app/infrastructure/persistence_sqla/registry.py rename to src/app/outbound/persistence_sqla/registry.py diff --git a/src/app/presentation/http/account/change_password.py b/src/app/presentation/http/account/change_password.py index 15c3de5e..d70bc11b 100644 --- a/src/app/presentation/http/account/change_password.py +++ b/src/app/presentation/http/account/change_password.py @@ -9,10 +9,10 @@ from app.core.common.authorization.exceptions import AuthorizationError from app.core.common.exceptions import BusinessTypeError -from app.infrastructure.adapters.exceptions import PasswordHasherBusyError -from app.infrastructure.auth_ctx.exceptions import AuthenticationChangeError, AuthenticationError, ReAuthenticationError -from app.infrastructure.auth_ctx.handlers.change_password import ChangePassword, ChangePasswordRequest -from app.infrastructure.exceptions import StorageError +from app.outbound.adapters.exceptions import PasswordHasherBusyError +from app.outbound.auth_ctx.exceptions import AuthenticationChangeError, AuthenticationError, ReAuthenticationError +from app.outbound.auth_ctx.handlers.change_password import ChangePassword, ChangePasswordRequest +from app.outbound.exceptions import StorageError from app.presentation.http.errors.callbacks import log_info from app.presentation.http.errors.rules import HTTP_503_SERVICE_UNAVAILABLE_RULE diff --git a/src/app/presentation/http/account/log_in.py b/src/app/presentation/http/account/log_in.py index e6fa49c2..0a204890 100644 --- a/src/app/presentation/http/account/log_in.py +++ b/src/app/presentation/http/account/log_in.py @@ -7,10 +7,10 @@ from app.core.common.authorization.exceptions import AuthorizationError from app.core.common.exceptions import BusinessTypeError -from app.infrastructure.adapters.exceptions import PasswordHasherBusyError -from app.infrastructure.auth_ctx.exceptions import AlreadyAuthenticatedError, AuthenticationError -from app.infrastructure.auth_ctx.handlers.log_in import LogIn, LogInRequest -from app.infrastructure.exceptions import StorageError +from app.outbound.adapters.exceptions import PasswordHasherBusyError +from app.outbound.auth_ctx.exceptions import AlreadyAuthenticatedError, AuthenticationError +from app.outbound.auth_ctx.handlers.log_in import LogIn, LogInRequest +from app.outbound.exceptions import StorageError from app.presentation.http.errors.callbacks import log_info from app.presentation.http.errors.rules import HTTP_503_SERVICE_UNAVAILABLE_RULE diff --git a/src/app/presentation/http/account/log_out.py b/src/app/presentation/http/account/log_out.py index ddfd8924..a59dbc4a 100644 --- a/src/app/presentation/http/account/log_out.py +++ b/src/app/presentation/http/account/log_out.py @@ -7,9 +7,9 @@ from fastapi_error_map import ErrorAwareRouter from app.core.common.authorization.exceptions import AuthorizationError -from app.infrastructure.auth_ctx.exceptions import AuthenticationError -from app.infrastructure.auth_ctx.handlers.log_out import LogOut -from app.infrastructure.exceptions import StorageError +from app.outbound.auth_ctx.exceptions import AuthenticationError +from app.outbound.auth_ctx.handlers.log_out import LogOut +from app.outbound.exceptions import StorageError from app.presentation.http.errors.callbacks import log_info from app.presentation.http.errors.rules import HTTP_503_SERVICE_UNAVAILABLE_RULE diff --git a/src/app/presentation/http/account/sign_up.py b/src/app/presentation/http/account/sign_up.py index 42c02a16..9c22c358 100644 --- a/src/app/presentation/http/account/sign_up.py +++ b/src/app/presentation/http/account/sign_up.py @@ -8,10 +8,10 @@ from app.core.commands.exceptions import UsernameAlreadyExistsError from app.core.common.authorization.exceptions import AuthorizationError from app.core.common.exceptions import BusinessTypeError -from app.infrastructure.adapters.exceptions import PasswordHasherBusyError -from app.infrastructure.auth_ctx.exceptions import AlreadyAuthenticatedError -from app.infrastructure.auth_ctx.handlers.sign_up import SignUp, SignUpRequest -from app.infrastructure.exceptions import StorageError +from app.outbound.adapters.exceptions import PasswordHasherBusyError +from app.outbound.auth_ctx.exceptions import AlreadyAuthenticatedError +from app.outbound.auth_ctx.handlers.sign_up import SignUp, SignUpRequest +from app.outbound.exceptions import StorageError from app.presentation.http.errors.callbacks import log_info from app.presentation.http.errors.rules import HTTP_503_SERVICE_UNAVAILABLE_RULE diff --git a/src/app/presentation/http/auth_cookie_middleware.py b/src/app/presentation/http/auth_cookie_middleware.py index 33d3cee0..d5f42e1c 100644 --- a/src/app/presentation/http/auth_cookie_middleware.py +++ b/src/app/presentation/http/auth_cookie_middleware.py @@ -5,7 +5,7 @@ from starlette.responses import Response from starlette.types import ASGIApp -from app.infrastructure.auth_ctx.cookie_manager import STAGED_COOKIE +from app.outbound.auth_ctx.cookie_manager import STAGED_COOKIE class AuthCookieMiddleware(BaseHTTPMiddleware): diff --git a/src/app/presentation/http/users/activate_user.py b/src/app/presentation/http/users/activate_user.py index 7a7e2747..12120a20 100644 --- a/src/app/presentation/http/users/activate_user.py +++ b/src/app/presentation/http/users/activate_user.py @@ -10,8 +10,8 @@ from app.core.commands.activate_user import ActivateUser, ActivateUserRequest from app.core.commands.exceptions import UserNotFoundError from app.core.common.authorization.exceptions import AuthorizationError -from app.infrastructure.auth_ctx.exceptions import AuthenticationError -from app.infrastructure.exceptions import StorageError +from app.outbound.auth_ctx.exceptions import AuthenticationError +from app.outbound.exceptions import StorageError from app.presentation.http.errors.callbacks import log_info from app.presentation.http.errors.rules import HTTP_503_SERVICE_UNAVAILABLE_RULE diff --git a/src/app/presentation/http/users/create_user.py b/src/app/presentation/http/users/create_user.py index c20752cf..49635a19 100644 --- a/src/app/presentation/http/users/create_user.py +++ b/src/app/presentation/http/users/create_user.py @@ -12,9 +12,9 @@ ) from app.core.common.authorization.exceptions import AuthorizationError from app.core.common.exceptions import BusinessTypeError -from app.infrastructure.adapters.exceptions import PasswordHasherBusyError -from app.infrastructure.auth_ctx.exceptions import AuthenticationError -from app.infrastructure.exceptions import StorageError +from app.outbound.adapters.exceptions import PasswordHasherBusyError +from app.outbound.auth_ctx.exceptions import AuthenticationError +from app.outbound.exceptions import StorageError from app.presentation.http.errors.callbacks import log_info from app.presentation.http.errors.rules import HTTP_503_SERVICE_UNAVAILABLE_RULE diff --git a/src/app/presentation/http/users/deactivate_user.py b/src/app/presentation/http/users/deactivate_user.py index 4c9a95c2..c8db35c7 100644 --- a/src/app/presentation/http/users/deactivate_user.py +++ b/src/app/presentation/http/users/deactivate_user.py @@ -10,8 +10,8 @@ from app.core.commands.deactivate_user import DeactivateUser, DeactivateUserRequest from app.core.commands.exceptions import UserNotFoundError from app.core.common.authorization.exceptions import AuthorizationError -from app.infrastructure.auth_ctx.exceptions import AuthenticationError -from app.infrastructure.exceptions import StorageError +from app.outbound.auth_ctx.exceptions import AuthenticationError +from app.outbound.exceptions import StorageError from app.presentation.http.errors.callbacks import log_info from app.presentation.http.errors.rules import HTTP_503_SERVICE_UNAVAILABLE_RULE diff --git a/src/app/presentation/http/users/grant_admin.py b/src/app/presentation/http/users/grant_admin.py index 7428f03c..6d9ba191 100644 --- a/src/app/presentation/http/users/grant_admin.py +++ b/src/app/presentation/http/users/grant_admin.py @@ -10,8 +10,8 @@ from app.core.commands.exceptions import UserNotFoundError from app.core.commands.grant_admin import GrantAdmin, GrantAdminRequest from app.core.common.authorization.exceptions import AuthorizationError -from app.infrastructure.auth_ctx.exceptions import AuthenticationError -from app.infrastructure.exceptions import StorageError +from app.outbound.auth_ctx.exceptions import AuthenticationError +from app.outbound.exceptions import StorageError from app.presentation.http.errors.callbacks import log_info from app.presentation.http.errors.rules import HTTP_503_SERVICE_UNAVAILABLE_RULE diff --git a/src/app/presentation/http/users/list_users.py b/src/app/presentation/http/users/list_users.py index 6e461b47..8357f4e4 100644 --- a/src/app/presentation/http/users/list_users.py +++ b/src/app/presentation/http/users/list_users.py @@ -14,8 +14,8 @@ from app.core.queries.query_support.exceptions import PaginationError from app.core.queries.query_support.offset_pagination import OffsetPaginationParams from app.core.queries.query_support.sorting import SortingOrder -from app.infrastructure.auth_ctx.exceptions import AuthenticationError -from app.infrastructure.exceptions import ReaderError, StorageError +from app.outbound.auth_ctx.exceptions import AuthenticationError +from app.outbound.exceptions import ReaderError, StorageError from app.presentation.http.errors.callbacks import log_info from app.presentation.http.errors.rules import HTTP_503_SERVICE_UNAVAILABLE_RULE diff --git a/src/app/presentation/http/users/revoke_admin.py b/src/app/presentation/http/users/revoke_admin.py index 46f0df6b..f6219d30 100644 --- a/src/app/presentation/http/users/revoke_admin.py +++ b/src/app/presentation/http/users/revoke_admin.py @@ -10,8 +10,8 @@ from app.core.commands.exceptions import UserNotFoundError from app.core.commands.revoke_admin import RevokeAdmin, RevokeAdminRequest from app.core.common.authorization.exceptions import AuthorizationError -from app.infrastructure.auth_ctx.exceptions import AuthenticationError -from app.infrastructure.exceptions import StorageError +from app.outbound.auth_ctx.exceptions import AuthenticationError +from app.outbound.exceptions import StorageError from app.presentation.http.errors.callbacks import log_info from app.presentation.http.errors.rules import HTTP_503_SERVICE_UNAVAILABLE_RULE diff --git a/src/app/presentation/http/users/set_user_password.py b/src/app/presentation/http/users/set_user_password.py index 1a5e6dd5..737d8ea1 100644 --- a/src/app/presentation/http/users/set_user_password.py +++ b/src/app/presentation/http/users/set_user_password.py @@ -13,9 +13,9 @@ from app.core.commands.set_user_password import SetUserPassword, SetUserPasswordRequest from app.core.common.authorization.exceptions import AuthorizationError from app.core.common.exceptions import BusinessTypeError -from app.infrastructure.adapters.exceptions import PasswordHasherBusyError -from app.infrastructure.auth_ctx.exceptions import AuthenticationError -from app.infrastructure.exceptions import StorageError +from app.outbound.adapters.exceptions import PasswordHasherBusyError +from app.outbound.auth_ctx.exceptions import AuthenticationError +from app.outbound.exceptions import StorageError from app.presentation.http.errors.callbacks import log_info from app.presentation.http.errors.rules import HTTP_503_SERVICE_UNAVAILABLE_RULE diff --git a/tests/integration/with_infra/account/test_sign_up.py b/tests/integration/with_infra/account/test_sign_up.py index c72d2ef3..5386beec 100644 --- a/tests/integration/with_infra/account/test_sign_up.py +++ b/tests/integration/with_infra/account/test_sign_up.py @@ -7,7 +7,7 @@ from app.core.common.services.user import UserService from app.core.common.value_objects.raw_password import RawPassword from app.core.common.value_objects.username import Username -from app.infrastructure.persistence_sqla.mappings.user import users_table +from app.outbound.persistence_sqla.mappings.user import users_table from tests.integration.with_infra.account.constants import SIGN_UP_ENDPOINT from tests.integration.with_infra.authentication import authenticate from tests.integration.with_infra.factories import ( diff --git a/tests/integration/with_infra/conftest.py b/tests/integration/with_infra/conftest.py index 72876d62..30adff5b 100644 --- a/tests/integration/with_infra/conftest.py +++ b/tests/integration/with_infra/conftest.py @@ -11,9 +11,9 @@ from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker from app.core.common.services.user import UserService -from app.infrastructure.persistence_sqla.registry import mapper_registry from app.main.config.settings import AppSettings from app.main.run import make_app +from app.outbound.persistence_sqla.registry import mapper_registry LIFESPAN_MANAGER_STARTUP_TIMEOUT_S: Final[int] = 30 ALLOW_DESTRUCTIVE_TEST_CLEANUP: Final[str] = "ALLOW_DESTRUCTIVE_TEST_CLEANUP" diff --git a/tests/performance/profile_bcrypt_password_hasher.py b/tests/performance/profile_bcrypt_password_hasher.py index 234c45d3..ffa8f988 100644 --- a/tests/performance/profile_bcrypt_password_hasher.py +++ b/tests/performance/profile_bcrypt_password_hasher.py @@ -3,7 +3,7 @@ from line_profiler import LineProfiler from app.core.common.value_objects.raw_password import RawPassword -from app.infrastructure.adapters.bcrypt_password_hasher import BcryptPasswordHasher +from app.outbound.adapters.bcrypt_password_hasher import BcryptPasswordHasher def profile_password_hashing(hasher: BcryptPasswordHasher) -> None: diff --git a/tests/unit/infrastructure/__init__.py b/tests/unit/outbound/__init__.py similarity index 100% rename from tests/unit/infrastructure/__init__.py rename to tests/unit/outbound/__init__.py diff --git a/tests/unit/infrastructure/conftest.py b/tests/unit/outbound/conftest.py similarity index 94% rename from tests/unit/infrastructure/conftest.py rename to tests/unit/outbound/conftest.py index 71735bac..57b5707b 100644 --- a/tests/unit/infrastructure/conftest.py +++ b/tests/unit/outbound/conftest.py @@ -5,7 +5,7 @@ import pytest -from app.infrastructure.adapters.bcrypt_password_hasher import ( +from app.outbound.adapters.bcrypt_password_hasher import ( BcryptPasswordHasher, HasherSemaphore, HasherThreadPoolExecutor, diff --git a/tests/unit/infrastructure/test_bcrypt_password_hasher.py b/tests/unit/outbound/test_bcrypt_password_hasher.py similarity index 96% rename from tests/unit/infrastructure/test_bcrypt_password_hasher.py rename to tests/unit/outbound/test_bcrypt_password_hasher.py index 08822758..c6380981 100644 --- a/tests/unit/infrastructure/test_bcrypt_password_hasher.py +++ b/tests/unit/outbound/test_bcrypt_password_hasher.py @@ -2,7 +2,7 @@ import pytest -from app.infrastructure.adapters.bcrypt_password_hasher import BcryptPasswordHasher +from app.outbound.adapters.bcrypt_password_hasher import BcryptPasswordHasher from tests.unit.core.common.services.factories import create_raw_password From 60300879332c157c2f714040b222f43b5966a87b Mon Sep 17 00:00:00 2001 From: ivan-borovets <130386813+ivan-borovets@users.noreply.github.com> Date: Fri, 17 Apr 2026 23:26:36 +0300 Subject: [PATCH 2/2] Presentation -> Inbound --- pyproject.toml | 2 +- src/app/{presentation => inbound}/__init__.py | 0 src/app/{presentation => inbound}/http/__init__.py | 0 .../http/account/__init__.py | 0 .../http/account/change_password.py | 4 ++-- .../http/account/log_in.py | 4 ++-- .../http/account/log_out.py | 4 ++-- .../http/account/router.py | 8 ++++---- .../http/account/sign_up.py | 4 ++-- .../http/api_v1_router.py | 4 ++-- .../http/auth_cookie_middleware.py | 0 .../http/errors/__init__.py | 0 .../http/errors/callbacks.py | 0 .../{presentation => inbound}/http/errors/rules.py | 2 +- .../http/errors/translators.py | 0 .../http/health/__init__.py | 0 .../http/health/checks.py | 0 .../http/health/router.py | 2 +- .../{presentation => inbound}/http/root_router.py | 4 ++-- .../http/users/__init__.py | 0 .../http/users/activate_user.py | 4 ++-- .../http/users/create_user.py | 4 ++-- .../http/users/deactivate_user.py | 4 ++-- .../http/users/grant_admin.py | 4 ++-- .../http/users/list_users.py | 4 ++-- .../http/users/revoke_admin.py | 4 ++-- .../{presentation => inbound}/http/users/router.py | 14 +++++++------- .../http/users/set_user_password.py | 4 ++-- src/app/main/run.py | 2 +- src/app/main/setup.py | 2 +- tests/smoke/{presentation => inbound}/__init__.py | 0 .../{presentation => inbound}/http/__init__.py | 0 .../http/test_health_router.py | 0 33 files changed, 42 insertions(+), 42 deletions(-) rename src/app/{presentation => inbound}/__init__.py (100%) rename src/app/{presentation => inbound}/http/__init__.py (100%) rename src/app/{presentation => inbound}/http/account/__init__.py (100%) rename src/app/{presentation => inbound}/http/account/change_password.py (94%) rename src/app/{presentation => inbound}/http/account/log_in.py (90%) rename src/app/{presentation => inbound}/http/account/log_out.py (89%) rename src/app/{presentation => inbound}/http/account/router.py (58%) rename src/app/{presentation => inbound}/http/account/sign_up.py (91%) rename src/app/{presentation => inbound}/http/api_v1_router.py (68%) rename src/app/{presentation => inbound}/http/auth_cookie_middleware.py (100%) rename src/app/{presentation => inbound}/http/errors/__init__.py (100%) rename src/app/{presentation => inbound}/http/errors/callbacks.py (100%) rename src/app/{presentation => inbound}/http/errors/rules.py (75%) rename src/app/{presentation => inbound}/http/errors/translators.py (100%) rename src/app/{presentation => inbound}/http/health/__init__.py (100%) rename src/app/{presentation => inbound}/http/health/checks.py (100%) rename src/app/{presentation => inbound}/http/health/router.py (94%) rename src/app/{presentation => inbound}/http/root_router.py (79%) rename src/app/{presentation => inbound}/http/users/__init__.py (100%) rename src/app/{presentation => inbound}/http/users/activate_user.py (90%) rename src/app/{presentation => inbound}/http/users/create_user.py (91%) rename src/app/{presentation => inbound}/http/users/deactivate_user.py (90%) rename src/app/{presentation => inbound}/http/users/grant_admin.py (90%) rename src/app/{presentation => inbound}/http/users/list_users.py (94%) rename src/app/{presentation => inbound}/http/users/revoke_admin.py (90%) rename src/app/{presentation => inbound}/http/users/router.py (55%) rename src/app/{presentation => inbound}/http/users/set_user_password.py (93%) rename tests/smoke/{presentation => inbound}/__init__.py (100%) rename tests/smoke/{presentation => inbound}/http/__init__.py (100%) rename tests/smoke/{presentation => inbound}/http/test_health_router.py (100%) diff --git a/pyproject.toml b/pyproject.toml index fedc6f39..f952c156 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -96,7 +96,7 @@ type = "layers" containers = ["app"] layers = [ "(main)", - "presentation", + "inbound", "outbound", "core", ] diff --git a/src/app/presentation/__init__.py b/src/app/inbound/__init__.py similarity index 100% rename from src/app/presentation/__init__.py rename to src/app/inbound/__init__.py diff --git a/src/app/presentation/http/__init__.py b/src/app/inbound/http/__init__.py similarity index 100% rename from src/app/presentation/http/__init__.py rename to src/app/inbound/http/__init__.py diff --git a/src/app/presentation/http/account/__init__.py b/src/app/inbound/http/account/__init__.py similarity index 100% rename from src/app/presentation/http/account/__init__.py rename to src/app/inbound/http/account/__init__.py diff --git a/src/app/presentation/http/account/change_password.py b/src/app/inbound/http/account/change_password.py similarity index 94% rename from src/app/presentation/http/account/change_password.py rename to src/app/inbound/http/account/change_password.py index d70bc11b..3aabc852 100644 --- a/src/app/presentation/http/account/change_password.py +++ b/src/app/inbound/http/account/change_password.py @@ -9,12 +9,12 @@ from app.core.common.authorization.exceptions import AuthorizationError from app.core.common.exceptions import BusinessTypeError +from app.inbound.http.errors.callbacks import log_info +from app.inbound.http.errors.rules import HTTP_503_SERVICE_UNAVAILABLE_RULE from app.outbound.adapters.exceptions import PasswordHasherBusyError from app.outbound.auth_ctx.exceptions import AuthenticationChangeError, AuthenticationError, ReAuthenticationError from app.outbound.auth_ctx.handlers.change_password import ChangePassword, ChangePasswordRequest from app.outbound.exceptions import StorageError -from app.presentation.http.errors.callbacks import log_info -from app.presentation.http.errors.rules import HTTP_503_SERVICE_UNAVAILABLE_RULE class ChangePasswordRequestSchema(BaseModel): diff --git a/src/app/presentation/http/account/log_in.py b/src/app/inbound/http/account/log_in.py similarity index 90% rename from src/app/presentation/http/account/log_in.py rename to src/app/inbound/http/account/log_in.py index 0a204890..d937ef34 100644 --- a/src/app/presentation/http/account/log_in.py +++ b/src/app/inbound/http/account/log_in.py @@ -7,12 +7,12 @@ from app.core.common.authorization.exceptions import AuthorizationError from app.core.common.exceptions import BusinessTypeError +from app.inbound.http.errors.callbacks import log_info +from app.inbound.http.errors.rules import HTTP_503_SERVICE_UNAVAILABLE_RULE from app.outbound.adapters.exceptions import PasswordHasherBusyError from app.outbound.auth_ctx.exceptions import AlreadyAuthenticatedError, AuthenticationError from app.outbound.auth_ctx.handlers.log_in import LogIn, LogInRequest from app.outbound.exceptions import StorageError -from app.presentation.http.errors.callbacks import log_info -from app.presentation.http.errors.rules import HTTP_503_SERVICE_UNAVAILABLE_RULE def make_log_in_router() -> APIRouter: diff --git a/src/app/presentation/http/account/log_out.py b/src/app/inbound/http/account/log_out.py similarity index 89% rename from src/app/presentation/http/account/log_out.py rename to src/app/inbound/http/account/log_out.py index a59dbc4a..62105a57 100644 --- a/src/app/presentation/http/account/log_out.py +++ b/src/app/inbound/http/account/log_out.py @@ -7,11 +7,11 @@ from fastapi_error_map import ErrorAwareRouter from app.core.common.authorization.exceptions import AuthorizationError +from app.inbound.http.errors.callbacks import log_info +from app.inbound.http.errors.rules import HTTP_503_SERVICE_UNAVAILABLE_RULE from app.outbound.auth_ctx.exceptions import AuthenticationError from app.outbound.auth_ctx.handlers.log_out import LogOut from app.outbound.exceptions import StorageError -from app.presentation.http.errors.callbacks import log_info -from app.presentation.http.errors.rules import HTTP_503_SERVICE_UNAVAILABLE_RULE def make_log_out_router(*, cookie_name: str) -> APIRouter: diff --git a/src/app/presentation/http/account/router.py b/src/app/inbound/http/account/router.py similarity index 58% rename from src/app/presentation/http/account/router.py rename to src/app/inbound/http/account/router.py index b39cf37e..de338106 100644 --- a/src/app/presentation/http/account/router.py +++ b/src/app/inbound/http/account/router.py @@ -1,9 +1,9 @@ from fastapi import APIRouter -from app.presentation.http.account.change_password import make_change_password_router -from app.presentation.http.account.log_in import make_log_in_router -from app.presentation.http.account.log_out import make_log_out_router -from app.presentation.http.account.sign_up import make_sign_up_router +from app.inbound.http.account.change_password import make_change_password_router +from app.inbound.http.account.log_in import make_log_in_router +from app.inbound.http.account.log_out import make_log_out_router +from app.inbound.http.account.sign_up import make_sign_up_router def make_account_router(*, cookie_name: str) -> APIRouter: diff --git a/src/app/presentation/http/account/sign_up.py b/src/app/inbound/http/account/sign_up.py similarity index 91% rename from src/app/presentation/http/account/sign_up.py rename to src/app/inbound/http/account/sign_up.py index 9c22c358..7d6c8817 100644 --- a/src/app/presentation/http/account/sign_up.py +++ b/src/app/inbound/http/account/sign_up.py @@ -8,12 +8,12 @@ from app.core.commands.exceptions import UsernameAlreadyExistsError from app.core.common.authorization.exceptions import AuthorizationError from app.core.common.exceptions import BusinessTypeError +from app.inbound.http.errors.callbacks import log_info +from app.inbound.http.errors.rules import HTTP_503_SERVICE_UNAVAILABLE_RULE from app.outbound.adapters.exceptions import PasswordHasherBusyError from app.outbound.auth_ctx.exceptions import AlreadyAuthenticatedError from app.outbound.auth_ctx.handlers.sign_up import SignUp, SignUpRequest from app.outbound.exceptions import StorageError -from app.presentation.http.errors.callbacks import log_info -from app.presentation.http.errors.rules import HTTP_503_SERVICE_UNAVAILABLE_RULE def make_sign_up_router() -> APIRouter: diff --git a/src/app/presentation/http/api_v1_router.py b/src/app/inbound/http/api_v1_router.py similarity index 68% rename from src/app/presentation/http/api_v1_router.py rename to src/app/inbound/http/api_v1_router.py index 07ee3f96..a3323ced 100644 --- a/src/app/presentation/http/api_v1_router.py +++ b/src/app/inbound/http/api_v1_router.py @@ -1,7 +1,7 @@ from fastapi import APIRouter -from app.presentation.http.account.router import make_account_router -from app.presentation.http.users.router import make_users_router +from app.inbound.http.account.router import make_account_router +from app.inbound.http.users.router import make_users_router def make_v1_router(*, cookie_name: str) -> APIRouter: diff --git a/src/app/presentation/http/auth_cookie_middleware.py b/src/app/inbound/http/auth_cookie_middleware.py similarity index 100% rename from src/app/presentation/http/auth_cookie_middleware.py rename to src/app/inbound/http/auth_cookie_middleware.py diff --git a/src/app/presentation/http/errors/__init__.py b/src/app/inbound/http/errors/__init__.py similarity index 100% rename from src/app/presentation/http/errors/__init__.py rename to src/app/inbound/http/errors/__init__.py diff --git a/src/app/presentation/http/errors/callbacks.py b/src/app/inbound/http/errors/callbacks.py similarity index 100% rename from src/app/presentation/http/errors/callbacks.py rename to src/app/inbound/http/errors/callbacks.py diff --git a/src/app/presentation/http/errors/rules.py b/src/app/inbound/http/errors/rules.py similarity index 75% rename from src/app/presentation/http/errors/rules.py rename to src/app/inbound/http/errors/rules.py index 7667f565..6662739e 100644 --- a/src/app/presentation/http/errors/rules.py +++ b/src/app/inbound/http/errors/rules.py @@ -3,7 +3,7 @@ from fastapi_error_map.rules import Rule, rule from starlette import status -from app.presentation.http.errors.translators import ServiceUnavailableTranslator +from app.inbound.http.errors.translators import ServiceUnavailableTranslator HTTP_503_SERVICE_UNAVAILABLE_RULE: Final[Rule] = rule( status=status.HTTP_503_SERVICE_UNAVAILABLE, diff --git a/src/app/presentation/http/errors/translators.py b/src/app/inbound/http/errors/translators.py similarity index 100% rename from src/app/presentation/http/errors/translators.py rename to src/app/inbound/http/errors/translators.py diff --git a/src/app/presentation/http/health/__init__.py b/src/app/inbound/http/health/__init__.py similarity index 100% rename from src/app/presentation/http/health/__init__.py rename to src/app/inbound/http/health/__init__.py diff --git a/src/app/presentation/http/health/checks.py b/src/app/inbound/http/health/checks.py similarity index 100% rename from src/app/presentation/http/health/checks.py rename to src/app/inbound/http/health/checks.py diff --git a/src/app/presentation/http/health/router.py b/src/app/inbound/http/health/router.py similarity index 94% rename from src/app/presentation/http/health/router.py rename to src/app/inbound/http/health/router.py index 7c9b1e24..7873cf34 100644 --- a/src/app/presentation/http/health/router.py +++ b/src/app/inbound/http/health/router.py @@ -3,7 +3,7 @@ from fastapi import APIRouter from sqlalchemy.ext.asyncio import AsyncSession -from app.presentation.http.health.checks import db_check +from app.inbound.http.health.checks import db_check class InternalServerError(Exception): diff --git a/src/app/presentation/http/root_router.py b/src/app/inbound/http/root_router.py similarity index 79% rename from src/app/presentation/http/root_router.py rename to src/app/inbound/http/root_router.py index 345b9db7..dc08901d 100644 --- a/src/app/presentation/http/root_router.py +++ b/src/app/inbound/http/root_router.py @@ -1,8 +1,8 @@ from fastapi import APIRouter from starlette.responses import RedirectResponse -from app.presentation.http.api_v1_router import make_v1_router -from app.presentation.http.health.router import make_health_router +from app.inbound.http.api_v1_router import make_v1_router +from app.inbound.http.health.router import make_health_router def make_fastapi_root_router(*, debug_mode: bool, cookie_name: str) -> APIRouter: diff --git a/src/app/presentation/http/users/__init__.py b/src/app/inbound/http/users/__init__.py similarity index 100% rename from src/app/presentation/http/users/__init__.py rename to src/app/inbound/http/users/__init__.py diff --git a/src/app/presentation/http/users/activate_user.py b/src/app/inbound/http/users/activate_user.py similarity index 90% rename from src/app/presentation/http/users/activate_user.py rename to src/app/inbound/http/users/activate_user.py index 12120a20..4264aa1c 100644 --- a/src/app/presentation/http/users/activate_user.py +++ b/src/app/inbound/http/users/activate_user.py @@ -10,10 +10,10 @@ from app.core.commands.activate_user import ActivateUser, ActivateUserRequest from app.core.commands.exceptions import UserNotFoundError from app.core.common.authorization.exceptions import AuthorizationError +from app.inbound.http.errors.callbacks import log_info +from app.inbound.http.errors.rules import HTTP_503_SERVICE_UNAVAILABLE_RULE from app.outbound.auth_ctx.exceptions import AuthenticationError from app.outbound.exceptions import StorageError -from app.presentation.http.errors.callbacks import log_info -from app.presentation.http.errors.rules import HTTP_503_SERVICE_UNAVAILABLE_RULE def make_activate_user_router() -> APIRouter: diff --git a/src/app/presentation/http/users/create_user.py b/src/app/inbound/http/users/create_user.py similarity index 91% rename from src/app/presentation/http/users/create_user.py rename to src/app/inbound/http/users/create_user.py index 49635a19..069f3f49 100644 --- a/src/app/presentation/http/users/create_user.py +++ b/src/app/inbound/http/users/create_user.py @@ -12,11 +12,11 @@ ) from app.core.common.authorization.exceptions import AuthorizationError from app.core.common.exceptions import BusinessTypeError +from app.inbound.http.errors.callbacks import log_info +from app.inbound.http.errors.rules import HTTP_503_SERVICE_UNAVAILABLE_RULE from app.outbound.adapters.exceptions import PasswordHasherBusyError from app.outbound.auth_ctx.exceptions import AuthenticationError from app.outbound.exceptions import StorageError -from app.presentation.http.errors.callbacks import log_info -from app.presentation.http.errors.rules import HTTP_503_SERVICE_UNAVAILABLE_RULE def make_create_user_router() -> APIRouter: diff --git a/src/app/presentation/http/users/deactivate_user.py b/src/app/inbound/http/users/deactivate_user.py similarity index 90% rename from src/app/presentation/http/users/deactivate_user.py rename to src/app/inbound/http/users/deactivate_user.py index c8db35c7..19541543 100644 --- a/src/app/presentation/http/users/deactivate_user.py +++ b/src/app/inbound/http/users/deactivate_user.py @@ -10,10 +10,10 @@ from app.core.commands.deactivate_user import DeactivateUser, DeactivateUserRequest from app.core.commands.exceptions import UserNotFoundError from app.core.common.authorization.exceptions import AuthorizationError +from app.inbound.http.errors.callbacks import log_info +from app.inbound.http.errors.rules import HTTP_503_SERVICE_UNAVAILABLE_RULE from app.outbound.auth_ctx.exceptions import AuthenticationError from app.outbound.exceptions import StorageError -from app.presentation.http.errors.callbacks import log_info -from app.presentation.http.errors.rules import HTTP_503_SERVICE_UNAVAILABLE_RULE def make_deactivate_user_router() -> APIRouter: diff --git a/src/app/presentation/http/users/grant_admin.py b/src/app/inbound/http/users/grant_admin.py similarity index 90% rename from src/app/presentation/http/users/grant_admin.py rename to src/app/inbound/http/users/grant_admin.py index 6d9ba191..c473e8a9 100644 --- a/src/app/presentation/http/users/grant_admin.py +++ b/src/app/inbound/http/users/grant_admin.py @@ -10,10 +10,10 @@ from app.core.commands.exceptions import UserNotFoundError from app.core.commands.grant_admin import GrantAdmin, GrantAdminRequest from app.core.common.authorization.exceptions import AuthorizationError +from app.inbound.http.errors.callbacks import log_info +from app.inbound.http.errors.rules import HTTP_503_SERVICE_UNAVAILABLE_RULE from app.outbound.auth_ctx.exceptions import AuthenticationError from app.outbound.exceptions import StorageError -from app.presentation.http.errors.callbacks import log_info -from app.presentation.http.errors.rules import HTTP_503_SERVICE_UNAVAILABLE_RULE def make_grant_admin_router() -> APIRouter: diff --git a/src/app/presentation/http/users/list_users.py b/src/app/inbound/http/users/list_users.py similarity index 94% rename from src/app/presentation/http/users/list_users.py rename to src/app/inbound/http/users/list_users.py index 8357f4e4..6994cdd4 100644 --- a/src/app/presentation/http/users/list_users.py +++ b/src/app/inbound/http/users/list_users.py @@ -14,10 +14,10 @@ from app.core.queries.query_support.exceptions import PaginationError from app.core.queries.query_support.offset_pagination import OffsetPaginationParams from app.core.queries.query_support.sorting import SortingOrder +from app.inbound.http.errors.callbacks import log_info +from app.inbound.http.errors.rules import HTTP_503_SERVICE_UNAVAILABLE_RULE from app.outbound.auth_ctx.exceptions import AuthenticationError from app.outbound.exceptions import ReaderError, StorageError -from app.presentation.http.errors.callbacks import log_info -from app.presentation.http.errors.rules import HTTP_503_SERVICE_UNAVAILABLE_RULE class ListUsersRequestSchema(BaseModel): diff --git a/src/app/presentation/http/users/revoke_admin.py b/src/app/inbound/http/users/revoke_admin.py similarity index 90% rename from src/app/presentation/http/users/revoke_admin.py rename to src/app/inbound/http/users/revoke_admin.py index f6219d30..8ba0d36c 100644 --- a/src/app/presentation/http/users/revoke_admin.py +++ b/src/app/inbound/http/users/revoke_admin.py @@ -10,10 +10,10 @@ from app.core.commands.exceptions import UserNotFoundError from app.core.commands.revoke_admin import RevokeAdmin, RevokeAdminRequest from app.core.common.authorization.exceptions import AuthorizationError +from app.inbound.http.errors.callbacks import log_info +from app.inbound.http.errors.rules import HTTP_503_SERVICE_UNAVAILABLE_RULE from app.outbound.auth_ctx.exceptions import AuthenticationError from app.outbound.exceptions import StorageError -from app.presentation.http.errors.callbacks import log_info -from app.presentation.http.errors.rules import HTTP_503_SERVICE_UNAVAILABLE_RULE def make_revoke_admin_router() -> APIRouter: diff --git a/src/app/presentation/http/users/router.py b/src/app/inbound/http/users/router.py similarity index 55% rename from src/app/presentation/http/users/router.py rename to src/app/inbound/http/users/router.py index ae2f39a2..4b21229c 100644 --- a/src/app/presentation/http/users/router.py +++ b/src/app/inbound/http/users/router.py @@ -1,13 +1,13 @@ from fastapi import APIRouter, Depends from fastapi.security import APIKeyCookie -from app.presentation.http.users.activate_user import make_activate_user_router -from app.presentation.http.users.create_user import make_create_user_router -from app.presentation.http.users.deactivate_user import make_deactivate_user_router -from app.presentation.http.users.grant_admin import make_grant_admin_router -from app.presentation.http.users.list_users import make_list_users_router -from app.presentation.http.users.revoke_admin import make_revoke_admin_router -from app.presentation.http.users.set_user_password import make_set_user_password_router +from app.inbound.http.users.activate_user import make_activate_user_router +from app.inbound.http.users.create_user import make_create_user_router +from app.inbound.http.users.deactivate_user import make_deactivate_user_router +from app.inbound.http.users.grant_admin import make_grant_admin_router +from app.inbound.http.users.list_users import make_list_users_router +from app.inbound.http.users.revoke_admin import make_revoke_admin_router +from app.inbound.http.users.set_user_password import make_set_user_password_router def make_users_router(*, cookie_name: str) -> APIRouter: diff --git a/src/app/presentation/http/users/set_user_password.py b/src/app/inbound/http/users/set_user_password.py similarity index 93% rename from src/app/presentation/http/users/set_user_password.py rename to src/app/inbound/http/users/set_user_password.py index 737d8ea1..febe18b9 100644 --- a/src/app/presentation/http/users/set_user_password.py +++ b/src/app/inbound/http/users/set_user_password.py @@ -13,11 +13,11 @@ from app.core.commands.set_user_password import SetUserPassword, SetUserPasswordRequest from app.core.common.authorization.exceptions import AuthorizationError from app.core.common.exceptions import BusinessTypeError +from app.inbound.http.errors.callbacks import log_info +from app.inbound.http.errors.rules import HTTP_503_SERVICE_UNAVAILABLE_RULE from app.outbound.adapters.exceptions import PasswordHasherBusyError from app.outbound.auth_ctx.exceptions import AuthenticationError from app.outbound.exceptions import StorageError -from app.presentation.http.errors.callbacks import log_info -from app.presentation.http.errors.rules import HTTP_503_SERVICE_UNAVAILABLE_RULE class SetUserPasswordRequestSchema(BaseModel): diff --git a/src/app/main/run.py b/src/app/main/run.py index 5581045b..8242ffd6 100644 --- a/src/app/main/run.py +++ b/src/app/main/run.py @@ -5,6 +5,7 @@ from dishka.integrations.fastapi import setup_dishka from fastapi import FastAPI +from app.inbound.http.root_router import make_fastapi_root_router from app.main.config.loader import ( load_app_settings, load_cookie_settings, @@ -26,7 +27,6 @@ from app.main.ioc.provider_registry import get_providers from app.main.setup import setup_global_exception_handlers, setup_logging, setup_middlewares from app.outbound.persistence_sqla.mappings.all import map_tables -from app.presentation.http.root_router import make_fastapi_root_router def make_lifespan() -> Callable[[FastAPI], AbstractAsyncContextManager[None]]: diff --git a/src/app/main/setup.py b/src/app/main/setup.py index 7f889735..4b947c73 100644 --- a/src/app/main/setup.py +++ b/src/app/main/setup.py @@ -2,9 +2,9 @@ from fastapi import FastAPI +from app.inbound.http.auth_cookie_middleware import AuthCookieMiddleware from app.main.config.logging_ import DATEFMT, FMT, LoggingLevel from app.main.config.settings import CookieSettings -from app.presentation.http.auth_cookie_middleware import AuthCookieMiddleware logger = logging.getLogger(__name__) diff --git a/tests/smoke/presentation/__init__.py b/tests/smoke/inbound/__init__.py similarity index 100% rename from tests/smoke/presentation/__init__.py rename to tests/smoke/inbound/__init__.py diff --git a/tests/smoke/presentation/http/__init__.py b/tests/smoke/inbound/http/__init__.py similarity index 100% rename from tests/smoke/presentation/http/__init__.py rename to tests/smoke/inbound/http/__init__.py diff --git a/tests/smoke/presentation/http/test_health_router.py b/tests/smoke/inbound/http/test_health_router.py similarity index 100% rename from tests/smoke/presentation/http/test_health_router.py rename to tests/smoke/inbound/http/test_health_router.py