Docs  /  Reference  /  Database schema

Database schema

8 custom tables. {prefix} is your site's $wpdb->prefix (usually wp_). Use these CREATE TABLE blocks as the authoritative shape when you write addons that read directly — but prefer OrderUpdatesDb for everything you can.

The plugin owns eight custom tables. No WordPress core or WooCommerce tables are touched. Each CREATE TABLE below is extracted verbatim from src/Shared/Updates/UpdatesTable.php, src/Shared/Attachments/AttachmentsTable.php, and src/Shared/Analytics/AnalyticsLookupTable.php — the source of truth for columns, types, indexes, and constraints.

Tables at a glance

TablePurpose
{prefix}order_updates_for_wooOne row per update. Title, status, assignee, customer-visible flag, timestamps.
{prefix}order_updates_for_woo_assigneesAssignment history per update — current and past assignees, useful for the participant list.
{prefix}order_updates_for_woo_internal_notesInternal notes (team-only). Belongs to an update.
{prefix}order_updates_for_woo_customer_notesCustomer-visible notes plus system markers (status changes, reopens, rating requests).
{prefix}order_updates_for_woo_customer_note_historyRevision snapshots for edited customer notes.
{prefix}order_updates_for_woo_ratingsOne row per rated update — stars, comment, timestamps.
{prefix}order_updates_for_woo_attachmentsAttachment metadata — pointer to the file on disk, MIME type, order / update / note bindings.
{prefix}order_updates_for_woo_analytics_lookupDenormalized per-update row driving the analytics dashboard. Read-only fast path.

Don’t read or write directly

Even though the schema is documented here, addon code should never $wpdb->query() these tables directly. Use OrderUpdatesDb or AttachmentsDb:

  • The methods on those classes handle caching and invalidation. Direct queries skip both.
  • Schema details can change between minor versions. The public API on those classes stays stable.
  • If your addon needs data the public API doesn’t expose, open an issue — a missing accessor method is a bug.

{prefix}order_updates_for_woo

CREATE TABLE {prefix}order_updates_for_woo (
			id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
			order_id BIGINT(20) UNSIGNED NOT NULL,
			title VARCHAR(191) NOT NULL,
			status VARCHAR(50) NOT NULL DEFAULT '',
			customer_visible TINYINT(1) NOT NULL DEFAULT 0,
			color VARCHAR(20) NOT NULL DEFAULT '#dca100',
			created_by BIGINT(20) UNSIGNED NOT NULL,
			last_updated_by BIGINT(20) UNSIGNED NULL,
			solved_by BIGINT(20) UNSIGNED NULL,
			is_resolved TINYINT(1) NOT NULL DEFAULT 0,
			solved_at DATETIME NULL,
			created_at DATETIME NOT NULL,
			last_updated_at DATETIME NULL,
			assignee_since_note_id BIGINT(20) UNSIGNED NULL,
			previous_assignee_name VARCHAR(100) NULL,
			PRIMARY KEY  (id),
			KEY order_id (order_id),
			KEY title (title),
			KEY order_title (order_id, title),
			KEY order_created_at (order_id, created_at),
			KEY resolved_order (is_resolved, order_id),
			KEY created_at (created_at),
			KEY resolved_created_at (is_resolved, created_at)
		) {charset_collate};

{prefix}order_updates_for_woo_assignees

CREATE TABLE {prefix}order_updates_for_woo_assignees (
			id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
			update_id BIGINT(20) UNSIGNED NOT NULL,
			assignee_user_id BIGINT(20) UNSIGNED NOT NULL,
			assigned_by BIGINT(20) UNSIGNED NOT NULL,
			assigned_at DATETIME NOT NULL,
			notified_at DATETIME NULL,
			is_active TINYINT(1) NOT NULL DEFAULT 1,
			unassigned_at DATETIME NULL,
			unassigned_by BIGINT(20) UNSIGNED NULL,
			last_updated_at DATETIME NULL,
			PRIMARY KEY  (id),
			KEY update_id (update_id),
			KEY assignee_user_id (assignee_user_id),
			KEY is_active (is_active),
			KEY assigned_by (assigned_by),
			KEY update_assignee (update_id, assignee_user_id),
			KEY update_active (update_id, is_active),
			KEY update_assigned_at (update_id, assigned_at)
		) {charset_collate};

{prefix}order_updates_for_woo_internal_notes

CREATE TABLE {prefix}order_updates_for_woo_internal_notes (
			id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
			update_id BIGINT(20) UNSIGNED NOT NULL,
			note VARCHAR(500) NOT NULL,
			mentioned_user_ids VARCHAR(191) NOT NULL DEFAULT '',
			created_by BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
			created_by_name VARCHAR(191) NOT NULL DEFAULT '',
			created_at DATETIME NOT NULL,
			edited_at DATETIME NULL,
			PRIMARY KEY  (id),
			KEY update_id (update_id)
		) {charset_collate};

{prefix}order_updates_for_woo_ratings

CREATE TABLE {prefix}order_updates_for_woo_ratings (
			id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
			update_id BIGINT(20) UNSIGNED NOT NULL,
			order_id BIGINT(20) UNSIGNED NOT NULL,
			stars TINYINT(1) UNSIGNED NULL,
			comment VARCHAR(500) NOT NULL DEFAULT '',
			created_by BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
			created_by_name VARCHAR(191) NOT NULL DEFAULT '',
			requested_at DATETIME NULL,
			request_notified_at DATETIME NULL,
			created_at DATETIME NULL,
			PRIMARY KEY  (id),
			UNIQUE KEY update_id (update_id),
			KEY order_id (order_id),
			KEY stars (stars)
		) {charset_collate};

{prefix}order_updates_for_woo_customer_notes

CREATE TABLE {prefix}order_updates_for_woo_customer_notes (
			id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
			update_id BIGINT(20) UNSIGNED NOT NULL,
			note VARCHAR(500) NOT NULL,
			kind VARCHAR(20) NOT NULL DEFAULT 'note',
			queued_at DATETIME NULL,
			notified_at DATETIME NULL,
			created_by BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
			created_by_name VARCHAR(191) NOT NULL DEFAULT '',
			created_at DATETIME NOT NULL,
			edited_at DATETIME NULL,
			PRIMARY KEY  (id),
			KEY update_id (update_id),
			KEY update_notified (update_id, notified_at)
		) {charset_collate};

{prefix}order_updates_for_woo_customer_note_history

CREATE TABLE {prefix}order_updates_for_woo_customer_note_history (
			id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
			note_id BIGINT(20) UNSIGNED NOT NULL,
			prior_note VARCHAR(500) NOT NULL,
			edited_by BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
			edited_by_name VARCHAR(191) NOT NULL DEFAULT '',
			edited_at DATETIME NOT NULL,
			PRIMARY KEY  (id),
			KEY note_id (note_id)
		) {charset_collate};

{prefix}order_updates_for_woo_attachments

CREATE TABLE {prefix}order_updates_for_woo_attachments (
			id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
			order_id BIGINT(20) UNSIGNED NOT NULL,
			update_id BIGINT(20) UNSIGNED NOT NULL,
			note_id BIGINT(20) UNSIGNED NOT NULL,
			note_type VARCHAR(20) NOT NULL DEFAULT 'internal',
			file_name VARCHAR(255) NOT NULL,
			original_name VARCHAR(255) NOT NULL,
			mime_type VARCHAR(100) NOT NULL,
			file_size BIGINT(20) UNSIGNED NOT NULL,
			uploaded_by BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
			uploaded_at DATETIME NOT NULL,
			PRIMARY KEY  (id),
			KEY order_id (order_id),
			KEY update_id (update_id),
			KEY note_lookup (note_id, note_type)
		) {charset_collate};

{prefix}order_updates_for_woo_analytics_lookup

CREATE TABLE {prefix}order_updates_for_woo_analytics_lookup (
			id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
			update_id BIGINT(20) UNSIGNED NOT NULL,
			order_id BIGINT(20) UNSIGNED NOT NULL,
			created_at DATETIME NOT NULL,
			created_date DATE NOT NULL,
			solved_at DATETIME NULL,
			solved_date DATE NULL,
			resolution_seconds INT UNSIGNED NULL,
			assignee_user_id BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
			created_by_user_id BIGINT(20) UNSIGNED NOT NULL DEFAULT 0,
			is_customer_initiated TINYINT(1) NOT NULL DEFAULT 0,
			customer_visible TINYINT(1) NOT NULL DEFAULT 0,
			rating TINYINT(1) UNSIGNED NULL,
			rating_at DATETIME NULL,
			has_rating_comment TINYINT(1) NOT NULL DEFAULT 0,
			product_id BIGINT(20) UNSIGNED NULL,
			PRIMARY KEY  (id),
			UNIQUE KEY update_id (update_id),
			KEY order_id (order_id),
			KEY created_date (created_date),
			KEY solved_date (solved_date),
			KEY assignee_created (assignee_user_id, created_date),
			KEY rating (rating),
			KEY product_id (product_id)
		) {charset_collate};