Files
sentry-toolkit/app/controllers/replays_controller.ts
2025-05-22 16:25:51 -04:00

122 lines
3.2 KiB
TypeScript

import Replay from '#models/replay'
import env from '#start/env'
import type { HttpContext } from '@adonisjs/core/http'
const SENTRY_ORG = env.get('SENTRY_ORG')
import redis from '@adonisjs/redis/services/main'
import { fetchBatch } from '../Helpers/Replays.js'
import { sendDataToWebhook } from '../Helpers/Webhook.js'
export default class ReplaysController {
public async stats({ request, response }: HttpContext) {
const { sendToWebhook } = request.qs()
const latestVersion = await redis.get(`replays:stats:latest_version`)
let results
if (!latestVersion) {
console.log('Cache miss')
results = await Replay.updateReplayStats()
} else {
console.log('cache hit')
let data = await redis.get(`replays:stats:version:${latestVersion}:results`)
if (data) {
results = JSON.parse(data)
}
}
let responseData = {
version: results.version,
updatedAt: results.updatedAt,
numberOfRecords: results.rows.length,
data: results.rows,
}
if (sendToWebhook) {
await sendDataToWebhook(responseData)
}
return response.json(responseData)
}
public async list({ request, inertia }: HttpContext) {
const page = request.input('page', 1)
const perPage = 20
const cacheKey = `replays:page:${page}`
let data = await redis.get(cacheKey)
let paginated, meta, replays
if (data) {
;({ paginated, meta, replays } = JSON.parse(data))
} else {
paginated = await Replay.query().paginate(page, perPage)
paginated.baseUrl('/list')
const json = paginated.toJSON()
meta = {
...json.meta,
links: buildPaginationLinks(json.meta),
}
replays = json.data
await redis.set(cacheKey, JSON.stringify({ paginated, meta, replays }), 'EX', 60)
}
return inertia.render('Replays/Index', {
data: {
replays,
meta,
},
})
}
async index({ request, response }: HttpContext) {
const { statsPeriod, start, end } = request.qs()
let queryString: string = '?statsPeriod=24h' // Default in case none is provided
if (statsPeriod) {
queryString = `?statsPeriod=${statsPeriod}`
} else if (start && end) {
queryString = `?start=${start}&end=${end}`
}
const queryFilter = env.get('QUERY_FILTER')
await fetchBatch(
`https://sentry.io/api/0/organizations/${SENTRY_ORG}/replays/${queryString}&field=id&field=user&field=duration&field=started_at&field=finished_at&query=${encodeURIComponent(queryFilter)}`
)
let queryResults = await Replay.updateReplayStats()
return response.json({ version: queryResults.latestVersion, ...queryResults })
}
}
function buildPaginationLinks(meta: {
previousPageUrl: string
lastPage: number
currentPage: number
nextPageUrl: string
}) {
const links = []
// Previous
links.push({
url: meta.previousPageUrl,
label: '« Prev',
active: false,
})
for (let page = 1; page <= meta.lastPage; page++) {
links.push({
url: `/list?page=${page}`,
label: page.toString(),
active: page === meta.currentPage,
})
}
// Next
links.push({
url: meta.nextPageUrl,
label: 'Next &raquo;',
active: false,
})
return links
}