Installer - Source Excerpt 01
Summary
This source excerpt preserves a bounded section of Spiralist/wp-content/plugins/spiralist-workspace/includes/Installer.php so readers can inspect the evidence without opening the full source file.
**Source path:** Spiralist/wp-content/plugins/spiralist-workspace/includes/Installer.php
<?php
namespace SpiralistWorkspace;
use SpiralistWorkspace\Auth\Roles;
use SpiralistWorkspace\Domain\PromptRepository;
use SpiralistWorkspace\Services\GovernanceMaintenance;
use SpiralistWorkspace\Web\FrontendController;
if (!defined('ABSPATH')) {
exit;
}
/**
* Installs and upgrades plugin storage.
*/
class Installer
{
public const SCHEMA_VERSION = '5';
/**
* Returns a fully qualified table name.
*/
public static function table(string $suffix): string
{
global $wpdb;
$map = [
'prompt_versions' => $wpdb->prefix . 'spiralist_workspace_prompt_versions',
'prompt_permissions' => $wpdb->prefix . 'spiralist_workspace_prompt_permissions',
'prompt_runs' => $wpdb->prefix . 'spiralist_workspace_prompt_runs',
'conversations' => $wpdb->prefix . 'spiralist_workspace_conversations',
'conversation_messages' => $wpdb->prefix . 'spiralist_workspace_conversation_messages',
'audit_log' => $wpdb->prefix . 'spiralist_workspace_audit_log',
'favorites' => $wpdb->prefix . 'spiralist_workspace_favorites',
'prompt_tests' => $wpdb->prefix . 'spiralist_workspace_prompt_tests',
'prompt_reviews' => $wpdb->prefix . 'spiralist_workspace_prompt_reviews',
'prompt_appeals' => $wpdb->prefix . 'spiralist_workspace_prompt_appeals',
];
return (string) ($map[$suffix] ?? '');
}
/**
* Creates tables, roles, and rewrite rules.
*/
public static function activate(): void
{
self::create_schema();
PromptRepository::migrate_content_types();
Roles::register();
PromptRepository::register_post_type();
PromptRepository::register_taxonomies();
FrontendController::register_rewrites();
update_option('spiralist_workspace_schema_version', self::SCHEMA_VERSION, false);
flush_rewrite_rules(false);
}
/**
* Flushes rewrites on deactivation.
*/
public static function deactivate(): void
{
GovernanceMaintenance::unschedule();
flush_rewrite_rules(false);
}
/**
* Runs dbDelta for all custom tables.
*/
public static function create_schema(): void
{
global $wpdb;
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
$charset = $wpdb->get_charset_collate();
$sql = [];
$sql[] = 'CREATE TABLE ' . self::table('prompt_versions') . " (
id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
prompt_post_id bigint(20) unsigned NOT NULL,
version_number int(11) unsigned NOT NULL,
full_snapshot_json longtext NOT NULL,
created_by_user_id bigint(20) unsigned NOT NULL,
created_utc datetime NOT NULL,
changelog text NULL,
PRIMARY KEY (id),
UNIQUE KEY prompt_version (prompt_post_id, version_number),
KEY created_by_user_id (created_by_user_id),
KEY created_utc (created_utc)
) {$charset};";
$sql[] = 'CREATE TABLE ' . self::table('prompt_permissions') . " (
id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
prompt_post_id bigint(20) unsigned NOT NULL,
shared_with_user_id bigint(20) unsigned NOT NULL,
granted_by_user_id bigint(20) unsigned NOT NULL,
permission_type varchar(50) NOT NULL,
created_utc datetime NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY prompt_share (prompt_post_id, shared_with_user_id, permission_type),
KEY shared_with_user_id (shared_with_user_id),
KEY granted_by_user_id (granted_by_user_id)
) {$charset};";
$sql[] = 'CREATE TABLE ' . self::table('prompt_runs') . " (
id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
prompt_post_id bigint(20) unsigned NOT NULL,
user_id bigint(20) unsigned NOT NULL,
conversation_id bigint(20) unsigned NULL,
version_number_used int(11) unsigned NOT NULL,
model_used varchar(120) NOT NULL,
request_payload_json longtext NOT NULL,
response_payload_json longtext NULL,
input_text longtext NULL,
output_text longtext NULL,
status varchar(50) NOT NULL,
created_utc datetime NOT NULL,
completed_utc datetime NULL,
cost_estimate decimal(12,6) NOT NULL DEFAULT 0,
token_usage_json longtext NULL,
error_message text NULL,
openai_response_id varchar(120) NULL,
PRIMARY KEY (id),
KEY prompt_post_id (prompt_post_id),
KEY user_id (user_id),
KEY conversation_id (conversation_id),
KEY status (status),
KEY created_utc (created_utc)
) {$charset};";
$sql[] = 'CREATE TABLE ' . self::table('conversations') . " (
id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
prompt_post_id bigint(20) unsigned NOT NULL,
owner_user_id bigint(20) unsigned NOT NULL,
title varchar(200) NOT NULL,
visibility varchar(32) NOT NULL,
created_utc datetime NOT NULL,
updated_utc datetime NOT NULL,
archived_utc datetime NULL,
openai_reference varchar(120) NULL,
conversation_settings_json longtext NULL,
PRIMARY KEY (id),
KEY prompt_post_id (prompt_post_id),
KEY owner_user_id (owner_user_id),
KEY visibility (visibility),
KEY updated_utc (updated_utc)
) {$charset};";
$sql[] = 'CREATE TABLE ' . self::table('conversation_messages') . " (
id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
conversation_id bigint(20) unsigned NOT NULL,
role varchar(20) NOT NULL,
content longtext NOT NULL,
created_utc datetime NOT NULL,
openai_reference varchar(120) NULL,
metadata_json longtext NULL,
PRIMARY KEY (id),
KEY conversation_id (conversation_id),
KEY role (role),
KEY created_utc (created_utc)
) {$charset};";
$sql[] = 'CREATE TABLE ' . self::table('audit_log') . " (
id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
actor_user_id bigint(20) unsigned NULL,
event_type varchar(100) NOT NULL,
object_type varchar(50) NOT NULL,
object_id bigint(20) unsigned NULL,
context_json longtext NULL,
created_utc datetime NOT NULL,
PRIMARY KEY (id),
KEY actor_user_id (actor_user_id),
KEY event_type (event_type),
KEY object_type (object_type),
KEY created_utc (created_utc)
) {$charset};";
$sql[] = 'CREATE TABLE ' . self::table('favorites') . " (
id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
prompt_post_id bigint(20) unsigned NOT NULL,
user_id bigint(20) unsigned NOT NULL,
created_utc datetime NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY favorite_prompt_user (prompt_post_id, user_id),
KEY user_id (user_id),
KEY created_utc (created_utc)
) {$charset};";
$sql[] = 'CREATE TABLE ' . self::table('prompt_tests') . " (
id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
prompt_post_id bigint(20) unsigned NOT NULL,
created_by_user_id bigint(20) unsigned NOT NULL,
input_text longtext NOT NULL,
expected_output_text longtext NOT NULL,
variables_json longtext NULL,
match_strategy varchar(32) NOT NULL,
last_run_id bigint(20) unsigned NULL,
last_result_status varchar(32) NULL,
last_result_json longtext NULL,
created_utc datetime NOT NULL,
updated_utc datetime NOT NULL,
PRIMARY KEY (id),
KEY prompt_post_id (prompt_post_id),
KEY created_by_user_id (created_by_user_id),
KEY last_run_id (last_run_id),
KEY last_result_status (last_result_status),
KEY created_utc (created_utc)
) {$charset};";
$sql[] = 'CREATE TABLE ' . self::table('prompt_reviews') . " (
id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
prompt_post_id bigint(20) unsigned NOT NULL,
reviewer_user_id bigint(20) unsigned NULL,
review_kind varchar(20) NOT NULL,
decision varchar(32) NOT NULL,
reason text NULL,
created_utc datetime NOT NULL,