TypeScript 97.6%
SQL 1.4%
JavaScript 0.5%
1/**2 * k6 load test — concurrent players spinning.3 * k6 run -e BASE=https://www.spinza.dev -e VUS=100 -e DURATION=60s qa/load/spin.k6.js4 * Each VU registers a throwaway account (username lt_<vu>_<rand>) and spins on neon-vault.5 * Never run against production without lowering the register rate limit awareness (10/10 min per IP):6 * use -e USERS_FILE with pre-created "username:password" lines to skip registration.7 */8import http from "k6/http";9import { check, sleep } from "k6";10import { uuidv4 } from "https://jslib.k6.io/k6-utils/1.4.0/index.js";1112const BASE = __ENV.BASE || "http://localhost:8230";13export const options = {14 scenarios: {15 spins: { executor: "constant-vus", vus: Number(__ENV.VUS || 50), duration: __ENV.DURATION || "60s" },16 },17 thresholds: {18 http_req_failed: ["rate<0.01"],19 "http_req_duration{name:spin}": ["p(95)<250"],20 },21};2223export function setup() {24 const users = [];25 if (__ENV.USERS_FILE) {26 for (const line of open(__ENV.USERS_FILE).split("\n")) {27 const [u, p] = line.trim().split(":");28 if (u && p) users.push({ username: u, password: p });29 }30 }31 return { users };32}3334export default function (data) {35 const jar = http.cookieJar();36 let creds = data.users.length ? data.users[(__VU - 1) % data.users.length] : null;37 if (!creds) {38 creds = { username: `lt_${__VU}_${Math.floor(Math.random() * 1e6)}`.slice(0, 24), password: "loadtest-pass-123" };39 const r = http.post(`${BASE}/api/auth/register`, JSON.stringify({ ...creds, confirmPassword: creds.password, ageConfirmed: true }), { headers: { "Content-Type": "application/json", Origin: BASE }, tags: { name: "register" } });40 check(r, { registered: (res) => res.status === 200 });41 } else {42 const r = http.post(`${BASE}/api/auth/login`, JSON.stringify(creds), { headers: { "Content-Type": "application/json", Origin: BASE }, tags: { name: "login" } });43 check(r, { logged_in: (res) => res.status === 200 });44 }45 for (let i = 0; i < 40; i++) {46 const r = http.post(`${BASE}/api/games/neon-vault/spin`, JSON.stringify({ bet: 10, clientRoundId: uuidv4() }), { headers: { "Content-Type": "application/json", Origin: BASE }, tags: { name: "spin" } });47 check(r, { spin_ok: (res) => res.status === 200 || res.status === 402 });48 if (r.status === 402) {49 http.post(`${BASE}/api/rewards/rescue/claim`, null, { headers: { Origin: BASE }, tags: { name: "rescue" } });50 }51 sleep(0.3);52 }53 void jar;54}55