Add print badges, pagination, route splitting, JWT auth fixes, and list page alignment
- Fix equipment badge barcode not rendering (loading race condition) - Fix printer QR code not rendering on initial load (same race condition) - Add model image to equipment badge via imageurl from Model table - Fix white-on-white machine number text on badge, tighten barcode spacing - Add PaginationBar component used across all list pages - Split monolithic router into per-plugin route modules - Fix 25 GET API endpoints returning 401 (jwt_required -> optional=True) - Align list page columns across Equipment, PCs, and Network pages - Add print views: EquipmentBadge, PrinterQRSingle, PrinterQRBatch, USBLabelBatch - Add PC Relationships report, migration docs, and CLAUDE.md project guide - Various plugin model, API, and frontend refinements Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
165
migrations/PRODUCTION_MIGRATION_GUIDE.md
Normal file
165
migrations/PRODUCTION_MIGRATION_GUIDE.md
Normal file
@@ -0,0 +1,165 @@
|
||||
# Production Migration Guide
|
||||
|
||||
## Overview
|
||||
This guide documents the process for migrating data from the legacy VBScript ShopDB site to the new Flask-based ShopDB.
|
||||
|
||||
## Database Architecture
|
||||
|
||||
### Legacy System (VBScript)
|
||||
- Single `machines` table containing all equipment, PCs, printers
|
||||
- `machinetypes` table for classification
|
||||
- `models` table with `machinetypeid` reference
|
||||
|
||||
### New System (Flask)
|
||||
- Core `assets` table (unified asset registry)
|
||||
- Plugin-specific extension tables:
|
||||
- `equipment` (equipmenttypeid → equipmenttypes)
|
||||
- `computers` (computertypeid → computertypes)
|
||||
- `printers` (printertypeid → printertypes)
|
||||
- `network_device` (networkdevicetypeid → networkdevicetypes)
|
||||
|
||||
## Key Mappings
|
||||
|
||||
### Asset Type Mapping
|
||||
| Legacy Category | New Asset Type | Extension Table |
|
||||
|-----------------|---------------|-----------------|
|
||||
| Equipment machines | Equipment | equipment |
|
||||
| PC/Computer | Computer | computers |
|
||||
| Printer | Printer | printers |
|
||||
| Network (IDF, Switch, AP) | Network Device | network_device |
|
||||
|
||||
### Type ID Alignment
|
||||
The `equipmenttypes` table IDs match `machinetypes` IDs for easy migration:
|
||||
- equipmenttypeid = machinetypeid (where applicable)
|
||||
|
||||
## Migration Steps
|
||||
|
||||
### Step 1: Export from Legacy Database
|
||||
```sql
|
||||
-- Export machines with all related data
|
||||
SELECT
|
||||
m.*,
|
||||
mt.machinetype,
|
||||
mo.modelnumber,
|
||||
mo.machinetypeid as model_typeid,
|
||||
v.vendor,
|
||||
bu.businessunit,
|
||||
s.status
|
||||
FROM machines m
|
||||
LEFT JOIN machinetypes mt ON mt.machinetypeid = m.machinetypeid
|
||||
LEFT JOIN models mo ON mo.modelnumberid = m.modelnumberid
|
||||
LEFT JOIN vendors v ON v.vendorid = m.vendorid
|
||||
LEFT JOIN businessunits bu ON bu.businessunitid = m.businessunitid
|
||||
LEFT JOIN statuses s ON s.statusid = m.statusid;
|
||||
```
|
||||
|
||||
### Step 2: Create Assets
|
||||
For each machine, create an asset record:
|
||||
```sql
|
||||
INSERT INTO assets (assetnumber, name, assettypeid, statusid, locationid, businessunitid, mapleft, maptop)
|
||||
SELECT
|
||||
CONCAT(machinenumber, '-', machineid), -- Unique asset number
|
||||
alias,
|
||||
CASE
|
||||
WHEN category = 'PC' THEN 2 -- Computer
|
||||
WHEN category = 'Printer' THEN 4 -- Printer
|
||||
ELSE 1 -- Equipment
|
||||
END,
|
||||
statusid,
|
||||
locationid,
|
||||
businessunitid,
|
||||
mapleft,
|
||||
maptop
|
||||
FROM machines;
|
||||
```
|
||||
|
||||
### Step 3: Create Extension Records
|
||||
```sql
|
||||
-- For Equipment
|
||||
INSERT INTO equipment (assetid, equipmenttypeid, vendorid, modelnumberid)
|
||||
SELECT
|
||||
a.assetid,
|
||||
COALESCE(mo.machinetypeid, m.machinetypeid), -- Use model's type if available!
|
||||
m.vendorid,
|
||||
m.modelnumberid
|
||||
FROM machines m
|
||||
JOIN assets a ON a.assetnumber = CONCAT(m.machinenumber, '-', m.machineid)
|
||||
LEFT JOIN models mo ON mo.modelnumberid = m.modelnumberid
|
||||
WHERE m.category = 'Equipment' OR m.category IS NULL;
|
||||
```
|
||||
|
||||
### Step 4: Post-Migration Fixes
|
||||
|
||||
#### Fix LocationOnly Equipment Types
|
||||
Equipment imported with LocationOnly type should inherit type from their model:
|
||||
```sql
|
||||
-- Fix equipment that has a model with a proper type
|
||||
UPDATE equipment e
|
||||
JOIN assets a ON a.assetid = e.assetid
|
||||
JOIN machines m ON m.machinenumber = SUBSTRING_INDEX(a.assetnumber, '-', 1)
|
||||
JOIN models mo ON mo.modelnumberid = m.modelnumberid
|
||||
SET e.equipmenttypeid = mo.machinetypeid
|
||||
WHERE e.equipmenttypeid = 1 -- LocationOnly
|
||||
AND mo.machinetypeid != 1; -- Model has real type
|
||||
```
|
||||
|
||||
## Validation Queries
|
||||
|
||||
### Check for Orphaned Assets
|
||||
```sql
|
||||
SELECT a.* FROM assets a
|
||||
LEFT JOIN equipment e ON e.assetid = a.assetid
|
||||
LEFT JOIN computers c ON c.assetid = a.assetid
|
||||
LEFT JOIN printers p ON p.assetid = a.assetid
|
||||
WHERE a.assettypeid = 1 -- Equipment type
|
||||
AND e.assetid IS NULL;
|
||||
```
|
||||
|
||||
### Check LocationOnly with Models
|
||||
```sql
|
||||
-- Should return 0 after migration fix
|
||||
SELECT COUNT(*)
|
||||
FROM equipment e
|
||||
JOIN assets a ON a.assetid = e.assetid
|
||||
JOIN machines m ON m.machinenumber = SUBSTRING_INDEX(a.assetnumber, '-', 1)
|
||||
JOIN models mo ON mo.modelnumberid = m.modelnumberid
|
||||
WHERE e.equipmenttypeid = 1
|
||||
AND mo.machinetypeid != 1;
|
||||
```
|
||||
|
||||
### Verify Type Distribution
|
||||
```sql
|
||||
SELECT et.equipmenttype, COUNT(*) as count
|
||||
FROM equipment e
|
||||
JOIN equipmenttypes et ON et.equipmenttypeid = e.equipmenttypeid
|
||||
GROUP BY et.equipmenttype
|
||||
ORDER BY count DESC;
|
||||
```
|
||||
|
||||
## Common Issues
|
||||
|
||||
### Issue: Equipment marked as LocationOnly but has model
|
||||
**Cause**: Migration copied machinetypeid from machines table instead of using model's type
|
||||
**Fix**: See FIX_LOCATIONONLY_EQUIPMENT_TYPES.md
|
||||
|
||||
### Issue: Missing model relationship
|
||||
**Cause**: Equipment table modelnumberid not populated during migration
|
||||
**Fix**: Link through machines table using asset number pattern
|
||||
|
||||
### Issue: Duplicate asset numbers
|
||||
**Cause**: Asset number generation didn't account for existing duplicates
|
||||
**Fix**: Use unique suffix or check before insert
|
||||
|
||||
## Scripts Location
|
||||
- `/migrations/FIX_LOCATIONONLY_EQUIPMENT_TYPES.md` - Fix for LocationOnly type issue
|
||||
- `/scripts/import_from_mysql.py` - Original import script (may need updates)
|
||||
- `/scripts/migration/` - Migration utilities
|
||||
|
||||
## Notes
|
||||
- Always backup before running migration fixes
|
||||
- Test on staging/dev before production
|
||||
- Verify counts before and after each fix
|
||||
- Keep legacy `machines` table for reference during transition
|
||||
|
||||
## Date Created
|
||||
2026-01-27
|
||||
Reference in New Issue
Block a user