- New "route" FilterType: RouteBody popover (searchable origin +
destination selects, apply once both are picked), wired into
ContractRequestsPage and BookingRequestsPage. Bookings already had
server-side originYardId/destinationYardId; contracts gets both new
(contract_routes is one-to-many, so origin/destination are separate
EXISTS subqueries, not a join).
- Inactive FilterPill trigger restyled to read like a closed Mantine
Select (opaque solid border, trailing chevron) instead of a dashed
"+" pill — trigger only, popover body/position unchanged.
- Search box text set to regular weight.
- A couple more filters (Direction, Freight) pinned by default per
page on top of the existing always-pinned ones; the rest stay behind
More filters.
Replace the ad-hoc filter controls with a URL-linkable pill filter bar:
each filter is a pill that opens a type-aware popover (text/enum/date/
number/boolean, each with the right operator set), overflow filters live
behind a searchable "More filters" menu, sorting is a separate control,
and filter state round-trips through the URL query string (shareable,
back/forward-safe, backward compatible with existing ?statuses=A,B links).
Frontend (apps/edr-freight-web/backoffice/src/components/filters/):
- FilterDef schema + a pure url.ts codec (parse/serialize/toApiParams),
with a 24-case round-trip + malformed-input test suite
- useFilters hook driving react-query params straight from useSearchParams,
debounced search, saved views in localStorage (@mantine/hooks
useLocalStorage), page-reset-on-filter-change baked into one
setSearchParams call instead of a separate effect
- FilterBar/FilterPill/OperatorSelect/MoreFiltersMenu/SortControl +
per-type popover bodies (Mantine)
- ContractRequestsPage migrated end to end as the pilot
Backend (apps/edr-freight-api):
- pagination.util: applySort() — whitelisted sortBy resolved against a
per-module column map (never interpolated), with a mandatory `id ASC`
tiebreaker so paginating a non-unique sort can't drop/duplicate rows
- facets.util: computeFacets() — one GROUP BY per enum column, each
omitting its own predicate, so picking a value doesn't hide its siblings
- contracts/bookings: list-summary now returns real filter-scoped facet
counts (contracts' getStatusCounts was unfiltered/global; superseded)
- deleted drivers/vehicles findAllWithFilters — dead code that
interpolated an unwhitelisted sortBy straight into orderBy()
- migration: missing bookings(status)/wagons(status) indexes +
(created_at DESC, id ASC) partials on the hot list tables
UI polish pass: inactive pill uses the opaque "default" variant instead
of a faint tinted outline, active pill uses "light" not "filled", larger
X hit target, applied filters sort first, sort control separated behind
a divider on the right and wraps independently from the filter row,
popover option rows are fully clickable (count moved inside the native
label) with bigger hit area and font, fixed a real date-filter bug where
the calendar's own portal falsely registered as an "outside click" and
closed the popover, and fixed a timezone bug where bare YYYY-MM-DD
strings were parsed as UTC instead of local time (shifts a day for EAT).
Not in this commit: rollout to the other ~59 list pages, the Ethiopian-
calendar DateBody branch, and the Family-B (client-side) bridge mode —
tracked in the filter-bar plan.
Emit the request line as raw JSON on stdout (level/time/logger as fields)
instead of through Nest's console logger, whose prefix made it unparsable.
Collect data points via logCtx at the flow chokepoints: BaseRepository
writes (status changes, creates, deletes), invoice transitions, payment
intent lifecycle + outbound payment-service calls, booking/contract entry
state, review-note reasons, signatures and OTP verify outcomes.
- Added pricing service integration to ContractsService for pre-persistence contract pricing.
- Updated LegCapacityPanel to display cargo weight instead of gross weight for better clarity on booked cargo.
- Enhanced train scheduling service to include cargo weight in booking details.
- Modified ClearanceDocumentsPage to include FULLY_EXECUTED status in booking status options.
- Refactored FileUploadSettingsPage to categorize file upload settings into tabs for better organization.
- Removed legacy onboarding fields and settings from file upload settings seeder.
- Improved type definitions for train scheduling to include cargo weight without wagon tare.
- Added functionality to cancel contracts, allowing users to provide a reason for cancellation.
- Updated contract statuses to include SUSPENDED and changed CLOSED to COMPLETED.
- Enhanced the UI to reflect the new cancellation option and updated messaging for contract statuses.
- Refactored contract booking actions to accommodate changes in booking logic for ONE_TIME and GENERAL contracts.
- Removed clearance document management from the contract detail page, as it is now handled per booking.
- Introduced a SQL script to reset bookings and train schedules for development purposes.
- Introduced HazardDeclarationPanel component to display dangerous goods declaration details.
- Updated URL constants to include CLEARANCE_PROCEED endpoint for re-requesting operations.
- Enhanced permissions to include hazardous approval roles for contract approvals.
- Integrated HazardDeclarationPanel into ContractRequestDetailPage and ContractClearanceDetailPage.
- Added proceedToOperation method in bookings service for handling operation re-requests.
- Updated contract forms and schemas to include hazard class and UN number fields.
- Implemented validation for hazardous contracts in the contract creation flow.
- Added expiry notice functionality for contracts nearing validity end.
- Created tests for expiry notice calculations and labels.
- Updated UI components to reflect hazardous cargo information and validation errors.
- Introduced StampUpload component for uploading company stamp images.
- Integrated stamp upload in contract signing modal, supporting PNG and JPG formats.
- Implemented validation for file type and size (max 5 MB).
- Added visual feedback for drag-and-drop functionality.
- Updated contract-related pages to handle duplicate contract alerts and pricing notices.
- Enhanced contract expiry management with a nightly sweep service.
- Added unit tests for new features and updated existing tests for contract handling.
A suspended customer trying to create a contract was told their account
was "awaiting approval" - the guards collapsed every non-active status
into the pending message. Contract and booking creation now go through a
shared assertCompanyActiveFor that names the real company status, and
the per-role guard names the role's actual state (suspended,
blacklisted, rejected - with the reviewer note) so a customer suspended
for one operation knows the others still work.
Portal: the operation dropdown gets a Suspended badge, the block modal a
suspended branch quoting the staff message, and the wizard a
suspended/blacklisted gate instead of falling through to a submit error.
EDRFREIGHT-234
- Added parameter to and for server-side free-text search on contract reference, company name, and booking details.
- Introduced new validation errors in for container clashes and space issues when creating bookings.
- Implemented paginated dropdown settings retrieval in .
- Updated to fetch active yards using a new method that handles pagination.
- Enhanced with a method to fetch all records by walking through pages.
- Refactored to support filtering and pagination in schedule listings.
- Improved to return a paginated list of facilities.
- Updated UI components in and to utilize debounced search inputs for better performance.
- Added alerts in to inform users about booking constraints related to splits and capacity.
- Enhanced to display notifications for split bookings and capacity usage.
- Updated ContractClearanceService and ContractsController to remove region parameter from queue method.
- Enhanced ContractsRepository to attach contract files for download and added attachContractFiles method.
- Modified ContractsService to persist cargo scope with quantity cap based on contract kind.
- Introduced quantityCap field in CreateContractCargoScopeDto and ContractCargoScope entity.
- Implemented capacity tracking in the frontend with ContractCapacityNotice component to display remaining bookable quantities.
- Updated various components and services to support new capacity features, including hooks and API calls.
- Added migration to include quantity_cap column in contract_cargo_scope table.