- 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
223 lines
6.6 KiB
Markdown
223 lines
6.6 KiB
Markdown
# 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
|