Add comprehensive load testing infrastructure: - k6 auth-dashboard flow (login → profile → dashboard KPIs → widgets → refresh → logout) - k6 CRUD flow (units, vendors, journal entries, payments, reports) - Environment configs with staging/production/local thresholds - Parameterized user pool CSV matching app roles - New Relic NRQL query library (25+ queries for perf analysis) - Empty baseline.json structure for all tested endpoints - CLAUDE.md documenting full stack, auth, route map, and conventions Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
271 lines
8.0 KiB
SQL
271 lines
8.0 KiB
SQL
-- =============================================================================
|
||
-- HOA Financial Platform (HOALedgerIQ) – New Relic NRQL Query Library
|
||
-- App Name: HOALedgerIQ_App (see NEW_RELIC_APP_NAME env var)
|
||
-- =============================================================================
|
||
|
||
-- ---------------------------------------------------------------------------
|
||
-- 1. OVERVIEW & THROUGHPUT
|
||
-- ---------------------------------------------------------------------------
|
||
|
||
-- Overall throughput (requests/min) over past hour
|
||
SELECT rate(count(*), 1 minute) AS 'RPM'
|
||
FROM Transaction
|
||
WHERE appName = 'HOALedgerIQ_App'
|
||
SINCE 1 hour ago
|
||
TIMESERIES AUTO;
|
||
|
||
-- Throughput by HTTP method
|
||
SELECT rate(count(*), 1 minute) AS 'RPM'
|
||
FROM Transaction
|
||
WHERE appName = 'HOALedgerIQ_App'
|
||
FACET request.method
|
||
SINCE 1 hour ago
|
||
TIMESERIES AUTO;
|
||
|
||
-- Apdex score over time
|
||
SELECT apdex(duration, t: 0.5)
|
||
FROM Transaction
|
||
WHERE appName = 'HOALedgerIQ_App'
|
||
SINCE 1 hour ago
|
||
TIMESERIES AUTO;
|
||
|
||
-- ---------------------------------------------------------------------------
|
||
-- 2. AUTHENTICATION ENDPOINTS
|
||
-- ---------------------------------------------------------------------------
|
||
|
||
-- Login latency (p50, p95, p99)
|
||
SELECT percentile(duration, 50, 95, 99) AS 'Login Latency (s)'
|
||
FROM Transaction
|
||
WHERE appName = 'HOALedgerIQ_App'
|
||
AND request.uri = '/api/auth/login'
|
||
SINCE 1 hour ago
|
||
TIMESERIES AUTO;
|
||
|
||
-- Login error rate
|
||
SELECT percentage(count(*), WHERE httpResponseCode >= 400) AS 'Login Error %'
|
||
FROM Transaction
|
||
WHERE appName = 'HOALedgerIQ_App'
|
||
AND request.uri = '/api/auth/login'
|
||
SINCE 1 hour ago
|
||
TIMESERIES AUTO;
|
||
|
||
-- Token refresh latency
|
||
SELECT percentile(duration, 50, 95, 99) AS 'Refresh Latency (s)'
|
||
FROM Transaction
|
||
WHERE appName = 'HOALedgerIQ_App'
|
||
AND request.uri = '/api/auth/refresh'
|
||
SINCE 1 hour ago
|
||
TIMESERIES AUTO;
|
||
|
||
-- Auth endpoints overview
|
||
SELECT count(*), average(duration), percentile(duration, 95)
|
||
FROM Transaction
|
||
WHERE appName = 'HOALedgerIQ_App'
|
||
AND request.uri LIKE '/api/auth/%'
|
||
FACET request.uri
|
||
SINCE 1 hour ago;
|
||
|
||
-- ---------------------------------------------------------------------------
|
||
-- 3. DASHBOARD & REPORTS
|
||
-- ---------------------------------------------------------------------------
|
||
|
||
-- Dashboard KPI latency
|
||
SELECT percentile(duration, 50, 95, 99) AS 'Dashboard Latency (s)'
|
||
FROM Transaction
|
||
WHERE appName = 'HOALedgerIQ_App'
|
||
AND request.uri = '/api/reports/dashboard'
|
||
SINCE 1 hour ago
|
||
TIMESERIES AUTO;
|
||
|
||
-- All report endpoints performance
|
||
SELECT count(*), average(duration), percentile(duration, 95)
|
||
FROM Transaction
|
||
WHERE appName = 'HOALedgerIQ_App'
|
||
AND request.uri LIKE '/api/reports/%'
|
||
FACET request.uri
|
||
SINCE 1 hour ago;
|
||
|
||
-- Slowest report queries (> 2s)
|
||
SELECT count(*)
|
||
FROM Transaction
|
||
WHERE appName = 'HOALedgerIQ_App'
|
||
AND request.uri LIKE '/api/reports/%'
|
||
AND duration > 2
|
||
FACET request.uri
|
||
SINCE 1 hour ago;
|
||
|
||
-- ---------------------------------------------------------------------------
|
||
-- 4. CRUD OPERATIONS
|
||
-- ---------------------------------------------------------------------------
|
||
|
||
-- Units endpoint latency by method
|
||
SELECT percentile(duration, 50, 95) AS 'Units Latency'
|
||
FROM Transaction
|
||
WHERE appName = 'HOALedgerIQ_App'
|
||
AND request.uri LIKE '/api/units%'
|
||
FACET request.method
|
||
SINCE 1 hour ago;
|
||
|
||
-- Vendors endpoint latency by method
|
||
SELECT percentile(duration, 50, 95) AS 'Vendors Latency'
|
||
FROM Transaction
|
||
WHERE appName = 'HOALedgerIQ_App'
|
||
AND request.uri LIKE '/api/vendors%'
|
||
FACET request.method
|
||
SINCE 1 hour ago;
|
||
|
||
-- Journal entries performance
|
||
SELECT percentile(duration, 50, 95) AS 'JE Latency'
|
||
FROM Transaction
|
||
WHERE appName = 'HOALedgerIQ_App'
|
||
AND request.uri LIKE '/api/journal-entries%'
|
||
FACET request.method
|
||
SINCE 1 hour ago;
|
||
|
||
-- Payments performance
|
||
SELECT percentile(duration, 50, 95) AS 'Payments Latency'
|
||
FROM Transaction
|
||
WHERE appName = 'HOALedgerIQ_App'
|
||
AND request.uri LIKE '/api/payments%'
|
||
FACET request.method
|
||
SINCE 1 hour ago;
|
||
|
||
-- Accounts performance
|
||
SELECT percentile(duration, 50, 95) AS 'Accounts Latency'
|
||
FROM Transaction
|
||
WHERE appName = 'HOALedgerIQ_App'
|
||
AND request.uri LIKE '/api/accounts%'
|
||
FACET request.method
|
||
SINCE 1 hour ago;
|
||
|
||
-- Invoices performance
|
||
SELECT percentile(duration, 50, 95) AS 'Invoices Latency'
|
||
FROM Transaction
|
||
WHERE appName = 'HOALedgerIQ_App'
|
||
AND request.uri LIKE '/api/invoices%'
|
||
FACET request.method
|
||
SINCE 1 hour ago;
|
||
|
||
-- ---------------------------------------------------------------------------
|
||
-- 5. MULTI-TENANT / ORG OPERATIONS
|
||
-- ---------------------------------------------------------------------------
|
||
|
||
-- Organizations endpoint performance
|
||
SELECT percentile(duration, 50, 95)
|
||
FROM Transaction
|
||
WHERE appName = 'HOALedgerIQ_App'
|
||
AND request.uri LIKE '/api/organizations%'
|
||
FACET request.method
|
||
SINCE 1 hour ago;
|
||
|
||
-- Board planning (complex module) latency
|
||
SELECT count(*), percentile(duration, 50, 95, 99)
|
||
FROM Transaction
|
||
WHERE appName = 'HOALedgerIQ_App'
|
||
AND request.uri LIKE '/api/board-planning%'
|
||
FACET request.uri
|
||
SINCE 1 hour ago;
|
||
|
||
-- ---------------------------------------------------------------------------
|
||
-- 6. ERROR ANALYSIS
|
||
-- ---------------------------------------------------------------------------
|
||
|
||
-- Error rate by endpoint (top 20 offenders)
|
||
SELECT percentage(count(*), WHERE httpResponseCode >= 400) AS 'Error %',
|
||
count(*) AS 'Total'
|
||
FROM Transaction
|
||
WHERE appName = 'HOALedgerIQ_App'
|
||
FACET request.uri
|
||
SINCE 1 hour ago
|
||
LIMIT 20;
|
||
|
||
-- 5xx errors specifically
|
||
SELECT count(*)
|
||
FROM Transaction
|
||
WHERE appName = 'HOALedgerIQ_App'
|
||
AND httpResponseCode >= 500
|
||
FACET request.uri, httpResponseCode
|
||
SINCE 1 hour ago;
|
||
|
||
-- Error rate over time
|
||
SELECT percentage(count(*), WHERE httpResponseCode >= 500) AS 'Server Error %',
|
||
percentage(count(*), WHERE httpResponseCode >= 400 AND httpResponseCode < 500) AS 'Client Error %'
|
||
FROM Transaction
|
||
WHERE appName = 'HOALedgerIQ_App'
|
||
SINCE 1 hour ago
|
||
TIMESERIES AUTO;
|
||
|
||
-- ---------------------------------------------------------------------------
|
||
-- 7. DATABASE & EXTERNAL SERVICES
|
||
-- ---------------------------------------------------------------------------
|
||
|
||
-- Database call duration (TypeORM / Postgres)
|
||
SELECT average(databaseDuration), percentile(databaseDuration, 95)
|
||
FROM Transaction
|
||
WHERE appName = 'HOALedgerIQ_App'
|
||
SINCE 1 hour ago
|
||
TIMESERIES AUTO;
|
||
|
||
-- Slowest DB transactions
|
||
SELECT average(databaseDuration), count(*)
|
||
FROM Transaction
|
||
WHERE appName = 'HOALedgerIQ_App'
|
||
AND databaseDuration > 1
|
||
FACET request.uri
|
||
SINCE 1 hour ago
|
||
LIMIT 20;
|
||
|
||
-- External service calls (Stripe, Resend, NVIDIA AI)
|
||
SELECT average(externalDuration), count(*)
|
||
FROM Transaction
|
||
WHERE appName = 'HOALedgerIQ_App'
|
||
AND externalDuration > 0
|
||
FACET request.uri
|
||
SINCE 1 hour ago;
|
||
|
||
-- ---------------------------------------------------------------------------
|
||
-- 8. LOAD TEST COMPARISON
|
||
-- ---------------------------------------------------------------------------
|
||
|
||
-- Compare metrics between two time windows (baseline vs test)
|
||
-- Adjust SINCE/UNTIL for your test windows
|
||
SELECT percentile(duration, 50, 95, 99), count(*), percentage(count(*), WHERE httpResponseCode >= 500)
|
||
FROM Transaction
|
||
WHERE appName = 'HOALedgerIQ_App'
|
||
SINCE 2 hours ago
|
||
UNTIL 1 hour ago
|
||
COMPARE WITH 1 hour ago;
|
||
|
||
-- Per-endpoint comparison during load test window
|
||
SELECT average(duration), percentile(duration, 95), count(*)
|
||
FROM Transaction
|
||
WHERE appName = 'HOALedgerIQ_App'
|
||
FACET request.uri
|
||
SINCE 1 hour ago
|
||
LIMIT 50;
|
||
|
||
-- ---------------------------------------------------------------------------
|
||
-- 9. INFRASTRUCTURE (if NR Infrastructure agent is installed)
|
||
-- ---------------------------------------------------------------------------
|
||
|
||
-- CPU utilization
|
||
SELECT average(cpuPercent)
|
||
FROM SystemSample
|
||
WHERE hostname LIKE '%hoaledgeriq%'
|
||
SINCE 1 hour ago
|
||
TIMESERIES AUTO;
|
||
|
||
-- Memory utilization
|
||
SELECT average(memoryUsedPercent)
|
||
FROM SystemSample
|
||
WHERE hostname LIKE '%hoaledgeriq%'
|
||
SINCE 1 hour ago
|
||
TIMESERIES AUTO;
|
||
|
||
-- Connection pool saturation (custom metric – requires NR custom events)
|
||
-- SELECT average(custom.db.pool.active), average(custom.db.pool.idle)
|
||
-- FROM Metric
|
||
-- WHERE appName = 'HOALedgerIQ_App'
|
||
-- SINCE 1 hour ago
|
||
-- TIMESERIES AUTO;
|