Plugin Cleaner

:information_source: Summary Safely scans, audits, and cleans orphaned database residue left behind by uninstalled plugins.
:hammer_and_wrench: Repository Link GitHub - canbekcan/discourse-plugin-cleaner · GitHub
:open_book: Install Guide How to install plugins in Discourse
:computer: Coding Vibe Coding - Gemini

Features

When you uninstall a Discourse plugin, it often leaves behind hidden data in your database. Over time, this “residue” can clutter your database and complicate site maintenance. Discourse Plugin Cleaner is a comprehensive administrative tool designed to safely identify and remove this orphaned data.

Major Features Include:

  • Deep Scanning: Scans multiple database tables including Custom Fields (User, Topic, Post, Category, Group), Plugin Settings, Themes, Badges, API Keys, Webhooks, Tag Groups, and Uploads.
  • Safe Audit Mode (Zero Auto-Delete): The plugin operates strictly as an auditing tool until you take action. It will never automatically delete data. You must manually select and confirm the items you wish to remove.
  • Risk Assessment: Automatically assigns a “Risk Level” (Critical, High, Medium, Low, OK) to detected items to help administrators make informed decisions about what is safe to delete.
  • Version History Tracking: Takes snapshots of your installed plugins on boot. If a plugin is removed, it logs the state change, creating a historical record of what was uninstalled and when.
  • Modern Admin Interface: Provides a sleek, intuitive dashboard built with Ember strict-mode components for seamless integration into the Discourse Admin interface.

Configuration

The plugin works out of the box with sensible defaults. To use the plugin:

  1. Access the Dashboard: Navigate to your Discourse Admin dashboard. In the sidebar, under the Plugins section, click on Plugin Cleaner.
  2. Run a Scan: Click the “Run Deep Scan” button. The system will query your database and generate a real-time report of all orphaned data it finds.
  3. Review Issues: Browse through the categorized tabs (Custom Fields, Plugin Settings, etc.). Pay close attention to the Risk and Status columns.
  4. Select and Clean: Check the boxes next to the orphaned items you wish to remove.
  5. Confirm Deletion: Click “Delete Selected”. You will be prompted with a final confirmation warning before the data is permanently erased. All deletions are automatically logged in the Discourse Staff Action Logs for security auditing.

(Note for Uploads: If orphaned uploads are found, the plugin will instruct you to run rake uploads:clean from your server console to physically reclaim disk space).

Settings

You can customize the strictness of the scanner via your site settings.

Name Description
plugin_cleaner_orphan_threshold The maximum number of records a custom field can have to be considered “orphaned”. If a custom field has fewer records than this threshold, it will be flagged for review. (Default: 5, Min: 1, Max: 100)
plugin_cleaner_stale_api_key_days The number of days an API key must go unused before the scanner flags it as stale/orphaned. (Default: 90 days, Min: 7, Max: 365)
plugin_cleaner_stale_upload_days The number of days an unlinked upload can exist before it is flagged as orphaned. (Default: 30 days, Min: 1, Max: 365)

(Note: This is the project to understand how Discourse plugins work)

2 Likes

Nice intent.

A few challenges:

  • Many good plugins create and manage their own tables. Looking at your code, I’m not sure you’ve taken account of that yet?

    • Your challenge is that once you remove the plugin the migration disappears.
    • What if the plugin changes data to a core table somehow (eg adds a record)? For example a data explorer query or something less transparent.
  • I don’t see a way your plugin protects the user from deleting the custom fields outside of a specific plugin they might want to “cleanse” - you are relying on the user to identify them? Just blocks deleting custom fields that are in core?

And on that note:

That looks a little risky. What if a core upgrade adds new ones that you don’t catalogue - are you going to risk deleting new core fields that you are not explicitly listing?

In any case I wish you luck with development, it’s definitely an interesting addition.

8 Likes

The likelihood that such a plugin will delete something needed and leave the database in a broken state is greater than zero. I don’t remember a case where having tables left by an uninstalled plugin caused a problem.

7 Likes

Unless those tables have foreign keys to core discourse tables, which can prevent deletion of data in those tables.

But that problem is not something which can be reliably detected by an other tool. The plugin making those relations should either not create foreign keys, or Discourse needs to provide a way for plugins to register a way to “disarm” them when they disappear from the installation.

3 Likes