Note: The {reviewers} block is always auto-generated from your reviewer configuration. It contains each reviewer's ID, name, language, and persona. You just need to place it where you want it in the template.
⏱
Cron Management
CLI commands for the queue processor
Enable / Disable Cron
The cron runs every 5 minutes and auto-discovers new songs. Use the Dashboard tab to toggle, or via CLI:
# Pause cron (via database config)
mysql -u root logiceverything_overnormal -e "UPDATE play_review_config SET config_value='0' WHERE config_key='cron_enabled';"
# Resume cron
mysql -u root logiceverything_overnormal -e "UPDATE play_review_config SET config_value='1' WHERE config_key='cron_enabled';"
# Check current status
mysql -u root logiceverything_overnormal -e "SELECT * FROM play_review_config WHERE config_key LIKE 'cron%';"
Crontab Entry
# View current crontab
crontab -l -u logiceverything
# The entry should look like:*/5 * * * * /usr/local/bin/ea-php82 /home/logiceverything/overnormal/play/api/process-review-queue.php >> /home/logiceverything/logs/review-cron.log 2>&1
# Edit crontab
crontab -e -u logiceverything
Manual Cron Run
# Run the queue processor manually
/usr/local/bin/ea-php82 /home/logiceverything/overnormal/play/api/process-review-queue.php
# Check cron log
tail -30 /home/logiceverything/logs/review-cron.log
# Generate (fails if already has reviews)
curl -X POST https://overnormal.com/play/api/admin/force-generate-reviews.php \
-H "Content-Type: application/json" \
-d '{"song_id":"SONG_UUID","regenerate":false}'
# Regenerate (delete existing + create new)
curl -X POST https://overnormal.com/play/api/admin/force-generate-reviews.php \
-H "Content-Type: application/json" \
-d '{"song_id":"SONG_UUID","regenerate":true}'
Batch Generate
# Generate for songs missing reviews only
curl -X POST https://overnormal.com/play/api/admin/batch-force-generate.php \
-H "Content-Type: application/json" \
-d '{"filter":"missing_only","regenerate":false}'
# Regenerate all songs
curl -X POST https://overnormal.com/play/api/admin/batch-force-generate.php \
-H "Content-Type: application/json" \
-d '{"filter":"all","regenerate":true}'
Queue Management
# List queue (status: all|pending|completed|failed)
curl "https://overnormal.com/play/api/admin/review-queue.php?status=pending&page=1&limit=20"
# Add to queue
curl -X POST https://overnormal.com/play/api/admin/review-queue.php \
-H "Content-Type: application/json" \
-d '{"action":"queue","song_id":"SONG_UUID","priority":1}'
# Retry failed
curl -X POST https://overnormal.com/play/api/admin/review-queue.php \
-H "Content-Type: application/json" \
-d '{"action":"retry","song_id":"SONG_UUID"}'
# Cancel pending/failed
curl -X POST https://overnormal.com/play/api/admin/review-queue.php \
-H "Content-Type: application/json" \
-d '{"action":"cancel","song_id":"SONG_UUID"}'
Config
# Get config + status
curl "https://overnormal.com/play/api/admin/review-config.php"
# Update config
curl -X POST https://overnormal.com/play/api/admin/review-config.php \
-H "Content-Type: application/json" \
-d '{"ai_model":"gpt-4o-mini","ai_temperature":"0.85"}'
🗄
Database Queries
Useful SQL for troubleshooting
-- Connect
mysql -u root logiceverything_overnormal
-- Count AI comments per song
SELECT song_id, COUNT(*) as cnt FROM play_ai_comments GROUP BY song_id ORDER BY cnt DESC;
-- View comments for a specific song
SELECT name, language, LEFT(text, 80) as preview FROM play_ai_comments WHERE song_id='SONG_UUID';
-- Songs without any AI reviews
SELECT s.id, s.title FROM play_songs s
LEFT JOIN play_review_history h ON h.song_id = s.id
WHERE h.song_id IS NULL;
-- Queue status summary
SELECT status, COUNT(*) FROM play_review_queue GROUP BY status;
-- Recent failures
SELECT q.song_id, s.title, q.error_msg, q.attempts
FROM play_review_queue q JOIN play_songs s ON q.song_id = s.id
WHERE q.status = 'failed' ORDER BY q.created_at DESC LIMIT 10;
-- Delete all AI comments for a song (manual cleanup)
DELETE FROM play_ai_comments WHERE song_id='SONG_UUID';
DELETE FROM play_review_history WHERE song_id='SONG_UUID';
-- Reset entire review system (DANGER)-- TRUNCATE play_ai_comments;-- TRUNCATE play_review_history;-- TRUNCATE play_review_queue;
📁
File Paths
All AI review system files
File
Purpose
/play/comment
Public AI reviews page
/play/admin/reviews
This admin page
/play/api/_schema_reviews.sql
Database schema (5 tables)
/play/api/seed-reviewers.php
Seed 12 reviewers + config
/play/api/get-ai-comments.php
Public API: get song + AI comments
/play/api/queue-review.php
Queue helper function
/play/api/generate-ai-comments.php
Core AI generation logic
/play/api/process-review-queue.php
Cron job processor
/play/api/backfill-review-queue.php
One-time backfill script
/play/api/admin/force-generate-reviews.php
Force generate single song
/play/api/admin/batch-force-generate.php
Batch generate
/play/api/admin/review-config.php
Config + status API
/play/api/admin/review-queue.php
Queue management API
📊
Database Tables
Schema reference
Table
Purpose
play_ai_comments
AI-generated review texts (separate from play_comments)
play_review_queue
Songs awaiting AI review generation
play_review_config
Key-value config (cron settings, AI params, etc.)
play_reviewers
12 AI reviewer personalities
play_review_history
Tracks which reviewer commented on which song
Note: These tables are completely separate from the existing play_comments table (human comments). No existing tables were modified.
Check daily limit hasn't been reached (see Config tab)
Generation fails with API error
Verify OPENAI_API_KEY is set in /home/logiceverything/overnormal/.env
Check the error_msg in the Queue tab for details
Try a manual generate from the Generate tab to see the full error
OpenAI rate limits: reduce queue_batch_size in Config
Reviews not showing on comment.php
Verify the song UUID is correct in the URL
Check play_ai_comments table has rows for that song_id
Run: SELECT COUNT(*) FROM play_ai_comments WHERE song_id='UUID';
Reset a song's reviews
Use the Generate tab with "Regenerate" checked, or via CLI:
mysql -u root logiceverything_overnormal -e "
DELETE FROM play_ai_comments WHERE song_id='SONG_UUID';
DELETE FROM play_review_history WHERE song_id='SONG_UUID';
DELETE FROM play_review_queue WHERE song_id='SONG_UUID';
"