Skip to content

Commit 726276e

Browse files
committed
elimination of redundant mappers
1 parent b6c7a22 commit 726276e

File tree

18 files changed

+40
-850
lines changed

18 files changed

+40
-850
lines changed

backend/app/api/routes/admin/events.py

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@
1212
from app.domain.enums.events import EventType
1313
from app.infrastructure.mappers import (
1414
AdminReplayApiMapper,
15-
EventDetailMapper,
1615
EventFilterMapper,
17-
EventMapper,
1816
)
1917
from app.schemas_pydantic.admin_events import (
2018
EventBrowseRequest,
@@ -48,9 +46,8 @@ async def browse_events(request: EventBrowseRequest, service: FromDishka[AdminEv
4846
sort_order=request.sort_order,
4947
)
5048

51-
event_mapper = EventMapper()
5249
return EventBrowseResponse(
53-
events=[jsonable_encoder(event_mapper.to_dict(event)) for event in result.events],
50+
events=[jsonable_encoder(event) for event in result.events],
5451
total=result.total,
5552
skip=result.skip,
5653
limit=result.limit,
@@ -144,12 +141,10 @@ async def get_event_detail(event_id: str, service: FromDishka[AdminEventsService
144141
if not result:
145142
raise HTTPException(status_code=404, detail="Event not found")
146143

147-
detail_mapper = EventDetailMapper()
148-
serialized_result = jsonable_encoder(detail_mapper.to_dict(result))
149144
return EventDetailResponse(
150-
event=serialized_result["event"],
151-
related_events=serialized_result["related_events"],
152-
timeline=serialized_result["timeline"],
145+
event=jsonable_encoder(result.event),
146+
related_events=[jsonable_encoder(e) for e in result.related_events],
147+
timeline=[jsonable_encoder(e) for e in result.timeline],
153148
)
154149

155150
except HTTPException:

backend/app/api/routes/admin/users.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,12 @@
99
from app.domain.enums.user import UserRole
1010
from app.domain.rate_limit import UserRateLimit
1111
from app.domain.user import UserUpdate as DomainUserUpdate
12-
from app.infrastructure.mappers import AdminOverviewApiMapper
13-
from app.schemas_pydantic.admin_user_overview import AdminUserOverview
12+
from app.schemas_pydantic.admin_user_overview import (
13+
AdminUserOverview,
14+
DerivedCounts,
15+
RateLimitSummary,
16+
)
17+
from app.schemas_pydantic.events import EventResponse, EventStatistics
1418
from app.schemas_pydantic.user import (
1519
DeleteUserResponse,
1620
MessageResponse,
@@ -110,8 +114,13 @@ async def get_user_overview(
110114
domain = await admin_user_service.get_user_overview(user_id=user_id, hours=24)
111115
except ValueError:
112116
raise HTTPException(status_code=404, detail="User not found")
113-
mapper = AdminOverviewApiMapper()
114-
return mapper.to_response(domain)
117+
return AdminUserOverview(
118+
user=UserResponse.model_validate(domain.user),
119+
stats=EventStatistics.model_validate(domain.stats),
120+
derived_counts=DerivedCounts.model_validate(domain.derived_counts),
121+
rate_limit_summary=RateLimitSummary.model_validate(domain.rate_limit_summary),
122+
recent_events=[EventResponse.model_validate(e).model_dump() for e in domain.recent_events],
123+
)
115124

116125

117126
@router.put("/{user_id}", response_model=UserResponse)

backend/app/api/routes/replay.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ async def list_replay_sessions(
7070
@router.get("/sessions/{session_id}", response_model=ReplaySession)
7171
async def get_replay_session(session_id: str, service: FromDishka[ReplayService]) -> ReplaySession:
7272
state = service.get_session(session_id)
73-
return ReplayApiMapper.session_to_response(state)
73+
return ReplaySession.model_validate(state)
7474

7575

7676
@router.post("/cleanup", response_model=CleanupResponse)

backend/app/api/routes/saga.py

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
from fastapi import APIRouter, Query, Request
44

55
from app.domain.enums.saga import SagaState
6-
from app.infrastructure.mappers import SagaResponseMapper
76
from app.infrastructure.mappers import UserMapper as AdminUserMapper
87
from app.schemas_pydantic.saga import (
98
SagaCancellationResponse,
@@ -47,8 +46,7 @@ async def get_saga_status(
4746
service_user = User.from_response(current_user)
4847
domain_user = AdminUserMapper.from_pydantic_service_user(service_user)
4948
saga = await saga_service.get_saga_with_access_check(saga_id, domain_user)
50-
mapper = SagaResponseMapper()
51-
return mapper.to_response(saga)
49+
return SagaStatusResponse.from_domain(saga)
5250

5351

5452
@router.get("/execution/{execution_id}", response_model=SagaListResponse)
@@ -79,8 +77,7 @@ async def get_execution_sagas(
7977
service_user = User.from_response(current_user)
8078
domain_user = AdminUserMapper.from_pydantic_service_user(service_user)
8179
sagas = await saga_service.get_execution_sagas(execution_id, domain_user, state)
82-
mapper = SagaResponseMapper()
83-
saga_responses = mapper.list_to_responses(sagas)
80+
saga_responses = [SagaStatusResponse.from_domain(s) for s in sagas]
8481
return SagaListResponse(sagas=saga_responses, total=len(saga_responses))
8582

8683

@@ -111,8 +108,7 @@ async def list_sagas(
111108
service_user = User.from_response(current_user)
112109
domain_user = AdminUserMapper.from_pydantic_service_user(service_user)
113110
result = await saga_service.list_user_sagas(domain_user, state, limit, offset)
114-
mapper = SagaResponseMapper()
115-
saga_responses = mapper.list_to_responses(result.sagas)
111+
saga_responses = [SagaStatusResponse.from_domain(s) for s in result.sagas]
116112
return SagaListResponse(sagas=saga_responses, total=result.total)
117113

118114

backend/app/domain/events/event_models.py

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
from dataclasses import dataclass, field
22
from datetime import datetime
33
from typing import Any
4-
from uuid import uuid4
54

65
from app.core.utils import StringEnum
76
from app.domain.enums.events import EventType
7+
from app.infrastructure.kafka.events.metadata import EventMetadata
88

99
MongoQueryValue = str | dict[str, str | list[str] | float | datetime]
1010
MongoQuery = dict[str, MongoQueryValue]
@@ -73,19 +73,6 @@ class CollectionNames(StringEnum):
7373
DLQ_MESSAGES = "dlq_messages"
7474

7575

76-
@dataclass
77-
class DomainEventMetadata:
78-
"""Domain model for event metadata."""
79-
80-
service_name: str
81-
service_version: str
82-
correlation_id: str = field(default_factory=lambda: str(uuid4()))
83-
user_id: str | None = None
84-
ip_address: str | None = None
85-
user_agent: str | None = None
86-
environment: str = "production"
87-
88-
8976
@dataclass
9077
class Event:
9178
"""Domain model for an event."""
@@ -94,7 +81,7 @@ class Event:
9481
event_type: EventType
9582
event_version: str
9683
timestamp: datetime
97-
metadata: DomainEventMetadata
84+
metadata: EventMetadata
9885
payload: dict[str, Any]
9986
aggregate_id: str | None = None
10087
stored_at: datetime | None = None

backend/app/infrastructure/mappers/__init__.py

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,13 @@
11
from .admin_mapper import (
22
AuditLogMapper,
33
SettingsMapper,
4-
UserListResultMapper,
54
UserMapper,
65
)
7-
from .admin_overview_api_mapper import AdminOverviewApiMapper
86
from .event_mapper import (
97
ArchivedEventMapper,
10-
EventBrowseResultMapper,
11-
EventDetailMapper,
128
EventExportRowMapper,
139
EventFilterMapper,
14-
EventListResultMapper,
1510
EventMapper,
16-
EventProjectionMapper,
17-
EventReplayInfoMapper,
18-
EventStatisticsMapper,
1911
EventSummaryMapper,
2012
)
2113
from .notification_mapper import NotificationMapper
@@ -38,7 +30,6 @@
3830
SagaFilterMapper,
3931
SagaInstanceMapper,
4032
SagaMapper,
41-
SagaResponseMapper,
4233
)
4334
from .saved_script_mapper import SavedScriptMapper
4435
from .sse_mapper import SSEMapper
@@ -47,22 +38,14 @@
4738
__all__ = [
4839
# Admin
4940
"UserMapper",
50-
"UserListResultMapper",
5141
"SettingsMapper",
5242
"AuditLogMapper",
53-
"AdminOverviewApiMapper",
5443
# Events
5544
"EventMapper",
5645
"EventSummaryMapper",
57-
"EventDetailMapper",
58-
"EventListResultMapper",
59-
"EventBrowseResultMapper",
60-
"EventStatisticsMapper",
61-
"EventProjectionMapper",
6246
"ArchivedEventMapper",
6347
"EventExportRowMapper",
6448
"EventFilterMapper",
65-
"EventReplayInfoMapper",
6649
# Notification
6750
"NotificationMapper",
6851
# Rate limit
@@ -86,7 +69,6 @@
8669
# Saga
8770
"SagaMapper",
8871
"SagaFilterMapper",
89-
"SagaResponseMapper",
9072
"SagaEventMapper",
9173
"SagaInstanceMapper",
9274
]

backend/app/infrastructure/mappers/admin_mapper.py

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
from app.domain.user import (
2020
UserCreation,
2121
UserFields,
22-
UserListResult,
2322
UserRole,
2423
UserSearchFilter,
2524
UserUpdate,
@@ -67,22 +66,6 @@ def from_mongo_document(data: Dict[str, Any]) -> DomainAdminUser:
6766
updated_at=data.get(UserFields.UPDATED_AT, datetime.now(timezone.utc)),
6867
)
6968

70-
@staticmethod
71-
def to_response_dict(user: DomainAdminUser) -> Dict[str, Any]:
72-
created_at_ts = user.created_at.timestamp() if user.created_at else 0.0
73-
updated_at_ts = user.updated_at.timestamp() if user.updated_at else 0.0
74-
75-
return {
76-
"user_id": user.user_id,
77-
"username": user.username,
78-
"email": user.email,
79-
"role": user.role.value,
80-
"is_active": user.is_active,
81-
"is_superuser": user.is_superuser,
82-
"created_at": created_at_ts,
83-
"updated_at": updated_at_ts,
84-
}
85-
8669
@staticmethod
8770
def from_pydantic_service_user(user: ServiceUser) -> DomainAdminUser:
8871
"""Convert internal service Pydantic user to domain admin user."""
@@ -140,18 +123,6 @@ def user_creation_to_dict(creation: UserCreation) -> Dict[str, Any]:
140123
}
141124

142125

143-
class UserListResultMapper:
144-
@staticmethod
145-
def to_dict(result: UserListResult) -> Dict[str, Any]:
146-
user_mapper = UserMapper()
147-
return {
148-
"users": [user_mapper.to_response_dict(user) for user in result.users],
149-
"total": result.total,
150-
"offset": result.offset,
151-
"limit": result.limit,
152-
}
153-
154-
155126
class SettingsMapper:
156127
@staticmethod
157128
def execution_limits_to_dict(limits: ExecutionLimits) -> dict[str, int]:

backend/app/infrastructure/mappers/admin_overview_api_mapper.py

Lines changed: 0 additions & 47 deletions
This file was deleted.

backend/app/infrastructure/mappers/dlq_mapper.py

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,11 @@
77
from confluent_kafka import Message
88

99
from app.dlq.models import (
10-
DLQBatchRetryResult,
1110
DLQFields,
1211
DLQMessage,
1312
DLQMessageFilter,
1413
DLQMessageStatus,
1514
DLQMessageUpdate,
16-
DLQRetryResult,
1715
)
1816
from app.events.schema.schema_registry import SchemaRegistryManager
1917
from app.infrastructure.kafka.events import BaseEvent
@@ -147,44 +145,6 @@ def from_kafka_message(message: Message, schema_registry: SchemaRegistryManager)
147145
dlq_partition=partition if partition >= 0 else None,
148146
)
149147

150-
@staticmethod
151-
def to_response_dict(message: DLQMessage) -> dict[str, object]:
152-
return {
153-
"event_id": message.event_id,
154-
"event_type": message.event_type,
155-
"event": message.event.to_dict(),
156-
"original_topic": message.original_topic,
157-
"error": message.error,
158-
"retry_count": message.retry_count,
159-
"failed_at": message.failed_at,
160-
"status": message.status,
161-
"age_seconds": message.age_seconds,
162-
"producer_id": message.producer_id,
163-
"dlq_offset": message.dlq_offset,
164-
"dlq_partition": message.dlq_partition,
165-
"last_error": message.last_error,
166-
"next_retry_at": message.next_retry_at,
167-
"retried_at": message.retried_at,
168-
"discarded_at": message.discarded_at,
169-
"discard_reason": message.discard_reason,
170-
}
171-
172-
@staticmethod
173-
def retry_result_to_dict(result: DLQRetryResult) -> dict[str, object]:
174-
d: dict[str, object] = {"event_id": result.event_id, "status": result.status}
175-
if result.error:
176-
d["error"] = result.error
177-
return d
178-
179-
@staticmethod
180-
def batch_retry_result_to_dict(result: DLQBatchRetryResult) -> dict[str, object]:
181-
return {
182-
"total": result.total,
183-
"successful": result.successful,
184-
"failed": result.failed,
185-
"details": [DLQMapper.retry_result_to_dict(d) for d in result.details],
186-
}
187-
188148
# Domain construction and updates
189149
@staticmethod
190150
def from_failed_event(

0 commit comments

Comments
 (0)