| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| import { prisma } from '../utils/prisma.js'; |
|
|
| export const marketsRepository = { |
| findMany({ limit, offset, category, status }) { |
| const where = { status }; |
| if (category) where.category = category; |
| |
| |
| |
| return prisma.market.findMany({ |
| where, |
| orderBy: [{ liquidityEur: 'desc' }, { volumeEur: 'desc' }], |
| take: limit, |
| skip: offset, |
| }); |
| }, |
|
|
| count({ category, status }) { |
| const where = { status }; |
| if (category) where.category = category; |
| return prisma.market.count({ where }); |
| }, |
|
|
| findById(id) { |
| return prisma.market.findUnique({ where: { id } }); |
| }, |
|
|
| upsert(market) { |
| return prisma.market.upsert({ |
| where: { id: market.id }, |
| update: market, |
| create: market, |
| }); |
| }, |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| async deactivateStale(activeIds) { |
| const result = await prisma.market.updateMany({ |
| where: { |
| id: { notIn: activeIds }, |
| status: 'active', |
| }, |
| data: { status: 'closed' }, |
| }); |
| return result.count; |
| }, |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| async findDiversified(total = 40) { |
| const weights = { |
| 'cripto': 0.20, |
| 'economía': 0.18, |
| 'geopolítica': 0.18, |
| 'política': 0.14, |
| 'ciencia': 0.12, |
| 'entretenimiento': 0.08, |
| 'deportes': 0.05, |
| 'general': 0.05, |
| }; |
|
|
| const slices = await Promise.all( |
| Object.entries(weights).map(async ([category, weight]) => { |
| const take = Math.max(1, Math.round(total * weight)); |
| |
| return prisma.market.findMany({ |
| where: { status: 'active', category }, |
| orderBy: [{ liquidityEur: 'desc' }, { volumeEur: 'desc' }], |
| take, |
| }); |
| }), |
| ); |
|
|
| const picked = slices.flat(); |
| const seen = new Set(picked.map((m) => m.id)); |
|
|
| |
| if (picked.length < total) { |
| const remaining = total - picked.length; |
| const filler = await prisma.market.findMany({ |
| where: { status: 'active', id: { notIn: Array.from(seen) } }, |
| orderBy: [{ liquidityEur: 'desc' }, { volumeEur: 'desc' }], |
| take: remaining, |
| }); |
| picked.push(...filler); |
| } |
|
|
| return picked.slice(0, total); |
| }, |
| }; |
|
|