Skip to content

Logistics MFE DTOs & Services Contracts

Goal

Provide implementation-ready DTO shapes and service abstractions so the logistics Blazor microfrontend can be built stub-first (UI + navigation + service interfaces ship before the real logistics backend API exists).

This document is explicitly mapped to: - LOG-MFE-001 (epic) / FOUND / ADMIN / SELF / INTG slices

Stub-first architecture & boundaries

The logistics MFE uses a configuration flag (name may be UseStubLogisticsApi or an equivalent) to switch between: - Stub/in-memory service implementations (seeded data, deterministic IDs for tests) - Future HTTP implementations (typed HttpClient and real backend)

Contract boundaries: 1. Razor pages/components should bind to UI view models, not DTOs directly. 2. Razor pages/components call UI services, which depend on service abstraction interfaces (queries/commands). 3. Service abstractions accept request DTOs and return response DTOs (including validation/error shapes). 4. DI wiring selects stub vs HTTP implementations without changing page code.

flowchart TB
  UI[Razor Pages/Components] --> VM[UI View Models]
  VM --> Svc[UI Services]
  Svc --> IFace[Service Abstractions - Queries/Commands]
  IFace --> Stub[Stub/InMemory Implementations]
  IFace --> Http[Future HttpClient Implementations]
  Stub --> DTO[Response DTOs]
  Http --> DTO[Response DTOs]
  DTO --> Map[DTO-to-VM Mapping]
  Map --> VM
Hold "Alt" / "Option" to enable pan & zoom

Suggested repository folder layout

Use a layout that keeps DTOs, interfaces, implementations, and mapping clearly separated.

Recommended (example) layout for the logistics MFE repository:

  • Contracts/
  • Common/ (shared IDs, pagination, error DTOs)
  • Equipment/ (EquipmentType*Dto, Location*Dto)
  • Inventory/ (InventoryByLocation*Dto, move-related DTOs)
  • Events/ (EventOrder*Dto, EventCalendar*Dto, EventOrderSummaryDto)
  • BrokenEquipment/ (BrokenEquipment*Dto)
  • Audit/ (ActivityLog*Dto)
  • Services/Abstractions/
  • query interfaces (*Queries)
  • command interfaces (*Commands)
  • Services/Stub/
  • in-memory seed stores + stub implementations
  • Services/Http/ (placeholder for the API epic)
  • ViewModels/
  • page-specific view models and lightweight UI types
  • Mapping/
  • DTO-to-VM mappers and request builders helpers

Shared DTO building blocks

These are DTOs that appear across all operations in this MFE.

Identity / tenancy references (IDs)

Use lightweight ID DTOs/types instead of full user entities: - TenantId (GUID/string) - UserId or ActorId (GUID/string)

Pagination

  • PagedRequestDto
  • pageNumber (int, 1-based)
  • pageSize (int)
  • PagedResponseDto<TItem>
  • items (TItem[])
  • pageNumber, pageSize
  • totalCount (long)

Validation + domain errors

Choose one consistent pattern across all service abstractions. Recommended (contract-explicit) approach: - ValidationProblemDto - title (string) - status (int, optional) - errors (dictionary: fieldName -> string[]) - traceId (string, optional) - DomainErrorDto - code (string) - message (string) - OperationResultDto<T> - isSuccess (bool) - data (T, nullable) - validation (ValidationProblemDto, nullable) - error (DomainErrorDto, nullable)

Notes: - The UI should rely on validation and/or error rather than parsing exception messages. - Stub implementations should emulate the same validation shapes so UI logic is stable.

DTO families mapped to List-It screens

This section lists DTO families needed to implement the following screen numbers: - Screen 3 Dashboard - Screen 7 Manage equipment types - Screen 8 Manage locations - Screen 9 Move equipment - Screen 10 Create / update event order - Screen 11 Lock order - Screen 12 Calendar view - Screen 13 Report broken equipment - Screen 14 Update status + resolve - Screen 15 Activity log with filters - Screen 16 Event order summary / print

1) Equipment catalog DTOs (Screens 7-8)

Equipment types

  • EquipmentTypeDto
  • id
  • name
  • icon (string)
  • description (string, optional)
  • imageUrl (string, optional)
  • EquipmentTypeListQueryRequestDto
  • pagination + optional search
  • EquipmentTypeUpsertRequestDto
  • fields for create/update
  • EquipmentTypeDeleteRequestDto
  • id

Locations

  • LocationDto
  • id
  • name
  • type (e.g., Hall, Storage) as string/enum
  • LocationListQueryRequestDto
  • pagination + optional search
  • LocationUpsertRequestDto
  • fields for create/update
  • LocationDeleteRequestDto
  • id

2) Dashboard + inventory summary DTOs (Screen 3)

  • DashboardQueryRequestDto
  • tenant scope (implicit via auth) + optional “asOf” timestamp
  • DashboardDto
  • inventorySummary (InventoryByLocationDto[])
  • recentActivityPreview (ActivityLogEntryPreviewDto[])
  • quickActions (lightweight UI hints; optional)

InventoryByLocationDto shape: - locationId, locationName - equipmentQuantities (list of: equipmentTypeId, equipmentTypeName, quantityAvailable)

3) Inventory move DTOs (Screen 9)

  • MoveEquipmentRequestDto
  • sourceLocationId
  • targetLocationId
  • items (MoveEquipmentLineItemDto[])
    • equipmentTypeId
    • quantity
  • note (optional)
  • MoveEquipmentResultDto
  • activityLogEntryId (optional for UI)
  • updatedInventory (optional, can be refreshed by re-querying)
  • validation and/or error come via OperationResultDto
  • MoveEquipmentValidationLineItemDto (optional)
  • equipmentTypeId
  • requestedQuantity
  • availableQuantity (for insufficient stock hints)

4) Event orders & scheduling DTOs (Screens 10-12, 16)

Terminology used here aligns with glossary: - Event order: date/time window + hall + equipment list + notes + status - Status flow at MVP: Pending -> Locked -> Completed/Cancelled (completion/cancel can be supported later; lock is core)

Create/update event order (Screen 10)

  • EventOrderUpsertRequestDto
  • id (nullable for create)
  • eventDate (date)
  • startTime, endTime (time)
  • hallLocationId
  • equipmentLines (EventOrderEquipmentLineDto[])
    • equipmentTypeId
    • quantity
  • notes (optional)
  • seating (optional; if in scope for MVP)
  • participants (optional; if in scope for MVP)
  • desiredStatus (recommended to be implicit: Pending on save while editing)
  • EventOrderDto
  • id
  • eventDate, startTime, endTime
  • hallLocationId
  • equipmentLines (normalized)
  • status (Pending/Locked/Completed/Cancelled)

Lock order (Screen 11)

  • LockOrderRequestDto
  • orderId
  • optional lockMoment (timestamp) for deterministic stub behavior
  • LockOrderAvailabilityResultDto
  • hallOccupancy availability result:
    • isHallFree (bool)
    • conflictingOrderIds (optional)
  • equipmentAvailability availability result:
    • lines (EquipmentAvailabilityLineDto[])
    • equipmentTypeId
    • availableQuantity
    • requestedQuantity
    • isSufficient (bool)
  • canLock (bool) computed from both hall + equipment checks
  • LockOrderResultDto
  • lockedOrderId (same as input)
  • newStatus (Locked)
  • error/validation shapes come from OperationResultDto

This is where UI validation errors should surface: - When hall occupancy fails (AC-O7) - When equipment availability fails (AC-O5)

Calendar view (Screen 12)

  • EventCalendarQueryRequestDto
  • fromDate, toDate
  • optional filters: hallLocationId, status
  • includeHebrewCalendarContext (bool) (AC-O6)
  • EventCalendarDto
  • days (EventCalendarDayDto[])
  • each day includes:
    • date
    • hebrewDateLabel (optional if includeHebrewCalendarContext)
    • cards (EventCalendarCardDto[])
    • orderId
    • status
    • startTime, endTime
    • hallLocationName

Event order summary / print (Screen 16)

  • EventOrderSummaryDto
  • id
  • orderMetadata
    • orderer (optional display fields)
    • eventDate, startTime, endTime
    • hallLocationName
  • equipmentLines (EventOrderEquipmentLineDto[])
  • notes
  • seating (optional)
  • participantCount (optional)
  • activity (optional for trace)

5) Broken equipment DTOs (Screens 13-14)

Glossary-aligned concepts: - Broken equipment report tied to a location, equipment type, quantity, reason/status - Resolve updates status and returns quantity to a target location

Report broken (Screen 13)

  • BrokenEquipmentReportRequestDto
  • locationId
  • equipmentTypeId
  • quantity
  • reason or statusReason (string/enum)
  • BrokenEquipmentDto
  • id
  • locationId
  • equipmentTypeId
  • quantity
  • currentStatus
  • createdAt

Update status + resolve (Screen 14)

  • BrokenEquipmentStatusUpdateRequestDto
  • brokenEquipmentId
  • newStatus (enum)
  • note (optional)
  • BrokenEquipmentResolveRequestDto
  • brokenEquipmentId
  • resolvedQuantity
  • targetLocationId
  • note (optional)
  • BrokenEquipmentResolveResultDto
  • newStatus
  • optional activityLogEntryId

6) Activity log DTOs (Screen 15)

  • ActivityLogQueryRequestDto
  • filters:
    • dateFrom, dateTo
    • type (move/order/broken/etc.)
    • optional userId
  • pagination
  • ActivityLogEntryDto
  • id
  • timestamp
  • type
  • message (or structured payload for rendering)
  • actorUserId / actorDisplayName
  • optional relatedEntityId (orderId/locationId/brokenEquipmentId)
  • ActivityLogEntryPreviewDto
  • a reduced version used by dashboard

Service abstractions (queries/commands) mapped to backlog slices

This section maps the needed service contracts to the backlog plan slices: - LOG-MFE-FOUND-001 (Foundation) - LOG-MFE-ADMIN-001 (Admin) - LOG-MFE-SELF-001 (Self-service) - LOG-MFE-INTG-001 (Shell integration)

LOG-MFE-FOUND-001 (Foundation)

Foundation establishes: - the DTO + service abstractions mentioned below - stub implementations (seeded data) controlled by the stub config flag - a minimal “smoke path” proving routing + stubs + Flowbite/UIKit assets work (per backlog plan)

Minimum service interfaces (include both queries and commands used across admin/self): - Queries - IDashboardQueries - GetDashboardAsync(DashboardQueryRequestDto, CancellationToken) - IEquipmentCatalogQueries - ListEquipmentTypesAsync(EquipmentTypeListQueryRequestDto, CancellationToken) - ListLocationsAsync(LocationListQueryRequestDto, CancellationToken) - IInventoryQueries - GetInventoryByLocationAsync(LocationId/List request, CancellationToken) (optional if dashboard covers it) - IEventOrdersQueries - GetEventCalendarAsync(EventCalendarQueryRequestDto, CancellationToken) - GetEventOrderSummaryAsync(orderId, CancellationToken) - IActivityLogQueries - QueryActivityLogAsync(ActivityLogQueryRequestDto, CancellationToken)

  • Commands
  • IEquipmentCatalogCommands
    • UpsertEquipmentTypeAsync(EquipmentTypeUpsertRequestDto, CancellationToken)
    • DeleteEquipmentTypeAsync(EquipmentTypeDeleteRequestDto, CancellationToken)
  • ILocationsCommands
    • UpsertLocationAsync(LocationUpsertRequestDto, CancellationToken)
    • DeleteLocationAsync(LocationDeleteRequestDto, CancellationToken)
  • IMoveEquipmentCommands
    • MoveEquipmentAsync(MoveEquipmentRequestDto, CancellationToken)
  • IEventOrdersCommands
    • UpsertEventOrderAsync(EventOrderUpsertRequestDto, CancellationToken) (returns Pending state)
    • LockOrderAsync(LockOrderRequestDto, CancellationToken) (returns LockOrderAvailabilityResultDto or Locked)
  • IBrokenEquipmentCommands
    • ReportBrokenEquipmentAsync(BrokenEquipmentReportRequestDto, CancellationToken)
    • UpdateBrokenEquipmentStatusAsync(BrokenEquipmentStatusUpdateRequestDto, CancellationToken)
    • ResolveBrokenEquipmentAsync(BrokenEquipmentResolveRequestDto, CancellationToken)

Stub implementations should return OperationResultDto<T> with consistent validation/error shapes.

LOG-MFE-ADMIN-001 (Admin)

Admin slice implements screens tied to admin navigation and role requirements, including at least: - Screen 3 Dashboard - Screen 7 Manage equipment types - Screen 8 Manage locations - Screen 9 Move equipment - Screen 10 Create/update event order - Screen 11 Lock order - Screen 12 Calendar view - Screen 13 Report broken equipment - Screen 14 Update status + resolve - Screen 15 Activity log with filters - Screen 16 Event order summary / print

DTO/service usage mapping (high level): - Catalog screens use: EquipmentType*Dto, Location*Dto + catalog commands/queries. - Dashboard uses: DashboardDto, InventoryByLocationDto, ActivityLogEntryPreviewDto. - Move uses: MoveEquipmentRequestDto and MoveEquipmentResultDto. - Orders/Calendar/Print use: EventOrder*Dto, LockOrder*Dto, EventCalendar*Dto, EventOrderSummaryDto. - Broken equipment uses: BrokenEquipment*Dto request DTOs for report/status/update/resolve. - Activity log uses: ActivityLogQueryRequestDto and ActivityLogEntryDto.

LOG-MFE-SELF-001 (Self-service)

Self-service slice: - routes under a self-service route group (e.g. /logistics/self) - reuses the same DTO shapes and service abstractions as Admin - provides a smaller set of pages according to self-service operator needs

At minimum, the self-service slice must support: - Screen 9 Move equipment - plus whichever order/broken workflows are permitted for self-service operators

Contract-wise, no new DTO families are required unless self-service needs different response payloads. Prefer reuse: - Use the same MoveEquipmentRequestDto - Use the same EventOrderUpsertRequestDto, LockOrderRequestDto, and broken equipment request DTOs where allowed

LOG-MFE-INTG-001 (Shell integration)

Shell integration slice is expected to wire: - MFE registration/configuration for navigation - route entry points for admin/self-service UI groups

No new domain DTOs are required here; reuse the contracts above and ensure: - DI registration for interface implementations (stub in MVP; HTTP in the next epic) - shell→MFE route loading works in dev/staging

Stub implementation expectations

Stub implementations (in-memory) must emulate the real contract behavior closely enough that UI logic is stable:

Deterministic seed data

  • Use deterministic IDs and stable timestamps for seeded entities.
  • Make time-dependent behavior (like filtering by date range) independent of local machine time by allowing a “clock” or using fixed seed time.

Validation behavior (order + lock)

Lock and upsert flows must reflect key business validation surfaced in UI: - Hall occupancy check failure should populate ValidationProblemDto for form errors or return availability details in LockOrderAvailabilityResultDto. - Equipment availability check failure should populate availability line details so UI can show “requested vs available”.

Pagination and filtering

  • PagedRequestDto should map to PagedResponseDto<T> consistently.
  • Filtering fields from request DTOs must be honored:
  • calendar: date range + optional hall/status
  • activity log: date range + type/user + pagination

Error/validation return shape

All service methods must return: - success with data OR - validation errors in validation OR - domain errors in error

Avoid mixing exception-driven flows with result-driven flows. If exceptions are used internally, convert them at the service boundary.

UI view-model mapping rules

Rule of thumb: - DTOs are contract shapes (service boundary). - View models are UI shapes (page/section boundary). - Mapping must happen in a dedicated mapping layer (or UI service wrapper) so Razor pages remain thin.

Example mapping: calendar list row

DTO: - EventCalendarDto contains EventCalendarCardDto list per day. VM: - CalendarCardVm contains the exact fields/labels the calendar component renders (status badge text, click target route, display time format).

Mapping: - EventCalendarCardDto.status -> CalendarCardVm.statusBadge - EventCalendarCardDto.startTime/endTime -> CalendarCardVm.displayTimeRange - EventCalendarCardDto.orderId -> CalendarCardVm.orderId (for navigation)

Example mapping: print/details

DTO: - EventOrderSummaryDto is print-friendly and read-only. VM: - EventOrderSummaryVm formats/renames labels, computes derived display strings (e.g., localized time formatting), and provides “Print” metadata.

Mapping: - EventOrderSummaryDto.equipmentLines -> EventOrderSummaryVm.equipmentRows - EventOrderSummaryDto.eventDate/startTime/endTime -> EventOrderSummaryVm.timeRangeDisplay

Testing checklist for DTO/service contracts

Even before the real backend exists, stub contracts should be testable: - Unit tests for stub filtering/pagination: - calendar date range selection - activity log filters by type/date/user - Unit tests for validation and availability: - LockOrderAsync hall occupancy failure returns consistent LockOrderAvailabilityResultDto - LockOrderAsync equipment insufficiency returns line-level availability - Unit tests for mapping: - DTO-to-VM mapping populates the exact fields the UI expects (status badge text, display time ranges)

Implementation notes

This doc is intentionally contract-focused: - It does not assume a specific backend transport. - It supports stub-first development by stabilizing DTO/service shapes early. - When the HTTP backend epic arrives, implementations can be swapped without changing UI pages, only by updating the Services/Http implementations and DTO conformance if needed.