⭐ Why this plugin is unlike anything else available
Grain-aware SQL that cannot produce wrong percentages
▸ Every other Moodle reporting plugin runs JOIN-heavy queries that multiply rows silently. A learner with 3 quiz attempts appears 3 times, inflating completion rates to 200%+ with no warning. Beacon's grain engine is different: it knows whether your question is about people (learner grain), learner×course pairs (enrolment grain), course-level rollups (course grain), or one of nine more specialised grains, and writes the SQL accordingly. Row-multiplication is architecturally impossible.
▸ Hard role isolation enforced inside the SQL — not just in the UI. Course-context access is locked via filterset::lock_course() baked into the WHERE clause, so a teacher cannot reach another course's data even by constructing a URL manually.
▸ Per-user cache key (_u[userid]) prevents cross-user data bleed from shared application caches. Personal report caches are always user-scoped; user A can never receive user B's cached result.
▸ 28 hand-written, audited SQL reports — not a drag-and-drop query builder generating arbitrary SQL. Every report was designed for a specific question a Moodle administrator or RTO actually asks.
▸ Funding participation evidence — durable proof of ongoing learner engagement for funding audits, built from completion, submission, quiz-attempt and forum-post records that remain available beyond your log-retention window while those source records are retained.
28 Curated Reports
Learner roster, course completion, quiz performance, SCORM attempts, certification status, policy acceptance, and more — every report hand-written for a question admins actually ask.
Grain-aware Engine
Every report is written at a declared grain — learner, enrolment, or course. Fan-out data is rolled up inside the SQL — one clear row per anchor, no duplicate counting.
Scheduled Delivery
Email any report as a CSV or branded PDF attachment on a daily, weekly, or monthly schedule. 11 stat cards and 7 KPI gauges keep the dashboard live between deliveries.
The problem Beacon solves
Traditional report builders join tables and multiply rows. A learner enrolled in 3 courses with 2 quiz attempts each produces 6 rows — and every SUM or COUNT that touches those rows is silently wrong.
Every Beacon report is hand-written at a declared grain — the anchor entity that defines one row. Data that fans out (one learner → many quiz attempts) is rolled up inside the SQL, so the result arrives as a single value (best score, count, average) rather than extra rows.
Every report tells you its grain. The report header states the grain label — "one row per learner", "one row per enrolment" — so you always know exactly what a row means before you read a single number.
Declared Grains
Every report states its grain in the header. The three most common are below; specialised reports use their own — one row per quiz, assignment, submission, cohort member, certificate, badge, policy acceptance, competency, or role assignment.
Learner
One row for every learner. Use this when your question is about people — who completed, who hasn't enrolled, who is overdue.
Enrolment
One row for every learner in every course. Use this when your question spans both people and courses — completion rate per course, scores across a cohort.
Course
One row for every course, with learner data rolled up. Use this for course-level metrics — how many people finished a unit, average score, storage used.
Audience Scope — Who Can See Whose Data
Site-wide dashboard — every report, stat card and KPI gauge across all courses.
Opens Beacon inside their course. Every course-context query has the course lock baked into the WHERE clause — not just hidden in the UI.
Personal My Reports view — their own courses, completions, grades, certificates and badges. Never anyone else's data.
Role isolation is enforced server-side. In course context the course lock is baked into the SQL WHERE clause itself — a teacher cannot reach another course's data by editing the URL.
Funding participation reporting
Beacon includes reporting designed to evidence participation for government funding and RTO compliance: evidence that a learner engaged with a course repeatedly over time, separate from whether they completed an assessment.
Funding participation evidence (Compliance)
One row per enrolled learner per course shows first activity, last activity, distinct active days and an activity count. Evidence comes from Moodle's durable activity completions, assignment submissions, quiz attempts and forum posts, rather than relying on the standard log.
This can evidence participation across an 18- or 24-month qualification even when logs are kept for only 12 months, provided those underlying records still exist. When the standard log is available, the supplementary Course views (12 mo) column shows course views from the past 365 days, subject to any shorter log-retention window.
Course access (recent) (Engagement)
A complementary standard-log report shows first and last logged access, active days, course views and total logged activity. It captures passive viewing, such as opening pages and resources, that does not itself create a durable participation action. It requires the standard log store to be enabled and can only report on logs still retained within the selected date range.
Participating learners — stat card
Counts distinct enrolled learners with a qualifying completion, submission, quiz attempt or forum post in the last 30 days.
Participation rate — KPI gauge
Shows the share of live enrolments with a qualifying action in the last 30 days. It measures learner–course enrolment pairs, not the percentage of unique site users.
Both reports support course, category, group, cohort and date-range filters, along with saved views, scheduled email delivery and CSV/PDF export. Filters are report-specific; do not assume every Beacon report or dashboard metric exposes the same filters.
Notes for auditors and admins
Completing an activity, submitting work, attempting a quiz and posting are meaningful actions. Completion tracking on activities enriches this evidence. Durable does not mean undeletable: course resets, record deletion and your site's retention and backup policies affect what remains available. The recent access report depends on the standard log store and itsloglifetimesetting. Use these reports as supporting evidence, not a guarantee that a funding authority's participation requirements have been met.
Report Library — 28 Curated Reports
Reports are grouped into six families. Every one is hand-written, audited SQL at a declared grain, with click-to-filter columns, saved views, and CSV/PDF export. Learners additionally get 5 personal reports — my courses, completions, grades, certificates, and badges.
- Learner roster
- Enrolment details
- Never logged in
- New users
- Cohort membership
- Course completion
- Activity completion
- Learner progress
- Course progress
- Competency progress
- Grade summary
- Quiz performance
- Quiz results
- Assignment status
- SCORM attempts
- Marking queue
- Not started
- Login activity
- Forum engagement
- Inactive learners
- Badges awarded
- Course access (recent)
- Certification status
- Policy acceptance
- Funding participation evidence
- Course catalogue health
- Staff & roles
- Course summary
Stats & KPIs
11 Stat Cards
Single computed values
Total learners, live enrolments, active learners, new enrolments, completions, in progress, awaiting marking, average grade, dormant learners, expiring soon, and participating learners — each a single audited value on the live dashboard.
7 KPI Gauges
0–100 % rates
Course completion, activity engagement, monthly active, pass rate, feedback rate, certification currency, and participation rate. Each gauge has a defined target and denominator so the percentage is always truthful.
Scheduled Delivery
Any report can be scheduled to run on a repeating basis and deliver the result as a CSV or branded PDF email attachment. Schedules are stored in local_beacon_delivery and executed by Moodle's cron via the "Send Beacon report email deliveries" task.
Recipient email addresses are set per schedule and do not need to be Moodle accounts. Deliveries are sent through your site's normal Moodle SMTP configuration.
Capabilities
local/beacon:viewOpen the dashboard and reports. Managers see site-wide data; teachers get course-context access locked to that course.
local/beacon:viewmineThe personal My Reports view — own courses, completions, grades, certificates, and badges only.
local/beacon:requestCapability defaults to managers, but the request form itself requires site administrator access (moodle/site:config).
Installation
Download the plugin
Click the Download button above to get the latest ZIP file.
Install in Moodle
Go to Site administration → Plugins → Install plugins. Upload the ZIP and follow the on-screen wizard.
Run the database upgrade
Moodle will automatically create 5 tables: local_beacon_savedview, local_beacon_delivery, local_beacon_snapshot, local_beacon_request, and local_beacon_metric_cache.
Check capabilities
Defaults work out of the box: local/beacon:view is granted to managers, course creators, and teachers (editing and non-editing); local/beacon:viewmine to learners for the personal My Reports view. New-report requests are submitted by site administrators.
Open the dashboard
Beacon appears in the main navigation (placement is configurable in plugin settings). The dashboard loads 11 stat cards and 7 KPI gauges; open any of the 28 reports from the six family sections.
Database Tables
local_beacon_savedviewlocal_beacon_deliverylocal_beacon_snapshotlocal_beacon_requestlocal_beacon_metric_cache