# Phase 3: Network Devices Migration to machines Table **Date:** 2025-11-10 **Status:** PLANNING **Follows:** Phase 2 (PC Migration - Completed) --- ## Executive Summary Consolidate all network infrastructure devices (servers, switches, cameras, access points, IDFs) into the unified `machines` table. This completes the infrastructure unification started in Phase 2 with PCs, creating a single source of truth for all physical assets except printers. --- ## Scope ### Migrate INTO machines Table: - **Servers** → machinetypeid 30 - **Switches** → machinetypeid 31 - **Cameras** → machinetypeid 32 - **Access Points** → machinetypeid 33 - **IDFs** → machinetypeid 34 - **Routers** → machinetypeid 35 (if exists) - **Firewalls** → machinetypeid 36 (if exists) ### Keep SEPARATE: - **Printers** → Stay in `printers` table (unique fields, workflows, APIs) --- ## Why This Migration? ### Current Problems: 1. **Data Fragmentation:** Network devices scattered across 5+ tables 2. **Code Duplication:** Separate pages for each device type 3. **Relationship Limitations:** Can't relate servers to switches to cameras 4. **Query Complexity:** UNION queries to find all devices on a network 5. **Inconsistent UI/UX:** Different interfaces for similar devices ### After Migration: 1. **Single Source of Truth:** All infrastructure in `machines` table 2. **Unified Relationships:** Camera → Switch → IDF using `machinerelationships` 3. **Unified Communications:** All IPs in `communications` table 4. **Consistent UI:** One set of pages for all devices 5. **Powerful Queries:** Cross-device reports and topology mapping 6. **Better Compliance:** All devices tracked in one place --- ## Architecture ### Current Structure: ``` machines table ├── Equipment (machinetypeid 1-24, pctypeid IS NULL) └── PCs (machinetypeid 25-29, pctypeid IS NOT NULL) servers table (separate) switches table (separate) cameras table (separate) accesspoints table (separate) idfs table (separate) printers table (stays separate) ``` ### Target Structure: ``` machines table ├── Equipment (machinetypeid 1-24, pctypeid IS NULL) ├── PCs (machinetypeid 25-29, pctypeid IS NOT NULL) └── Network Devices (machinetypeid 30-36, pctypeid IS NULL) ← NEW printers table (stays separate - by design) ``` --- ## New Machine Types (30-36) ```sql INSERT INTO machinetypes (machinetypeid, machinetype, category, description, displayorder) VALUES (30, 'Server', 'Network', 'Physical or virtual server', 30), (31, 'Switch', 'Network', 'Network switch', 31), (32, 'Camera', 'Network', 'IP camera or security camera', 32), (33, 'Access Point', 'Network', 'Wireless access point', 33), (34, 'IDF', 'Network', 'Intermediate Distribution Frame', 34), (35, 'Router', 'Network', 'Network router', 35), (36, 'Firewall', 'Network', 'Network firewall', 36); ``` --- ## Filtering Strategy ```sql -- All PCs SELECT * FROM machines WHERE pctypeid IS NOT NULL; -- All Equipment (CNC machines, mills, lathes, etc.) SELECT * FROM machines WHERE pctypeid IS NULL AND machinetypeid BETWEEN 1 AND 24; -- All Network Devices SELECT * FROM machines WHERE pctypeid IS NULL AND machinetypeid BETWEEN 30 AND 36; -- Specific device types SELECT * FROM machines WHERE machinetypeid = 30; -- Servers SELECT * FROM machines WHERE machinetypeid = 31; -- Switches SELECT * FROM machines WHERE machinetypeid = 32; -- Cameras -- All non-printer infrastructure SELECT * FROM machines; -- Everything except printers ``` --- ## Data Migration Mapping ### Servers Table → Machines ``` servers.serverid → machines.machineid (new) servers.modelid → machines.modelnumberid servers.serialnumber → machines.serialnumber servers.description → machines.alias servers.maptop → machines.maptop servers.mapleft → machines.mapleft servers.isactive → machines.isactive servers.ipaddress → communications.address (comstypeid=1) 30 (constant) → machines.machinetypeid NULL → machines.pctypeid 'SERVER-{serverid}' → machines.machinenumber (generated) ``` ### Switches Table → Machines ``` switches.switchid → machines.machineid (new) switches.modelid → machines.modelnumberid switches.serialnumber → machines.serialnumber switches.description → machines.alias switches.maptop → machines.maptop switches.mapleft → machines.mapleft switches.isactive → machines.isactive switches.ipaddress → communications.address (comstypeid=1) 31 (constant) → machines.machinetypeid NULL → machines.pctypeid 'SWITCH-{switchid}' → machines.machinenumber (generated) ``` ### Cameras Table → Machines ``` cameras.cameraid → machines.machineid (new) cameras.modelid → machines.modelnumberid cameras.serialnumber → machines.serialnumber cameras.description → machines.alias cameras.maptop → machines.maptop cameras.mapleft → machines.mapleft cameras.isactive → machines.isactive cameras.ipaddress → communications.address (comstypeid=1) 32 (constant) → machines.machinetypeid NULL → machines.pctypeid 'CAMERA-{cameraid}' → machines.machinenumber (generated) ``` ### Access Points Table → Machines (if exists) ``` accesspoints.accesspointid → machines.machineid (new) accesspoints.modelid → machines.modelnumberid accesspoints.serialnumber → machines.serialnumber accesspoints.description → machines.alias accesspoints.maptop → machines.maptop accesspoints.mapleft → machines.mapleft accesspoints.isactive → machines.isactive accesspoints.ipaddress → communications.address (comstypeid=1) 33 (constant) → machines.machinetypeid NULL → machines.pctypeid 'AP-{accesspointid}' → machines.machinenumber (generated) ``` ### IDFs Table → Machines (if exists) ``` idfs.idfid → machines.machineid (new) idfs.name → machines.machinenumber idfs.description → machines.alias idfs.maptop → machines.maptop idfs.mapleft → machines.mapleft idfs.isactive → machines.isactive 34 (constant) → machines.machinetypeid NULL → machines.pctypeid ``` --- ## New Relationship Types ```sql INSERT INTO relationshiptypes (relationshiptype, description, isbidirectional) VALUES -- Existing relationships ('Dualpath', 'Machines sharing the same controller', 1), ('Controlled By', 'Machine controlled by PC', 0), ('Controls', 'PC controls this machine', 0), -- New network relationships ('Connected To', 'Device physically connected to infrastructure', 0), ('Powered By', 'Device powered by this power source', 0), ('Mounted In', 'Device mounted in rack/cabinet', 0), ('Feeds Video To', 'Camera feeds video to this server/NVR', 0), ('Provides Network', 'Infrastructure provides network to device', 0); ``` --- ## Migration Scripts Structure ``` /home/camp/projects/windows/shopdb/sql/migration_phase3/ ├── 01_create_network_machinetypes.sql ├── 02_migrate_servers_to_machines.sql ├── 03_migrate_switches_to_machines.sql ├── 04_migrate_cameras_to_machines.sql ├── 05_migrate_accesspoints_to_machines.sql ├── 06_migrate_idfs_to_machines.sql ├── 07_migrate_network_communications.sql ├── 08_create_network_relationships.sql ├── 09_update_views_for_network_devices.sql ├── 10_update_vendor_flags.sql ├── VERIFY_PHASE3_MIGRATION.sql ├── RUN_ALL_PHASE3_SCRIPTS.sql └── ROLLBACK_PHASE3.sql ``` --- ## Migration Order ### Pre-Migration: 1. **Backup database** 2. **Verify Phase 2 is stable** 3. **Document current table structures** 4. **Count records in each table** ### Migration Steps: 1. **Create new machinetypes** (30-36) 2. **Migrate servers** → machines + communications 3. **Migrate switches** → machines + communications 4. **Migrate cameras** → machines + communications 5. **Migrate access points** → machines + communications (if exists) 6. **Migrate IDFs** → machines (if exists) 7. **Create network relationships** (camera → switch → IDF) 8. **Update vendor flags** (isserver, isswitch, etc.) 9. **Update views** (create vw_network_devices if needed) 10. **Verify data integrity** ### Post-Migration: 1. **Run verification queries** 2. **Test UI pages** 3. **Update code references** 4. **Keep old tables temporarily** (for rollback safety) 5. **Monitor for issues** 6. **Drop old tables after 30 days** (if stable) --- ## Code Updates Required ### Pages to Update: 1. **displaymachines.asp** - Add filter tabs for network devices 2. **displaymachine.asp** - Already supports all types via machinetypeid 3. **machine_edit.asp** - Already supports all types 4. **adddevice.asp** - Update to include network device types ### Pages to Deprecate: 1. **displayservers.asp** → Redirect to displaymachines.asp?type=server 2. **displayswitches.asp** → Redirect to displaymachines.asp?type=switch 3. **displaycameras.asp** → Redirect to displaymachines.asp?type=camera 4. **network_devices.asp** → Redirect to displaymachines.asp?category=network ### Views to Update: ```sql -- Update or create CREATE OR REPLACE VIEW vw_all_infrastructure AS SELECT m.machineid, m.machinenumber, m.alias, mt.machinetype, mt.category, mo.modelnumber, v.vendor, c.address AS ipaddress, CASE WHEN m.pctypeid IS NOT NULL THEN 'PC' WHEN mt.category = 'Network' THEN 'Network Device' ELSE 'Equipment' END AS device_category FROM machines m LEFT JOIN machinetypes mt ON m.machinetypeid = mt.machinetypeid LEFT JOIN models mo ON m.modelnumberid = mo.modelnumberid LEFT JOIN vendors v ON mo.vendorid = v.vendorid LEFT JOIN communications c ON m.machineid = c.machineid AND c.isprimary = 1 WHERE m.isactive = 1; ``` --- ## Verification Queries ### Record Counts ```sql -- Before migration SELECT 'servers' AS table_name, COUNT(*) AS count FROM servers UNION ALL SELECT 'switches', COUNT(*) FROM switches UNION ALL SELECT 'cameras', COUNT(*) FROM cameras UNION ALL SELECT 'accesspoints', COUNT(*) FROM accesspoints UNION ALL SELECT 'idfs', COUNT(*) FROM idfs; -- After migration SELECT mt.machinetype, COUNT(*) AS count FROM machines m JOIN machinetypes mt ON m.machinetypeid = mt.machinetypeid WHERE mt.machinetypeid BETWEEN 30 AND 36 GROUP BY mt.machinetype; ``` ### Data Integrity ```sql -- Verify all network devices have machine types SELECT COUNT(*) FROM machines WHERE machinetypeid BETWEEN 30 AND 36 AND machinetypeid IS NULL; -- Should be 0 -- Verify all network devices have pctypeid = NULL SELECT COUNT(*) FROM machines WHERE machinetypeid BETWEEN 30 AND 36 AND pctypeid IS NOT NULL; -- Should be 0 -- Verify IP addresses migrated SELECT mt.machinetype, COUNT(DISTINCT m.machineid) AS total_devices, COUNT(DISTINCT c.machineid) AS devices_with_ip FROM machines m JOIN machinetypes mt ON m.machinetypeid = mt.machinetypeid LEFT JOIN communications c ON m.machineid = c.machineid AND c.comstypeid = 1 WHERE mt.machinetypeid BETWEEN 30 AND 36 GROUP BY mt.machinetype; ``` --- ## Rollback Plan ### If Issues Found: 1. **Stop immediately** 2. **Run ROLLBACK_PHASE3.sql** 3. **Verify old tables intact** 4. **Restore from backup if needed** 5. **Review errors** 6. **Fix and retry** ### Rollback Script (High-Level): ```sql -- Delete migrated network devices from machines DELETE FROM machines WHERE machinetypeid BETWEEN 30 AND 36; -- Delete migrated communications DELETE FROM communications WHERE machineid NOT IN (SELECT machineid FROM machines); -- Delete new relationship types DELETE FROM relationshiptypes WHERE relationshiptypeid > 5; -- Delete new machinetypes DELETE FROM machinetypes WHERE machinetypeid BETWEEN 30 AND 36; -- Verify old tables still have data SELECT COUNT(*) FROM servers; SELECT COUNT(*) FROM switches; SELECT COUNT(*) FROM cameras; ``` --- ## Success Criteria ### Migration Successful If: 1. All records migrated (counts match) 2. All IP addresses migrated to communications 3. All relationships preserved 4. No NULL values in required fields 5. UI pages display correctly 6. Queries perform well 7. No data loss 8. Rollback tested and works --- ## Timeline Estimate - **Planning & Script Creation:** 2-3 hours - **Testing on Dev/Backup:** 1-2 hours - **Production Migration:** 30-45 minutes - **Verification:** 1 hour - **Code Updates:** 3-4 hours - **Testing & Bug Fixes:** 2-3 hours **Total:** ~10-15 hours of work --- ## Risk Assessment ### Low Risk: - Pattern proven with Phase 2 PC migration - Can be rolled back easily - Old tables kept temporarily - Comprehensive verification ### Medium Risk: - Multiple tables being migrated - Code references to update - Testing required for all device types ### Mitigation: - **Test on backup database first** - **Migrate one device type at a time** - **Verify after each migration** - **Keep old tables for 30 days** - **Update code incrementally** --- ## Benefits After Completion ### Immediate: 1. Single query for all infrastructure 2. Unified relationship management 3. Camera → IDF relationships work 4. Consistent UI across all devices 5. Better network topology visibility ### Long-Term: 1. Easier to add new device types 2. Less code duplication 3. Better reporting capabilities 4. Simplified maintenance 5. CMDB-style asset management 6. Better compliance tracking --- ## Next Steps 1. **Create migration SQL scripts** 2. **Create verification scripts** 3. **Create rollback scripts** 4. **Test on backup database** 5. **Review and approve plan** 6. **Schedule migration window** 7. **Execute migration** 8. **Update code** 9. **Monitor and verify** --- **Status:** Ready for script creation **Approval Required:** Yes **Backup Required:** Yes **Estimated Duration:** 30-45 minutes (migration only) --- ## Questions to Answer Before Migration 1. Do accesspoints and idfs tables exist? 2. Are there any custom fields in device tables we need to preserve? 3. Are there any foreign key constraints to old tables? 4. What's the maintenance window schedule? 5. Should we create camera → IDF relationships during migration or manually after? --- **Ready to proceed with script creation!**