joshburt.com.au
January 6, 2026 Β· View on GitHub
Production-ready serverless web application for workshop management and product ordering.
π Live Sites
- Primary: https://joshburt.netlify.app/
(Netlify + Functions)
- Mirror: https://joshburt.com.au/
(FTP static mirror)
π― Overview
Modern full-stack application with:
- π¨ Frontend: Static HTML + TailwindCSS v4 + Vanilla JS
- β‘ Backend: Netlify Functions (serverless Node.js)
- πΎ Database: PostgreSQL (Neon)
- π Auth: JWT + optional Auth0 OAuth
- π Features: Admin dashboard, product management, order system, audit logging
Code Quality: Fully audited, production-ready, no dead code or debug logic.
β¨ Key Features
User-Facing
- Product Catalogs: Oil products, consumables, filters
- Order Management: Create, track, and review orders
- User Profiles: Avatar upload, preferences, 2FA
- Notifications: Real-time in-app notifications
- Multi-Theme: Dark, light, neon, ocean, high-contrast
Admin Features
- User Management: CRUD operations with role-based access
- Analytics Dashboard: Usage stats, product insights
- Audit Logging: Comprehensive action tracking with search/export
- Site Settings: Database-backed configuration
- Inventory Control: Stock tracking and alerts
- Error Tracking: Self-hosted error monitoring (Phase 1.1)
- Email Queue: Reliable email delivery with retry logic (Phase 1.2)
Technical Features
- Serverless Architecture: Zero server management
- Database Management: PostgreSQL schema with full CRUD operations
- Permission System: Role-based access control (mechanic/manager/admin)
- Error Tracking: Database-backed error logging with grouping
- Email Queue: Priority-based email delivery with templates
- Testing Suite: Jest unit/integration + function smoke tests
- CI/CD: Automated testing, linting, and deployment
π Quick Start
Prerequisites
- Node.js 20+ (recommended; CI uses Node 22)
- PostgreSQL database (Neon recommended)
- Netlify account (for deployment)
Local Development
# 1. Clone repository
git clone https://github.com/SmokeHound/joshburt.com.au.git
cd joshburt.com.au
# 2. Install dependencies
npm install
# 3. Set up environment variables
cp .env.example .env
# Edit .env with your database credentials
# 4. Apply database schema
psql -h $DB_HOST -U $DB_USER -d $DB_NAME -f database-schema.sql
# 5. Start development servers
# Option A: Static only (no API)
npm run dev
# Visit http://localhost:8000
Note (Windows): `npm run dev` uses `python3 -m http.server 8000`. If `python3` is not available on your PATH, install Python 3 and run `python -m http.server 8000`, or add a `python3` alias.
# Option B: Full-stack (static + serverless)
npm run dev:functions
# Visit http://localhost:8888
Note: `npm run dev:functions` uses `npx` to run the Netlify CLI. The first run may take longer (downloads `netlify-cli`).
# Option C: Both (recommended)
# Terminal 1: npm run dev
# Terminal 2: npm run dev:functions
Environment Variables
SMTP can be configured via a provider (simplest) or by running your own mail server. For the self-hosted route, see docs/SMTP_SELF_HOSTED.md.
# Database (required)
DB_HOST=your-db-host.neon.tech
DB_PORT=5432
DB_USER=your-username
DB_PASS=your-password
DB_NAME=your-database
# Neon (Postgres) for Netlify Functions
DATABASE_URL=postgres://<username>:<password>@<host>/<database>?sslmode=require
# Database Connection Pool (PostgreSQL)
DB_POOL_MAX=20
DB_POOL_MIN=2
DB_IDLE_TIMEOUT=30000
DB_CONNECTION_TIMEOUT=3000
DB_QUERY_TIMEOUT=10000
DB_STATEMENT_TIMEOUT=10000
# Authentication (required)
JWT_SECRET=your-secret-key-min-32-chars
JWT_EXPIRES_IN=7d
JWT_REFRESH_EXPIRES_IN=30d
# Auth0 (optional - enables OAuth)
AUTH0_DOMAIN=your-tenant.auth0.com
AUTH0_CLIENT_ID=your-client-id
AUTH0_AUDIENCE=https://your-api-identifier
# Email (optional - for password reset)
SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_USER=your-email@example.com
SMTP_PASS=your-smtp-password
FROM_EMAIL=noreply@joshburt.com.au
# Security
BCRYPT_ROUNDS=12
RATE_LIMIT_WINDOW_MS=900000
RATE_LIMIT_MAX_REQUESTS=100
# Self-Hosted Error Tracking
ERROR_TRACKING_ENABLED=true
# Email Queue System
EMAIL_QUEUE_ENABLED=false
EMAIL_WORKER_BATCH_SIZE=10
EMAIL_WORKER_POLL_INTERVAL=60000
EMAIL_WORKER_MAX_TIME=300000
# Push Notifications (Web Push)
# Generate VAPID keys with: npx web-push generate-vapid-keys
VAPID_PUBLIC_KEY=your-vapid-public-key
VAPID_PRIVATE_KEY=your-vapid-private-key
VAPID_SUBJECT=mailto:admin@joshburt.com.au
# Logging
DEBUG=false
π§ͺ Testing
# Run all tests (recommended before commits)
npm run validate
# Individual test suites
npm test # Jest tests only
npm run test:unit # Unit tests
npm run test:integration # Integration tests
npm run test:functions # Function smoke tests
# Linting
npm run lint # JS + HTML
npm run lint:js # JavaScript only
npm run lint:html # HTML only
# Health check
npm run health # Verify database connectivity
π·οΈ Versioning & Releases
This repo supports automatic version bumps and GitHub releases via semantic-release.
- Trigger: push/merge to
main - Logic: version is derived from commit messages (Conventional Commits)
- Output: creates a Git tag
vX.Y.Z, updatespackage.json+package-lock.json, and appends toCHANGELOG.md
The GitHub Actions βReleaseβ workflow can also be triggered manually from the Actions UI.
Note: the application code (Netlify Functions) is CommonJS today (uses require). We keep the repo as CommonJS to avoid breaking the runtime, and run semantic-release in GitHub Actions with Node 22 (ESM-compatible).
Commit examples:
fix: correct order status email textβ patch bumpfeat: add email queue templatesβ minor bumpfeat!: change auth token format(orBREAKING CHANGE:in body) β major bump
π Project Structure
joshburt.com.au/
βββ index.html # Landing page
βββ login.html, register.html # Authentication
βββ administration.html # Admin dashboard
βββ users.html # User management
βββ oil-products.html # Product catalog
βββ orders-review.html # Order management
βββ settings.html # Site configuration
β
βββ assets/
β βββ css/styles.css # Compiled TailwindCSS
β βββ js/ # Frontend JavaScript
β βββ images/ # Static assets
β
βββ netlify/functions/ # Serverless API
β βββ auth.js # Authentication (multi-action)
β βββ users.js # User CRUD
β βββ products.js # Product catalog
β βββ orders.js # Order management
β βββ consumables.js # Consumables
β βββ filters.js # Filters/parts
β βββ audit-logs.js # Audit trail
β βββ notifications.js # User notifications
β βββ settings.js # Site settings
β βββ ... # Other endpoints
β
βββ config/
β βββ database.js # PostgreSQL connection
β
βββ utils/
β βββ fn.js # Function helpers
β βββ http.js # Auth middleware
β βββ rbac.js # Role-based access
β βββ ... # Other utilities
β
βββ migrations/ # Database migrations
βββ tests/ # Test suites
βββ scripts/ # Utility scripts
βββ docs/ # Documentation
π API Reference
Base URL
- Local:
http://localhost:8888/.netlify/functions - Production:
https://joshburt.netlify.app/.netlify/functions
Authentication Endpoint
POST /.netlify/functions/auth?action={action}
Actions: login, register, refresh, logout, me, forgot-password, reset-password, verify-email, 2fa-setup, 2fa-enable, 2fa-disable
# Example: Login
curl -X POST '/.netlify/functions/auth?action=login' \
-H 'Content-Type: application/json' \
-d '{"email":"user@example.com","password":"password123"}'
Resource Endpoints
| Endpoint | Methods | Description |
|---|---|---|
/users | GET, POST, PUT, DELETE | User management |
/products | GET, POST, PUT, DELETE | Product catalog |
/orders | GET, POST, PUT, DELETE | Order management |
/consumables | GET, POST, PUT, DELETE | Consumables |
/filters | GET, POST, PUT, DELETE | Filters/parts |
/audit-logs | GET, POST, DELETE | Audit logging |
/settings | GET, PUT | Site settings |
/notifications | GET, POST, PUT, DELETE | Notifications |
/health | GET | Health check (no auth) |
Full API documentation: See docs/API_DOCUMENTATION.md
π¨ Frontend Architecture
Shared Components
<!-- Include in all pages -->
<div id="main-nav"></div>
<script src="/shared-nav.html"></script>
<script src="/shared-theme.html"></script>
<script src="/shared-config.html"></script>
Theme System
// Apply saved theme (automatic on load)
window.Theme.applyFromStorage();
// Set theme preset
window.Theme.setTheme('dark'); // dark, light, neon, ocean, high-contrast
// Custom colors
window.Theme.setPalette({
primary: '#3b82f6',
secondary: '#10b981',
accent: '#8b5cf6'
});
API Calls
const FN_BASE = window.FN_BASE || '/.netlify/functions';
// Authenticated request
const response = await fetch(`${FN_BASE}/products`, {
headers: { Authorization: `Bearer ${localStorage.getItem('accessToken')}` }
});
// Multi-action auth
await fetch(`${FN_BASE}/auth?action=login`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email, password })
});
πΎ Database
Schema Management
The database uses a single master schema file for all tables and indexes.
# Apply complete schema
psql -h $DB_HOST -U $DB_USER -d $DB_NAME -f database-schema.sql
# Alternative (often easiest cross-platform):
psql "$DATABASE_URL" -f database-schema.sql
# Health check
npm run health
Core Tables
users- User accounts with roles and authproducts- Product catalog with categoriesorders- Order headers with status trackingorder_items- Order line itemsaudit_logs- System audit trailnotifications- User notificationssettings- Site configuration
Full schema reference: See docs/DATABASE.md
π’ Deployment
Netlify (Primary)
Automatically deploys on push to main:
- Static files β Netlify CDN
- Functions β Serverless runtime
- Environment variables via Netlify dashboard
FTP Mirror (Optional)
GitHub Actions workflow deploys to FTP server.
Configure via GitHub Secrets: FTP_SERVER, FTP_USERNAME, FTP_PASSWORD
Manual Deploy
# Build CSS
npm run build:css
# Test before deploy
npm run validate
# Commit and push (triggers auto-deploy)
git push origin main
π Security
- Authentication: JWT with refresh tokens
- Authorization: Role-based access control (RBAC)
- Password Hashing: bcrypt with salt
- 2FA: TOTP support (optional)
- Rate Limiting: Login attempt tracking
- Audit Logging: All admin actions tracked
- SQL Injection: Parameterized queries
- XSS Protection: Input sanitization
π― Performance
Optimizations Implemented
- Browser caching (1 year for assets)
- Gzip/Brotli compression
- Database connection pooling
- Comprehensive indexing (20+ indexes)
- Lazy loading for images
- CDN delivery (Netlify)
Metrics
- Page load: <2s (was 3.5s)
- Asset size: 80KB (was 250KB)
- Database queries: <50ms (was 500ms)
- Lighthouse score: 95/100
Full optimization details: See OPTIMIZATIONS.md
π Documentation
π Upgrade & Improvements Plan
Want to add features without paid services? Start here β START_HERE.md
The upgrade plan includes:
- Self-hosted error tracking (replaces Sentry)
- Email queue system (no external SMTP)
- Full-text search (PostgreSQL native)
- Advanced analytics & automated reports
- Multi-layer caching
- Security monitoring & API keys
- Offline PWA support
- Business intelligence & forecasting
- And 30+ more features!
Total cost: $0 | Savings: $500-5000/year | Timeline: 6-21 weeks
Technical Documentation
Comprehensive documentation in /docs:
- START_HERE.md - π New to upgrades? Start here!
- UPGRADE_SUMMARY.md - π Quick upgrade plan overview
- VISUAL_ROADMAP.md - π Interactive visual journey
- UPGRADE_PLAN.md - π Complete upgrade specification (1100+ lines)
- IMPLEMENTATION_GUIDE.md - π Step-by-step how-to guide
- ARCHITECTURE.md - System design
- API_DOCUMENTATION.md - API reference
- DATABASE.md - Schema and queries
- DEPLOYMENT.md - Deployment guide
- AUTHENTICATION.md - Auth flows
- CONTRIBUTING.md - Contribution guide
Documentation index: DOCS_INDEX.md
π€ Contributing
- Fork the repository
- Create feature branch (
git checkout -b feature/amazing-feature) - Write tests for new functionality
- Ensure all tests pass (
npm run validate) - Commit changes (
git commit -m 'Add amazing feature') - Push to branch (
git push origin feature/amazing-feature) - Open Pull Request
See CONTRIBUTING.md for detailed guidelines.
π Common Tasks
Add New Page
# 1. Create HTML file
touch my-page.html
# 2. Include shared components
<!-- Add to my-page.html -->
<script src="/shared-nav.html"></script>
<script src="/shared-theme.html"></script>
# 3. Add navigation link in shared-nav.html
Add New Function
# 1. Create function file
touch netlify/functions/my-function.js
# 2. Use withHandler wrapper
const { withHandler, error } = require('../../utils/fn');
exports.handler = withHandler(async (event) => {
// Your code here
});
# 3. Test locally
npm run dev:functions
curl http://localhost:8888/.netlify/functions/my-function
Database Migration
# 1. Create a new migration in migrations/ (next number)
# Example: migrations/005_add_my_table.sql
# 2. Update database-schema.sql to match
# 3. Apply migrations
npm run migrate
# Optional: dry run
node scripts/run-migrations.js --dry-run
π Browser Support
- β Firefox 88+
- β Safari 14+
- β Edge 90+
Progressive enhancement ensures core functionality without JavaScript.
π License
This project is licensed under the MIT License.
π Links
- Live Site: https://joshburt.com.au/
- GitHub: https://github.com/SmokeHound/joshburt.com.au
- Issues: https://github.com/SmokeHound/joshburt.com.au/issues
- Netlify: https://joshburt.netlify.app/
π€ Author
Josh Burt
- Website: https://joshburt.com.au
- GitHub: @SmokeHound
Built with β€οΈ using Netlify Functions, PostgreSQL, and TailwindCSS