Commit Graph

129 Commits

Author SHA1 Message Date
827dfcdf2f fix(08): fix infinite recursion in config manager 2026-04-23 14:51:51 +03:00
c14a28b093 fix(08): fix AI key status detection and enable saving to secrets.yaml 2026-04-23 14:45:07 +03:00
a5a460e765 feat(08): implement SSOT architecture for network configuration 2026-04-23 13:58:33 +03:00
88e5d66f36 chore(07): integrate LDAP config into YAML and remove JSON files 2026-04-23 12:58:15 +03:00
d9dffdc389 chore(07): remove deprecated bash scripts and legacy env files 2026-04-23 12:56:30 +03:00
6b7becfe2d feat(07-04): update backend/entrypoint.sh with config validation 2026-04-23 12:53:03 +03:00
5b3a23f90f feat(07-04): update backend/Dockerfile with config/ documentation 2026-04-23 12:52:37 +03:00
225972b8d0 chore(07-02): update entrypoint.sh to document YAML config
- Add comments about D-06 load order and YAML config path
- Add warning if backend.yaml is missing
- Remove any implied inventory.env dependencies
2026-04-23 12:48:18 +03:00
938fd2daf8 feat(07-02): update main.py to use new YAML config loader
- Replace os.environ calls with get_config()
- Use configuration for CORS and network settings
- Remove direct dotenv/inventory.env references
2026-04-23 12:46:49 +03:00
28cdc90056 feat(07-02): update config_manager.py for YAML support
- Replace dotenv with PyYAML
- Implement read_config, update_config, validate_config_file for backend.yaml
- Update get_masked_key to use new config structure
- Remove inventory.env references
2026-04-23 12:45:51 +03:00
ae61fa6382 feat(07-02): refactor config_loader.py for YAML and D-06 load order
- Replace dotenv with PyYAML
- Implement D-06 load order: env vars > YAML > defaults
- Add validation and logging for config
- Remove inventory.env references
- Update requirements.txt
2026-04-23 12:45:26 +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
ce9fd32f68 fix(6): update openpyxl version constraint
- Change openpyxl>=3.10.0 to openpyxl>=3.1.0
- Version 3.10.0 doesn't exist in PyPI
- 3.1.5 is the latest stable version and compatible
2026-04-22 18:57:21 +03:00
fc149184e9 feat(6): phase 6 plan 02 - operational runbook and documentation
- Created OPERATIONAL_RUNBOOK.md: comprehensive step-by-step procedures for both Docker and Standalone deployment modes covering deployment, daily ops, troubleshooting, backup/restore, disaster recovery, scaling, and updates
- Created HEALTH_MONITORING_CHECKLIST.md: daily/weekly/monthly health check procedures with alert thresholds and quick troubleshooting reference
- Created DISASTER_RECOVERY_PLAN.md: detailed procedures for 6 failure scenarios (database corruption, hardware failure, data center failure, app crash, disk full, network isolation) with RTO/RPO targets
- Created CONFIGURATION_REFERENCE.md: complete documentation of all inventory.env parameters for both deployment modes with common scenarios and troubleshooting
- Created EMERGENCY_PROCEDURES.md: quick-reference incident response playbook with 7 critical scenarios, decision tree, escalation path, and printable cheat sheet
- Created scripts/backup.sh: automated backup script supporting both Docker and Standalone with integrity verification and retention management
- Created scripts/restore.sh: restore script with triple confirmation, safety backups, and validation tests for both deployment modes
- Created config/backup-cron.sh: installer for daily/weekly automated backup cron jobs (2 AM daily, 3 AM Sunday)

All documentation covers dual-deployment modes with shared configuration files.
Documentation is operator-ready with copy-paste commands and clear expected outputs.
2026-04-22 18:25:32 +03:00
42fb8a1d63 feat(5-plan-02-t1,t6): add backend search endpoint with comprehensive test coverage 2026-04-22 17:44:00 +03:00
fd13f63c28 test(5-03-07): add comprehensive export tests for CSV/Excel generation and endpoint authorization 2026-04-22 17:43:23 +03:00
798cf4bfd5 feat(5-03-06): add openpyxl to backend dependencies for Excel export support 2026-04-22 17:43:21 +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
9fc3de4798 feat(5-03-01): create export service with CSV and Excel generation for inventory and audit trails 2026-04-22 17:43:05 +03:00
a7746a14ea test(5.1): add integration and unit tests for quick quantity adjustment
- Vitest hook tests for useQuantityAdjustment (optimistic updates, debouncing)
- Pytest backend tests for PATCH /items/{itemId} endpoint
- Tests cover success, failure, validation, and audit logging scenarios
2026-04-22 17:42:08 +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
8dca073c50 feat(4.1-03,4.1-04): implement search orchestrator and integration tests 2026-04-22 16:37:38 +03:00
6e5642ff06 feat(4.1-02): implement web scraper and spec extractor services for spare-parts search 2026-04-22 16:37:01 +03:00
2ecaa6b2e8 feat(4.1-01): create spare-parts classification whitelist module with fuzzy matching 2026-04-22 16:34:10 +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
1425856af5 fix: transform crop_bounds from EXIF-applied to raw image space
Gemini analyzes images with EXIF orientation applied (e.g., 90° CW rotation),
returning crop_bounds in that coordinate space. We need to transform them back
to raw image coordinates before cropping.

For EXIF orientation 6 (Rotate 90 CW):
- Raw: 4032×3024 (landscape)
- Displayed (after EXIF): 3024×4032 (portrait)
- Transform portrait coords back to landscape before cropping

This fixes the issue where crop was applied to wrong image region.
2026-04-22 10:25:44 +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
4e23899f87 fix: remove negation from rotation to match prompt semantics
New prompt defines rotation_degrees as already signed:
- positive = counter-clockwise rotation
- negative = clockwise rotation

Old code negated it: rotate(-rotation_degrees), which inverted the direction.
Now: rotate(rotation_degrees) directly uses Gemini's signed value.
2026-04-22 10:06:29 +03:00
92c8517663 debug: add explicit logging to show crop bounds and rotation values 2026-04-22 09:55:53 +03:00
197dcadfee fix: apply crop bounds before EXIF rotation to match AI analysis
Gemini analyzes raw image and returns crop_bounds for that coordinate space.
Previous code applied EXIF rotation first, changing image dimensions, then
used crop_bounds on the rotated image (coordinate mismatch).

Now: crop on raw image (matches AI) → then apply EXIF + manual rotation.
This ensures cropped region contains the actual item, not background.
2026-04-22 09:50:08 +03:00
a2847092ac debug: add detailed logging to image processing pipeline
- Log input image size, crop bounds, and rotation degrees
- Log crop rectangle coordinates and result size
- Log OpenCV smart crop success/failure details
- Track pixel count to detect zero-size crops
2026-04-22 09:23:51 +03:00
e5615826d6 Revert "fix: apply rotation before cropping for better text orientation"
This reverts commit f8e54d0f8b.
2026-04-22 09:02:22 +03:00
f8e54d0f8b fix: apply rotation before cropping for better text orientation
- Move manual rotation before cropping and text detection
- Detect text orientation on full rotated image (not just cropped region)
- This allows text angle detection to see full context and properly orient labels
- Crop happens after orientation correction for cleaner results
2026-04-22 08:58:17 +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
bbe60bb471 test: add integration tests for item creation with auto-photo-save 2026-04-21 19:31:26 +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
ada3669217 test: add tests for image_processing field from AI extraction
- Added 11 comprehensive tests for image_processing parsing
- Tests validate crop_bounds structure: {x, y, width, height} all ints >= 0
- Tests validate rotation_degrees: int/float, -360 to +360
- Tests validate confidence: float, 0.0 to 1.0
- Tests graceful handling when image_processing field is missing
- Tests multiple items with image_processing data
- Tests partial data handling (optional fields)
- Tests with both Gemini and Claude providers
- Updated extract_label_info() to preserve and validate image_processing field
- All tests passing, no regressions
2026-04-21 18:53:04 +03:00
770b02864d fix: handle CORS preflight OPTIONS requests before routing 2026-04-21 18:17:00 +03:00
6f1e7731d7 fix: implement subnet-aware CORS middleware to replace insecure wildcard origins 2026-04-21 17:58:14 +03:00
904e153d8a temp: allow all CORS origins for debugging LDAP login issue
Temporarily using allow_origins=['*'] to debug whether CORS is blocking
LDAP login requests from VPN client. This is insecure for production.
TODO: Fix subnet pattern matching in ALLOWED_ORIGINS configuration.
2026-04-21 15:32:01 +03:00
2078cd9ade fix: resolve CORS preflight issues and Next.js dev origin warnings
- Simplify backend CORS middleware to use standard FastAPI implementation
- Keep subnet validation function for future use in route-level checks
- Add Tailscale subnet pattern to Next.js allowedDevOrigins config
- Both individual IPs and subnet configurations now work correctly
2026-04-21 15:19:45 +03:00
983d6e4bb4 feat: add subnet-based CORS validation support for VPN/Tailscale origins
- Add ipaddress module for subnet parsing (10.0.0.0/24 format)
- Implement subnet validation in CORS middleware
- Separate individual IPs from subnet definitions in EXTRA_ALLOWED_ORIGINS
- Custom SubnetAwareCORSMiddleware for dynamic origin validation
- Support both exact IP matches and subnet ranges
- Backward compatible with existing ALLOWED_ORIGINS list
2026-04-21 15:17:29 +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