Add QR code tracker to admin panel
Each QR code gets a /qr/<slug> redirect that logs scans (IP, user agent, timestamp) to disk. The admin QR Codes view lets you add, edit, enable/disable, and delete codes, with per-code scan history inline. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import express from 'express'
|
||||
import { hasVisitorConsent } from './server/helpers.js'
|
||||
import { isValidAdminSession } from './server/auth.js'
|
||||
import { BACKUP_INTERVAL_MS } from './server/config.js'
|
||||
import { state } from './server/state.js'
|
||||
import {
|
||||
@@ -18,6 +19,7 @@ import {
|
||||
loadEpisodeScriptsFromDisk,
|
||||
migrateStudyNotesIfNeeded,
|
||||
loadDownloadCountsFromDisk,
|
||||
loadQrCodesFromDisk,
|
||||
loadPodcastChecklistFromDisk,
|
||||
createBackupSnapshot,
|
||||
refreshContentCaches,
|
||||
@@ -48,6 +50,7 @@ import { register as registerQuestions } from './server/routes/questions.js'
|
||||
import { register as registerAnalytics } from './server/routes/analytics.js'
|
||||
import { register as registerDownloads } from './server/routes/downloads.js'
|
||||
import { register as registerEpisodes } from './server/routes/episodes.js'
|
||||
import { register as registerQrCodes } from './server/routes/qr-codes.js'
|
||||
import { register as registerPublic } from './server/routes/public.js'
|
||||
|
||||
const app = express()
|
||||
@@ -70,6 +73,7 @@ registerQuestions(app)
|
||||
registerAnalytics(app)
|
||||
registerDownloads(app)
|
||||
registerEpisodes(app)
|
||||
registerQrCodes(app)
|
||||
|
||||
// Hit-counting middleware (must come before public routes)
|
||||
app.use((req, res, next) => {
|
||||
@@ -78,7 +82,7 @@ app.use((req, res, next) => {
|
||||
const botDetection = detectBot(ua)
|
||||
recordHit(req.path, botDetection.isBot, botDetection.reason)
|
||||
queueHitStatsWrite()
|
||||
if (hasVisitorConsent(req) && !botDetection.isBot) {
|
||||
if (hasVisitorConsent(req) && !botDetection.isBot && !isValidAdminSession(req)) {
|
||||
recordVisitor(req, res).catch(err => {
|
||||
console.error('[visitor-stats] failed to record visitor:', err)
|
||||
})
|
||||
@@ -107,6 +111,7 @@ Promise.all([
|
||||
loadEpisodeScriptsFromDisk(),
|
||||
migrateStudyNotesIfNeeded(),
|
||||
loadDownloadCountsFromDisk(),
|
||||
loadQrCodesFromDisk(),
|
||||
loadPodcastChecklistFromDisk(),
|
||||
refreshContentCaches(),
|
||||
])
|
||||
|
||||
Reference in New Issue
Block a user