- Strip emojis from 47 markdown files across docs/, sql/, and root - Add docs/DOCS_CONSOLIDATION_PLAN.md with plan to reduce 45 docs to 8 - Establish no-emoji rule for documentation going forward 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
20 KiB
ShopDB API (ASP) - PowerShell Data Collection Endpoint
File: api.asp
Created: 2025-11-13
Purpose: Receive PC asset data from PowerShell scripts and store in Phase 2 schema
Schema: Phase 2 (machines, communications, machinerelationships)
Overview
This ASP API replaces the PHP api.php and provides the same functionality but runs on IIS with the ShopDB ASP application. It's designed to work with Phase 2 schema from day one.
Key Features:
- Uses Phase 2 schema (machines, communications)
- Parameterized queries (SQL injection protection)
- JSON request/response handling
- Automatic vendor/model/pctype creation
- PC-to-equipment relationship management
- Network interface tracking
- DNC configuration storage
- Warranty data management
- Application tracking
Endpoints
1. updateCompleteAsset
Purpose: Main endpoint for PowerShell data collection
Method: POST
Parameters:
Basic PC Info (Required):
hostname- PC hostnameserialNumber- Serial numbermanufacturer- Manufacturer (e.g., "Dell", "HP")model- Model namepcType- PC type ("Engineer", "Shopfloor", "Standard")
Basic PC Info (Optional):
loggedInUser- Current logged in usermachineNo- Machine number (for shopfloor PCs)osVersion- Operating system version
Warranty Info (Optional):
warrantyEndDate- Warranty end date (YYYY-MM-DD)warrantyStatus- Status ("Active", "Expired", etc.)warrantyServiceLevel- Service level descriptionwarrantyDaysRemaining- Days until warranty expires
Shopfloor Data (Optional):
networkInterfaces- JSON array of network interfacescommConfigs- JSON array of serial port configsdncConfig- JSON object with DNC configuration
DNC/GE Registry Data (Optional):
dncDualPathEnabled- Boolean (true/false)dncPath1Name- Path 1 namedncPath2Name- Path 2 namedncGeRegistry32Bit- Boolean for 32-bit registrydncGeRegistry64Bit- Boolean for 64-bit registrydncGeRegistryNotes- Registry notes
Response:
{
"success": true,
"message": "PC asset data updated successfully",
"machineid": 123,
"hostname": "PC-NAME",
"operation": "complete",
"data": {
"networkInterfaces": 3,
"commConfigs": 2,
"dncConfig": true,
"relationshipCreated": true
}
}
Database Operations:
- Insert/update record in
machinestable withpctypeid IS NOT NULL - Clear old network interfaces from
communications - Insert new network interfaces to
communicationswithcomstypeid = 1 - Clear old serial port configs from
pc_comm_config - Insert new serial port configs to
pc_comm_config - Clear old DNC config from
pc_dnc_config - Insert new DNC config to
pc_dnc_config - Create PC-to-equipment relationship in
machinerelationshipsifmachineNoprovided - Update warranty data in
warrantiestable
2. updatePrinterMapping
Purpose: Map a PC to its default printer
Method: POST
Parameters:
hostname- PC hostnameprinterFQDN- Printer FQDN or IP address
Response:
{
"success": true,
"message": "Printer mapping updated",
"data": {
"printerId": 45,
"machinesUpdated": 1,
"matchMethod": "ip"
}
}
Database Operations:
- Find PC by hostname in
machinestable - Find printer by FQDN (tries name match, then IP match)
- Update
machines.printeridto link PC to printer
3. updateInstalledApps
Purpose: Update installed applications for a PC
Method: POST
Parameters:
hostname- PC hostnameinstalledApps- JSON array of applications
installedApps Format:
[
{"Name": "SolidWorks 2024", "Version": "32.1.0"},
{"Name": "AutoCAD", "Version": "2024.1"},
{"Name": "Microsoft Office", "Version": "16.0"}
]
Response:
{
"success": true,
"message": "Installed applications updated",
"data": {
"appsProcessed": 3
}
}
Database Operations:
- Find PC by hostname in
machinestable - Delete existing app mappings from
machineapplications - Create applications in
applicationstable if they don't exist - Insert new app mappings to
machineapplications
4. getDashboardData
Purpose: Health check / connection test
Method: GET or POST
Parameters: None
Response:
{
"success": true,
"message": "ShopDB API is online",
"version": "1.0",
"schema": "Phase 2"
}
JSON Formats
Network Interfaces Format
[
{
"IPAddress": "10.48.130.100",
"MACAddress": "00:1A:2B:3C:4D:5E",
"SubnetMask": "255.255.255.0",
"DefaultGateway": "10.48.130.1",
"InterfaceName": "Ethernet",
"IsMachineNetwork": false
},
{
"IPAddress": "192.168.1.100",
"MACAddress": "00:1A:2B:3C:4D:5F",
"SubnetMask": "255.255.255.0",
"DefaultGateway": "192.168.1.1",
"InterfaceName": "Machine Network",
"IsMachineNetwork": true
}
]
Stored in: communications table
comstypeid = 1(Network Interface)- First interface with valid IP marked as
isprimary = 1
Communication Configs Format (Serial Ports)
[
{
"PortName": "COM1",
"BaudRate": 9600,
"DataBits": 8,
"Parity": "None",
"StopBits": "One",
"FlowControl": "None"
},
{
"PortName": "COM2",
"BaudRate": 19200,
"DataBits": 8,
"Parity": "Even",
"StopBits": "One",
"FlowControl": "Hardware"
}
]
Stored in: pc_comm_config table
DNC Config Format
{
"Site": "West Jefferson",
"CNC": "FANUC",
"NCIF": "eFOCAS",
"MachineNumber": "2001",
"HostType": "Control",
"FTPHostPrimary": "192.168.1.100",
"FTPHostSecondary": "192.168.1.101",
"FTPAccount": "dnc_user",
"Debug": "Off",
"Uploads": "C:\\DNC\\Uploads",
"Scanner": "On",
"DripFeed": "Off",
"AdditionalSettings": "timeout=30"
}
Stored in: pc_dnc_config table
Additional DNC fields sent as separate parameters:
dncDualPathEnabled- true/falsedncPath1Name- Path 1 namedncPath2Name- Path 2 namedncGeRegistry32Bit- true/falsedncGeRegistry64Bit- true/falsedncGeRegistryNotes- Text notes
Database Schema
Tables Used
machines (Main PC Storage)
CREATE TABLE machines (
machineid INT(11) PRIMARY KEY AUTO_INCREMENT,
hostname VARCHAR(100),
serialnumber VARCHAR(50),
modelnumberid INT(11),
pctypeid INT(11), -- NOT NULL = PC, NULL = Equipment
machinetypeid INT(11), -- 28-32 for PC types
loggedinuser VARCHAR(100),
machinenumber VARCHAR(50), -- For shopfloor PCs
osid INT(11),
machinestatusid INT(11),
machinenotes TEXT,
printerid INT(11), -- Default printer
isactive TINYINT(1),
lastupdated DATETIME
);
communications (Network Interfaces)
CREATE TABLE communications (
comid INT(11) PRIMARY KEY AUTO_INCREMENT,
machineid INT(11),
comstypeid INT(11), -- 1 = Network Interface
address VARCHAR(45), -- IP address
macaddress VARCHAR(17),
subnetmask VARCHAR(45),
gateway VARCHAR(45),
interfacename VARCHAR(50),
isprimary TINYINT(1),
isactive TINYINT(1)
);
pc_comm_config (Serial Port Configs)
CREATE TABLE pc_comm_config (
commconfigid INT(11) PRIMARY KEY AUTO_INCREMENT,
machineid INT(11), -- Changed from pcid
portname VARCHAR(50),
baudrate INT(11),
databits INT(11),
parity VARCHAR(20),
stopbits VARCHAR(20),
flowcontrol VARCHAR(50)
);
pc_dnc_config (DNC Configuration)
CREATE TABLE pc_dnc_config (
dncconfigid INT(11) PRIMARY KEY AUTO_INCREMENT,
machineid INT(11), -- Changed from pcid
site VARCHAR(50),
cnc VARCHAR(50),
ncif VARCHAR(50),
machinenumber VARCHAR(50),
hosttype VARCHAR(50),
ftphostprimary VARCHAR(100),
ftphostsecondary VARCHAR(100),
ftpaccount VARCHAR(100),
debug VARCHAR(50),
uploads VARCHAR(100),
scanner VARCHAR(50),
dripfeed VARCHAR(50),
additionalsettings VARCHAR(255),
dualpath_enabled TINYINT(1),
path1_name VARCHAR(100),
path2_name VARCHAR(100),
ge_registry_32bit TINYINT(1),
ge_registry_64bit TINYINT(1),
ge_registry_notes VARCHAR(255),
lastupdated DATETIME
);
machinerelationships (PC-to-Equipment Links)
CREATE TABLE machinerelationships (
relationshipid INT(11) PRIMARY KEY AUTO_INCREMENT,
machineid INT(11), -- Equipment ID
related_machineid INT(11), -- PC ID
relationshiptypeid INT(11), -- 3 = Controls
isactive TINYINT(1)
);
warranties (Warranty Tracking)
CREATE TABLE warranties (
warrantyid INT(11) PRIMARY KEY AUTO_INCREMENT,
machineid INT(11),
enddate DATE,
servicelevel VARCHAR(100),
status VARCHAR(50),
daysremaining INT(11),
lastcheckeddate DATETIME
);
machineapplications (Installed Applications)
CREATE TABLE machineapplications (
machineappid INT(11) PRIMARY KEY AUTO_INCREMENT,
machineid INT(11),
applicationid INT(11)
);
Automatic Lookups
The API automatically creates records in these tables if they don't exist:
vendors
- Created when new manufacturer is encountered
- Lookup:
SELECT vendorid FROM vendors WHERE vendor = ? - Create:
INSERT INTO vendors (vendor) VALUES (?)
models
- Created when new model is encountered for a vendor
- Lookup:
SELECT modelnumberid FROM models WHERE modelnumber = ? AND vendorid = ? - Create:
INSERT INTO models (modelnumber, vendorid, notes, isactive) VALUES (?, ?, 'Auto-imported via PowerShell', 1)
pctype
- Created when new PC type is encountered
- Lookup:
SELECT pctypeid FROM pctype WHERE typename = ? - Create:
INSERT INTO pctype (typename) VALUES (?)
operatingsystems
- Created when new OS version is encountered
- Lookup:
SELECT osid FROM operatingsystems WHERE osname = ? - Create:
INSERT INTO operatingsystems (osname) VALUES (?)
applications
- Created when new application is encountered
- Lookup:
SELECT applicationid FROM applications WHERE applicationname = ? - Create:
INSERT INTO applications (applicationname, version) VALUES (?, ?)
PC Type to Machine Type Mapping
When creating PCs, machinetypeid is automatically determined from pctypeid:
| PC Type Name | pctypeid | machinetypeid | Machine Type |
|---|---|---|---|
| Engineer | varies | 30 | Workstation |
| Shopfloor | varies | 28 | Desktop PC |
| Standard | varies | 28 | Desktop PC |
| Laptop | varies | 29 | Laptop |
| Thin Client | varies | 31 | Thin Client |
| Server | varies | 32 | Server |
This mapping allows:
- PCs to be filtered with
WHERE pctypeid IS NOT NULL - PC-specific queries to join to
machinetypestable - Unified reporting across PCs and equipment
Error Responses
All errors return HTTP 200 with JSON:
{
"success": false,
"error": "Error message here"
}
Common Errors:
"hostname and serialNumber are required"- Missing required fields"PC not found: HOSTNAME"- PC doesn't exist in database"Printer not found: FQDN"- Printer not found by FQDN or IP"Failed to insert/update PC: SQL error"- Database error"Invalid action: ACTION"- Unknown action parameter
Security Features
SQL Injection Protection
All queries use parameterized commands:
Set cmd = Server.CreateObject("ADODB.Command")
cmd.ActiveConnection = objConn
cmd.CommandText = "SELECT machineid FROM machines WHERE hostname = ?"
cmd.Parameters.Append cmd.CreateParameter("@hostname", 200, 1, 100, hostname)
Set rsResult = cmd.Execute
Input Validation
- Required field checks
- Numeric validation for IDs
- Boolean conversion for true/false values
- String length limits enforced
HTML/JSON Escaping
- All JSON output properly escaped
- Special characters handled:
\,", CR, LF, TAB
Logging
API logs to: /logs/api.log
Log Format: YYYY-MM-DD HH:MM:SS - Message
Logged Events:
- New requests with hostname/serial/pctype
- Vendor/Model/PCType ID lookups
- Record creation (machineid)
- Network interface insertion counts
- Comm config insertion counts
- DNC config insertion success
- PC-Machine relationship creation
- Errors with full error descriptions
Log Directory: Must exist and be writable by IIS process
PowerShell Integration
Default URL Configuration
PowerShell scripts should use:
$DashboardURL = "http://192.168.122.151:8080/api.asp"
Example PowerShell Call
$postData = @{
action = 'updateCompleteAsset'
hostname = $env:COMPUTERNAME
serialNumber = $serialNumber
manufacturer = $manufacturer
model = $model
pcType = "Shopfloor"
loggedInUser = $env:USERNAME
machineNo = "2001"
osVersion = $osVersion
networkInterfaces = $networkInterfacesJSON
commConfigs = $commConfigsJSON
dncConfig = $dncConfigJSON
dncDualPathEnabled = $true
dncPath1Name = "Path1"
dncPath2Name = "Path2"
}
$response = Invoke-RestMethod -Uri $DashboardURL -Method Post -Body $postData
Testing
Test 1: Health Check
curl "http://192.168.122.151:8080/api.asp?action=getDashboardData"
Expected:
{"success":true,"message":"ShopDB API is online","version":"1.0","schema":"Phase 2"}
Test 2: Create New PC
$postData = @{
action = 'updateCompleteAsset'
hostname = 'TEST-PC-01'
serialNumber = 'ABC123456'
manufacturer = 'Dell'
model = 'OptiPlex 7090'
pcType = 'Standard'
osVersion = 'Windows 11 Pro'
}
Invoke-RestMethod -Uri "http://192.168.122.151:8080/api.asp" -Method Post -Body $postData
Verify in Database:
SELECT machineid, hostname, serialnumber, pctypeid, machinetypeid
FROM machines
WHERE hostname = 'TEST-PC-01' AND pctypeid IS NOT NULL;
Test 3: Update Existing PC with Network Interfaces
$networkInterfaces = @(
@{
IPAddress = '10.48.130.100'
MACAddress = '00:1A:2B:3C:4D:5E'
SubnetMask = '255.255.255.0'
DefaultGateway = '10.48.130.1'
InterfaceName = 'Ethernet'
}
) | ConvertTo-Json
$postData = @{
action = 'updateCompleteAsset'
hostname = 'TEST-PC-01'
serialNumber = 'ABC123456'
manufacturer = 'Dell'
model = 'OptiPlex 7090'
pcType = 'Standard'
networkInterfaces = $networkInterfaces
}
Invoke-RestMethod -Uri "http://192.168.122.151:8080/api.asp" -Method Post -Body $postData
Verify in Database:
SELECT c.comid, c.address, c.macaddress, c.isprimary
FROM communications c
JOIN machines m ON c.machineid = m.machineid
WHERE m.hostname = 'TEST-PC-01' AND c.comstypeid = 1;
Test 4: Shopfloor PC with Machine Relationship
$postData = @{
action = 'updateCompleteAsset'
hostname = 'SHOPFLOOR-PC'
serialNumber = 'XYZ789'
manufacturer = 'HP'
model = 'EliteDesk 800'
pcType = 'Shopfloor'
machineNo = '2001'
}
Invoke-RestMethod -Uri "http://192.168.122.151:8080/api.asp" -Method Post -Body $postData
Verify Relationship:
SELECT
equipment.machinenumber AS equipment,
pc.hostname AS controlling_pc
FROM machinerelationships mr
JOIN machines equipment ON mr.machineid = equipment.machineid
JOIN machines pc ON mr.related_machineid = pc.machineid
JOIN relationshiptypes rt ON mr.relationshiptypeid = rt.relationshiptypeid
WHERE equipment.machinenumber = '2001' AND rt.relationshiptype = 'Controls';
Deployment
Step 1: Database Schema Update
Run the migration script:
mysql -h 192.168.122.1 -u root -p shopdb < sql/migration_phase2/08_update_schema_for_api.sql
This renames pcid → machineid in:
pc_comm_configpc_dnc_config
Step 2: Deploy api.asp
Copy api.asp to ShopDB root directory:
cp api.asp /home/camp/projects/windows/shopdb/
Step 3: Create Logs Directory
Ensure logs directory exists and is writable:
mkdir -p /home/camp/projects/windows/shopdb/logs
chmod 755 /home/camp/projects/windows/shopdb/logs
Step 4: Update PowerShell Scripts
Change default dashboard URL in Update-PC-CompleteAsset.ps1:
# OLD:
[string]$DashboardURL = "http://10.48.130.197/dashboard-v2/api.php"
# NEW:
[string]$DashboardURL = "http://192.168.122.151:8080/api.asp"
Step 5: Test
Run PowerShell script on one test PC:
.\Update-PC-CompleteAsset.ps1
Check logs:
tail -f /home/camp/projects/windows/shopdb/logs/api.log
Verify in ShopDB:
http://192.168.122.151:8080/displaypcs.asp
Troubleshooting
Issue: "Object required" error
Cause: RegExp object not created properly
Fix: Check that VBScript RegExp is enabled:
Dim regex
Set regex = New RegExp
Issue: "ADO error" when inserting
Cause: Parameter type mismatch
Fix: Verify parameter types match database column types:
- VARCHAR:
200(adVarChar) - INT:
3(adInteger) - DATE:
135(adDBDate) - TINYINT:
16(adTinyInt)
Issue: Network interfaces not appearing
Cause: comstypeid not set correctly
Fix: Ensure comstypeid = 1 for network interfaces
Issue: PC relationships not created
Cause: Equipment with matching machine number doesn't exist
Fix: Ensure equipment record exists with pctypeid IS NULL and matching machinenumber
Issue: Logs not writing
Cause: Logs directory doesn't exist or isn't writable
Fix:
mkdir -p /home/camp/projects/windows/shopdb/logs
chmod 755 /home/camp/projects/windows/shopdb/logs
Performance Considerations
Indexes Required
Ensure these indexes exist for optimal performance:
-- machines table
ALTER TABLE machines ADD INDEX idx_hostname (hostname);
ALTER TABLE machines ADD INDEX idx_pctypeid (pctypeid);
ALTER TABLE machines ADD INDEX idx_machinenumber (machinenumber);
-- communications table
ALTER TABLE communications ADD INDEX idx_machineid (machineid);
ALTER TABLE communications ADD INDEX idx_comstypeid (comstypeid);
-- pc_comm_config table
ALTER TABLE pc_comm_config ADD INDEX idx_machineid (machineid);
-- pc_dnc_config table
ALTER TABLE pc_dnc_config ADD INDEX idx_machineid (machineid);
-- machinerelationships table
ALTER TABLE machinerelationships ADD INDEX idx_machineid (machineid);
ALTER TABLE machinerelationships ADD INDEX idx_related_machineid (related_machineid);
Query Optimization
- Uses parameterized queries for all SELECT/INSERT/UPDATE operations
- Deletes old records before inserting new (avoids duplicate detection overhead)
- Single transaction per request (faster than individual commits)
- Lookup caching could be added for frequently accessed vendor/model/pctype IDs
Maintenance
Log Rotation
Recommend setting up log rotation for /logs/api.log:
Windows Task Scheduler:
# Rotate logs weekly
Get-Content "C:\inetpub\wwwroot\shopdb\logs\api.log" |
Set-Content "C:\inetpub\wwwroot\shopdb\logs\api_$(Get-Date -Format 'yyyyMMdd').log"
Clear-Content "C:\inetpub\wwwroot\shopdb\logs\api.log"
Monitoring
Monitor these metrics:
- Request count per hour
- Error rate (failed requests / total requests)
- Average response time
- Database connection pool usage
- Disk space for logs directory
Future Enhancements
Planned Features:
- Batch Processing: Accept arrays of PCs in single request
- Delta Updates: Only update changed fields (reduces write load)
- Webhook Callbacks: Notify on successful PC creation
- API Key Authentication: Secure API access
- Rate Limiting: Prevent abuse
- Caching Layer: Cache vendor/model/pctype lookups
- Async Processing: Queue large updates for background processing
Nice to Have:
- GraphQL endpoint for flexible queries
- WebSocket support for real-time updates
- OpenAPI/Swagger documentation
- Postman collection for testing
- Health metrics endpoint (uptime, request count, error rate)
Version: 1.0
Last Updated: 2025-11-13
Maintained By: ShopDB Development Team
Support: Review /logs/api.log for troubleshooting