LaneAward Infrastructure Reference

Environment Topology Map

Reference for the current LaneAward environment — the local Mac, the single AWS server (staging and live production), the on-prem office file server lane-fs and the lane-gw connector, the Twingate overlay that ties them together, and the nightly ProfitMaker reference pipeline. Production went live 2026-04-25.

Production live since 2026-04-25 Nightly ProfitMaker pipeline Twingate zero-trust overlay PIN → 12h session-token auth

The Big Picture

Development starts on the Mac and promotes to the single AWS server — staging first, then live production. The server also pulls a nightly ProfitMaker snapshot from the office file server and sends status email out. The Mac reaches the server on its public address for all deploys and backups, and uses Twingate to reach the office LAN and the server's private address. Each piece is expanded in the sections below.
Current state

Local Mac

Primary development workstation — source of truth for all code and local SQLite refreshes
/Users/donaldscott/Project-Code/laneaward/repo
workforce_app/data/workforce.db — local SQLite database
pm_database/ — canonical promoted ProfitMaker DBF snapshots
timeontasks/ · ops_console/ · workforce_app/backend/
Safe to reset, experiment, and iterate freely. Never push local workforce.db to staging.
rsync + SSH deploy

AWS Staging Runtime

Production-like environment — real contributors use it; treat every operation with production-level care
SSH: ssh -i ~/.ssh/lane_webserver.pem ubuntu@3.130.69.109
Contributor app: staging.timeontasks.laneaward.com → /var/www/laneaward-staging
Operations console: staging.console.laneaward.com → /var/www/laneaward-staging-console
Legacy alias: staging.laneaward.com (backward compat, still active)
Shared DB: /var/lib/laneaward-staging/workforce.db
Backend service: laneaward-workforce-api-staging.service · port 9193
TLS: /etc/letsencrypt/live/staging.timeontasks.laneaward.com/
Real users and live sessions — verify before every deploy or database operation.
promote via deploy scripts (staging verified first)

AWS Production

Live production environment — same AWS instance, fully isolated from staging
SSH: ssh -i ~/.ssh/lane_webserver.pem ubuntu@3.130.69.109
Contributor app: timeontasks.laneaward.com → /var/www/laneaward-timeontasks/
Operations console: console.laneaward.com → /var/www/laneaward-console
Shared DB: /var/lib/laneaward/workforce.db
Backend service: laneaward-workforce-api.service · port 9194
App Launchpad: ai.laneaward.com → /var/www/ai-laneaward/
TLS: /etc/letsencrypt/live/timeontasks.laneaward.com/
Live operations — treat every deploy and database operation with maximum care.

Mac to AWS Staging

  • SSH key: ~/.ssh/lane_webserver.pem · server: ubuntu@3.130.69.109
  • Contributor app web root: /var/www/laneaward-staging
  • Console web root: /var/www/laneaward-staging-console
  • Shared database: /var/lib/laneaward-staging/workforce.db
  • Backend service: laneaward-workforce-api-staging.service

AWS Staging URLs — Canonical Subdomains (post-2026-04-13)

  • Contributor app: https://staging.timeontasks.laneaward.com/
  • Operations console: https://staging.console.laneaward.com/
  • API health check: https://staging.timeontasks.laneaward.com/api/health
  • API direct (on host): 127.0.0.1:9193
  • Legacy alias (still active): https://staging.laneaward.com/

AWS Production

  • Public landing: https://ai.laneaward.com/
  • Web root: /var/www/ai-laneaward/
  • Elastic IP: 3.130.69.109
  • Role: public entry point linking to the live app family

Office, On-Prem & Twingate

The Lane Award office runs two Lane-Award-managed machines that the AWS server never talks to directly: the ProfitMaker file server and a small connector that puts the office LAN on the Twingate overlay.
On-prem

lane-fs — ProfitMaker File Server

Windows 11 Pro workgroup server · office LAN · moving on-site with the office move
Hosts the ProfitMaker DBF share (live path D:\asidta after migration)
22:15 loader stages the newest dropped ASIDTA zip as the snapshot source
22:30 zips the snapshot and uploads it to the AWS server
Service account: svc-pmsync (read-only on the ProfitMaker data)
Origin of the nightly reference refresh — see the ProfitMaker pipeline below.

lane-gw — Office Twingate Connector

Intel Mac mini · Ubuntu · systemd Twingate connector (repurposed home-lab box)
LAN 192.168.50.38 (home LAN today; static reservation at the office)
Outbound-only — publishes the office LAN as a Twingate remote network
Lets the Mac reach lane-fs and other office hosts with no opened ports
The management plane lives off the file server, so office access survives even if lane-fs is down.

Twingate — Zero-Trust Overlay

  • Connects the Mac to the AWS private IP 172.31.7.224 and to the office LAN
  • Runs on the Mac (client) and as connectors on AWS and lane-gw
  • Replaces opening inbound ports; the nightly automation does not use this path
  • Off the home/office network, Twingate must be connected to reach either LAN

Cox Office IPs — AWS Security-Group Allowlist

  • Port 22 on sg-0cc9719fa0e029c40 allows the office static IPs
  • 98.175.1.150 — Cox Fiber (primary)
  • 72.215.199.214 — Cox Cable (failover)
  • The path lane-fs uses for the nightly upload; survives ISP failover
  • Cox must not change these without coordinating — a silent change breaks the upload

Nightly ProfitMaker Reference Pipeline

Reference data — customers, orders, descriptions — refreshes automatically every night, and has been the sole writer of reference data since 2026-07-14. The only manual step during the file-migration period is dropping the newest snapshot zip on lane-fs.
Automated nightly

lane-fs — 22:30 Arizona

Zips the newest ProfitMaker snapshot and uploads it with a checksum
Upload over the Cox office IPs to a restricted, upload-only SFTP drop
Checksum arrival is the "transfer complete" signal for the VM
SFTP upload (upload-only jail)

AWS VM intake — 23:15 Arizona

pm-import.timer verifies, extracts, and imports
Drop: /var/pm-incoming/upload/ · importer: pm_sync/vm_import_incoming.py
Verifies checksum → extracts → computes the rolling reference window
Updates reference tables only — never operational data
import + health check — staging first

Staging database

/var/lib/laneaward-staging/workforce.db — refreshed and health-checked
then production

Production database

/var/lib/laneaward/workforce.db — refreshed, health-checked, snapshot archived

Schedule & Timers

  • lane-fs 22:15 loader (stage dropped zip) · 22:30 upload
  • VM pm-import.timer at 23:15 Arizona
  • Weekly production report: weekly-production-report.timer, Mondays 8:00 AM Arizona

Status Email — Microsoft 365 Graph

  • Every successful run emails a step-by-step confirmation to Donald
  • A failure emails a separate alert — silence means nothing ran
  • The same pipeline sends the weekly production report to the production manager

Interim Operator Routine

  • Drop the newest ASIDTA zip into D:\Automation\bucket on lane-fs
  • The nightly loader, upload, and import do the rest — staging then production
  • Full design: _documents/pm-reference-automation-architecture.html

Backup & Recovery Topology

Three layers protect production, arranged so that no single failure — a lost server, a lost Mac, or an attacker who takes control of the server — can reach all of them. Two run on a schedule; the third is taken deliberately around change.
Live

AWS Production — the live databases

/var/lib/laneaward/workforce.db and the staging equivalent
Every copy below is taken with SQLite's online backup, safe while the apps are writing
push — outbound, 4× daily (19:00 · 01:00 · 07:00 · 13:00 Arizona)

Amazon S3 — the offsite copy

laneaward-db-backups-364410974402 · us-east-2
The server pushes to itself-outward using an attached identity role — no stored keys
Write-only: the server cannot delete, read, or list what is already there
Versioned and encrypted; a failed run emails Donald automatically
Independent of the Mac entirely — works whether or not it is switched on
pull — inbound to the Mac, every 12 h

Development Mac — the local copy

PWA BDR menu bar service · ~/projectbackups/laneaward/
Connects to the server's public address through the laneaward-vm SSH entry
14 most recent copies of each database; the fastest path for a guided restore
Needs the Mac awake and its address allowed on the security group
whole-machine images — taken around update cycles

EC2 machine images — the server itself

Operating system, packages, services, nginx configuration, certificates
laneaward-prod-20260812-post-update — current known-good starting point
laneaward-prod-20260812-pre-update — fallback, verified bootable
Rebuild procedure: production runbook, Process 2C

What Each Layer Survives

  • Server destroyed — S3 copy and Mac copy both survive; images rebuild the machine
  • Mac lost or stolen — S3 copy and the server are untouched
  • Server fully compromised — the S3 archive cannot be deleted or read from the server
  • Bad data written by the application — every layer holds earlier copies

Two Things Worth Knowing

  • Backups no longer depend on Twingate — the Mac reaches the server on its public address
  • A machine image carries the office connector identity; a machine started from one must have that connector stopped or reissued before it runs alongside production

AWS Runtime Split

Staging and production share one AWS instance (same Elastic IP) but are isolated by Nginx host header, web root, backend service, and SQLite database. The two staging frontends (contributor app and console) each have their own web root and subdomain.
Current target

Local Mac

Development origin — deploys to staging and production via SSH / rsync
ssh -i ~/.ssh/lane_webserver.pem ubuntu@3.130.69.109
/Users/donaldscott/Project-Code/laneaward/repo — source of truth for all code

Staging — Contributor App

AWS Ubuntu Server · Host: staging.timeontasks.laneaward.com
Nginx server_name: staging.timeontasks.laneaward.com
Web root: /var/www/laneaward-staging
DB: /var/lib/laneaward-staging/workforce.db (shared)
Service: laneaward-workforce-api-staging.service · port 9193
TLS: /etc/letsencrypt/live/staging.timeontasks.laneaward.com/
Serves Time On Tasks — PIN sign-in, task setup, live session timing. Real contributors use this environment.

Staging — Operations Console

AWS Ubuntu Server · Host: staging.console.laneaward.com
Nginx server_name: staging.console.laneaward.com
Web root: /var/www/laneaward-staging-console
DB: /var/lib/laneaward-staging/workforce.db (shared with contributor app)
Service: laneaward-workforce-api-staging.service · port 9193 (shared)
TLS: /etc/letsencrypt/live/staging.console.laneaward.com/
Serves the Operations Console — user management, reports, time corrections, runbook.

Production — Contributor App

AWS Ubuntu Server · Host: timeontasks.laneaward.com
Nginx server_name: timeontasks.laneaward.com
Web root: /var/www/laneaward-timeontasks/
DB: /var/lib/laneaward/workforce.db (shared)
Service: laneaward-workforce-api.service · port 9194
TLS: /etc/letsencrypt/live/timeontasks.laneaward.com/
Serves Time On Tasks — live contributor sign-in, task setup, and session timing.

Production — Operations Console

AWS Ubuntu Server · Host: console.laneaward.com
Nginx server_name: console.laneaward.com
Web root: /var/www/laneaward-console
DB: /var/lib/laneaward/workforce.db (shared with contributor app)
Service: laneaward-workforce-api.service · port 9194 (shared)
TLS: /etc/letsencrypt/live/timeontasks.laneaward.com/ (shared cert)
Serves the Operations Console — user management, reports, time corrections, runbook.

Production — App Launchpad

AWS Ubuntu Server · Host: ai.laneaward.com
Nginx server_name: ai.laneaward.com
Web root: /var/www/ai-laneaward/
TLS: /etc/letsencrypt/live/ai.laneaward.com/
Role: public entry point · links to both production apps and staging tab
All six hosts share Elastic IP 3.130.69.109 — isolated by Nginx host header, web root, and service.
timeontasks.laneaward.com → 3.130.69.109
console.laneaward.com → 3.130.69.109
staging.timeontasks.laneaward.com → 3.130.69.109
staging.console.laneaward.com → 3.130.69.109
ai.laneaward.com → 3.130.69.109
staging.laneaward.com → 3.130.69.109 (legacy alias, still active)

AWS Staging Isolation

  • Separate Nginx vhost for staging.timeontasks.laneaward.com (contributor app)
  • Separate Nginx vhost for staging.console.laneaward.com (operations console)
  • Separate web roots: /var/www/laneaward-staging and /var/www/laneaward-staging-console
  • Shared SQLite DB: /var/lib/laneaward-staging/workforce.db
  • Shared backend service: laneaward-workforce-api-staging.service on port 9193
  • Legacy alias staging.laneaward.com still active for backward compatibility

AWS Production Isolation

  • Separate Nginx vhost for timeontasks.laneaward.com (contributor app)
  • Separate Nginx vhost for console.laneaward.com (operations console)
  • Separate web roots: /var/www/laneaward-timeontasks/ and /var/www/laneaward-console
  • Shared SQLite DB: /var/lib/laneaward/workforce.db
  • Shared backend service: laneaward-workforce-api.service on port 9194
  • App Launchpad: ai.laneaward.com/var/www/ai-laneaward/
  • Staging and production share no runtime data — databases, services, and web roots are fully isolated

Why This Split Helps

  • One authoritative public staging path that is much closer to production behavior
  • Contributor app and console stay on separate subdomains — clean PWA install targets on tablets and laptops
  • Production and staging share no runtime data — safe to reset staging without affecting public landing
  • Removes the need to validate over a weaker home-network path

Current Truth Notes

  • All six hosts resolve to the AWS Elastic IP 3.130.69.109 via Cloudflare DNS
  • PIN sign-in issues a 12-hour sliding session token; the order-search API requires it
  • Reference data (customers, orders) refreshes automatically every night — see the ProfitMaker pipeline
  • Deploys, backups and restores reach the server on its public address — no tunnel involved
  • Twingate carries interactive access to the server's private address and to the office LAN
  • Legacy staging.laneaward.com host remains active — /workforce/ redirects to root on that host

Terminal Connection Matrix

Quick reference for direct terminal entry points and active URLs.

SSH Entry — AWS Server

  • ssh -i ~/.ssh/lane_webserver.pem ubuntu@3.130.69.109
  • Elastic IP: 3.130.69.109
  • Hosts on this instance: all six — timeontasks.laneaward.com, console.laneaward.com, both staging.* subdomains, and ai.laneaward.com

Active Production URLs

  • Contributor app: https://timeontasks.laneaward.com/
  • Operations console: https://console.laneaward.com/
  • API health (Nginx): https://timeontasks.laneaward.com/api/health
  • API health (direct): http://127.0.0.1:9194/api/health (on host)
  • App Launchpad: https://ai.laneaward.com/

Active Staging URLs

  • Contributor app: https://staging.timeontasks.laneaward.com/
  • Operations console: https://staging.console.laneaward.com/
  • API health (Nginx): https://staging.timeontasks.laneaward.com/api/health
  • API health (direct): http://127.0.0.1:9193/api/health (on host)
  • Legacy alias: https://staging.laneaward.com/

Key File Paths on VM — Production

  • Contributor web root: /var/www/laneaward-timeontasks/
  • Console web root: /var/www/laneaward-console
  • Shared production DB: /var/lib/laneaward/workforce.db
  • App Launchpad web root: /var/www/ai-laneaward/
  • App source on VM: /opt/laneaward/workforce_app
  • Backup drop: ~/projectbackups/laneaward/production-database/ (Mac)

Key File Paths on VM — Staging

  • Contributor web root: /var/www/laneaward-staging
  • Console web root: /var/www/laneaward-staging-console
  • Shared staging DB: /var/lib/laneaward-staging/workforce.db
  • App source on VM: /opt/laneaward-staging
  • Backup drop: ~/projectbackups/laneaward/staging-database/ (Mac)

Twingate, Auth & On-Prem

  • Twingate reaches the AWS private IP 172.31.7.224 and the office LAN
  • Office LAN connector: lane-gw at 192.168.50.38
  • ProfitMaker file server: lane-fs (Windows 11 Pro, office LAN)
  • Nightly upload lands in /var/pm-incoming/upload/ on the VM
  • PIN sign-in issues a 12-hour sliding session token required by the order-search API