This guide explains how Sybgo generates weekly reports, calculates trends, and delivers email digests.
Monday-Sunday: Collect Events
↓
Sunday 23:55: Freeze Report
↓
Calculate Trends & Summary
↓
Monday 00:05: Send Email
↓
Monday 00:06: New Week Starts
Every report progresses through three states:
- When: Monday 00:06 - Sunday 23:55
- Status:
active - Events: New events have
report_id = NULL(unassigned) - Behavior: Collecting events throughout the week
- When: Sunday 23:55
- Status:
frozen - Events: All unassigned events get assigned to this report
- Summary: Trends and statistics calculated
- Next: Ready for email delivery
- When: Monday 00:05
- Status:
emailed - Delivery: Email sent to all configured recipients
- Archive: Stored for 1 year for reference
Every Sunday at 23:55, the freeze process runs automatically:
SELECT * FROM wp_sybgo_events
WHERE report_id IS NULL
ORDER BY created_at ASC;$totals = [
'post_published' => 12,
'post_edited' => 45,
'user_registered' => 3,
'comment_posted' => 28,
// ... all enabled event types
];Compare current week to previous week:
$trends = [
'post_published' => [
'current' => 12,
'previous' => 10,
'change_percent' => 20.0,
'direction' => 'up'
],
'user_registered' => [
'current' => 3,
'previous' => 5,
'change_percent' => -40.0,
'direction' => 'down'
]
];Automatically create human-readable highlights:
- "12 new posts published ↑ 20%"
- "WordPress updated to 6.5"
- "3 new users registered ↓ 40%"
If an Anthropic API key is configured in settings, an AI-generated summary is also produced via the Claude API and stored in summary_data.ai_summary.
UPDATE wp_sybgo_events
SET report_id = 123
WHERE report_id IS NULL;{
"id": 123,
"status": "frozen",
"period_start": "2026-02-10 00:00:00",
"period_end": "2026-02-16 23:59:59",
"event_count": 88,
"summary_data": {
"total_events": 88,
"totals": { ... },
"trends": { ... },
"highlights": [ ... ],
"top_authors": [ ... ],
"ai_summary": "A busy week with 12 new posts..."
}
}Monday at 00:05, the email delivery process runs:
SELECT * FROM wp_sybgo_reports
WHERE status = 'frozen'
ORDER BY period_end DESC
LIMIT 1;From Settings → Sybgo → Email Recipients:
admin@example.com
editor@example.com
Using the email template:
- Header with date range
- Highlights section (bulleted list)
- Statistics cards (total posts, users, comments)
- Link to view full report in admin
wp_mail(
'admin@example.com',
'Your Weekly Digest - Feb 10-16',
$html_content,
['Content-Type: text/html; charset=UTF-8']
);INSERT INTO wp_sybgo_email_log (
report_id,
recipient_email,
status,
sent_at
) VALUES (123, 'admin@example.com', 'sent', NOW());UPDATE wp_sybgo_reports
SET status = 'emailed', emailed_at = NOW()
WHERE id = 123;Trends show week-over-week changes with percentage and direction.
change_percent = ((current - previous) / previous) * 100
- ↑ up: Current week > previous week
- ↓ down: Current week < previous week
- → same: Current week = previous week
Scenario 1: Growth
- Previous week: 10 posts
- Current week: 12 posts
- Change: +20%
- Display: "12 new posts published ↑ 20%"
Scenario 2: Decline
- Previous week: 5 users
- Current week: 3 users
- Change: -40%
- Display: "3 new users registered ↓ 40%"
Scenario 3: No Previous Data
- Previous week: No report exists
- Current week: 15 comments
- Change: N/A
- Display: "15 new comments"
You can manually trigger a freeze at any time from the Reports admin page (Sybgo Reports in the WP admin menu).
The active report always appears as the first row in the reports table, showing the current period start date, a live event count, and a "Freeze & Send Now" action button. Clicking the button opens a confirmation modal before submitting. The form posts to admin-post.php with action sybgo_freeze_now (handled by Reports_Page::handle_manual_freeze()).
This will:
- End the current week early
- Freeze report with current events
- Send email immediately
- Create new active report
Use cases:
- Testing email template
- Sending mid-week updates
- Demonstrating to stakeholders
If email delivery failed or you need to send to additional recipients:
Admin UI: Sybgo Reports → "Resend Email" button on any frozen or emailed report row.
Admin UI: Sybgo Reports (top-level admin menu)
The table shows the active (ongoing) report first, followed by all frozen/emailed reports in reverse chronological order:
- Date range (active row shows "Now" as end date)
- Live or frozen event count
- Status badge (Active, Frozen, Sent)
- Actions (Freeze & Send Now for active row; View Details and Resend Email for past rows)
Clicking View Details on the active report row opens the report details page. Because the active report has no frozen summary_data yet, Sybgo generates a live summary on the fly:
- Fetches all unassigned events (
report_id IS NULL). - Calls
Report_Generator::generate_live_summary(), which runs the same computation pipeline as the freeze process (totals → trends → highlights → top_authors) — but skips the AI summarizer and does not persist anything. - Renders the same summary cards and highlights UI as a frozen report.
This gives an accurate, real-time preview of what the next frozen report will look like. The same generate_live_summary() method is used by the dashboard widget preview modal.
If no events occurred during the week, Sybgo handles it gracefully:
Setting Disabled (default):
- Report freezes as normal
- Email is NOT sent
- Report status →
emailed(even though not actually sent) - Prevents inbox clutter
Setting Enabled:
- Report freezes as normal
- Email IS sent with "All quiet" message
- Useful for confirming monitoring is working
Configure: Settings → Sybgo → "Send email even if no events"
Subject: Your Weekly Digest - Feb 10-16
All Quiet This Week
No significant activity occurred on your site this week.
This is normal and not a cause for concern.
Check cron schedule:
wp cron event list | grep sybgo_freezeExpected output:
sybgo_freeze_weekly_report 2026-02-16 23:55:00
Manual trigger:
wp cron event run sybgo_freeze_weekly_reportCommon causes:
- WordPress cron disabled (
DISABLE_WP_CRON = true) - Low-traffic site (no page loads to trigger cron)
- PHP errors in freeze callback
Solution: Set up system cron:
# In crontab -e
55 23 * * 0 wget -q -O - https://yoursite.com/wp-cron.php?doing_wp_cronCheck email log:
SELECT * FROM wp_sybgo_email_log
WHERE status = 'failed'
ORDER BY sent_at DESC;Check recipients configured:
SELECT option_value FROM wp_options
WHERE option_name = 'sybgo_settings';Test wp_mail():
wp_mail('test@example.com', 'Test', 'Test message');Common causes:
- SMTP not configured (install WP Mail SMTP plugin)
- Invalid email addresses
- Server email limits exceeded
- HTML emails blocked by recipient
Cause: First week has no previous report to compare
Solution: Wait until week 2 for trends to appear
Verify:
SELECT COUNT(*) FROM wp_sybgo_reports WHERE status = 'emailed';Must be >= 2 reports for trends to work.
CREATE TABLE wp_sybgo_reports (
id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
report_type varchar(20) DEFAULT 'weekly',
status varchar(20) DEFAULT 'active', -- 'active', 'frozen', 'emailed'
period_start datetime NOT NULL,
period_end datetime,
event_count int UNSIGNED DEFAULT 0,
summary_data LONGTEXT, -- JSON with totals, trends, highlights, ai_summary
frozen_at datetime,
emailed_at datetime,
created_at datetime NOT NULL,
PRIMARY KEY (id),
KEY idx_status (status),
KEY idx_period (period_start, period_end)
);CREATE TABLE wp_sybgo_email_log (
id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
report_id bigint(20) UNSIGNED NOT NULL,
recipient_email varchar(255) NOT NULL,
sent_at datetime NOT NULL,
status varchar(20) NOT NULL, -- 'sent', 'failed', 'pending'
error_message TEXT,
PRIMARY KEY (id),
KEY idx_report_id (report_id),
KEY idx_status (status)
);All times are in WordPress timezone (Settings → General):
| Cron Hook | Schedule | Purpose |
|---|---|---|
sybgo_freeze_weekly_report |
Sunday 23:55 | Freeze current week's report |
sybgo_send_report_emails |
Monday 00:05 | Send digest emails |
sybgo_cleanup_old_events |
Daily 03:00 | Delete events >1 year old |
sybgo_retry_failed_emails |
Daily 09:00 | Retry failed email deliveries |
Freeze Duration:
- 100 events: ~1 second
- 1,000 events: ~3 seconds
- 10,000 events: ~15 seconds
Email Generation:
- HTML rendering: ~200ms
- wp_mail() call: ~500ms per recipient
Recommendations:
- Keep recipient list under 20 people
- For larger lists, use email service (Mailchimp, SendGrid)
- Event Tracking - What events feed into reports
- Extension API - Customize report generation
- Development Guide - Testing report freezing