feat(warehouses): backoffice UI for container stack positions

Surfaces the physical stack/slot model in the staff app.

- ZoneLayoutModal: stacks drawn level by level with occupancy colours,
  configured-vs-built-vs-occupied counts, and stack create/delete plus
  block/reserve/free on empty levels
- SlotPicker in the store and move modals, offering only the next
  fillable level of each stack so the form cannot suggest a position
  the API will refuse
- move modal warns when a container is buried, lists the blockers, and
  disables the action instead of firing a 409
- fix: move() now asserts accessibility server-side, matching release —
  both are exits from a stack
This commit is contained in:
Hagernesh
2026-08-29 06:37:53 +00:00
parent abfd55d43e
commit 312c1f1da3
22 changed files with 1074 additions and 27 deletions

View File

@@ -3140,6 +3140,13 @@ export class WarehouseInventoryService {
const { warehouse, yard, zone } = await this.validateLocation(manager, dto);
// Taking a box out of a stack is physically impossible while others stand
// on top of it — the same rule the release path enforces. Moving is one of
// those exits, so it is checked here rather than only at release.
if (item.slotId) {
await this.placement.assertAccessible(item.id, manager);
}
// A move that names a slot is validated against the hierarchy it claims;
// one that does not clears the old slot, because the box has left it.
if (dto.slotId) {