Full Content
TITLE: NSG Coding Standards
# NSG Coding Standards
## Purpose
Standards for all code written for North Star Group projects. These standards ensure code is maintainable by Michael (vibe coder, not trained programmer), AI assistants (primarily Claude), and junior developers.
---
## File Length Limits
| File Type | Soft Limit | Hard Limit |
|-----------|------------|------------|
| Python | 400 | 600 |
| JavaScript | 300 | 500 |
| HTML | 200 | 300 |
| CSS | 200 | 400 |
Soft limit: prefer to stay under. Hard limit: split the file.
**Why these limits exist:** Files beyond hard limits cause problems with non-Claude AIs, manual editing without IDE, and human cognitive load. Claude handles longer files fine, but code should be portable.
---
## Change Log Requirements
Every file must have a change log at the top.
**Python:**
```python
# CHANGE LOG
# File: /path/to/file.py
# Purpose: What this file does
# Main App: which app.py
# Blueprint: which blueprint (if applicable)
# Routes: /route1, /route2 (if applicable)
# Dependencies: flask, mysql.connector, etc.
# Version History:
# 2025-01-02 v1.1 - Added feature X
# 2025-01-01 v1.0 - Initial creation
```
**HTML:**
```html
<!--
CHANGE LOG
File: /templates/page.html
Purpose: What this template does
Parent: base.html
Route: /page
Partials: lists any included partials
Version History:
2025-01-02 v1.1 - Added section X
2025-01-01 v1.0 - Initial creation
-->
```
**JavaScript:**
```javascript
/*
CHANGE LOG
File: /static/js/script.js
Purpose: What this script does
Template: which HTML template uses it
Dependencies: any libraries
Version History:
2025-01-02 v1.1 - Added function X
2025-01-01 v1.0 - Initial creation
*/
```
**CSS:**
```css
/*
CHANGE LOG
File: /static/css/style.css
Purpose: What styles this provides
Templates: which templates use it
Version History:
2025-01-02 v1.1 - Added responsive styles
2025-01-01 v1.0 - Initial creation
*/
```
**Why change logs matter:** When returning to code months later, or when a new AI session starts, the file explains itself. No guessing about relationships, routes, or dependencies.
---
## Python Standards
### No Classes
Use functions, not classes.
**Why:** Classes require proper indentation across multiple methods. Without an IDE, manual editing breaks indentation. Non-Claude AIs often refuse to rewrite entire files, expecting you to make surgical edits yourself. Flat function structure stays portable.
**Exception:** If a library requires a class (Flask-WTF forms, etc.), keep it minimal.
### Early Return Pattern
Validate inputs first, return early on failure. Avoid deep nesting.
```python
def get_user(user_id):
if not user_id:
print("ERROR: get_user - Missing user_id")
return None
conn = get_db_connection()
if not conn:
print("ERROR: get_user - No database connection")
return None
try:
cur = conn.cursor(dictionary=True)
cur.execute("SELECT * FROM users WHERE id = %s", (user_id,))
result = cur.fetchone()
if not result:
print("DEBUG: get_user - User not found")
return None
print("DEBUG: get_user - User found")
return result
except MySQLError as e:
print(f"ERROR: get_user - MySQL error: {e}")
print(f"ERROR: get_user - Traceback: {traceback.format_exc()}")
return None
except Exception as e:
print(f"ERROR: get_user - Unexpected error: {e}")
print(f"ERROR: get_user - Traceback: {traceback.format_exc()}")
return None
finally:
if conn:
conn.close()
```
### Mandatory Error Handling
Every function must have try/except. Every database operation must handle MySQLError and generic Exception. Every error must print with ERROR: prefix. Every success path should print with DEBUG: prefix.
**Why full traceback:** AI debugging with context is fast. The traceback tells the AI exactly where and why it failed. Debugging is a tenth of the time it used to be.
### Print Statement Format
```python
print(f"DEBUG: function_name - Description of what happened")
print(f"ERROR: function_name - What went wrong: {e}")
print(f"ERROR: function_name - Traceback: {traceback.format_exc()}")
```
---
## HTML Standards
### No Jinja in Comments
**Wrong:**
```html
<!--
Parent: base.html ({% include 'partials/_navbar.html' %})
-->
```
**Right:**
```html
<!--
Parent: base.html (includes partials/_navbar.html)
-->
```
**Why:** Jinja2 parses everything, including comments. Jinja tags in comments cause template errors or infinite recursion.
### Use Partials
Templates over 200 lines should be split into partials. Main template includes them:
```html
{% include 'partials/_navbar.html' %}
{% include 'sections/_hero.html' %}
{% include 'sections/_content.html' %}
```
### Accordion Structure
NSG sites use a 4-level accordion hierarchy:
| Level | Button Class | Panel Class |
|-------|--------------|-------------|
| 1 | accordion-section | panel-section |
| 2 | accordion | panel |
| 3 | accordion nested | panel nested |
| 4 | accordion-spec | panel-spec |
Main headings use BOTH classes: `class="accordion accordion-section"`
---
## Pre-Coding Checklist
Before writing any code:
1. Fetch source material (existing site, spec doc, source URLs)
2. Read NSG Coding Standards (this document)
3. Read NSG Communication Standards
4. Check PostMortem Errors for relevant past failures
5. Ask where files should go (exact paths)
6. Examine existing working code ("What already works?")
7. Get outline/narrative approval before HTML
8. Map directory structure before creating files
---
## The 5-Failure Rule
After 5 failed attempts at anything:
- STOP
- Review architecture
- Ask what already works
- Don't keep trying random fixes
---
## Deployment Rules
### File Paths
- All sites live under `/var/www/html/` as `sitename.nsgia.com`
- Downloads go direct to server paths (e.g., `/var/www/html/sample/static/css/`)
- Always specify exact target path
### SCP Syntax
```bash
scp file.py mh@104.191.236.122:/var/www/html/sitename.nsgia.com/
```
Use `mh@`, not `root@`.
### Server Reference
- Web Server (PHR): 104.191.236.122
- Workstation (ws): 104.191.236.121
### Adding New Pages
Copy a working page exactly, then change only the content. Don't invent new patterns.
---
## What NOT to Add
- Icons, progress bars, loading spinners, animations
- Copy buttons, tooltips, help modals, pretty styling
- Extra validation, auto-complete, suggestions
- Gradients, shadows, hover effects, decorative elements
- Auto-save, draft functionality, convenience features
- Settings, preferences, customization options
- Search, filtering, sorting unless specifically requested
Only implement what is specifically requested. Every additional feature is a potential bug.
---
## Endpoint Accuracy
Never change existing endpoint names. If endpoint is `/upload-photos`, do not change to `/api/upload-photos`. Use exact routes as provided.
Hours of debugging result from mismatched endpoint names. When in doubt, ask for the exact endpoint name.
---
*Last Updated: 2025-01-02*