diff --git a/CLAUDE.md b/CLAUDE.md index 39f1102..26698ef 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -36,8 +36,8 @@ For production tasks, user must: ``` machines table (unified) -├── Equipment (machinetypeid 1-24, pctypeid IS NULL) -├── PCs (machinetypeid 33-35, pctypeid IS NOT NULL) +├── Equipment (machinetypeid 1-15 and 21-25, pctypeid IS NULL) +├── PCs (machinetypeid 33+, pctypeid IS NOT NULL) └── Network Devices (machinetypeid 16-20) printers table (separate) @@ -51,8 +51,9 @@ machinerelationships table (PC↔equipment links) -- All PCs SELECT * FROM machines WHERE pctypeid IS NOT NULL; --- All Equipment -SELECT * FROM machines WHERE pctypeid IS NULL AND machinetypeid < 16; +-- All Equipment (excludes network devices and PCs) +SELECT * FROM machines WHERE pctypeid IS NULL + AND machinetypeid NOT IN (16,17,18,19,20) AND machinetypeid < 33; -- Network devices SELECT * FROM machines WHERE machinetypeid IN (16,17,18,19,20); diff --git a/computers.asp b/computers.asp index 9adf52d..e77a9a4 100644 --- a/computers.asp +++ b/computers.asp @@ -1,3 +1,8 @@ +<%@ Language=VBScript %> +<% +Option Explicit +Dim theme, strSQL, rs, objConn +%> @@ -6,7 +11,6 @@ <% - ' Force IIS recompile - timestamp: 20251110-143600 theme = Request.Cookies("theme") IF theme = "" THEN theme="bg-theme1" @@ -61,7 +65,7 @@ While Not rsTypes.EOF If CStr(rsTypes("pctypeid")) = CStr(currentPCType) Then selectedAttr = " selected" End If - Response.Write "" & vbCrLf + Response.Write "" & vbCrLf rsTypes.MoveNext Wend rsTypes.Close @@ -77,7 +81,7 @@ While Not rsStatus.EOF If CStr(rsStatus("machinestatusid")) = CStr(currentPCStatus) Then selectedAttr = " selected" End If - Response.Write "" & vbCrLf + Response.Write "" & vbCrLf rsStatus.MoveNext Wend rsStatus.Close @@ -162,20 +166,20 @@ Set rsStatus = Nothing while not rs.eof %> - " title="Click to Show PC Details"><% + " title="Click to Show PC Details"><% Dim displayName If IsNull(rs("hostname")) Or rs("hostname") = "" Then - displayName = rs("serialnumber") + displayName = rs("serialnumber") & "" Else - displayName = rs("hostname") + displayName = rs("hostname") & "" End If - Response.Write(displayName) + Response.Write(Server.HTMLEncode(displayName)) %> - <%Response.Write(rs("serialnumber"))%> - <%Response.Write(rs("ipaddress"))%> - <%Response.Write(rs("modelnumber"))%> - <%Response.Write(rs("operatingsystem"))%> - " title="Click to Show Machine Details"><%Response.Write(rs("machinenumber"))%> + <%=Server.HTMLEncode(rs("serialnumber") & "")%> + <%=Server.HTMLEncode(rs("ipaddress") & "")%> + <%=Server.HTMLEncode(rs("modelnumber") & "")%> + <%=Server.HTMLEncode(rs("operatingsystem") & "")%> + " title="Click to Show Machine Details"><%=Server.HTMLEncode(rs("machinenumber") & "")%> <% diff --git a/displayapplication.asp b/displayapplication.asp index ffef42d..0de2199 100644 --- a/displayapplication.asp +++ b/displayapplication.asp @@ -1,6 +1,10 @@ +<%@ Language=VBScript %> +<% +Option Explicit +%> <% - Dim appid + Dim appid, rs appid = Request.Querystring("appid") ' Basic validation - must be numeric and positive @@ -59,10 +63,10 @@
- " alt="Card image cap"> + " alt="Card image cap">
- " alt="profile-image" class="profile"> + " alt="profile-image" class="profile">

@@ -85,7 +89,7 @@
-
<%Response.Write(rs("appname"))%>
+
<%=Server.HTMLEncode(rs("appname") & "")%>

Support Team:

diff --git a/displaymachines.asp b/displaymachines.asp index 06bd4e5..2169ae9 100644 --- a/displaymachines.asp +++ b/displaymachines.asp @@ -1,3 +1,8 @@ +<%@ Language=VBScript %> +<% +Option Explicit +Dim theme, strSQL, rs, objConn +%> @@ -105,21 +110,21 @@ Response.write("") %> - " style="cursor:pointer;"> + " style="cursor:pointer;"> - " title="View Machine Details"><% + " title="View Machine Details"><% Dim displayName displayName = rs("machinenumber") & "" If displayName = "" Then displayName = rs("hostname") & "" If displayName = "" Then displayName = "ID:" & rs("machineid") Response.Write(Server.HTMLEncode(displayName)) %> - <%Response.Write(rs("machinetype"))%> - <%Response.Write(rs("vendor"))%> - <%Response.Write(rs("modelnumber"))%> - <%Response.Write(rs("businessunit"))%> + <%=Server.HTMLEncode(rs("machinetype") & "")%> + <%=Server.HTMLEncode(rs("vendor") & "")%> + <%=Server.HTMLEncode(rs("modelnumber") & "")%> + <%=Server.HTMLEncode(rs("businessunit") & "")%> diff --git a/displaypcs.asp b/displaypcs.asp index b6a8987..af5e8da 100644 --- a/displaypcs.asp +++ b/displaypcs.asp @@ -1,3 +1,8 @@ +<%@ Language=VBScript %> +<% +Option Explicit +Dim theme, strSQL, rs, displayName, uptimeDays, hasVnc, hasWinrm, vncHost, objConn +%> @@ -6,7 +11,7 @@ <% - ' displaypcs.asp - PC List Page (Phase 2 Schema) - Last Updated: 20251110-1440 + ' displaypcs.asp - PC List Page (Phase 2 Schema) theme = Request.Cookies("theme") IF theme = "" THEN theme="bg-theme1" @@ -148,7 +153,6 @@ Set rsStatus = Nothing <% ' Build query based on filters Dim pcStatusFilter, winrmFilterSQL, deviceTypeFilterSQL, pcTypeFilterSQL, uptimeFilterSQL, needsRelationshipFilter, whereClause - Dim displayName, hasVnc, vncHost, hasWinrm, uptimeDays pcStatusFilter = Request.QueryString("pcstatus") winrmFilterSQL = Request.QueryString("winrm") deviceTypeFilterSQL = Request.QueryString("devicetype") @@ -221,17 +225,17 @@ Set rsStatus = Nothing %> - " title="Click to Show PC Details"><% + " title="Click to Show PC Details"><% If IsNull(rs("hostname")) Or rs("hostname") = "" Then - displayName = rs("serialnumber") + displayName = rs("serialnumber") & "" Else - displayName = rs("hostname") + displayName = rs("hostname") & "" End If - Response.Write(displayName) + Response.Write(Server.HTMLEncode(displayName)) %> - <%Response.Write(rs("serialnumber"))%> - <%Response.Write(rs("modelnumber"))%> - <%Response.Write(rs("operatingsystem"))%> + <%=Server.HTMLEncode(rs("serialnumber") & "")%> + <%=Server.HTMLEncode(rs("modelnumber") & "")%> + <%=Server.HTMLEncode(rs("operatingsystem") & "")%> <% ' Equipment relationship column If Not IsNull(rs("equipment_id")) And rs("equipment_id") <> "" Then diff --git a/displayprofile.asp b/displayprofile.asp index 96013c7..010c061 100644 --- a/displayprofile.asp +++ b/displayprofile.asp @@ -1,3 +1,7 @@ +<%@ Language=VBScript %> +<% +Option Explicit +%> @@ -8,12 +12,19 @@ <% + Dim theme, sso, strSQL, rs, cmd + theme = Request.Cookies("theme") IF theme = "" THEN theme="bg-theme1" END IF + ' Validate SSO - must be numeric sso = Request.Querystring("sso") + If Not IsNumeric(sso) Or sso = "" Then + sso = "1" + End If + sso = CLng(sso) %> @@ -45,20 +56,33 @@
<% + ' Use parameterized query to prevent SQL injection + Set cmd = Server.CreateObject("ADODB.Command") + cmd.ActiveConnection = objconn + cmd.CommandText = "SELECT * FROM employees WHERE SSO = ?" + cmd.CommandType = 1 + cmd.Parameters.Append cmd.CreateParameter("@sso", 3, 1, , sso) + Set rs = cmd.Execute() - strSQL = "SELECT * from employees WHERE SSO="&sso - set rs = objconn.Execute(strSQL) - if rs.eof THEN - strSQL = "SELECT * from employees WHERE SSO=1" - set rs = objconn.Execute(strSQL) - END IF - + If rs.EOF Then + ' Default to SSO 1 if not found + rs.Close + Set rs = Nothing + Set cmd = Nothing + Set cmd = Server.CreateObject("ADODB.Command") + cmd.ActiveConnection = objconn + cmd.CommandText = "SELECT * FROM employees WHERE SSO = ?" + cmd.CommandType = 1 + cmd.Parameters.Append cmd.CreateParameter("@sso", 3, 1, , 1) + Set rs = cmd.Execute() + End If + Set cmd = Nothing %> - " alt="Card image cap"> + " alt="Card image cap">
-
<%Response.Write(rs("First_Name"))%> <%Response.Write(rs("Last_Name"))%>
+
<%=Server.HTMLEncode(rs("First_Name") & "")%> <%=Server.HTMLEncode(rs("Last_Name") & "")%>
<% ' Easter Egg for SSO 570005354 @@ -234,7 +258,7 @@ END IF
Profile
-
<%Response.Write(rs("First_Name"))%> <%Response.Write(rs("Last_Name"))%>
+
<%=Server.HTMLEncode(rs("First_Name") & "")%> <%=Server.HTMLEncode(rs("Last_Name") & "")%>
SSO
Shift
Role
@@ -243,11 +267,11 @@ END IF
 
-
<%Response.Write(rs("SSO"))%>
-
<%Response.Write(rs("shift"))%>
-
<%Response.Write(rs("Role"))%>
-
<%Response.Write(rs("Team"))%>
-
<%Response.Write(rs("Payno"))%>
+
<%=Server.HTMLEncode(rs("SSO") & "")%>
+
<%=Server.HTMLEncode(rs("shift") & "")%>
+
<%=Server.HTMLEncode(rs("Role") & "")%>
+
<%=Server.HTMLEncode(rs("Team") & "")%>
+
<%=Server.HTMLEncode(rs("Payno") & "")%>
diff --git a/docs/QUICK_REFERENCE.md b/docs/QUICK_REFERENCE.md index 8681daa..e76630e 100644 --- a/docs/QUICK_REFERENCE.md +++ b/docs/QUICK_REFERENCE.md @@ -39,9 +39,10 @@ machines (machineid, hostname, serialnumber, alias, machinenumber, loggedinuser, machinenotes, isactive, maptop, mapleft, lastupdated) -- Identify record type: --- PCs: pctypeid IS NOT NULL (machinetypeid 33-35) --- Equipment: pctypeid IS NULL AND machinetypeid < 16 +-- PCs: pctypeid IS NOT NULL (machinetypeid 33+) +-- Equipment: pctypeid IS NULL AND machinetypeid NOT IN (16,17,18,19,20) AND machinetypeid < 33 -- Network Devices: machinetypeid IN (16,17,18,19,20) +-- Equipment types: 1-15, 21-25 (e.g., Lathe, Mill, CMM, Hobbing Machine, etc.) ``` ### PC-Related Tables diff --git a/docs/STANDARDS.md b/docs/STANDARDS.md index ac7abea..39a7c2e 100644 --- a/docs/STANDARDS.md +++ b/docs/STANDARDS.md @@ -1,8 +1,8 @@ # Classic ASP Development Standards ## ShopDB Application -**Version:** 1.0 -**Last Updated:** 2025-10-10 +**Version:** 1.1 +**Last Updated:** 2025-12-11 **Status:** MANDATORY for all new development and modifications --- @@ -414,7 +414,7 @@ Standard error codes for user messaging: ' - machines (primary) ' - machinetypes, models, vendors, businessunits ' - printers (LEFT JOIN - may be NULL) -' - pc (LEFT JOIN - may be NULL) +' - communications (LEFT JOIN - may be NULL) ' ' SECURITY: ' - Requires authentication @@ -691,9 +691,9 @@ Sub LogError(source, errorNum, errorDesc) **Style:** lowercase, plural nouns ```sql -machines +machines -- Unified table: Equipment, PCs, Network Devices printers -pc (exception - acronym) +communications -- Network interfaces (IP/MAC) machinetypes vendors models @@ -713,6 +713,23 @@ createdate lastupdated ``` +### Column Naming Gotchas + +**IMPORTANT:** Be aware of these non-obvious column names: + +| Expected | Actual | Table | +|----------|--------|-------| +| `ipaddress` | `address` | communications | +| `gateway` | `defaultgateway` | communications | +| `notes` | `machinenotes` | machines | +| `pcid` | `machineid` | machines (PCs are in unified table) | +| `pc_comm_config` | `commconfig` | (table name) | +| `pc_dnc_config` | `dncconfig` | (table name) | + +**PC Identification:** PCs are in the `machines` table, identified by: +- `pctypeid IS NOT NULL` +- `machinetypeid IN (33, 34, 35)` + --- ## Documentation Standards @@ -904,6 +921,22 @@ Response.Write(RenderCachedUnitDropdown()) ## Testing Standards +### Automated Form Testing + +**REQUIRED:** Run the comprehensive test suite after making changes to ASP pages. + +```bash +./tests/test_forms.sh +``` + +This script tests 41 endpoints including: +- Page load tests (dashboards, list views, maps) +- Add form page loads +- Form submissions (notifications, equipment, printers, subnets, applications, KB, vendors, models, network devices) +- API endpoints + +Test data uses `AUTOTEST_` prefix for easy cleanup. See `tests/cleanup_test_data.sql`. + ### Unit Testing **REQUIRED:** Test all validation functions. @@ -1021,6 +1054,20 @@ Before committing code, verify: 2. Never commit `config.asp` to source control 3. Add `config.asp` to `.gitignore` +### Secrets Management + +**MANDATORY:** Store sensitive credentials in `secrets.md` (gitignored). + +**Contents:** +- Zabbix API URL and token +- Gitea API URL and token +- Database credentials (per environment) + +**NEVER commit:** +- API tokens +- Database passwords +- Authentication credentials + ### Configuration Template ```vbscript @@ -1216,6 +1263,7 @@ Call CleanupResources() | Version | Date | Changes | Author | |---------|------|---------|--------| | 1.0 | 2025-10-10 | Initial standards document created from audit findings | Claude | +| 1.1 | 2025-12-11 | Updated for Phase 2 schema (unified machines table), added test script reference, secrets management, column naming gotchas | Claude | --- diff --git a/sql/migration_cleanup_pc_types.sql b/sql/migration_cleanup_pc_types.sql new file mode 100644 index 0000000..b34eb43 --- /dev/null +++ b/sql/migration_cleanup_pc_types.sql @@ -0,0 +1,110 @@ +-- ============================================================================ +-- ShopDB Database Migration: Cleanup Redundant PC Machinetypes +-- Date: 2025-12-12 +-- Purpose: Remove redundant PC machinetypes (34-46) since pctypeid handles categorization +-- ============================================================================ +-- +-- CHANGES: +-- 1. Add primary key to installedapps table +-- 2. Migrate machines using PC-specific machinetypes to generic PC (33) + pctypeid +-- 3. Update models to use generic PC machinetype +-- 4. Remove unused PC machinetypes (34-43, 45-46), keep USB Device (44) +-- +-- RUN ON: Production database +-- BACKUP FIRST: mysqldump -u root -p shopdb > shopdb_backup_$(date +%Y%m%d).sql +-- ============================================================================ + +-- Start transaction for safety +START TRANSACTION; + +-- ============================================================================ +-- 1. ADD PRIMARY KEY TO INSTALLEDAPPS TABLE +-- ============================================================================ +ALTER TABLE installedapps +ADD COLUMN installedappid INT AUTO_INCREMENT PRIMARY KEY FIRST; + +SELECT 'Added PK to installedapps' AS status; + +-- ============================================================================ +-- 2. MIGRATE MACHINES FROM PC-SPECIFIC TYPES TO GENERIC PC (33) + PCTYPEID +-- ============================================================================ + +-- PC - Standard (36) → machinetypeid=33, pctypeid=1 (Standard) +UPDATE machines +SET machinetypeid = 33, pctypeid = 1 +WHERE machinetypeid = 36; + +SELECT CONCAT('Migrated ', ROW_COUNT(), ' PC-Standard machines') AS status; + +-- PC - CMM (41) → machinetypeid=33, pctypeid=5 (CMM) +UPDATE machines +SET machinetypeid = 33, pctypeid = 5 +WHERE machinetypeid = 41; + +SELECT CONCAT('Migrated ', ROW_COUNT(), ' PC-CMM machines') AS status; + +-- Handle any other PC types that might exist in production +-- PC - Shopfloor (37) → machinetypeid=33, pctypeid=3 (Shopfloor) +UPDATE machines +SET machinetypeid = 33, pctypeid = 3 +WHERE machinetypeid = 37 AND pctypeid IS NULL; + +-- PC - Engineer (38) → machinetypeid=33, pctypeid=2 (Engineer) +UPDATE machines +SET machinetypeid = 33, pctypeid = 2 +WHERE machinetypeid = 38 AND pctypeid IS NULL; + +-- PC - Wax Trace (42) → machinetypeid=33, pctypeid=6 (Wax / Trace) +UPDATE machines +SET machinetypeid = 33, pctypeid = 6 +WHERE machinetypeid = 42 AND pctypeid IS NULL; + +-- Catch-all: Any remaining 34-46 → machinetypeid=33, pctypeid=4 (Uncategorized) +UPDATE machines +SET machinetypeid = 33, pctypeid = 4 +WHERE machinetypeid BETWEEN 34 AND 46 AND pctypeid IS NULL; + +SELECT CONCAT('Total machines now using machinetypeid 34-46: ', + (SELECT COUNT(*) FROM machines WHERE machinetypeid BETWEEN 34 AND 46)) AS status; + +-- ============================================================================ +-- 3. UPDATE MODELS TO USE GENERIC PC MACHINETYPE (33) +-- ============================================================================ +UPDATE models +SET machinetypeid = 33 +WHERE machinetypeid BETWEEN 34 AND 46; + +SELECT CONCAT('Updated ', ROW_COUNT(), ' models to generic PC type') AS status; + +-- ============================================================================ +-- 4. DELETE REDUNDANT MACHINETYPES +-- ============================================================================ +-- Keep 33 (PC) and 44 (USB Device), remove 34-43 and 45-46 + +DELETE FROM machinetypes WHERE machinetypeid BETWEEN 34 AND 43; +SELECT CONCAT('Deleted ', ROW_COUNT(), ' machinetypes (34-43)') AS status; + +DELETE FROM machinetypes WHERE machinetypeid BETWEEN 45 AND 46; +SELECT CONCAT('Deleted ', ROW_COUNT(), ' machinetypes (45-46)') AS status; + +-- ============================================================================ +-- VERIFICATION +-- ============================================================================ +SELECT 'VERIFICATION - Remaining machinetypes >= 33:' AS info; +SELECT machinetypeid, machinetype FROM machinetypes WHERE machinetypeid >= 33; + +SELECT 'VERIFICATION - Machines by pctypeid:' AS info; +SELECT pt.typename, COUNT(*) as count +FROM machines m +JOIN pctype pt ON m.pctypeid = pt.pctypeid +WHERE m.pctypeid IS NOT NULL +GROUP BY m.pctypeid +ORDER BY count DESC; + +-- ============================================================================ +-- COMMIT (uncomment when ready to apply) +-- ============================================================================ +COMMIT; +-- ROLLBACK; -- Use this instead if something looks wrong + +SELECT 'Migration completed successfully!' AS status;