feat: Implement warehouse module roles with auto-schema repair and remove module access section
- Add SchemaVerifier class for automatic database schema verification and repair - Implement warehouse_manager (Level 75) and warehouse_worker (Level 35) roles - Add zone-based access control for warehouse workers - Implement worker-manager binding system with zone filtering - Add comprehensive database auto-repair on Docker initialization - Remove Module Access section from user form (role-based access only) - Add autocomplete attributes to password fields for better UX - Include detailed documentation for warehouse implementation - Update initialize_db.py with schema verification as Step 0
This commit is contained in:
222
documentation/WAREHOUSE_QUICK_REFERENCE.md
Normal file
222
documentation/WAREHOUSE_QUICK_REFERENCE.md
Normal file
@@ -0,0 +1,222 @@
|
||||
# Warehouse Roles & Zone Binding: Quick Reference
|
||||
|
||||
## Role Quick Lookup
|
||||
|
||||
| Role | Level | Modules | Input Pages | Reports | Manage Workers | Zone Restricted |
|
||||
|------|-------|---------|-------------|---------|-----------------|-----------------|
|
||||
| Super Admin | 100 | All | ✓ | ✓ | ✓ | ✗ |
|
||||
| Admin | 90 | All | ✓ | ✓ | ✓ | ✗ |
|
||||
| Manager - Warehouse | 75 | Warehouse | ✓ | ✓ | ✓ | ✗ |
|
||||
| Manager - Quality | 70 | Quality | ✗ | ✗ | ✗ | N/A |
|
||||
| Worker - Quality | 50 | Quality | ✗ | ✗ | ✗ | N/A |
|
||||
| Worker - Warehouse | 35 | Warehouse | ✓ | ✗ | ✗ | ✓ |
|
||||
|
||||
---
|
||||
|
||||
## Zone Binding Quick Reference
|
||||
|
||||
### Create Binding (Python)
|
||||
```python
|
||||
from app.modules.settings.warehouse_worker_management import assign_worker_to_manager
|
||||
|
||||
# With zone restriction
|
||||
assign_worker_to_manager(manager_id=6, worker_id=15, warehouse_zone="Cold Storage")
|
||||
|
||||
# Without zone (all zones)
|
||||
assign_worker_to_manager(manager_id=6, worker_id=15, warehouse_zone=None)
|
||||
```
|
||||
|
||||
### Query Zone Filters
|
||||
```python
|
||||
from app.access_control import build_zone_filter_sql
|
||||
|
||||
# Get SQL filter based on role
|
||||
filter_sql = build_zone_filter_sql(user_id=15, user_role='warehouse_worker')
|
||||
# Result: "AND created_by_user_id = 15"
|
||||
|
||||
query = f"SELECT * FROM warehouse_entries WHERE status='active' {filter_sql}"
|
||||
```
|
||||
|
||||
### Get Worker's Zone
|
||||
```python
|
||||
from app.modules.settings.warehouse_worker_management import get_worker_binding_info
|
||||
|
||||
info = get_worker_binding_info(worker_id=15)
|
||||
# Result: {
|
||||
# 'manager_id': 6,
|
||||
# 'manager_name': 'Maria Garcia',
|
||||
# 'zone': 'Cold Storage',
|
||||
# 'is_active': 1
|
||||
# }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Access Checks in Routes
|
||||
|
||||
### Check Input Access
|
||||
```python
|
||||
from app.access_control import can_access_warehouse_input
|
||||
|
||||
if not can_access_warehouse_input(session.get('role')):
|
||||
flash('Access denied', 'error')
|
||||
return redirect(url_for('main.dashboard'))
|
||||
```
|
||||
|
||||
### Check Report Access
|
||||
```python
|
||||
from app.access_control import can_access_warehouse_reports
|
||||
|
||||
if not can_access_warehouse_reports(session.get('role')):
|
||||
flash('Only managers can view reports', 'error')
|
||||
return redirect(url_for('warehouse.warehouse_index'))
|
||||
```
|
||||
|
||||
### Check Worker Zone
|
||||
```python
|
||||
from app.modules.settings.warehouse_worker_management import validate_worker_zone_access
|
||||
|
||||
can_access = validate_worker_zone_access(
|
||||
worker_id=15,
|
||||
manager_id=6,
|
||||
zone='Cold Storage'
|
||||
)
|
||||
|
||||
if not can_access:
|
||||
flash('You cannot input to this zone', 'error')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Scenario Examples
|
||||
|
||||
### Scenario 1: Manager Creates Entry
|
||||
```
|
||||
Maria Garcia (warehouse_manager) at /warehouse/set-boxes-locations
|
||||
├─ Role check: ✓ can_access_warehouse_input('warehouse_manager')
|
||||
├─ Zone check: No zone restriction (NULL)
|
||||
├─ Can select: Any zone in dropdown
|
||||
└─ Result: Entry created with any zone, visible in her reports
|
||||
```
|
||||
|
||||
### Scenario 2: Worker Creates Entry
|
||||
```
|
||||
David Chen (warehouse_worker) at /warehouse/set-boxes-locations
|
||||
├─ Role check: ✓ can_access_warehouse_input('warehouse_worker')
|
||||
├─ Zone check: Binding exists (zone='Cold Storage')
|
||||
├─ Can select: Only 'Cold Storage' in dropdown
|
||||
├─ Tries to submit zone='High Shelf'
|
||||
└─ Result: ✗ DENIED - "Cannot input to zone High Shelf"
|
||||
```
|
||||
|
||||
### Scenario 3: Worker Views Reports
|
||||
```
|
||||
David Chen (warehouse_worker) tries /warehouse/reports
|
||||
├─ Role check: ✗ can_access_warehouse_reports('warehouse_worker')
|
||||
└─ Result: ✗ DENIED - Redirected to warehouse home
|
||||
```
|
||||
|
||||
### Scenario 4: Unassigned Worker
|
||||
```
|
||||
Frank Thompson (warehouse_worker, no binding) at /warehouse/
|
||||
├─ Role: ✓ warehouse_worker
|
||||
├─ Binding check: ✗ No binding found
|
||||
└─ Result: ✗ DENIED - "Not assigned to a manager"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Database Quick Commands
|
||||
|
||||
### See All Worker Bindings
|
||||
```sql
|
||||
SELECT m.full_name as Manager, u.full_name as Worker, wmb.warehouse_zone as Zone
|
||||
FROM worker_manager_bindings wmb
|
||||
JOIN users m ON wmb.manager_id = m.id
|
||||
JOIN users u ON wmb.worker_id = u.id
|
||||
WHERE wmb.is_active = 1
|
||||
ORDER BY m.full_name, u.full_name;
|
||||
```
|
||||
|
||||
### See All Warehouse Zones
|
||||
```sql
|
||||
SELECT DISTINCT warehouse_zone
|
||||
FROM worker_manager_bindings
|
||||
WHERE is_active = 1 AND warehouse_zone IS NOT NULL
|
||||
ORDER BY warehouse_zone;
|
||||
```
|
||||
|
||||
### Get Workers for Manager
|
||||
```sql
|
||||
SELECT u.full_name, wmb.warehouse_zone
|
||||
FROM worker_manager_bindings wmb
|
||||
JOIN users u ON wmb.worker_id = u.id
|
||||
WHERE wmb.manager_id = 6 AND wmb.is_active = 1;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Common Errors & Solutions
|
||||
|
||||
| Error | Cause | Solution |
|
||||
|-------|-------|----------|
|
||||
| "Access denied: warehouse input" | User role not warehouse_manager/worker | Assign correct warehouse role |
|
||||
| "Cannot input to zone X" | Worker zone mismatch | Check binding: `SELECT * FROM worker_manager_bindings WHERE worker_id=?` |
|
||||
| "Not assigned to a manager" | Worker has no binding | Create binding: `assign_worker_to_manager(...)` |
|
||||
| "Only managers can view reports" | Worker trying to access /reports | Workers cannot access reports by design |
|
||||
| Unassigned worker can't see warehouse | No module access checked | Grant 'warehouse' in user_modules table |
|
||||
|
||||
---
|
||||
|
||||
## Implementation Checklist
|
||||
|
||||
### For New Warehouse Route
|
||||
- [ ] Add access check decorator (`@warehouse_input_required` or `@warehouse_reports_required`)
|
||||
- [ ] Get user_id and role from session
|
||||
- [ ] If warehouse_worker, get and validate zone binding
|
||||
- [ ] Build zone filter SQL for queries
|
||||
- [ ] Apply filter to all SELECT statements
|
||||
- [ ] Log zone/role in audit trail
|
||||
- [ ] Test with manager (should see all workers' data)
|
||||
- [ ] Test with worker (should see own zone only)
|
||||
- [ ] Test with unassigned worker (should be denied)
|
||||
|
||||
---
|
||||
|
||||
## Files to Reference
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `access_control.py` | Role definitions, permission checks, helper functions |
|
||||
| `warehouse_worker_management.py` | Worker binding CRUD operations |
|
||||
| `WAREHOUSE_ROLES_AND_ACCESS_CONTROL.md` | Complete system design |
|
||||
| `WORKER_MANAGER_BINDING_MODEL.md` | Visual guide and examples |
|
||||
| `ZONE_FILTERING_IMPLEMENTATION.md` | Implementation guide with code samples |
|
||||
|
||||
---
|
||||
|
||||
## Key Functions
|
||||
|
||||
```python
|
||||
# Role Checks
|
||||
can_access_warehouse_input(role) # ✓ Manager & Worker
|
||||
can_access_warehouse_reports(role) # ✓ Manager only
|
||||
can_manage_warehouse_workers(role) # ✓ Manager only
|
||||
|
||||
# Worker Binding
|
||||
assign_worker_to_manager(mgr_id, worker_id, zone)
|
||||
get_manager_workers(manager_id) # List all workers
|
||||
get_worker_binding_info(worker_id) # Get manager & zone
|
||||
validate_worker_zone_access(worker_id, mgr_id, zone)
|
||||
|
||||
# Zone Filtering
|
||||
build_zone_filter_sql(user_id, role) # Get SQL WHERE fragment
|
||||
get_warehouse_zones() # List all zones in use
|
||||
get_worker_warehouse_zone(worker_id) # Get worker's zone
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: January 28, 2026
|
||||
**Version**: 1.0
|
||||
**Status**: ✅ Ready for Implementation
|
||||
Reference in New Issue
Block a user