Dashboard Report - User Notes

AI-generated summary

This post by SaraDev presents an SQL-based dashboard report for viewing user notes, which requires the Discourse User Notes plugin. The report retrieves staff-created annotations on user profiles within a specified date range, extracting them from the plugin_store_rows table where they’re stored as JSON. The query uses a CTE to parse note data — including user ID, creation timestamp, note content, and creator — then joins with the users table to validate user existence and filters by date. Results are ordered chronologically and include columns for user, moderator, creation date, and note content (with HTML support). Example output shows rows like user_1 annotated by staff_user_2 on 2024-01-10 with a sample note. Parameters :start_date and :end_date (format: YYYY-MM-DD) allow date-range filtering. This report aids moderation by providing a structured, time-bound view of user annotations.

This is an SQL version of the Dashboard Report for User Notes.

:discourse: This report requires the Discourse User Notes plugin to be enabled.

This dashboard report lists user notes created by staff users within a specific date range. User notes are annotations or comments added by moderators or administrators to a user’s profile, often used to track behavior, issues, or important information about the user.

-- [params]
-- date :start_date = 2024-01-07
-- date :end_date = 2024-02-08

WITH user_notes AS (
    SELECT 
        REPLACE(key, 'notes:', '')::int AS user_id,
        notes.value->>'created_at' AS created_at,
        notes.value->>'raw' AS user_note,
        notes.value->>'created_by' AS created_by
    FROM plugin_store_rows,
    LATERAL json_array_elements(value::json) notes
    WHERE plugin_name = 'user_notes'
    ORDER BY 2 DESC 
)
SELECT 
    un.user_id,
    un.created_by AS moderator_user_id,
    un.created_at::date,
    un.user_note as html$user_note
FROM user_notes un
JOIN users u ON u.id = un.user_id
WHERE un.created_at BETWEEN :start_date AND :end_date
ORDER BY un.created_at ASC

SQL Query Explanation

This report extracts these notes from the plugin_store_rows table, where they are stored in a JSON format by the user_notes plugin, and presents them in an easily digestible format.

The query operates in several steps:

  • Parameters:
    • The query starts by defining two parameters, :start_date and :end_date, to specify the time period for the report. Both date parameters accept the format of YYYY-MM-DD.
  • Common Table Expression (CTE) - user_notes: The query begins with a CTE named user_notes that extracts and transforms the relevant data from the plugin_store_rows table. This table stores various plugin data in a key-value format, where the key for user notes is prefixed with notes: followed by the user’s ID. The CTE performs the following operations:
    • Filters rows where plugin_name is 'user_notes', ensuring only user notes data is selected.
    • Uses the json_array_elements function in a LATERAL join to expand the JSON array stored in the value column into individual JSON objects, each representing a note.
    • Extracts the user ID from the key by removing the notes: prefix and casting the result to an integer.
    • Extracts the note’s creation date, raw note content, and the ID of the user who created the note from the JSON object.
  • Main Query:
    • Joins the user_notes CTE with the users table to ensure that only notes for existing users are included.
    • Filters notes based on the created_at date to include only those within the specified date range (:start_date to :end_date).
    • Selects the user ID, moderator user ID (the note creator), note creation date, and the note content.
    • Orders the results by the note creation date in ascending order to present the notes chronologically.

Example Results

user moderator_user created_at user_note
user_1 staff_user_2 2024-01-10 example user note with HTML formatting
user_3 staff_user_4 2024-01-14 this is an example note about user_3
… … … …
3 Likes