Files
shopdb/docs/STANDARDS.md
cproudlock e598f72616 Remove emojis from all markdown docs, add consolidation plan
- 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>
2025-12-11 07:42:52 -05:00

1233 lines
30 KiB
Markdown

# Classic ASP Development Standards
## ShopDB Application
**Version:** 1.0
**Last Updated:** 2025-10-10
**Status:** MANDATORY for all new development and modifications
---
## Table of Contents
1. [Security Standards](#security-standards)
2. [Database Access Standards](#database-access-standards)
3. [Input Validation Standards](#input-validation-standards)
4. [Output Encoding Standards](#output-encoding-standards)
5. [Error Handling Standards](#error-handling-standards)
6. [Code Structure Standards](#code-structure-standards)
7. [Naming Conventions](#naming-conventions)
8. [Documentation Standards](#documentation-standards)
9. [Performance Standards](#performance-standards)
10. [Testing Standards](#testing-standards)
---
## Security Standards
### Authentication & Authorization
**MANDATORY:** All pages MUST implement authentication checks.
```vbscript
<!--#include file="./includes/auth_check.asp"-->
<%
' This will redirect to login if user is not authenticated
Call RequireAuthentication()
' For administrative functions:
Call RequireRole("Admin")
%>
```
**Exception:** Only the following pages may skip authentication:
- `login.asp`
- `error.asp`
- `404.asp`
### Session Management
```vbscript
' Standard session configuration (in sql.asp)
Session.Timeout = APP_SESSION_TIMEOUT ' From config.asp
' After successful authentication:
Session("authenticated") = True
Session("userId") = userId
Session("userName") = userName
Session("userRole") = userRole
Session("loginTime") = Now()
Session.Abandon ' Only on explicit logout
```
### Password Requirements
- **Minimum Length:** 12 characters
- **Complexity:** Must include uppercase, lowercase, number, special character
- **Storage:** Never store plaintext passwords
- **Transmission:** HTTPS only (enforce in IIS)
### Security Headers
All pages MUST set appropriate security headers:
```vbscript
Response.AddHeader "X-Content-Type-Options", "nosniff"
Response.AddHeader "X-Frame-Options", "SAMEORIGIN"
Response.AddHeader "X-XSS-Protection", "1; mode=block"
Response.AddHeader "Content-Security-Policy", "default-src 'self'"
```
---
## Database Access Standards
### Connection String
**MANDATORY:** Use configuration file, NEVER hard-code credentials.
```vbscript
<!--#include file="./includes/config.asp"-->
<%
' In sql.asp - use config constants
objConn.ConnectionString = GetConnectionString()
objConn.Open
%>
```
### Parameterized Queries
**MANDATORY:** ALL database queries MUST use parameterization.
** NEVER DO THIS:**
```vbscript
' WRONG - SQL Injection vulnerable
machineId = Request.QueryString("machineid")
strSQL = "SELECT * FROM machines WHERE machineid = " & machineId
Set rs = objConn.Execute(strSQL)
```
** ALWAYS DO THIS:**
```vbscript
' CORRECT - Parameterized query
machineId = GetSafeInteger("QS", "machineid", 0, 1, 999999)
Set cmd = Server.CreateObject("ADODB.Command")
cmd.ActiveConnection = objConn
cmd.CommandText = "SELECT * FROM machines WHERE machineid = ?"
cmd.CommandType = 1 ' adCmdText
Set param = cmd.CreateParameter("@machineid", 3, 1, , machineId) ' 3=adInteger, 1=adParamInput
cmd.Parameters.Append param
Set rs = cmd.Execute()
```
### Resource Cleanup
**MANDATORY:** Always clean up database resources.
```vbscript
<%
' At the end of EVERY page:
Call CleanupResources()
%>
```
**Template:**
```vbscript
<!--#include file="./includes/cleanup.asp"-->
<%
On Error Resume Next
' Database operations here
' Before any Response.Redirect:
Call CleanupResources()
Response.Redirect("page.asp")
Response.End
' At end of page:
Call CleanupResources()
On Error Goto 0
%>
```
### Connection Pooling
**MANDATORY:** Enable connection pooling in configuration.
```vbscript
' In config.asp GetConnectionString() function:
connectionString = connectionString & "Pooling=True;Max Pool Size=100;"
```
---
## Input Validation Standards
### Validation Library
**MANDATORY:** Use validation functions for ALL user input.
```vbscript
<!--#include file="./includes/validation.asp"-->
```
### Common Validation Patterns
#### Integer IDs
```vbscript
Dim machineId
machineId = GetSafeInteger("QS", "machineid", 0, 1, 999999)
If machineId = 0 Then
Response.Redirect("error.asp?msg=INVALID_ID")
Response.End
End If
```
#### String Fields
```vbscript
Dim serialNumber
serialNumber = GetSafeString("FORM", "serialnumber", "", 7, 50, "^[A-Z0-9]+$")
If serialNumber = "" Then
Response.Redirect("adddevice.asp?error=INVALID_SERIAL")
Response.End
End If
```
#### IP Addresses
```vbscript
Dim ipAddress
ipAddress = Request.Form("ipaddress")
If Not ValidateIPAddress(ipAddress) Then
Response.Redirect("error.asp?msg=INVALID_IP")
Response.End
End If
```
#### Email Addresses
```vbscript
Dim email
email = Request.Form("email")
If Not ValidateEmail(email) Then
Response.Redirect("error.asp?msg=INVALID_EMAIL")
Response.End
End If
```
### Whitelist Validation
**PREFERRED:** Use whitelist validation whenever possible.
```vbscript
' Example: Only allow specific status values
Dim status
status = Request.Form("status")
If status <> "active" And status <> "inactive" And status <> "pending" Then
Response.Redirect("error.asp?msg=INVALID_STATUS")
Response.End
End If
```
### Client-Side Validation
**REQUIRED:** Implement client-side validation for user experience.
**CRITICAL:** Client-side validation does NOT replace server-side validation.
```html
<form onsubmit="return validateForm();">
<input type="text"
name="serialnumber"
id="serialnumber"
required
minlength="7"
maxlength="50"
pattern="[A-Za-z0-9]+"
title="7-50 alphanumeric characters">
</form>
<script>
function validateForm() {
var serial = document.getElementById("serialnumber").value;
if (!/^[A-Z0-9]{7,50}$/i.test(serial)) {
alert("Serial number must be 7-50 alphanumeric characters");
return false;
}
return true;
}
</script>
```
---
## Output Encoding Standards
### HTML Output
**MANDATORY:** ALL user-controlled output MUST be HTML-encoded.
** NEVER DO THIS:**
```vbscript
<h5><%=rs("machinename")%></h5>
<p><%Response.Write(rs("description"))%></p>
```
** ALWAYS DO THIS:**
```vbscript
<h5><%=Server.HTMLEncode(rs("machinename"))%></h5>
<p><%Response.Write(Server.HTMLEncode(rs("description")))%></p>
```
### JavaScript Context
**MANDATORY:** Use JavaScript encoding for data in JavaScript.
```vbscript
<script>
var machineName = "<%=JavaScriptEncode(rs("machinename"))%>";
</script>
```
```vbscript
' Helper function in includes/encoding.asp
Function JavaScriptEncode(str)
Dim result
result = Replace(str, "\", "\\")
result = Replace(result, "'", "\'")
result = Replace(result, """", "\""")
result = Replace(result, vbCrLf, "\n")
result = Replace(result, vbCr, "\n")
result = Replace(result, vbLf, "\n")
JavaScriptEncode = result
End Function
```
### URL Parameters
**MANDATORY:** Use URLEncode for URL parameters.
```vbscript
<a href="displaymachine.asp?name=<%=Server.URLEncode(rs("machinename"))%>">Link</a>
```
### JSON Output
**MANDATORY:** Properly escape JSON output.
```vbscript
<!--#include file="./includes/json_helper.asp"-->
<%
Response.ContentType = "application/json"
Response.Write(CreateJSONFromRecordset(rs))
%>
```
---
## Error Handling Standards
### Standard Error Handler
**MANDATORY:** Include error handler in ALL pages.
```vbscript
<!--#include file="./includes/error_handler.asp"-->
<%
Call InitializeErrorHandling("pagename.asp")
' Page logic here
Call CheckForErrors() ' After each critical operation
Call CleanupResources()
%>
```
### Error Logging
**MANDATORY:** Log all errors to server-side log file.
```vbscript
' In error_handler.asp
Call LogError(pageName, Err.Number, Err.Description, Request.ServerVariables("REMOTE_ADDR"))
```
**Log Format:**
```
2025-10-10 14:35:22 | displaymachine.asp | -2147467259 | Syntax error in SQL | 192.168.122.1
```
### User-Facing Error Messages
**MANDATORY:** NEVER expose technical details to users.
** WRONG:**
```vbscript
Response.Write("Error: " & Err.Description)
```
** CORRECT:**
```vbscript
Response.Redirect("error.asp?code=DATABASE_ERROR")
```
### Error Codes
Standard error codes for user messaging:
- `INVALID_INPUT` - User input validation failed
- `NOT_FOUND` - Record not found
- `UNAUTHORIZED` - User lacks permission
- `DATABASE_ERROR` - Database operation failed
- `GENERAL_ERROR` - Catch-all for unexpected errors
---
## Code Structure Standards
### File Header
**MANDATORY:** Every ASP file must have a header comment block.
```vbscript
<%
'=============================================================================
' FILE: displaymachine.asp
' PURPOSE: Display detailed information for a single machine
'
' PARAMETERS:
' machineid (QueryString, Required) - Integer ID of machine to display
'
' DEPENDENCIES:
' - includes/config.asp - Application configuration
' - includes/sql.asp - Database connection
' - includes/validation.asp - Input validation functions
' - includes/auth_check.asp - Authentication verification
'
' DATABASE TABLES:
' - machines (primary)
' - machinetypes, models, vendors, businessunits
' - printers (LEFT JOIN - may be NULL)
' - pc (LEFT JOIN - may be NULL)
'
' SECURITY:
' - Requires authentication
' - No special role required (read-only)
' - Uses parameterized queries
'
' AUTHOR: [Your Name]
' CREATED: 2025-10-10
' MODIFIED: 2025-10-10 - Initial version
'
'=============================================================================
%>
```
### Standard Page Template
```vbscript
<%@ Language=VBScript %>
<%
Option Explicit ' MANDATORY - Forces variable declaration
%>
<!--#include file="./includes/config.asp"-->
<!--#include file="./includes/sql.asp"-->
<!--#include file="./includes/validation.asp"-->
<!--#include file="./includes/auth_check.asp"-->
<!--#include file="./includes/error_handler.asp"-->
<!DOCTYPE html>
<html lang="en">
<head>
<!--#include file="./includes/header.asp"-->
<title>Page Title</title>
</head>
<%
'-----------------------------------------------------------------------------
' AUTHENTICATION
'-----------------------------------------------------------------------------
Call RequireAuthentication()
'-----------------------------------------------------------------------------
' INITIALIZATION
'-----------------------------------------------------------------------------
Call InitializeErrorHandling("pagename.asp")
' Get and validate parameters
Dim paramId
paramId = GetSafeInteger("QS", "id", 0, 1, 999999)
If paramId = 0 Then
Call CleanupResources()
Response.Redirect("error.asp?msg=INVALID_ID")
Response.End
End If
' Get theme preference
Dim theme
theme = Request.Cookies("theme")
If theme = "" Then theme = "bg-theme1"
'-----------------------------------------------------------------------------
' DATABASE OPERATIONS
'-----------------------------------------------------------------------------
Dim strSQL, objRS
strSQL = "SELECT * FROM tablename WHERE id = ?"
Set objRS = ExecuteParameterizedQuery(objConn, strSQL, Array(paramId))
Call CheckForErrors()
If objRS.EOF Then
Call CleanupResources()
Response.Redirect("error.asp?msg=NOT_FOUND")
Response.End
End If
%>
<body class="bg-theme <%=theme%>">
<div id="wrapper">
<!--#include file="./includes/leftsidebar.asp"-->
<!--#include file="./includes/topbarheader.asp"-->
<div class="clearfix"></div>
<div class="content-wrapper">
<div class="container-fluid">
<!-- Page Content -->
<h5><%=Server.HTMLEncode(objRS("name"))%></h5>
</div>
</div>
<!--#include file="./includes/footer.asp"-->
</div>
<!-- JavaScript -->
<script src="assets/js/jquery.min.js"></script>
<script src="assets/js/bootstrap.min.js"></script>
<script src="assets/js/app-script.js"></script>
</body>
</html>
<%
'-----------------------------------------------------------------------------
' CLEANUP
'-----------------------------------------------------------------------------
Call CleanupResources()
%>
```
### Form Processing Template
```vbscript
<%@ Language=VBScript %>
<%
Option Explicit
%>
<!--#include file="./includes/config.asp"-->
<!--#include file="./includes/sql.asp"-->
<!--#include file="./includes/validation.asp"-->
<!--#include file="./includes/auth_check.asp"-->
<!--#include file="./includes/error_handler.asp"-->
<%
'-----------------------------------------------------------------------------
' AUTHENTICATION
'-----------------------------------------------------------------------------
Call RequireAuthentication()
Call RequireRole("Editor") ' If write operation requires special role
'-----------------------------------------------------------------------------
' INITIALIZATION
'-----------------------------------------------------------------------------
Call InitializeErrorHandling("savepage.asp")
'-----------------------------------------------------------------------------
' VALIDATE INPUT
'-----------------------------------------------------------------------------
Dim recordId, fieldValue1, fieldValue2
recordId = GetSafeInteger("FORM", "id", 0, 0, 999999)
fieldValue1 = GetSafeString("FORM", "field1", "", 1, 100, "^[A-Za-z0-9 ]+$")
fieldValue2 = GetSafeString("FORM", "field2", "", 0, 200, "")
If fieldValue1 = "" Then
Call CleanupResources()
Response.Redirect("editpage.asp?id=" & recordId & "&error=REQUIRED_FIELD")
Response.End
End If
'-----------------------------------------------------------------------------
' DATABASE OPERATION
'-----------------------------------------------------------------------------
Dim strSQL
If recordId > 0 Then
' Update existing record
strSQL = "UPDATE tablename SET field1 = ?, field2 = ?, lastupdated = NOW() WHERE id = ?"
Call ExecuteParameterizedUpdate(objConn, strSQL, Array(fieldValue1, fieldValue2, recordId))
Else
' Insert new record
strSQL = "INSERT INTO tablename (field1, field2, created) VALUES (?, ?, NOW())"
Call ExecuteParameterizedInsert(objConn, strSQL, Array(fieldValue1, fieldValue2))
recordId = CLng(objConn.Execute("SELECT LAST_INSERT_ID() AS id")(0))
End If
Call CheckForErrors()
'-----------------------------------------------------------------------------
' CLEANUP AND REDIRECT
'-----------------------------------------------------------------------------
Call CleanupResources()
Response.Redirect("displaypage.asp?id=" & recordId & "&success=1")
%>
```
---
## Naming Conventions
### Variables
**Style:** camelCase
```vbscript
' IDs - use "Id" suffix
Dim machineId, printerId, userId
' Strings - descriptive names
Dim serialNumber, ipAddress, userName, description
' Booleans - use "is" or "has" prefix
Dim isActive, hasPermission, isValid
' Database objects - use obj prefix
Dim objConn, objCmd, objRS
' SQL queries - use str prefix
Dim strSQL, strSQL2
' Counters/indexes - single letter or descriptive
Dim i, j, rowCount, itemIndex
```
### Constants
**Style:** UPPER_CASE_WITH_UNDERSCORES
```vbscript
Const DB_SERVER = "192.168.122.1"
Const MAX_FILE_SIZE = 10485760
Const SESSION_TIMEOUT = 30
Const DEFAULT_PAGE_SIZE = 50
```
### Functions
**Style:** PascalCase, verb-noun format
```vbscript
Function GetMachineById(machineId)
Function ValidateIPAddress(ipAddress)
Function RenderVendorDropdown(selectedId, filterType)
Function CreateJSONResponse(success, message, data)
Function CalculateTotalCost(items)
```
### Subroutines
**Style:** PascalCase, verb-noun format
```vbscript
Sub InitializeErrorHandling(pageName)
Sub CleanupResources()
Sub RequireAuthentication()
Sub LogError(source, errorNum, errorDesc)
```
### Files
**Display Pages (single record):** display[noun-singular].asp
- `displaymachine.asp`
- `displayprinter.asp`
- `displaypc.asp`
**List Pages (multiple records):** display[noun-plural].asp
- `displaymachines.asp`
- `displayprinters.asp`
- `displaypcs.asp`
**Edit Pages:** edit[noun-singular].asp
- `editmachine.asp`
- `editprinter.asp`
- `editpc.asp`
**Add Pages:** add[noun-singular].asp
- `addmachine.asp`
- `addprinter.asp`
- `addpc.asp`
**Form Processors:** [verb][noun].asp
- `savemachine.asp`
- `updatemachine.asp`
- `deletemachine.asp`
**Include Files:** descriptive lowercase
- `sql.asp`
- `config.asp`
- `validation.asp`
- `error_handler.asp`
- `auth_check.asp`
### Database Tables
**Style:** lowercase, plural nouns
```sql
machines
printers
pc (exception - acronym)
machinetypes
vendors
models
```
### Database Columns
**Style:** lowercase, descriptive
```sql
machineid
machinenumber
serialnumber
ipaddress
isactive
createdate
lastupdated
```
---
## Documentation Standards
### Inline Comments
**REQUIRED:** Comment complex logic and business rules.
```vbscript
'-----------------------------------------------------------------------------
' Search Logic:
' 1. Check if input matches machine number (exact) or alias (partial)
' 2. If starts with "csf" and length=5, search printer CSF names
' 3. If 7 alphanumeric chars, treat as PC serial number
' 4. If valid IP, find containing subnet
' 5. If 9 digits, treat as SSO employee number
' 6. If starts with ticket prefix, redirect to ServiceNow
' 7. Otherwise, full-text search knowledge base
'-----------------------------------------------------------------------------
```
### SQL Query Comments
**RECOMMENDED:** Document complex queries.
```vbscript
'-----------------------------------------------------------------------------
' QUERY: Get machine with all related data
'
' Retrieves:
' - Machine details (machines table)
' - Type and function account (for billing)
' - Model and vendor information
' - Business unit assignment
' - Associated printer (LEFT JOIN - may be NULL)
' - Associated PC (LEFT JOIN - may be NULL)
'
' LEFT JOINs used because not all machines have printers/PCs.
'-----------------------------------------------------------------------------
strSQL = "SELECT m.*, mt.machinetype, mdl.modelnumber, " & _
" v.vendor, bu.businessunit, " & _
" p.ipaddress AS printerip " & _
"FROM machines m " & _
"INNER JOIN machinetypes mt ON m.machinetypeid = mt.machinetypeid " & _
"LEFT JOIN printers p ON m.printerid = p.printerid " & _
"WHERE m.machineid = ?"
```
### Function Documentation
**MANDATORY:** Document all functions and subroutines.
```vbscript
'-----------------------------------------------------------------------------
' FUNCTION: ValidateIPAddress
' PURPOSE: Validates that a string is a valid IPv4 address
'
' PARAMETERS:
' ipAddress (String) - The IP address to validate
'
' RETURNS:
' Boolean - True if valid IPv4 address, False otherwise
'
' EXAMPLES:
' ValidateIPAddress("192.168.1.1") -> True
' ValidateIPAddress("192.168.1.256") -> False
' ValidateIPAddress("not an ip") -> False
'
' VALIDATION:
' - Must match pattern: XXX.XXX.XXX.XXX
' - Each octet must be 0-255
' - No leading zeros allowed
'-----------------------------------------------------------------------------
Function ValidateIPAddress(ipAddress)
Dim objRegEx, pattern
Set objRegEx = New RegExp
pattern = "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"
objRegEx.Pattern = pattern
ValidateIPAddress = objRegEx.Test(ipAddress)
End Function
```
### TODO Comments
**ENCOURAGED:** Use standardized TODO format.
```vbscript
' TODO: SECURITY - Add authentication check (HIGH PRIORITY)
' TODO: PERFORMANCE - Cache this query result
' TODO: VALIDATION - Add email format validation
' TODO: REFACTOR - Extract to reusable function
' TODO: BUG - Handle null value edge case
```
---
## Performance Standards
### Database Query Optimization
**REQUIRED:** Follow these query optimization practices.
#### Use Specific Columns
```vbscript
' BAD
strSQL = "SELECT * FROM machines"
' GOOD
strSQL = "SELECT machineid, machinenumber, machinetype FROM machines"
```
#### Use Appropriate JOINs
```vbscript
' Use INNER JOIN when relationship is required
' Use LEFT JOIN when relationship is optional
' Avoid RIGHT JOIN (use LEFT JOIN instead for clarity)
```
#### Limit Result Sets
```vbscript
' For list views, always implement paging
strSQL = "SELECT * FROM machines WHERE isactive = 1 " & _
"ORDER BY machinenumber " & _
"LIMIT " & pageSize & " OFFSET " & offset
```
### Caching Strategy
**REQUIRED:** Cache reference data at application scope.
```vbscript
' In global.asa Application_OnStart
Sub Application_OnStart
' Cache rarely-changing reference data
Call LoadVendorCache()
Call LoadModelCache()
Call LoadMachineTypeCache()
End Sub
' In data_cache.asp
Function GetCachedVendors()
If IsEmpty(Application("CachedVendors")) Or _
DateDiff("s", Application("VendorCacheTime"), Now()) > CACHE_DURATION Then
Call LoadVendorCache()
End If
GetCachedVendors = Application("CachedVendors")
End Function
```
**Cache Invalidation:**
- Time-based: 5-30 minutes for reference data
- Event-based: Invalidate when data is modified
- Manual: Provide admin function to clear cache
### Response Buffering
**REQUIRED:** Enable response buffering.
```vbscript
<%
Response.Buffer = True
%>
```
**Benefits:**
- Allows headers to be set after content generation
- Enables proper error handling with redirects
- Improves performance by sending larger chunks
### Minimize Database Roundtrips
**PREFERRED:** Consolidate queries when possible.
```vbscript
' BAD - 4 separate queries
Set rsVendors = objConn.Execute("SELECT * FROM vendors")
Set rsModels = objConn.Execute("SELECT * FROM models")
Set rsTypes = objConn.Execute("SELECT * FROM machinetypes")
Set rsUnits = objConn.Execute("SELECT * FROM businessunits")
' BETTER - Use cached data
Response.Write(RenderCachedVendorDropdown())
Response.Write(RenderCachedModelDropdown())
Response.Write(RenderCachedTypeDropdown())
Response.Write(RenderCachedUnitDropdown())
```
---
## Testing Standards
### Unit Testing
**REQUIRED:** Test all validation functions.
Create test file: `tests/test_validation.asp`
```vbscript
<!--#include file="../includes/validation.asp"-->
<%
Sub TestValidateIPAddress()
If ValidateIPAddress("192.168.1.1") Then
Response.Write("PASS: Valid IP accepted<br>")
Else
Response.Write("FAIL: Valid IP rejected<br>")
End If
If Not ValidateIPAddress("999.999.999.999") Then
Response.Write("PASS: Invalid IP rejected<br>")
Else
Response.Write("FAIL: Invalid IP accepted<br>")
End If
End Sub
Call TestValidateIPAddress()
%>
```
### Integration Testing
**RECOMMENDED:** Test critical user flows.
**Test Cases:**
1. User login flow
2. Machine creation flow
3. Machine update flow
4. Search functionality
5. Report generation
### Security Testing
**REQUIRED:** Test for common vulnerabilities.
**Test Checklist:**
- [ ] SQL injection attempts on all input fields
- [ ] XSS payloads in all text fields
- [ ] Access control bypass attempts
- [ ] Session hijacking scenarios
- [ ] CSRF token validation
### Load Testing
**RECOMMENDED:** Test under expected load.
**Metrics to Monitor:**
- Response time per page
- Database connection pool usage
- Memory consumption
- Concurrent user capacity
---
## Code Review Checklist
Before committing code, verify:
### Security
- [ ] Authentication check present
- [ ] All queries use parameterization
- [ ] All output is HTML-encoded
- [ ] Input validation implemented
- [ ] No credentials in code
### Error Handling
- [ ] Error handler included
- [ ] Resources cleaned up on all paths
- [ ] No technical details exposed to users
- [ ] Errors logged to server
### Code Quality
- [ ] File header present
- [ ] Complex logic commented
- [ ] Naming conventions followed
- [ ] No code duplication
- [ ] No commented-out debug code
### Performance
- [ ] Queries optimized
- [ ] Appropriate caching used
- [ ] Resources properly closed
- [ ] Result sets limited/paged
### Testing
- [ ] Manually tested happy path
- [ ] Tested error conditions
- [ ] Tested with invalid input
- [ ] Cross-browser tested (if UI changes)
---
## Configuration Management
### Environment-Specific Configurations
**Structure:**
```
/includes/
config.asp.template (Template with placeholders)
config.dev.asp (Development settings)
config.test.asp (Testing settings)
config.prod.asp (Production settings)
```
**Deployment Process:**
1. Copy appropriate config file to `config.asp`
2. Never commit `config.asp` to source control
3. Add `config.asp` to `.gitignore`
### Configuration Template
```vbscript
<%
'=============================================================================
' Application Configuration
' IMPORTANT: Copy this to config.asp and update values for your environment
'=============================================================================
'-----------------------------------------------------------------------------
' Database Configuration
'-----------------------------------------------------------------------------
Const DB_DRIVER = "MySQL ODBC 9.4 Unicode Driver"
Const DB_SERVER = "192.168.122.1"
Const DB_PORT = "3306"
Const DB_NAME = "shopdb"
Const DB_USER = "appuser"
Const DB_PASSWORD = "CHANGE_THIS_PASSWORD"
'-----------------------------------------------------------------------------
' Application Settings
'-----------------------------------------------------------------------------
Const APP_SESSION_TIMEOUT = 30
Const APP_PAGE_SIZE = 50
Const APP_CACHE_DURATION = 300 ' seconds
'-----------------------------------------------------------------------------
' Business Logic Configuration
'-----------------------------------------------------------------------------
Const SERIAL_NUMBER_LENGTH = 7
Const SSO_NUMBER_LENGTH = 9
Const CSF_PREFIX = "csf"
Const CSF_LENGTH = 5
'-----------------------------------------------------------------------------
' Default Values
'-----------------------------------------------------------------------------
Const DEFAULT_PC_STATUS_ID = 2
Const DEFAULT_MODEL_ID = 1
Const DEFAULT_OS_ID = 1
'-----------------------------------------------------------------------------
' External Services
'-----------------------------------------------------------------------------
Const SNOW_BASE_URL = "https://geit.service-now.com/now/nav/ui/search/"
Const ZABBIX_API_URL = "http://zabbix.example.com/api_jsonrpc.php"
'-----------------------------------------------------------------------------
' File Upload
'-----------------------------------------------------------------------------
Const MAX_FILE_SIZE = 10485760 ' 10MB
Const ALLOWED_EXTENSIONS = "jpg,jpeg,png,gif,pdf"
'-----------------------------------------------------------------------------
' Helper Functions
'-----------------------------------------------------------------------------
Function GetConnectionString()
GetConnectionString = "Driver={" & DB_DRIVER & "};" & _
"Server=" & DB_SERVER & ";" & _
"Port=" & DB_PORT & ";" & _
"Database=" & DB_NAME & ";" & _
"User=" & DB_USER & ";" & _
"Password=" & DB_PASSWORD & ";" & _
"Option=3;" & _
"Pooling=True;Max Pool Size=100;"
End Function
%>
```
---
## Migration Guide
### Updating Existing Files to Meet Standards
**Priority Order:**
1. Add authentication check
2. Fix SQL injection vulnerabilities
3. Add HTML encoding to output
4. Add error handling
5. Add file header documentation
6. Refactor for code quality
### Example Migration
**Before (Non-Compliant):**
```vbscript
<!DOCTYPE html>
<html>
<head><title>Machine</title></head>
<body>
<%
machineid = Request.QueryString("machineid")
strSQL = "SELECT * FROM machines WHERE machineid = " & machineid
set rs = objconn.Execute(strSQL)
%>
<h1><%=rs("machinename")%></h1>
</body>
</html>
```
**After (Standards-Compliant):**
```vbscript
<%@ Language=VBScript %>
<%
Option Explicit
%>
<!--#include file="./includes/config.asp"-->
<!--#include file="./includes/sql.asp"-->
<!--#include file="./includes/validation.asp"-->
<!--#include file="./includes/auth_check.asp"-->
<!--#include file="./includes/error_handler.asp"-->
<!DOCTYPE html>
<html lang="en">
<head>
<!--#include file="./includes/header.asp"-->
<title>Machine Details</title>
</head>
<%
'-----------------------------------------------------------------------------
' FILE: displaymachine.asp
' PURPOSE: Display machine details
'-----------------------------------------------------------------------------
Call RequireAuthentication()
Call InitializeErrorHandling("displaymachine.asp")
Dim machineId, strSQL, objRS
machineId = GetSafeInteger("QS", "machineid", 0, 1, 999999)
If machineId = 0 Then
Call CleanupResources()
Response.Redirect("error.asp?msg=INVALID_ID")
Response.End
End If
strSQL = "SELECT * FROM machines WHERE machineid = ?"
Set objRS = ExecuteParameterizedQuery(objConn, strSQL, Array(machineId))
Call CheckForErrors()
If objRS.EOF Then
Call CleanupResources()
Response.Redirect("error.asp?msg=NOT_FOUND")
Response.End
End If
%>
<body>
<h1><%=Server.HTMLEncode(objRS("machinename"))%></h1>
</body>
</html>
<%
Call CleanupResources()
%>
```
---
## Enforcement
### Code Review Process
**MANDATORY:** All code changes must be reviewed before deployment.
**Reviewer Checklist:**
1. Standards compliance verified
2. Security vulnerabilities checked
3. Performance impact assessed
4. Documentation adequate
5. Tests passed
### Automated Checks
**RECOMMENDED:** Implement automated scanning where possible.
**Tools:**
- SQL injection scanner
- XSS vulnerability scanner
- Code style checker
- Dead code detector
### Training
**REQUIRED:** All developers must:
1. Read this standards document
2. Complete security training
3. Review example compliant code
4. Pass knowledge assessment
---
## Version History
| Version | Date | Changes | Author |
|---------|------|---------|--------|
| 1.0 | 2025-10-10 | Initial standards document created from audit findings | Claude |
---
## Questions & Support
For questions about these standards:
1. Review the examples in this document
2. Check existing compliant code for patterns
3. Consult with team lead
4. Document unclear areas for future clarification
---
**REMEMBER:** These standards exist to protect our application and data. Following them is not optional—it's a requirement for all development work.