fix: prevent duplicate item creation with barcode conflict detection

Backend:
- Added UNIQUE constraint check on barcode before item creation
- Returns 409 Conflict with user-friendly message if duplicate exists
- Prevents sqlite3.IntegrityError crashes

Frontend:
- Improved error handling for cloud sync failures
- Detects 409 status code (duplicate barcode)
- Shows specific error message to user
- Gracefully falls back to local-only save

Example error message: 'Item already exists. Item with barcode P66093-002 already exists (ID: 42). Update it instead or use a different barcode.'
This commit is contained in:
2026-04-17 12:29:53 +03:00
parent 9baa5612de
commit ade8dcde78
2 changed files with 19 additions and 3 deletions

View File

@@ -97,6 +97,15 @@ def create_item(
current_user: auth.TokenData = Depends(auth.get_current_user)
):
"""[C-01] Create item — only for authenticated users. [M-02] user_id from token."""
# [DUPLICATE CHECK] Prevent duplicate barcodes (part numbers)
if item.barcode:
existing = db.query(models.Item).filter(models.Item.barcode == item.barcode).first()
if existing:
raise HTTPException(
status_code=409,
detail=f"Item with barcode '{item.barcode}' already exists (ID: {existing.id}). Update it instead or use a different barcode."
)
# [AUTO-PERSIST] Create Category/Color if not exists
if item.category:
cat = db.query(models.Category).filter(models.Category.name == item.category).first()

View File

@@ -170,9 +170,16 @@ export default function Home() {
await inventoryApi.createItem(currentUser.id, itemData);
toast.success("Item saved to cloud catalog!");
} catch (err: any) {
console.error("Cloud sync failed:", err.message);
const status = err.response?.status;
const detail = err.response?.data?.detail || err.message;
console.error("Cloud sync failed:", detail);
if (status === 409) {
toast.error(`Item already exists. ${detail}`);
} else {
toast.error("Item saved locally. Cloud sync failed.");
}
}
} else if (!isOnline) {
toast.success("Item saved locally. Will sync when online.");
} else {