Everything a technical buyer's team needs before asking questions: stack, data flow, AI layer, module structure, integration architecture, and security posture. This document is updated on every architectural change.
No proprietary infrastructure. No framework lock-in. Everything listed here is standard, replaceable, and readable by any senior engineer in the first hour.
| Layer | Technology | Why |
|---|---|---|
| Runtime | Node.js 20 LTS | Long-term support, V8 engine, broad talent pool. Version pinned via .nvmrc. |
| HTTP framework | Express 4 | Minimal surface area. 1,000+ route handlers mounted via src/routes/_mount.js. No magic — every route is explicit. |
| Primary database | SQLite via better-sqlite3 | Synchronous, zero-dependency, single-file. Runs on the dealer's machine with no network exposure. WAL mode + 5s busy_timeout on every connection. Singleton connection pool — no per-request open/close. |
| ORM (models only) | Sequelize 6 | Used for Vehicles, Customers, Deals models. Raw SQL via src/helpers/sqlite.js for everything performance-sensitive. |
| Process manager | PM2 (cluster mode) | Multi-core utilization. ecosystem.config.js defines cluster mode, 1GB restart threshold. Online in under 3 seconds on restart. |
| Reverse proxy | nginx | SSL termination (Let's Encrypt), gzip, cache headers. Port 4011 internal, 443 external. |
| Frontend | Vanilla JavaScript | 96 versioned JS modules loaded on demand. No React, no Vite, no build step. Any engineer can open a file and read it. Cache-busted via version hashes. |
| AI inference | Anthropic Claude API | Brain / coaching / deal structuring layer. Data-retention: none (zero training on dealer data). Local simulation engine handles lender routing and nightly reweighting with zero external API calls. |
| Auth | JWT + bcryptjs | Signed tokens, single-login enforcement via active_sessions table. requireAuth middleware on all sensitive mutations and financial data GET endpoints. Public analytics, lead capture, and webhook endpoints use rate limiting instead. Demo accounts flagged with demo: true for fast token validation. |
| Payments | Stripe | Checkout sessions for subscription tier. Webhook validates payment state. Kill switch enforced via license check on API access if payment >7 days overdue. |
| Real-time | Socket.io 4 | Live deal desk updates, BDC queue notifications, equity alert push. |
| Telephony | Twilio / Telnyx | SMS inbox, AI voice BDC (Vapi.ai + ElevenLabs), inbound call screen pop. |
Resend | Transactional email for deal notifications, stip alerts, morning briefings. | |
| Charts | Chart.js | All data visualization in the frontend. No external charting service. |
| PDF generation | PDFKit | Deal jackets, adverse action letters, compliance reports. Generated server-side. |
From DMS input to AI output — the complete path a deal takes through the system.
┌─────────────────────────────────────────────────────────────────────────┐ │ DEALERSHIP DATA IN │ │ CSV export from DMS (legacy DMS, legacy DMS providers, cloud DMS providers, legacy F&I software, legacy CRM software) │ │ → /api/ingest/upload → parsed → normalized → SQLite │ └──────────────────────────────┬──────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────┐ │ CORE DATABASE LAYER │ │ │ │ louieauto.db Deals, Customers, Vehicles, DealerUsers, AuditLog │ │ simulation.db sim_runs, sim_scenarios, lender_outcomes │ │ dealership-data.db InventoryCurrent, CreditStaffRoster, moat signals │ │ [module].db Per-module isolated DBs (bdc.db, lead-intake.db...) │ │ │ │ All queries filtered by dealershipId(req) — zero cross-tenant leakage │ └──────────────────────────────┬──────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────┐ │ AI BRAIN LAYER │ │ │ │ src/agent.js Nightly cron: lender reweight, morning briefings │ │ src/local-brain.js Local pattern matching (zero API cost) │ │ simulation/ Deal simulation engine (SQLite, no external API) │ │ │ │ Hybrid routing: local patterns first → Claude API fallback │ │ Every API call: data-retention: none — PII stripped before send │ └──────────────────────────────┬──────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────┐ │ CLOSED-LOOP LEARNING │ │ │ │ Deal outcome logged → lender_outcomes table │ │ 1:30am nightly → sync-sims-to-closed-loop.js │ │ lender_weight_cache updated → getWeights(dealershipId) returns │ │ freshly calibrated routing on every subsequent deal │ └──────────────────────────────┬──────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────┐ │ FRONTEND OUTPUT │ │ │ │ 96 versioned JS modules · 1,267 open__() entry points │ │ Role-based nav: GM / Desk / F&I / BDC / Service / Owner │ │ Real-time updates via Socket.io · Mobile-responsive │ └─────────────────────────────────────────────────────────────────────────┘
13 dedicated AI files. Three tiers: local pattern engine (zero cost), Anthropic Claude (coaching and complex reasoning), and the closed-loop simulator (nightly calibration, no external calls).
src/local-brain.js — Pattern matching engine. 3,059 operator-encoded rows across 12 tables. Handles lender routing, objection responses, pricing velocity, and stocking recommendations without any external API call. Lazy singleton SQLite connections — opened once per process, not per request.
Confidence threshold: 0.65. Below that, escalates to Tier 2.
Anthropic Claude Sonnet — Used for: Brain Command Center (natural language query over live dealer data), deal coaching, adverse action explanation, morning briefing narrative, and any query that requires judgment beyond pattern matching.
All calls: data-retention: none. PII stripped before transmission. No dealer data trains Anthropic models.
simulation/ + scripts/sync-sims-to-closed-loop.js — The real moat. Every funded or declined deal is logged with its outcome in lender_outcomes. At 1:30am nightly, the sync script reweights the lender routing matrix using the store's own deal history. getWeights(dealershipId) returns a fresh probability map consumed by matchLenders() on every deal submission. After 12 months of operation, routing accuracy is calibrated to that specific store's deal mix — a competitor with no outcome data cannot match this.
// Closed-loop learning cycle — runs every deal 1. Deal submitted → matchLenders(deal, getWeights(dealershipId)) ↑ reads nightly-updated weight cache 2. Lender decision → lender_outcomes row written {lender, decision, days_to_fund, loan_amount} 3. 1:30am nightly → sync-sims-to-closed-loop.js Reads lender_outcomes → recalculates approval probability per lender per FICO band → writes lender_weight_cache 4. Next deal → routing uses updated weights Loop compounds every day the store operates
Every module is live, deployed, and included in the perpetual license from day one. Console-verifiable: 1,267 callable open__() functions in the live demo (count grows during the ~20s page-load window as scripts finish initializing — this is the settled figure).
Object.keys(window).filter(k => k.startsWith('open')).length. Settles at 1,267 — more than the 220 marketed. The gap is the right direction.
CSV-via-email today. Full REST API layer built — gated by DMS partner agreements, not engineering. An acquirer with existing DMS API access flips to real-time immediately post-close.
Path: Dealer emails daily DMS export → /api/ingest/upload → auto-column mapping → normalized into SQLite.
Supports: legacy DMS, legacy DMS providers, cloud DMS providers, legacy F&I software, legacy CRM software, legacy CRM software, and any DMS that exports CSV (all of them).
Limitation: Daily refresh, not real-time. Sufficient for morning briefing and coaching modules. Insufficient for live deal desk integration at the second-by-second level.
1,000+ API routes in src/routes/, all documented. Real-time DMS integration requires vendor partner agreements:
legacy DMS Partner Program · legacy DMS providers RCI Network · cloud DMS providers Developer Portal · legacy F&I portals API · legacy CRM software
Acquirer advantage: Any DMS platform with an existing partner agreement flips LouieAuto to real-time on day one post-close. The integration engineering is done — only agreement transfer required.
| Integration type | Status | What's needed to go live |
|---|---|---|
| CSV / flat-file DMS | ✓ Live | Nothing. Works today on any DMS. |
| Twilio SMS / Voice | ✓ Live | Twilio account credentials in .env. |
| Stripe billing | ✓ Live | Stripe secret key + price IDs in .env. |
| Anthropic (AI Brain) | ✓ Live | API key in .env. Enterprise agreement for volume pricing. |
| legacy DMS API (real-time) | Architecture ready | legacy DMS Partner Program membership (acquirer likely has). |
| legacy DMS providers RCI (real-time) | Architecture ready | RCI Network agreement (acquirer likely has). |
| legacy F&I portals / legacy CRM software | Architecture ready | API partner agreement. |
| Credit bureaus (full pull) | Soft pull ready | Hooks built for iSoftPull / 700Credit. Activates when API credentials are added in provider setup. Hard pull requires FCRA permissible purpose agreement. |
Hardened for dealer operations. Not SOC 2 certified yet — that's the Q3 2026 milestone. What is in place today covers the controls that matter for going live.
| Control | Status | Implementation |
|---|---|---|
| Authentication | ✓ Live | JWT signed tokens · bcrypt password hashing · single-login enforcement (session invalidated on second login) · fail-closed on DB errors (503, not pass-through) |
| Authorization | ✓ Live | Auth required on POST/PUT/DELETE and sensitive GET endpoints (deal data, customer data, financials) · Public read-only endpoints (market scan, health checks) have rate limiting · dealershipId(req) on every authenticated query — zero cross-tenant data access possible |
| SQL injection | ✓ Fixed | Parameterized queries throughout · table names quoted and sanitized where dynamic SQL is unavoidable (audit.js) |
| Data isolation | ✓ Live | Each dealership's data filtered by dealershipId at query level · no shared cloud DB · SQLite on-premises |
| HTTPS / HSTS | ✓ Live | Let's Encrypt SSL · HSTS max-age=31536000; includeSubDomains · enforced at nginx layer |
| Security headers | ✓ Live | Helmet.js · CSP configured · X-Frame-Options · no clickjacking surface |
| Rate limiting | ✓ Live | express-rate-limit on all public endpoints · magic-link endpoint: 3 per hour per IP · deal create: 50 per hour |
| FTC Safeguards / GLBA | ✓ Compliant | PII stripped before any LLM call · financial data bucketed not transmitted raw · US-region infrastructure |
| AI data retention | ✓ Live | Anthropic API called with data-retention: none · no dealer data trains Anthropic models · JSONL portability on request |
| SOC 2 Type II | Q3 2026 | Control matrix and readiness roadmap in data room. Process gap, not security gap. Enterprise deals require it — available 60–90 days post-engagement. |
Transparency on endpoint classification — what requires auth, what's public, and why.
| Endpoint Category | Auth Required | Reasoning & Examples |
|---|---|---|
| Sensitive mutations | ✓ Yes | POST/PUT/DELETE operations on deal data, customer records, financial details, inventory. e.g. /api/deals, /api/customers, /api/ingest/upload |
| Financial & personal data | ✓ Yes | GET requests returning PII, credit profiles, pricing, commissions, payroll. e.g. /api/customer/360, /api/deals/{id}, /api/payroll |
| Admin / configuration | ✓ Yes | Role-based access control, user management, provider setup, compliance settings. e.g. /api/admin/*, /api/provider-setup |
| Public analytics & monitoring | No (rate-limited) | Health checks, market scan aggregates, public demo data statistics. e.g. /api/health/score, /api/market-scan/public |
| Lead capture & webhooks | No (rate-limited) | Public lead intake, contact forms, third-party webhooks (Stripe, integrations). Validation + rate limits protect from abuse. e.g. /api/leads, /api/webhook/* |
| Licensee data (demo account) | No (rate-limited) | Demo dealership shares metrics and case studies. Dealership ID is public; customer names and sensitive data are redacted. e.g. /api/demo/stats, marketing pages |
/api/* route is protected by token-bucket rate limits (3–50 requests per hour per IP depending on endpoint sensitivity). Magic-link authentication endpoints capped at 3 per hour. This prevents enumeration and DDoS while permitting legitimate public access (lead forms, market data).
Standard Ubuntu VPS. 48-hour cold deploy. An acquirer running a cloud-native stack can containerize and migrate to Kubernetes in one sprint.
# Full deploy sequence — 48 hours cold start 1. Provision server (2h) Ubuntu 22.04+ · 4 vCPU · 8GB RAM nginx + Let's Encrypt · Certbot auto-renew Node.js 20 via nvm 2. Clone + configure (2h) git clone → set .env npm install · pm2 start ecosystem.config.js 3. Seed dealer data (4–8h) First DMS CSV import via /api/ingest/upload Lender matrix mapped to dealer's lenders Demo data available immediately 4. Staff orientation (4h) GM walkthrough · BDC lead · F&I manager Role-based UI — no certification required ───────────────────────────────────── Total: Live system processing real deals in 48 hours DMS API integration (real-time): 30–90 days (agreement transfer)
DigitalOcean NYC3 · 8GB/4vCPU · PM2 cluster mode · nginx reverse proxy · SSL via Let's Encrypt · Port 4011 internal · Automated nightly jobs via node-cron
Monthly infra cost: ~$48/month. Scales horizontally — add servers, point nginx upstream.
No proprietary infrastructure dependencies. The entire application is a standard Node.js process + SQLite files. Dockerizes in one afternoon. Kubernetes-ready in one sprint.
SQLite → Postgres migration path is 75% complete (USE_POSTGRES=true flag in .env switches the query layer).