diff --git a/README.md b/README.md index 2245bb1..9749a14 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ pip install flask werkzeug --break-system-packages ### 2. Initialize Database ```bash -cd /home/claude/scanlook +cd /path/to/scanlook python database/init_db.py ``` @@ -39,7 +39,7 @@ Access at: **http://localhost:5000** ## 📱 Accessing from Scanner Devices -For Zebra Android scanners or tablets on the same network: +For Zebra MC9300 scanners or tablets on the same network: 1. Find your server's IP address: ```bash @@ -55,11 +55,32 @@ For Zebra Android scanners or tablets on the same network: --- +## 🏗️ Modular Architecture + +ScanLook uses a modular system designed to grow into a full WMS. Modules can be enabled/disabled per user. + +### Current Modules: +- **Counts** - Cycle Counts and Physical Inventory + +### Planned Modules: +- Shipping +- Receiving +- Transfers +- Production + +### Module Access +- Admins assign modules to users via User Management +- Users only see modules they have access to on the home screen +- Route guards prevent URL bypassing + +--- + ## 👥 User Roles ### Owner (Level 1) - Super admin privileges -- Manage all admins +- Manage all users (admins and staff) +- Access to all modules - View all sessions across branches ### Admin (Level 2) @@ -68,9 +89,10 @@ For Zebra Android scanners or tablets on the same network: - Upload CURRENT baseline (refresh anytime) - View real-time dashboard - Export variance reports -- Manage staff users +- Manage staff users and module assignments ### Staff/Counter (Level 3) +- Access assigned modules only - Select active count session - Scan locations and lots - Enter weights @@ -79,36 +101,36 @@ For Zebra Android scanners or tablets on the same network: --- -## 🔄 Core Workflow +## 🔄 Core Workflow (Counts Module) ### Phase 1: Session Setup (Admin) 1. **Log in as admin** -2. **Create new count session**: +2. **Navigate to Admin Console** +3. **Create new count session**: - Session name: "January 17, 2026 - Daily Cycle Count" - Type: Cycle Count OR Full Physical Inventory -3. **Upload MASTER baseline** CSV from NetSuite: +4. **Upload MASTER baseline** CSV from NetSuite: - Format: `Item, Description, Lot Number, Location, Bin Number, On Hand` - - Creates baseline version 1 -4. Session status: **Active** -5. Counters can now begin +5. Session status: **Active** +6. Counters can now begin ### Phase 2: Counting (Staff) 1. **Log in as staff** -2. **Select active session** -3. **Scan location barcode** (e.g., R903B) - - System marks location "in progress" - - Shows: "Counting R903B" -4. **Scan lot barcode** -5. System checks lot against MASTER baseline: +2. **Select Counts module** from home screen +3. **Select active session** +4. **Start a new bin** - scan or enter bin number +5. **Scan lot barcode** +6. System checks lot against MASTER baseline: - ✅ **MATCH**: Expected here, location correct - ⚠️ **WRONG LOCATION**: Lot exists but system says different location - ❌ **GHOST LOT**: Not in system at all -6. **Enter weight** -7. Save → returns to scan input (autofocus) -8. Repeat for all lots in location -9. Click **"Finish Location"** + - 🔵 **DUPLICATE**: Lot already scanned (same or different location) +7. **Enter weight** +8. Save → returns to scan input (autofocus) +9. Repeat for all lots in bin +10. Click **"Finish Location"** to finalize ### Phase 3: Admin Monitoring @@ -155,8 +177,9 @@ Item,Description,Lot Number,Location,Bin Number,On Hand - What counters validate against - Represents "what should have been there when we started" -**CURRENT Baseline**: +**CURRENT Baseline** (Global): - Admin can refresh unlimited times +- Shared across all sessions - Only affects admin dashboard/reporting - Counters never see it - Shows "where is it in the system NOW" @@ -170,16 +193,29 @@ Item,Description,Lot Number,Location,Bin Number,On Hand - **Ghost Lot**: Scanned but not in baseline at all - **Missing/Phantom**: In baseline but not found during count -### Blind Counting +### Duplicate Detection -- Counters don't see expected quantities -- Prevents bias -- Ensures honest count +- **Status 00**: First scan of lot (no duplicate) +- **Status 01**: Duplicate in same location by same user +- **Status 03**: Found in different location +- **Status 04**: Both same location duplicate AND different location + +### Count Types + +**Cycle Count:** +- Shows expected lots for the bin +- Staff can see what should be there +- Good for regular inventory checks + +**Full Physical Inventory:** +- Blind count (no expected list shown) +- Staff only sees what they've scanned +- Missing lots determined after finalization ### Real-Time Dashboard -- Active counters with current location -- Progress by location +- Active sessions with progress stats +- Location completion tracking - Variance counts updating live - Dual view (MASTER vs CURRENT) after refresh @@ -188,32 +224,38 @@ Item,Description,Lot Number,Location,Bin Number,On Hand - Every scan timestamped with user - Soft deletes tracked - Edits tracked with modified timestamp -- Baseline version tracking +- Session archival (archived sessions are read-only) --- ## 🗂️ Database Schema -### Tables: +### Core Tables: - **Users**: Authentication and role management +- **Modules**: Available system modules +- **UserModules**: Per-user module access - **CountSessions**: Count session metadata -- **BaselineInventory_Master**: Morning baseline (never changes) -- **BaselineInventory_Current**: Refreshable baseline (soft delete) -- **LocationCounts**: Location-by-location progress -- **ScanEntries**: Every lot scan with dual status tracking -- **MissingLots**: Expected lots not found +- **BaselineInventory_Master**: Session-specific baseline (immutable) +- **BaselineInventory_Current**: Global refreshable baseline +- **LocationCounts**: Bin-by-bin progress tracking +- **ScanEntries**: Every lot scan with status tracking +- **MissingLots**: Expected lots not found after finalization -### Indexes: -Optimized for fast lookups on lot numbers, locations, and statuses. +### Key Relationships: +- Users → UserModules → Modules (many-to-many) +- CountSessions → BaselineInventory_Master (one-to-many) +- CountSessions → LocationCounts → ScanEntries (hierarchical) --- ## 🔧 Technology Stack - **Backend**: Python 3.13 + Flask -- **Database**: SQLite +- **Database**: SQLite (auto-initializes on first run) - **Frontend**: HTML5 + CSS3 + Vanilla JavaScript - **Templates**: Jinja2 +- **Icons**: Font Awesome 6.5 +- **Deployment**: Docker (Linux) --- @@ -221,23 +263,37 @@ Optimized for fast lookups on lot numbers, locations, and statuses. ``` scanlook/ -├── app.py # Main Flask application +├── app.py # Main Flask application & routes +├── db.py # Database helper functions +├── utils.py # Decorators (login_required, role_required) +├── blueprints/ +│ ├── counting.py # Counts module routes +│ ├── sessions.py # Session management routes +│ ├── users.py # User management routes +│ ├── data_imports.py # CSV upload routes +│ └── admin_locations.py # Admin location management ├── database/ -│ ├── init_db.py # Database initialization -│ └── scanlook.db # SQLite database (created) +│ ├── init_db.py # Database initialization & schema +│ └── scanlook.db # SQLite database (created at runtime) ├── static/ │ ├── css/ -│ │ └── style.css # Main stylesheet -│ └── js/ -│ └── main.js # Client-side JavaScript +│ │ ├── style.css # Base/desktop styles +│ │ ├── mobile.css # Mobile overrides (360-767px) +│ │ └── scanner.css # MC9300 scanner overrides (<360px) +│ ├── js/ +│ │ └── main.js # Client-side JavaScript +│ ├── manifest.json # PWA manifest +│ └── sw.js # Service worker └── templates/ - ├── base.html # Base template + ├── base.html # Base template with navbar ├── login.html # Login page + ├── home.html # Module selection (landing page) ├── admin_dashboard.html ├── staff_dashboard.html + ├── manage_users.html ├── create_session.html ├── session_detail.html - ├── count_session.html + ├── my_counts.html └── count_location.html ``` @@ -245,7 +301,7 @@ scanlook/ ## 🎨 Design Philosophy -**Mobile-First, Warehouse-Optimized:** +**Desktop-First, Multi-Device Optimized:** - High contrast dark theme for warehouse lighting - Large touch targets (44px minimum) - Autofocus on scan inputs @@ -253,52 +309,47 @@ scanlook/ - Visual feedback with color-coded statuses - Minimal typing required +**CSS Architecture:** +- `style.css` - Base/desktop styles (768px+) +- `mobile.css` - Phone overrides (360-767px) +- `scanner.css` - MC9300 scanner overrides (<360px) + **Color Coding:** -- ✅ Green: Perfect match -- ⚠️ Yellow: Wrong location -- ❌ Red: Missing or ghost lot -- 🔵 Blue: Weight variance +- ✅ Green (`--color-success`): Perfect match +- ⚠️ Yellow (`--color-warning`): Wrong location / Expected +- ❌ Red (`--color-danger`): Missing or ghost lot +- 🔵 Blue (`--color-duplicate`): Duplicate scan +- 🟠 Orange (`--color-orange`): Weight variance --- -## 🚧 Current Status: Phase 1 Complete (MVP) +## 🐳 Docker Deployment -### ✅ Implemented: -- User authentication (3 roles) -- Session creation -- MASTER baseline upload -- Location scanning -- Lot scanning with MASTER status -- Weight entry -- Basic dashboard -- Real-time progress tracking -- Mobile-optimized UI +```bash +# Build +docker build -t scanlook . -### 🔜 Next Phases: -- **Phase 2**: CURRENT baseline refresh & dual status recalculation -- **Phase 3**: Missing lot detection, enhanced dashboard -- **Phase 4**: Excel export with multiple tabs -- **Phase 5**: Data retention automation, user management -- **Phase 6**: Docker deployment +# Run (preserves database between updates) +docker run -d \ + -p 5000:5000 \ + -v /path/to/data:/app/database \ + -e SCANLOOK_SECRET_KEY=your-secret-key \ + scanlook +``` + +**Important:** Only `/app/database` is volume-mounted to preserve data between container updates. --- -## 📝 Development Notes +## 🔐 Security Considerations -### Default Accounts (Testing) -All passwords should be changed in production! - -### Security Considerations -- Passwords are hashed with Werkzeug +- Passwords hashed with Werkzeug - Session management via Flask sessions - SQL injection prevention (parameterized queries) +- Role-based access control +- Module-based access control with route guards - Soft deletes preserve audit trail -### Data Retention -- Plan: Keep data for 30 days -- Nightly cleanup job (to be implemented) -- Archive old sessions - --- ## 🎯 Success Metrics @@ -319,6 +370,7 @@ All passwords should be changed in production! ## 💡 Future Enhancements +- Additional WMS modules (Shipping, Receiving, Transfers, Production) - Multi-branch support - Direct NetSuite API integration - Photo capture for variance proof @@ -328,7 +380,16 @@ All passwords should be changed in production! --- -## 📧 Support +## 📝 Version History + +- **v0.12.0** - Modular architecture with user-based module access +- **v0.11.x** - CSS refactoring, multi-device support, duplicate detection +- **v0.10.x** - Global CURRENT baseline, session archival +- **v0.9.x** - Core counting workflow, dual baseline system + +--- + +## 🔧 Support This is a custom internal tool. Contact your system administrator for support. diff --git a/app.py b/app.py index c1a4839..77b8c97 100644 --- a/app.py +++ b/app.py @@ -36,7 +36,7 @@ app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(hours=1) # 1. Define the version -APP_VERSION = '0.12.0' +APP_VERSION = '0.12.1' # 2. Inject it into all templates automatically @app.context_processor