pretty much ready to 'ship'

This commit is contained in:
cottongin
2025-10-30 17:18:30 -04:00
parent 7bb3aabd72
commit 8f3a12ad76
10 changed files with 518 additions and 190 deletions

View File

@@ -1,9 +1,18 @@
const express = require('express');
const crypto = require('crypto');
const { authenticateToken } = require('../middleware/auth');
const db = require('../database');
const router = express.Router();
// Helper function to create a hash of a message
function createMessageHash(username, message, timestamp) {
return crypto
.createHash('sha256')
.update(`${username}:${message}:${timestamp}`)
.digest('hex');
}
// Get all sessions
router.get('/', (req, res) => {
try {
@@ -175,7 +184,9 @@ router.get('/:id/games', (req, res) => {
g.game_type,
g.min_players,
g.max_players,
g.popularity_score
g.popularity_score,
g.upvotes,
g.downvotes
FROM session_games sg
JOIN games g ON sg.game_id = g.id
WHERE sg.session_id = ?
@@ -270,7 +281,7 @@ router.post('/:id/chat-import', authenticateToken, (req, res) => {
// Get all games played in this session with timestamps
const sessionGames = db.prepare(`
SELECT sg.game_id, sg.played_at, g.title
SELECT sg.game_id, sg.played_at, g.title, g.upvotes, g.downvotes
FROM session_games sg
JOIN games g ON sg.game_id = g.id
WHERE sg.session_id = ?
@@ -282,15 +293,26 @@ router.post('/:id/chat-import', authenticateToken, (req, res) => {
}
let votesProcessed = 0;
let duplicatesSkipped = 0;
const votesByGame = {};
const sessionId = parseInt(req.params.id);
const voteMatches = []; // Debug: track which votes matched to which games
const insertChatLog = db.prepare(`
INSERT INTO chat_logs (session_id, chatter_name, message, timestamp, parsed_vote)
VALUES (?, ?, ?, ?, ?)
INSERT INTO chat_logs (session_id, chatter_name, message, timestamp, parsed_vote, message_hash)
VALUES (?, ?, ?, ?, ?, ?)
`);
const updatePopularity = db.prepare(`
UPDATE games SET popularity_score = popularity_score + ? WHERE id = ?
const checkDuplicate = db.prepare(`
SELECT id FROM chat_logs WHERE message_hash = ? LIMIT 1
`);
const updateUpvote = db.prepare(`
UPDATE games SET upvotes = upvotes + 1, popularity_score = popularity_score + 1 WHERE id = ?
`);
const updateDownvote = db.prepare(`
UPDATE games SET downvotes = downvotes + 1, popularity_score = popularity_score - 1 WHERE id = ?
`);
const processVotes = db.transaction((messages) => {
@@ -301,6 +323,16 @@ router.post('/:id/chat-import', authenticateToken, (req, res) => {
continue;
}
// Create hash for this message
const messageHash = createMessageHash(username, message, timestamp);
// Check if we've already imported this exact message
const existing = checkDuplicate.get(messageHash);
if (existing) {
duplicatesSkipped++;
continue; // Skip this duplicate message
}
// Check for vote patterns
let vote = null;
if (message.includes('thisgame++')) {
@@ -309,13 +341,14 @@ router.post('/:id/chat-import', authenticateToken, (req, res) => {
vote = 'thisgame--';
}
// Insert into chat logs
// Insert into chat logs with hash
insertChatLog.run(
req.params.id,
sessionId,
username,
message,
timestamp,
vote
vote,
messageHash
);
if (vote) {
@@ -345,8 +378,24 @@ router.post('/:id/chat-import', authenticateToken, (req, res) => {
}
if (matchedGame) {
const points = vote === 'thisgame++' ? 1 : -1;
updatePopularity.run(points, matchedGame.game_id);
const isUpvote = vote === 'thisgame++';
// Debug: track this vote match
voteMatches.push({
username: username,
vote: vote,
timestamp: timestamp,
timestamp_ms: messageTime,
matched_game: matchedGame.title,
game_played_at: matchedGame.played_at,
game_played_at_ms: new Date(matchedGame.played_at).getTime()
});
if (isUpvote) {
updateUpvote.run(matchedGame.game_id);
} else {
updateDownvote.run(matchedGame.game_id);
}
if (!votesByGame[matchedGame.game_id]) {
votesByGame[matchedGame.game_id] = {
@@ -356,7 +405,7 @@ router.post('/:id/chat-import', authenticateToken, (req, res) => {
};
}
if (points > 0) {
if (isUpvote) {
votesByGame[matchedGame.game_id].upvotes++;
} else {
votesByGame[matchedGame.game_id].downvotes++;
@@ -373,8 +422,17 @@ router.post('/:id/chat-import', authenticateToken, (req, res) => {
res.json({
message: 'Chat log imported and processed successfully',
messagesImported: chatData.length,
duplicatesSkipped,
votesProcessed,
votesByGame
votesByGame,
debug: {
sessionGamesTimeline: sessionGames.map(sg => ({
title: sg.title,
played_at: sg.played_at,
played_at_ms: new Date(sg.played_at).getTime()
})),
voteMatches: voteMatches
}
});
} catch (error) {
res.status(500).json({ error: error.message });

View File

@@ -14,14 +14,14 @@ router.get('/', (req, res) => {
activeSessions: db.prepare('SELECT COUNT(*) as count FROM sessions WHERE is_active = 1').get(),
totalGamesPlayed: db.prepare('SELECT COUNT(*) as count FROM session_games').get(),
mostPlayedGames: db.prepare(`
SELECT g.id, g.title, g.pack_name, g.play_count, g.popularity_score
SELECT g.id, g.title, g.pack_name, g.play_count, g.popularity_score, g.upvotes, g.downvotes
FROM games g
WHERE g.play_count > 0
ORDER BY g.play_count DESC
LIMIT 10
`).all(),
topRatedGames: db.prepare(`
SELECT g.id, g.title, g.pack_name, g.play_count, g.popularity_score
SELECT g.id, g.title, g.pack_name, g.play_count, g.popularity_score, g.upvotes, g.downvotes
FROM games g
WHERE g.popularity_score > 0
ORDER BY g.popularity_score DESC