Lagerorte per 10-Zeichen-Code statt fortlaufender ID; iOS-Einlagern ohne Kamerazwang

Lagerort-IDs sind jetzt ein zufaelliger 10-Zeichen-Code (wie die Einzelstueck-UIDs) statt einer fortlaufenden Zahl - so kollidiert die Stammdaten-Sicherung zwischen zwei Instanzen praktisch nie mehr, und der Code ist zugleich der Inhalt des QR /l/<code>. Alle Fremdschluessel (lots, movements, items, Mindestbestaende, parent_id) ziehen mit; die Umstellung laeuft einmalig und transaktional beim Serverstart (_migrate_locations_to_code) und rollt bei Fehlern komplett zurueck. Vor dem Deploy ein DB-Backup machen.

iOS-Einlagern oeffnet nicht mehr sofort die Kamera, sondern ein Formular mit Artikelsuche; die Kamera kommt erst per Button. Im Formular laesst sich der Lagerort zusaetzlich per /l/-QR scannen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-07-27 12:15:25 +02:00
parent 6e48cd0a7a
commit d518b4aa23
23 changed files with 507 additions and 220 deletions

View File

@@ -10,10 +10,10 @@ from ..schemas import LocationCreate, LocationOut, LocationUpdate
router = APIRouter(prefix="/locations", tags=["locations"])
def _descendant_ids(db: Session, location_id: int) -> set[int]:
def _descendant_ids(db: Session, location_id: str) -> set[str]:
"""Alle Unterorte (rekursiv) als Ziel beim Umhängen ausgeschlossen, sonst
entstünde ein Ring."""
result: set[int] = set()
result: set[str] = set()
stack = [location_id]
while stack:
cur = stack.pop()
@@ -46,7 +46,7 @@ def create_location(
@router.patch("/{location_id}", response_model=LocationOut)
def update_location(
location_id: int,
location_id: str,
payload: LocationUpdate,
db: Session = Depends(get_db),
_: User = Depends(require_admin),
@@ -93,7 +93,7 @@ def update_location(
@router.delete("/{location_id}", status_code=status.HTTP_204_NO_CONTENT)
def delete_location(
location_id: int,
location_id: str,
db: Session = Depends(get_db),
_: User = Depends(require_admin),
) -> None: