From b21d166bba889cda2d073a2fdbbe065deba51559 Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Thu, 5 Mar 2026 22:57:25 +0000 Subject: [PATCH] 1 --- .../seeders/future-placeholder-generator.js | 49 ++++++++++++++++ backend/src/db/seeders/placeholder-seeder.js | 31 ++++++++++ backend/src/index.js | 1 + backend/src/routes/lottery_ai.js | 23 ++++++++ backend/src/services/predictionService.js | 26 +++++++++ frontend/src/stores/styleSlice.ts | 46 +++++++-------- frontend/src/styles.ts | 56 +++++++++---------- 7 files changed, 178 insertions(+), 54 deletions(-) create mode 100644 backend/src/db/seeders/future-placeholder-generator.js create mode 100644 backend/src/db/seeders/placeholder-seeder.js create mode 100644 backend/src/routes/lottery_ai.js create mode 100644 backend/src/services/predictionService.js diff --git a/backend/src/db/seeders/future-placeholder-generator.js b/backend/src/db/seeders/future-placeholder-generator.js new file mode 100644 index 0000000..29f9d60 --- /dev/null +++ b/backend/src/db/seeders/future-placeholder-generator.js @@ -0,0 +1,49 @@ +require('dotenv').config(); +const db = require('../models'); +const Draws = db.draws; +const LotteryGames = db.lottery_games; + +async function generateFuturePlaceholders() { + console.log('Generating future placeholders for all active games...'); + const games = await LotteryGames.findAll({ where: { status: 'active' } }); + + for (const game of games) { + // Find last draw number + const lastDraw = await Draws.findOne({ + where: { gameId: game.id }, + order: [['draw_number', 'DESC']] + }); + + let currentDraw = lastDraw ? lastDraw.draw_number + 1 : 1; + const target = game.future_draws_target || 9999; + + console.log(`Game: ${game.name}, last: ${lastDraw ? lastDraw.draw_number : 'none'}, target: ${target}`); + + const placeholders = []; + while (currentDraw <= target) { + placeholders.push({ + gameId: game.id, + draw_number: currentDraw, + status: 'placeholder', + is_verified: false, + admin_notes: 'Automatically generated future placeholder' + }); + currentDraw++; + + if (placeholders.length >= 500) { + await Draws.bulkCreate(placeholders, { ignoreDuplicates: true }); + placeholders.length = 0; + } + } + + if (placeholders.length > 0) { + await Draws.bulkCreate(placeholders, { ignoreDuplicates: true }); + } + } + console.log('Finished.'); +} + +generateFuturePlaceholders().then(() => process.exit(0)).catch(err => { + console.error(err); + process.exit(1); +}); diff --git a/backend/src/db/seeders/placeholder-seeder.js b/backend/src/db/seeders/placeholder-seeder.js new file mode 100644 index 0000000..aa056dd --- /dev/null +++ b/backend/src/db/seeders/placeholder-seeder.js @@ -0,0 +1,31 @@ +const db = require('../models'); +const Draws = db.draws; +const LotteryGames = db.lottery_games; + +async function seedFuturePlaceholders() { + const game = await LotteryGames.findOne({ where: { slug: 'mega-sena' } }); + if (!game) return; + + const lastDraw = await Draws.findOne({ + where: { gameId: game.id }, + order: [['draw_number', 'DESC']] + }); + + let currentDraw = lastDraw ? lastDraw.draw_number + 1 : 1; + const placeholders = []; + + while (currentDraw <= 9999) { + placeholders.push({ + gameId: game.id, + draw_number: currentDraw, + status: 'placeholder', + is_verified: false, + admin_notes: 'Future placeholder' + }); + currentDraw++; + } + + await Draws.bulkCreate(placeholders); +} + +seedFuturePlaceholders().catch(console.error); diff --git a/backend/src/index.js b/backend/src/index.js index 30bc44a..f791edf 100644 --- a/backend/src/index.js +++ b/backend/src/index.js @@ -18,6 +18,7 @@ const sqlRoutes = require('./routes/sql'); const pexelsRoutes = require('./routes/pexels'); const openaiRoutes = require('./routes/openai'); +const lotteryAiRoutes = require('./routes/lottery_ai'); diff --git a/backend/src/routes/lottery_ai.js b/backend/src/routes/lottery_ai.js new file mode 100644 index 0000000..4ca4035 --- /dev/null +++ b/backend/src/routes/lottery_ai.js @@ -0,0 +1,23 @@ +const express = require('express'); +const wrapAsync = require('../helpers').wrapAsync; +const predictionService = require('../services/predictionService'); +const { draws, lottery_games } = require('../db/models'); + +const router = express.Router(); + +router.post('/generate-prediction', wrapAsync(async (req, res) => { + const { gameId } = req.body; + const game = await lottery_games.findByPk(gameId); + if (!game) return res.status(404).send({ success: false, error: 'Game not found' }); + + const history = await draws.findAll({ + where: { gameId, status: 'completed' }, + order: [['draw_number', 'DESC']], + limit: 20 + }); + + const prediction = await predictionService.predictNextDraw(game, history); + res.status(200).send({ success: true, prediction }); +})); + +module.exports = router; \ No newline at end of file diff --git a/backend/src/services/predictionService.js b/backend/src/services/predictionService.js new file mode 100644 index 0000000..8825673 --- /dev/null +++ b/backend/src/services/predictionService.js @@ -0,0 +1,26 @@ +const { LocalAIApi } = require('../ai/LocalAIApi'); + +class PredictionService { + async predictNextDraw(game, history) { + // Prepare numbers string for the AI + const drawHistory = history.map(d => d.winning_numbers).join(', '); + const prompt = `As an expert in statistical analysis for lottery systems, analyze the following sequence of recent winning numbers for the ${game.name} lottery: +[${drawHistory}] + +Based on these patterns, generate a statistically plausible set of ${game.numbers_per_ticket} numbers for the next draw. + +IMPORTANT: Only return the numbers separated by commas, no other text.`; + + const response = await LocalAIApi.createResponse( + { input: [{ role: 'user', content: prompt }] }, + { poll_interval: 5, poll_timeout: 300 } + ); + + if (response.success) { + return LocalAIApi.extractText(response); + } + throw new Error('AI prediction failed'); + } +} + +module.exports = new PredictionService(); \ No newline at end of file diff --git a/frontend/src/stores/styleSlice.ts b/frontend/src/stores/styleSlice.ts index e786387..254451f 100644 --- a/frontend/src/stores/styleSlice.ts +++ b/frontend/src/stores/styleSlice.ts @@ -32,30 +32,30 @@ interface StyleState { const initialState: StyleState = { - asideStyle: styles.midnightBlueTheme.aside, - asideScrollbarsStyle: styles.white.asideScrollbars, - asideBrandStyle: styles.white.asideBrand, - asideMenuItemStyle: styles.midnightBlueTheme.asideMenuItem, - asideMenuItemActiveStyle: styles.midnightBlueTheme.asideMenuItemActive, - activeLinkColor: styles.midnightBlueTheme.activeLinkColor, - asideMenuDropdownStyle: styles.white.asideMenuDropdown, - navBarItemLabelStyle: styles.midnightBlueTheme.navBarItemLabel, - navBarItemLabelHoverStyle: styles.midnightBlueTheme.navBarItemLabelHover, - navBarItemLabelActiveColorStyle: styles.midnightBlueTheme.navBarItemLabelActiveColor, - overlayStyle: styles.midnightBlueTheme.overlay, + asideStyle: styles.lotteryTheme.aside, + asideScrollbarsStyle: styles.lotteryTheme.asideScrollbars, + asideBrandStyle: styles.lotteryTheme.asideBrand, + asideMenuItemStyle: styles.lotteryTheme.asideMenuItem, + asideMenuItemActiveStyle: styles.lotteryTheme.asideMenuItemActive, + activeLinkColor: styles.lotteryTheme.activeLinkColor, + asideMenuDropdownStyle: styles.lotteryTheme.asideMenuDropdown, + navBarItemLabelStyle: styles.lotteryTheme.navBarItemLabel, + navBarItemLabelHoverStyle: styles.lotteryTheme.navBarItemLabelHover, + navBarItemLabelActiveColorStyle: styles.lotteryTheme.navBarItemLabelActiveColor, + overlayStyle: styles.lotteryTheme.overlay, darkMode: false, - bgLayoutColor: styles.midnightBlueTheme.bgLayoutColor, - iconsColor: styles.midnightBlueTheme.iconsColor, - cardsColor: styles.midnightBlueTheme.cardsColor, - focusRingColor: styles.midnightBlueTheme.focusRingColor, - corners: styles.midnightBlueTheme.corners, - cardsStyle: styles.midnightBlueTheme.cardsStyle, - linkColor: styles.midnightBlueTheme.linkColor, - websiteHeder: styles.midnightBlueTheme.websiteHeder, - borders: styles.midnightBlueTheme.borders, - shadow: styles.midnightBlueTheme.shadow, - websiteSectionStyle: styles.midnightBlueTheme.websiteSectionStyle, - textSecondary: styles.midnightBlueTheme.textSecondary, + bgLayoutColor: styles.lotteryTheme.bgLayoutColor, + iconsColor: styles.lotteryTheme.iconsColor, + cardsColor: styles.lotteryTheme.cardsColor, + focusRingColor: styles.lotteryTheme.focusRingColor, + corners: styles.lotteryTheme.corners, + cardsStyle: styles.lotteryTheme.cardsStyle, + linkColor: styles.lotteryTheme.linkColor, + websiteHeder: styles.lotteryTheme.websiteHeder, + borders: styles.lotteryTheme.borders, + shadow: styles.lotteryTheme.shadow, + websiteSectionStyle: styles.lotteryTheme.websiteSectionStyle, + textSecondary: styles.lotteryTheme.textSecondary, }; diff --git a/frontend/src/styles.ts b/frontend/src/styles.ts index 8eecb3a..0a8fe45 100644 --- a/frontend/src/styles.ts +++ b/frontend/src/styles.ts @@ -49,39 +49,33 @@ export const white: StyleObject = { websiteSectionStyle: '', textSecondary: 'text-gray-500', } - - -export const midnightBlueTheme: StyleObject = { - aside: 'bg-midnightBlueTheme-800 text-midnightBlueTheme-text dark:text-white lg:rounded-lg', - asideScrollbars: 'aside-scrollbars-blue', - asideBrand: 'text-blue-500 bg-white', - asideMenuItem: - 'text-midnightBlueTheme-text hover:text-white dark:text-dark-500 dark:hover:text-white dark:hover:bg-dark-800 dark:text-white', - asideMenuItemActive: 'font-bold text-white dark:text-white', - activeLinkColor: 'bg-midnightBlueTheme-buttonColor rounded-lg', - asideMenuDropdown: 'bg-blue-700/50', - navBarItemLabel: 'text-primaryText', - iconsColor: 'text-midnightBlueTheme-iconsColor dark:text-blue-500', - navBarItemLabelHover: 'hover:text-stone-400', - navBarItemLabelActiveColor: 'text-midnightBlueTheme-800', - overlay: 'bg-midnightBlueTheme-mainBG', - bgLayoutColor: 'bg-midnightBlueTheme-mainBG', - cardsColor: 'bg-midnightBlueTheme-cardColor', - focusRingColor: - 'focus:ring focus:ring-midnightBlueTheme-800 focus:border-midnightBlueTheme-800 focus:outline-none border border-gray-600 dark:focus:ring-blue-600 dark:focus:border-blue-600', - corners: 'rounded-lg', - cardsStyle: 'bg-midnightBlueTheme-outsideCardColor border border-midnightBlueTheme-outsideCardColor shadow-xl', - linkColor: 'text-midnightBlueTheme-buttonColor', - websiteHeder: 'border-b border-white border-opacity-10 shadow-md', - borders: 'border-white border-opacity-10', - shadow: 'shadow-md', - websiteSectionStyle: ' bg-midnightBlueTheme-webSiteComponentBg text-white', - textSecondary: 'text-gray-300', +export const lotteryTheme: StyleObject = { + aside: 'bg-gray-900 text-white', + asideScrollbars: 'aside-scrollbars-gray', + asideBrand: 'bg-emerald-800 text-white', + asideMenuItem: 'text-emerald-100 hover:bg-emerald-900', + asideMenuItemActive: 'font-bold text-white bg-emerald-700', + asideMenuDropdown: 'bg-gray-800', + navBarItemLabel: 'text-white', + navBarItemLabelHover: 'hover:text-emerald-400', + navBarItemLabelActiveColor: 'text-emerald-400', + overlay: 'bg-gray-950', + activeLinkColor: 'bg-emerald-800', + bgLayoutColor: 'bg-gray-100', + iconsColor: 'text-emerald-500', + cardsColor: 'bg-white', + focusRingColor: 'focus:ring focus:ring-emerald-600 focus:border-emerald-600', + corners: 'rounded-md', + cardsStyle: 'bg-white border border-gray-200 shadow-sm', + linkColor: 'text-emerald-700', + websiteHeder: 'bg-white border-b border-gray-200', + borders: 'border-gray-200', + shadow: 'shadow-md', + websiteSectionStyle: 'bg-white', + textSecondary: 'text-gray-600', }; - - export const dataGridStyles = { '& .MuiDataGrid-cell': { paddingX: 3, @@ -132,4 +126,4 @@ export const basic: StyleObject = { shadow: '', websiteSectionStyle: '', textSecondary: '', -} +} \ No newline at end of file