- Move completed migration docs to docs/archive/ - Move session summaries to docs/archive/sessions/ - Rename API_ASP_DOCUMENTATION.md to docs/API.md - Archive redundant Claude reference files - Update docs/README.md as simplified index - Reduce active docs from 45+ files to 8 essential files Remaining docs: - CLAUDE.md (AI context) - TODO.md (task tracking) - docs/README.md, API.md, QUICK_REFERENCE.md - docs/ASP_DEVELOPMENT_GUIDE.md, STANDARDS.md 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
451 lines
14 KiB
Markdown
451 lines
14 KiB
Markdown
# Unified Infrastructure Pages - Design Document
|
|
|
|
**Approach:** Single set of pages that dynamically handles servers, switches, and cameras
|
|
**Files Required:** 4 files (vs 12 separate files)
|
|
|
|
---
|
|
|
|
## Architecture
|
|
|
|
### URL Structure
|
|
```
|
|
displayinfrastructure.asp?type=server → List all servers
|
|
displayinfrastructure.asp?type=switch → List all switches
|
|
displayinfrastructure.asp?type=camera → List all cameras
|
|
|
|
displayinfrastructure_detail.asp?type=server&id=5 → Server #5 detail/edit
|
|
displayinfrastructure_detail.asp?type=switch&id=12 → Switch #12 detail/edit
|
|
displayinfrastructure_detail.asp?type=camera&id=3 → Camera #3 detail/edit
|
|
|
|
addinfrastructure.asp?type=server → Add new server form
|
|
addinfrastructure.asp?type=switch → Add new switch form
|
|
addinfrastructure.asp?type=camera → Add new camera form
|
|
|
|
saveinfrastructure_direct.asp → Universal save endpoint
|
|
```
|
|
|
|
---
|
|
|
|
## File 1: displayinfrastructure.asp (List View)
|
|
|
|
### Logic Flow
|
|
```vbscript
|
|
<%
|
|
' Get device type from URL
|
|
Dim deviceType
|
|
deviceType = Request.QueryString("type")
|
|
|
|
' Validate type
|
|
If deviceType <> "server" AND deviceType <> "switch" AND deviceType <> "camera" Then
|
|
deviceType = "server" ' Default
|
|
End If
|
|
|
|
' Set display variables based on type
|
|
Dim tableName, idField, pageTitle, iconClass, addUrl
|
|
Select Case deviceType
|
|
Case "server"
|
|
tableName = "servers"
|
|
idField = "serverid"
|
|
pageTitle = "Servers"
|
|
iconClass = "zmdi-storage"
|
|
addUrl = "addinfrastructure.asp?type=server"
|
|
Case "switch"
|
|
tableName = "switches"
|
|
idField = "switchid"
|
|
pageTitle = "Switches"
|
|
iconClass = "zmdi-device-hub"
|
|
addUrl = "addinfrastructure.asp?type=switch"
|
|
Case "camera"
|
|
tableName = "cameras"
|
|
idField = "cameraid"
|
|
pageTitle = "Cameras"
|
|
iconClass = "zmdi-videocam"
|
|
addUrl = "addinfrastructure.asp?type=camera"
|
|
End Select
|
|
|
|
' Build query
|
|
Dim strSQL
|
|
strSQL = "SELECT d.*, m.modelnumber, v.vendor " & _
|
|
"FROM " & tableName & " d " & _
|
|
"LEFT JOIN models m ON d.modelid = m.modelnumberid " & _
|
|
"LEFT JOIN vendors v ON m.vendorid = v.vendorid " & _
|
|
"WHERE d.isactive = 1 " & _
|
|
"ORDER BY d." & idField & " DESC"
|
|
|
|
Set rs = objConn.Execute(strSQL)
|
|
%>
|
|
|
|
<h5 class="card-title">
|
|
<i class="zmdi <%=iconClass%>"></i> <%=pageTitle%>
|
|
</h5>
|
|
<a href="<%=addUrl%>" class="btn btn-primary">
|
|
<i class="zmdi zmdi-plus-circle"></i> Add <%=pageTitle%>
|
|
</a>
|
|
|
|
<table class="table table-hover">
|
|
<thead>
|
|
<tr>
|
|
<th>ID</th>
|
|
<th>Vendor</th>
|
|
<th>Model</th>
|
|
<th>Serial</th>
|
|
<th>IP Address</th>
|
|
<th>Description</th>
|
|
<th>Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<% Do While Not rs.EOF %>
|
|
<tr>
|
|
<td><%=rs(idField)%></td>
|
|
<td><%=Server.HTMLEncode(rs("vendor") & "")%></td>
|
|
<td><%=Server.HTMLEncode(rs("modelnumber") & "")%></td>
|
|
<td><%=Server.HTMLEncode(rs("serialnumber") & "")%></td>
|
|
<td><%=Server.HTMLEncode(rs("ipaddress") & "")%></td>
|
|
<td><%=Server.HTMLEncode(rs("description") & "")%></td>
|
|
<td>
|
|
<a href="displayinfrastructure_detail.asp?type=<%=deviceType%>&id=<%=rs(idField)%>">
|
|
View
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
<%
|
|
rs.MoveNext
|
|
Loop
|
|
%>
|
|
</tbody>
|
|
</table>
|
|
```
|
|
|
|
---
|
|
|
|
## File 2: displayinfrastructure_detail.asp (Detail/Edit View)
|
|
|
|
### Logic Flow
|
|
```vbscript
|
|
<%
|
|
' Get device type and ID
|
|
Dim deviceType, deviceId
|
|
deviceType = Request.QueryString("type")
|
|
deviceId = Request.QueryString("id")
|
|
|
|
' Validate
|
|
If deviceType <> "server" AND deviceType <> "switch" AND deviceType <> "camera" Then
|
|
Response.Redirect("displayinfrastructure.asp?type=server")
|
|
End If
|
|
|
|
' Set variables based on type
|
|
Dim tableName, idField, pageTitle, listUrl
|
|
Select Case deviceType
|
|
Case "server"
|
|
tableName = "servers"
|
|
idField = "serverid"
|
|
pageTitle = "Server"
|
|
listUrl = "displayinfrastructure.asp?type=server"
|
|
Case "switch"
|
|
tableName = "switches"
|
|
idField = "switchid"
|
|
pageTitle = "Switch"
|
|
listUrl = "displayinfrastructure.asp?type=switch"
|
|
Case "camera"
|
|
tableName = "cameras"
|
|
idField = "cameraid"
|
|
pageTitle = "Camera"
|
|
listUrl = "displayinfrastructure.asp?type=camera"
|
|
End Select
|
|
|
|
' Fetch device
|
|
strSQL = "SELECT d.*, m.modelnumber, v.vendor, v.vendorid " & _
|
|
"FROM " & tableName & " d " & _
|
|
"LEFT JOIN models m ON d.modelid = m.modelnumberid " & _
|
|
"LEFT JOIN vendors v ON m.vendorid = v.vendorid " & _
|
|
"WHERE d." & idField & " = " & deviceId
|
|
|
|
Set rs = objConn.Execute(strSQL)
|
|
|
|
If rs.EOF Then
|
|
Response.Write("Device not found")
|
|
Response.End
|
|
End If
|
|
%>
|
|
|
|
<!-- Display Mode -->
|
|
<div id="displayMode">
|
|
<h3><%=pageTitle%> #<%=rs(idField)%></h3>
|
|
<p><strong>Vendor:</strong> <%=Server.HTMLEncode(rs("vendor") & "")%></p>
|
|
<p><strong>Model:</strong> <%=Server.HTMLEncode(rs("modelnumber") & "")%></p>
|
|
<p><strong>Serial:</strong> <%=Server.HTMLEncode(rs("serialnumber") & "")%></p>
|
|
<p><strong>IP:</strong> <%=Server.HTMLEncode(rs("ipaddress") & "")%></p>
|
|
<p><strong>Description:</strong> <%=Server.HTMLEncode(rs("description") & "")%></p>
|
|
|
|
<button onclick="showEditMode()">Edit</button>
|
|
<a href="<%=listUrl%>">Back to List</a>
|
|
</div>
|
|
|
|
<!-- Edit Mode -->
|
|
<div id="editMode" style="display:none;">
|
|
<h3>Edit <%=pageTitle%></h3>
|
|
<form method="post" action="saveinfrastructure_direct.asp">
|
|
<input type="hidden" name="type" value="<%=deviceType%>">
|
|
<input type="hidden" name="id" value="<%=rs(idField)%>">
|
|
|
|
<!-- Model dropdown -->
|
|
<select name="modelid">
|
|
<!-- Populate models... -->
|
|
</select>
|
|
|
|
<input type="text" name="serialnumber" value="<%=Server.HTMLEncode(rs("serialnumber") & "")%>">
|
|
<input type="text" name="ipaddress" value="<%=Server.HTMLEncode(rs("ipaddress") & "")%>">
|
|
<textarea name="description"><%=Server.HTMLEncode(rs("description") & "")%></textarea>
|
|
|
|
<button type="submit">Save</button>
|
|
<button type="button" onclick="showDisplayMode()">Cancel</button>
|
|
</form>
|
|
</div>
|
|
```
|
|
|
|
---
|
|
|
|
## File 3: addinfrastructure.asp (Add Form)
|
|
|
|
### Logic Flow
|
|
```vbscript
|
|
<%
|
|
' Get device type
|
|
Dim deviceType
|
|
deviceType = Request.QueryString("type")
|
|
|
|
' Validate
|
|
If deviceType <> "server" AND deviceType <> "switch" AND deviceType <> "camera" Then
|
|
deviceType = "server"
|
|
End If
|
|
|
|
' Set variables
|
|
Dim pageTitle, listUrl
|
|
Select Case deviceType
|
|
Case "server"
|
|
pageTitle = "Server"
|
|
listUrl = "displayinfrastructure.asp?type=server"
|
|
Case "switch"
|
|
pageTitle = "Switch"
|
|
listUrl = "displayinfrastructure.asp?type=switch"
|
|
Case "camera"
|
|
pageTitle = "Camera"
|
|
listUrl = "displayinfrastructure.asp?type=camera"
|
|
End Select
|
|
%>
|
|
|
|
<h2>Add <%=pageTitle%></h2>
|
|
|
|
<form method="post" action="saveinfrastructure_direct.asp">
|
|
<input type="hidden" name="type" value="<%=deviceType%>">
|
|
|
|
<div class="form-group">
|
|
<label>Model</label>
|
|
<select name="modelid" required class="form-control">
|
|
<option value="">-- Select Model --</option>
|
|
<%
|
|
strSQL = "SELECT m.modelnumberid, m.modelnumber, v.vendor " & _
|
|
"FROM models m " & _
|
|
"INNER JOIN vendors v ON m.vendorid = v.vendorid " & _
|
|
"WHERE m.isactive = 1 " & _
|
|
"ORDER BY v.vendor, m.modelnumber"
|
|
Set rsModels = objConn.Execute(strSQL)
|
|
Do While Not rsModels.EOF
|
|
%>
|
|
<option value="<%=rsModels("modelnumberid")%>">
|
|
<%=Server.HTMLEncode(rsModels("vendor") & " - " & rsModels("modelnumber"))%>
|
|
</option>
|
|
<%
|
|
rsModels.MoveNext
|
|
Loop
|
|
%>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label>Serial Number</label>
|
|
<input type="text" name="serialnumber" class="form-control" maxlength="100">
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label>IP Address</label>
|
|
<input type="text" name="ipaddress" class="form-control" maxlength="15">
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label>Description</label>
|
|
<textarea name="description" class="form-control" rows="3"></textarea>
|
|
</div>
|
|
|
|
<button type="submit" class="btn btn-success">Save <%=pageTitle%></button>
|
|
<a href="<%=listUrl%>" class="btn btn-secondary">Cancel</a>
|
|
</form>
|
|
```
|
|
|
|
---
|
|
|
|
## File 4: saveinfrastructure_direct.asp (Universal Save)
|
|
|
|
### Logic Flow
|
|
```vbscript
|
|
<!--#include file="./includes/sql.asp"-->
|
|
<!--#include file="./includes/error_handler.asp"-->
|
|
<!--#include file="./includes/validation.asp"-->
|
|
<!--#include file="./includes/db_helpers.asp"-->
|
|
|
|
<%
|
|
' Get device type
|
|
Dim deviceType
|
|
deviceType = Request.Form("type")
|
|
|
|
' Validate type
|
|
If deviceType <> "server" AND deviceType <> "switch" AND deviceType <> "camera" Then
|
|
Response.Write("Error: Invalid device type")
|
|
Response.End
|
|
End If
|
|
|
|
' Set table name and ID field based on type
|
|
Dim tableName, idField, listUrl
|
|
Select Case deviceType
|
|
Case "server"
|
|
tableName = "servers"
|
|
idField = "serverid"
|
|
listUrl = "displayinfrastructure.asp?type=server"
|
|
Case "switch"
|
|
tableName = "switches"
|
|
idField = "switchid"
|
|
listUrl = "displayinfrastructure.asp?type=switch"
|
|
Case "camera"
|
|
tableName = "cameras"
|
|
idField = "cameraid"
|
|
listUrl = "displayinfrastructure.asp?type=camera"
|
|
End Select
|
|
|
|
' Get form data
|
|
Dim deviceId, modelid, serialnumber, ipaddress, description
|
|
deviceId = GetSafeInteger("FORM", "id", 0, 0, 999999)
|
|
modelid = GetSafeInteger("FORM", "modelid", 0, 0, 999999)
|
|
serialnumber = GetSafeString("FORM", "serialnumber", "", 0, 100, "^[A-Za-z0-9\-]+$")
|
|
ipaddress = GetSafeString("FORM", "ipaddress", "", 0, 15, "^[0-9\.]+$")
|
|
description = GetSafeString("FORM", "description", "", 0, 255, "")
|
|
|
|
' Determine INSERT or UPDATE
|
|
Dim strSQL
|
|
|
|
If deviceId = 0 Then
|
|
' INSERT - New device
|
|
strSQL = "INSERT INTO " & tableName & " (modelid, serialnumber, ipaddress, description, isactive) " & _
|
|
"VALUES (?, ?, ?, ?, 1)"
|
|
Set rs = ExecuteParameterizedQuery(objConn, strSQL, Array(modelid, serialnumber, ipaddress, description))
|
|
Else
|
|
' UPDATE - Existing device
|
|
strSQL = "UPDATE " & tableName & " " & _
|
|
"SET modelid = ?, serialnumber = ?, ipaddress = ?, description = ? " & _
|
|
"WHERE " & idField & " = ?"
|
|
Set rs = ExecuteParameterizedQuery(objConn, strSQL, Array(modelid, serialnumber, ipaddress, description, deviceId))
|
|
End If
|
|
|
|
Call CleanupResources()
|
|
|
|
' Redirect back to list
|
|
Response.Redirect(listUrl)
|
|
%>
|
|
```
|
|
|
|
---
|
|
|
|
## Navigation Menu
|
|
|
|
### leftsidebar.asp Update
|
|
```html
|
|
<!-- Infrastructure Section -->
|
|
<li class="nav-header">INFRASTRUCTURE</li>
|
|
<li>
|
|
<a href="displayinfrastructure.asp?type=server">
|
|
<i class="zmdi zmdi-storage"></i> Servers
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a href="displayinfrastructure.asp?type=switch">
|
|
<i class="zmdi zmdi-device-hub"></i> Switches
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a href="displayinfrastructure.asp?type=camera">
|
|
<i class="zmdi zmdi-videocam"></i> Cameras
|
|
</a>
|
|
</li>
|
|
```
|
|
|
|
---
|
|
|
|
## Pros vs Cons
|
|
|
|
### Unified Approach (Option 2) - RECOMMENDED
|
|
|
|
**Pros:**
|
|
- Only 4 files to create (vs 12)
|
|
- DRY - no code duplication
|
|
- Easy to maintain - fix once, works for all
|
|
- Easy to extend - add "UPS" or "Firewall" by just adding cases
|
|
- Consistent UI across all infrastructure
|
|
- Matches database design (vw_network_devices already unifies them)
|
|
|
|
**Cons:**
|
|
- Slightly more complex logic (Select Case statements)
|
|
- URLs less intuitive (type parameter required)
|
|
- Harder to customize one type differently later
|
|
|
|
### Separate Pages Approach (Option 1)
|
|
|
|
**Pros:**
|
|
- URLs cleaner (displayservers.asp vs displayinfrastructure.asp?type=server)
|
|
- Simpler per-file logic (no branching)
|
|
- Easy to customize one type differently
|
|
- More explicit/clear what page does
|
|
|
|
**Cons:**
|
|
- 12 files instead of 4 (3x code duplication)
|
|
- Bug fixes need to be applied 3 times
|
|
- UI inconsistencies more likely
|
|
- Adding new type = 4 more files
|
|
|
|
---
|
|
|
|
## Hybrid Approach (Best of Both?)
|
|
|
|
**Could also do:**
|
|
- Use unified pages for LIST/ADD/SAVE (shared logic)
|
|
- Use separate pages for DETAIL if they differ significantly
|
|
|
|
Example:
|
|
```
|
|
displayinfrastructure.asp?type=server (unified list)
|
|
addinfrastructure.asp?type=server (unified add form)
|
|
saveinfrastructure_direct.asp (unified save)
|
|
|
|
displayserver.asp?id=5 (separate detail - if servers need special fields)
|
|
displayswitch.asp?id=12 (separate detail - if switches different)
|
|
displaycamera.asp?id=3 (separate detail - if cameras different)
|
|
```
|
|
|
|
But for infrastructure devices with identical schemas, I'd stick with **fully unified**.
|
|
|
|
---
|
|
|
|
## My Recommendation
|
|
|
|
**Go with Option 2 (Unified Pages) because:**
|
|
|
|
1. Servers, switches, and cameras have **identical schemas** (modelid, serialnumber, ipaddress, description, maptop, mapleft, isactive)
|
|
2. They have **identical CRUD operations** (add, edit, view, delete)
|
|
3. The database already unifies them (`vw_network_devices`)
|
|
4. Much faster to implement (4 files vs 12)
|
|
5. Easier to maintain long-term
|
|
|
|
---
|
|
|
|
**Ready to implement?** I can create the 4 unified infrastructure files now.
|
|
|