62 Commits

Author SHA1 Message Date
dc999991a5 Restore enterprise/LDAP login mode detection
- Added /users/auth-mode public endpoint to detect LDAP status
- Updated frontend to call getAuthMode() instead of hardcoded false
- Login page now automatically switches to enterprise mode when LDAP is enabled
- Fixes missing LDAP user login UI that was previously disabled with TODO comment

This restores the functionality that was commented out earlier where the login
page would auto-detect whether to show local user list or enterprise username input.
2026-04-26 13:27:46 +03:00
51716faf87 Fix LDAP login: ensure password encoding and include user in response
- Fix password encoding: Convert password to UTF-8 bytes for LDAP protocol compatibility
- Add 'user' field to TokenResponse schema for frontend compatibility
- Update login endpoint to populate user object in response
- Resolves 'Invalid Protocol Password' error on LDAP login attempts

The issue was that frontend expected response.user but backend only returned
individual fields (user_id, username, role), causing localStorage assignment to fail.
2026-04-26 13:13:55 +03:00
7c4441a962 Build [v1.14.22] 2026-04-23 16:16:04 +03:00
b87b1eceae fix(09): match export UI styles and fix backend user_id error 2026-04-23 15:18:14 +03:00
6f9716c32b fix(09): resolve export data quality and integrate UI 2026-04-23 15:08:46 +03:00
c14a28b093 fix(08): fix AI key status detection and enable saving to secrets.yaml 2026-04-23 14:45:07 +03:00
88e5d66f36 chore(07): integrate LDAP config into YAML and remove JSON files 2026-04-23 12:58:15 +03:00
7dfa993b57 feat(export): add /admin/db/export endpoint for frontend
- Changed router prefix from /admin/exports to /admin
- Added GET /admin/db/export endpoint
- Supports type: inventory|audit|combined
- Supports format: csv|xlsx
- Maintains auth guard and audit logging
- Fixes frontend 404 error on export calls
2026-04-23 10:54:07 +03:00
cbdb2f04f6 fix(auth): use actual hostname instead of localhost in frontend API client
- Modified frontend/lib/api.ts to use window.location.hostname as fallback
- Ensures browser on external IP reaches correct backend HTTPS port
- Allows admin/admin login to work from any access point
- Auth is fully functional and working
2026-04-23 10:39:18 +03:00
b6eb284568 feat(5-03-02): create admin export endpoints for inventory snapshot and audit trail with authorization 2026-04-22 17:43:09 +03:00
9fd20fff7c feat(5.1): implement quantity display component and adjustment hook
- Create QuantityDisplay component with tap-to-edit UI + +/- buttons
- Implement useQuantityAdjustment hook with optimistic updates, debouncing
- Add PATCH /items/{itemId} backend endpoint with audit logging
- Components support inline quantity adjustment without modal friction
2026-04-22 17:42:04 +03:00
c46c8414b8 feat: store original EXIF-stripped image for debugging
- Save original image before crop/rotation with '_debug_original' variant
- Store original_photo_path in labels_data.image_processing for debug access
- Update DebugRotationPanel to display original image instead of processed
- Update ItemDetailModal to pass original image path to debug panel
- Enables accurate crop/rotation visualization with true original image
2026-04-22 11:13:09 +03:00
500d090dfc fix: strip EXIF from image blob in backend before processing
Backend receives the original blob which may have EXIF orientation metadata.
Strip it before processing to ensure backend analyzes the same raw image space
that Gemini analyzed (which had EXIF stripped before sending).

This ensures rotation_degrees are applied correctly to the same image state.
2026-04-22 10:32:38 +03:00
bc2a6219fe refactor: strip EXIF orientation before Gemini analysis for coordinate accuracy
Instead of transforming coordinates after Gemini returns crop_bounds, strip EXIF
orientation from image before sending to Gemini. This ensures:
- Gemini analyzes the same raw image as our backend
- crop_bounds are in raw image coordinate space
- No coordinate transformation needed
- Works for all images (with or without EXIF)

Added strip_exif_orientation() utility that removes orientation tag and
re-encodes image. Used in extract_label endpoint before sending to Gemini.
2026-04-22 10:29:11 +03:00
ee1fcfbee6 fix: remove duplicate log imports in create_item function 2026-04-22 10:17:34 +03:00
79d8a71c97 fix: import log at module level for extraction logging 2026-04-22 10:15:25 +03:00
9586aecfdc debug: log file sizes at extraction and processing stages
Add logging to compare file sizes:
- [EXTRACT] sent to Gemini
- [CREATE_ITEM] received when creating item

This will reveal if image is being processed/changed between extraction and local processing.
2026-04-22 10:14:03 +03:00
92c8517663 debug: add explicit logging to show crop bounds and rotation values 2026-04-22 09:55:53 +03:00
09a66bd3d5 feat: clean up image files when item is deleted from catalog
- Delete photo_path and photo_thumbnail_path files on item deletion
- Handle file not found gracefully with logging
- Preserves audit logs while removing actual image files
2026-04-22 08:54:22 +03:00
64d177e791 fix: complete image pipeline - rotation, URL, preview
- Add rotation_degrees parameter to ImageProcessor.process_photo()
- Pass rotation through _auto_save_photo_from_extraction() to processor
- Allow no-crop fallback when crop_bounds is None
- Add buildPhotoUrl() helper to resolve backend URLs correctly
- Update frontend components to use backend URL for image sources
- Replace Use/Skip Photo buttons with checkbox in AI extraction UI
- Add images/ to .gitignore to prevent accidental commits

Addresses: rotation never applied, image 404s (relative to Next.js not backend), preview blank in edit form
2026-04-22 08:50:25 +03:00
4f63b3b99e feat: integrate auto-photo-save into item creation endpoint
- Extend ItemCreate schema with optional extracted_image_bytes (base64) and image_processing (dict)
- Update create_item endpoint to call _auto_save_photo_from_extraction after item creation
- Decode base64 image bytes and pass crop_bounds, rotation_degrees to helper
- Don't block item creation if photo save fails (log warning instead)
- Item returned with photo_path, photo_thumbnail_path populated if save succeeded
- Full backward compatibility: old clients without image fields work unchanged
- Add 5 integration tests covering all scenarios:
  - Create item WITH image_processing → photo auto-saved
  - Create item WITHOUT image_processing → no photo (backward compatible)
  - Create item WITH invalid image_processing → item created, photo skipped
  - Create item WITH crop_bounds=None → item created, photo skipped
  - Create item WITH bytes but NO processing metadata → item created, photo skipped
- All 158 backend tests passing, zero regressions
2026-04-21 19:00:06 +03:00
eca1ab7fd0 feat: add _auto_save_photo_from_extraction helper with graceful fallbacks 2026-04-21 18:56:17 +03:00
e46777b933 merge: Phase 1 image system implementation complete
- Database: Added photo_path, photo_thumbnail_path, photo_upload_date fields
- Services: ImageStorage (file ops) + ImageProcessor (image processing pipeline)
- API: POST/PUT /api/items/{id}/photo upload endpoints with validation
- API: GET /api/items/{id} returns photo URLs
- Static: FastAPI StaticFiles mount for /images/ directory
- Tests: 127+ comprehensive tests across all components
- Security: Fixed race conditions, path traversal, crop validation
- Ready for Phase 2 (frontend UI)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-04-20 22:47:31 +03:00
294555c574 feat(phase1): add static file serving for /images/ 2026-04-20 22:43:33 +03:00
af8dcbae3a fix(phase1): fix race condition, path traversal, double processing, validation in photo API 2026-04-20 22:39:02 +03:00
92f6977cae fix(phase1): add photo fields to schemas and set datetime default 2026-04-20 21:49:51 +03:00
d9ead1aafd fix: repair login endpoint registration in auth router 2026-04-19 17:20:11 +03:00
8fcd4150e5 refactor: split admin/config.py into ai_config and db_config 2026-04-19 17:10:56 +03:00
6dc300d339 refactor: split bulk-sync into backend/routers/sync.py 2026-04-19 12:37:09 +03:00
90e9a60640 refactor: split LDAP auth into backend/routers/auth.py 2026-04-19 12:35:40 +03:00
da83c91a5b feat: add side-by-side item comparison for duplicate Part Numbers
New Component: ItemComparisonModal.tsx
- Shows existing vs new item side-by-side
- Highlights fields that are different (in yellow)
- Options to Update item or Skip (local-only save)
- Shows existing item ID and comparison details

Backend Changes:
- Updated error message to say 'Part Number' not 'barcode'
- 409 response includes existing item data for comparison
- Clear, user-friendly conflict messaging

Frontend Changes:
- New state for comparison modal (newItem, existingItem, existingId)
- handleOnboardingComplete() shows modal on 409 conflict
- handleComparisonUpdate() calls updateItem() API
- handleComparisonSkip() saves locally without syncing
- Better error handling distinguishes 409 from other failures

Workflow:
1. User imports item with Part Number that already exists
2. System shows comparison modal
3. User can:
   - Update (merges new data into existing)
   - Skip (saves locally, doesn't sync to cloud)
2026-04-17 12:35:42 +03:00
ade8dcde78 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.'
2026-04-17 12:29:53 +03:00
db918a86ab feat(admin): finalizing modular refactoring with testing suite and UI polish 2026-04-15 16:41:20 +03:00
Daniel Bedeleanu
1893c4f38b modificari mari 2026-04-15 15:20:45 +03:00
Daniel Bedeleanu
6c57b1b0c2 blabla 2026-04-14 22:54:19 +03:00
Daniel Bedeleanu
00ee4cf9c5 Build [v1.9.19] 2026-04-14 20:44:01 +03:00
Daniel Bedeleanu
fcb187974e Build [v1.9.18] 2026-04-13 23:43:52 +03:00
Daniel Bedeleanu
ee7e7b7bd7 Build [v1.9.12] (Secure Seal & LDAP Sync: Custom Caddy & Config Volume) 2026-04-13 22:25:19 +03:00
Daniel Bedeleanu
bdf6d605cd Build [v1.9.10] (Access & SSL Recovery: Fixed Admin info and Explicit IP Proxy) 2026-04-13 22:07:15 +03:00
Daniel Bedeleanu
81b775c9ae Build [v1.8.0] 2026-04-13 19:23:48 +03:00
Daniel Bedeleanu
994920bda2 Build [v1.7.0] - GitGuard - Infrastructure Hardening 2026-04-12 22:45:27 +03:00
Daniel Bedeleanu
2e5c666cc8 Build [v1.5.0] - Box Management & Label Printing 2026-04-12 21:30:50 +03:00
Daniel Bedeleanu
50ae3671c9 Build [v1.4.1] - Security hardening, PWA and UI refinements 2026-04-12 10:45:57 +03:00
Daniel Bedeleanu
f3d861b1a2 Build [v1.4.0] - Audit Dashboard & LDAP Restoration 2026-04-12 09:39:17 +03:00
Daniel Bedeleanu
704934165f Build [v.1.3.6] 2026-04-11 17:14:22 +03:00
Daniel Bedeleanu
02a4951901 refactor: centralize configuration in backend/config/ and frontend/config/
- Move ldap_config.json from ./data/ to backend/config/
- Update users.py to read LDAP config from backend/config/ldap_config.json
- Create frontend/config/ directory for future frontend configs
- DATA_DIR still used for database and runtime files in ./data/
- Update .gitignore to track backend/config/ but ignore runtime data dirs
2026-04-11 15:06:56 +03:00
Daniel Bedeleanu
a6d2d176ba debug: add detailed LDAP authentication logging with error traceback 2026-04-11 15:02:57 +03:00
Daniel Bedeleanu
3c8d50162b debug: add detailed logging to login authentication flow
- Log when local auth succeeds/fails
- Log when password mismatch occurs
- Log LDAP auth attempts and failures
- Helps diagnose why login is returning 401
2026-04-11 14:55:31 +03:00
Daniel Bedeleanu
c2bd8e44fb fix: add Request parameter to extract_label for slowapi rate limiter 2026-04-11 14:37:28 +03:00
Daniel Bedeleanu
45b0f8b35c fix: make getUsers endpoint public for login page + translate remaining Romanian comments 2026-04-11 14:32:17 +03:00