70 Commits

Author SHA1 Message Date
40c919fc64 feat: add viewer voting on user answers with leaderboard scoring
Viewers can now vote for their favourite audience answers during the
30-second voting window. Votes are persisted to the DB at round end
and aggregated as SUM(votes) in the JUGADORES leaderboard.

- db.ts: add persistUserAnswerVotes(); switch getPlayerScores() to SUM(votes)
- game.ts: add userAnswerVotes to RoundState; persist votes before saveRound
- server.ts: add userAnswerVoters map + /api/vote/respuesta endpoint
- frontend.tsx: add userAnswerVotes type; vote state/handler in App; ▲ buttons in Arena
- frontend.css: flex layout for user-answer rows; user-vote-btn styles

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-05 18:26:09 +01:00
fe5bb5a5c2 feat: admin can answer questions without paying for testing
- Server: /api/respuesta/enviar checks admin cookie; if authorized,
  bypasses credit check and stores answer via insertAdminAnswer()
- DB: insertAdminAnswer() inserts directly into user_answers with
  username='Admin', skipping the credit budget entirely
- Frontend: ProposeAnswer checks /api/admin/status on mount; if admin
  is logged in, shows the answer form directly (orange Admin badge)
  instead of the payment tier selection

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-05 18:15:46 +01:00
f9a8e2544f feat: users answer alongside AI instead of proposing questions
- Core mechanic change: users now submit answers to the live prompt,
  competing alongside AI models; answers broadcast to all viewers
- New pricing (no time limit, pure count-based, refillable):
  0,99€ = 10 resp · 9,99€ = 300 resp · 19,99€ = 1000 resp
- DB: new user_answers table; submitUserAnswer() atomically validates
  credit, inserts answer, decrements budget; JUGADORES leaderboard
  now scores by user_answers count
- server: /api/respuesta/enviar endpoint; credit activation sets
  expires_at 10 years out (effectively no expiry); answers injected
  into live round state and broadcast via WebSocket
- frontend: ProposeAnswer widget shows current prompt, textarea active
  during answering phase, tracks per-round submission state;
  Arena shows Respuestas del público section live

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-05 12:09:53 +01:00
3e5c080466 feat: embed propose-question widget inline in main game page
- Move /pregunta flow into a compact ProposeQuestion component
  rendered inside <main> above the footer
- Tier cards, username input, Redsys payment, polling, and question
  submission all work inline without leaving the game page
- Payment redirects now go to /?credito_ok=ORDER and /?ko=1
  so the game stays in view during the full payment cycle
- Badge shows live questions remaining; updates on each submission
- Removed /pregunta link from footer (functionality is now inline)
- .propose-* CSS: compact tier grid, textarea+button row, spinner

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 17:21:35 +01:00
d42e93b013 feat: question-count tiers, footer in main, pregunta footer
- Pricing: 0,99€/10q · 9,99€/200q · 19,99€/unlimited (all 30 days)
- DB: max_questions + questions_used columns on credits table;
  consumeCreditQuestion() atomically validates, creates question,
  and decrements quota in a single transaction
- Server: updated CREDIT_TIERS, /api/credito/estado returns questionsLeft,
  /api/pregunta/enviar returns updated questionsLeft after each submission
- pregunta.tsx: badge shows live question count; submit disabled when exhausted;
  questionsLeft synced to localStorage after each submission; Cloud Host footer added
- footer: moved from Standings sidebar into <main> (scrolls with game content);
  also added to all pregunta page states

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 17:13:02 +01:00
e772fb5cc0 feat: time-based credits, JUGADORES leaderboard, fix footer visibility
- Credits system: 1€/day, 5€/week, 15€/month time-based access via Redsys
  - credits table with token, tier, expires_at, status lifecycle
  - /api/credito/iniciar, /api/credito/estado, /api/pregunta/enviar endpoints
  - Polling-based token delivery to browser after Redsys URLOK redirect
  - localStorage token storage with expiry check on load
- JUGADORES leaderboard: top 7 players by questions used, polled every 60s
  - /api/jugadores endpoint, PlayerLeaderboard component in Standings sidebar
- Footer: moved into Standings sidebar (.standings__footer) so it's always visible
- pregunta.tsx: complete redesign with tier cards, credit badge, spinner, success state
- pregunta.css: new styles for tier cards, input, badge, spinner, success, link-btn

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 14:43:25 +01:00
2fac92356d feat: footer, auto-pause on no viewers, and Redsys question submissions
- Footer: add site-footer with one-liner + Cloud Host branding linking to cloudhost.es (mobile only, hidden on desktop)
- Auto-pause: game pauses automatically after AUTOPAUSE_DELAY_MS (default 60s) with no viewers connected; auto-resumes when first viewer connects; shows "Esperando espectadores…" in the UI
- Redsys: new /pregunta page lets viewers pay 1€ via Redsys to submit a fill-in question; submitted questions are used as prompts in the next round instead of AI generation; new redsys.ts implements HMAC_SHA256_V1 signing (3DES key derivation + HMAC-SHA256); notification endpoint at /api/redsys/notificacion handles server-to-server confirmation
- db.ts: questions table with createPendingQuestion / markQuestionPaid / getNextPendingQuestion / markQuestionUsed
- .env.sample: added AUTOPAUSE_DELAY_MS, PUBLIC_URL, REDSYS_* vars

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 14:03:30 +01:00
4b0b9f8f50 chore: remove all Twitch/streaming references
- Remove Twitch link from standings sidebar
- Delete scripts/stream-browser.ts (Twitch streaming script)
- Remove start:stream and start:stream:dryrun npm scripts
- Fix quipslop-export filename fallback in admin.tsx
- Fix hardcoded quipslop.sqlite in check-db.ts
- Rewrite README.md in Spanish, no Twitch mentions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 13:30:58 +01:00
2abea42c18 feat: convert to argument.es — Spanish, vote buttons, Docker
- Translate all ~430 prompts to Spanish with cultural adaptations
- Translate all UI strings (frontend, admin, history, broadcast)
- Translate AI system prompts; models now respond in Spanish
- Replace Twitch/Fossabot viewer voting with in-site vote buttons
- Add POST /api/vote endpoint (IP-based, supports vote switching)
- Vote buttons appear during voting phase with active state highlight
- Rename project to argument.es throughout (package.json, cookie, DB)
- Add docker-compose.yml with SQLite volume mount
- Add .env.sample documenting all required and optional vars

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 13:09:00 +01:00
Theo Browne
ccaa86b4a6 send on transitions 2026-02-22 21:50:01 -08:00
Theo Browne
79f9dab7fb new layout for model rankings 2026-02-22 18:44:49 -08:00
Theo Browne
f33277a095 update way faster 2026-02-22 18:32:51 -08:00
Theo Browne
af2f055939 dedupe 2026-02-22 18:28:36 -08:00
Theo Browne
41deee807a fossabot setup 2026-02-22 18:25:15 -08:00
Theo Browne
8f52bee72b Merge pull request #34 from matteomekhail/anti-spoof-thing
Anti spoof thing
2026-02-22 18:16:40 -08:00
Matteo Mekhail
8489927b67 normalize socket IP format 2026-02-23 13:12:42 +11:00
Matteo Mekhail
0295041cda add support for railway internal proxy 2026-02-23 13:10:25 +11:00
Theo Browne
eda80110c6 Merge pull request #31 from matteomekhail/anti-spoof-thing
This should fix the vuln from that script
2026-02-22 18:05:44 -08:00
Matteo Mekhail
0dcb6f71ab Suggestion from coderabbit and macros, both valid 2026-02-23 13:04:06 +11:00
Matteo Mekhail
ba543c1f25 This should fix the vuln from that script 2026-02-23 12:57:13 +11:00
Theo Browne
d80c40ed3f ui fixes 2026-02-22 17:52:37 -08:00
Theo Browne
6e98a183ac ip specific votes + ui fixes 2026-02-22 17:45:08 -08:00
Theo Browne
1a5c8354a0 Merge pull request #28 from matteomekhail/feature/x-real-ip
Anti-spoofing system, fixes the counter viewer
2026-02-22 17:35:29 -08:00
Theo Browne
e7d1cb3bf7 Vote fixing 2026-02-22 17:33:52 -08:00
Matteo Mekhail
0b03c7c55c Anti-spoofing system, fixes the counter viewer 2026-02-23 12:29:57 +11:00
Theo Browne
845065ac8f voting why not lol 2026-02-22 17:22:59 -08:00
Theo Browne
fb24f6e198 todos 2026-02-22 17:06:08 -08:00
Theo Browne
f859c73662 Throttle more 2026-02-22 17:05:59 -08:00
Theo Browne
b2b5a0bdf5 fix outputs 2026-02-22 16:54:05 -08:00
Theo Browne
7629a56889 fix stream 2026-02-22 16:47:47 -08:00
Theo Browne
4d56f95f9f bug fixes 2026-02-22 16:40:30 -08:00
Theo Browne
9763cdf0de Throttle view count updates 2026-02-22 16:35:20 -08:00
Theo Browne
797d05345a fix ips 2026-02-22 16:30:41 -08:00
Theo Browne
c01f3ff076 cleanup events + limits + more logs 2026-02-22 16:23:46 -08:00
Theo Browne
43003a5b01 no more view count on broadcast 2026-02-22 16:05:08 -08:00
Theo Browne
9ea6c68edd remove links 2026-02-22 16:02:56 -08:00
Theo Browne
20bdc7b771 Merge pull request #1 from mantrakp04/patch-1
Update wording from 'Built' to 'Streamed'
2026-02-22 16:00:44 -08:00
Mantra
ff0cba62e5 Update wording from 'Built' to 'Streamed' 2026-02-22 15:59:49 -08:00
Theo Browne
d44c6806ac license and readme 2026-02-22 15:58:49 -08:00
Theo Browne
5fbdee5ecc reasoning 2026-02-22 05:23:46 -08:00
Theo Browne
54c45f6028 reset fix 2026-02-22 04:32:41 -08:00
Theo Browne
deeeeae8f7 auto refresh 2026-02-22 03:12:44 -08:00
Theo Browne
a7b2a24f02 fix layout a bit 2026-02-22 03:09:01 -08:00
Theo Browne
c1d817b271 changes 2026-02-22 03:03:43 -08:00
Theo Browne
8d2aa7e7d6 Fix loading states 2026-02-22 03:00:37 -08:00
Theo Browne
4fe8432a16 broadcast 2026-02-22 02:15:29 -08:00
Theo Browne
dc9ac4e7c8 admin and higher limits 2026-02-22 01:20:19 -08:00
Theo Browne
4786fcfedb fix layout a bit 2026-02-22 00:25:50 -08:00
Theo Browne
ea9d844f4b rename 2026-02-22 00:23:35 -08:00
Theo Browne
a25097cd4a hardened 2026-02-22 00:22:42 -08:00