{"id":4960,"date":"2026-01-26T01:51:08","date_gmt":"2026-01-26T06:51:08","guid":{"rendered":"https:\/\/chubes.net\/?documentation=chat-database"},"modified":"2026-02-13T20:21:07","modified_gmt":"2026-02-14T01:21:07","slug":"chat-database","status":"publish","type":"documentation","link":"https:\/\/chubes.net\/docs\/data-machine\/core-system\/chat-database\/","title":{"rendered":"Chat Database"},"content":{"rendered":"<p><strong>Location<\/strong>: <code>\/inc\/Core\/Database\/Chat\/Chat.php<\/code><\/p><p><strong>Since<\/strong>: v0.2.0 (Universal Engine Architecture)<\/p><p><strong>Namespace<\/strong>: <code>DataMachineCoreDatabaseChat<\/code><\/p><p><strong>Table<\/strong>: <code>wp_datamachine_chat_sessions<\/code><\/p><h2 class=\"wp-block-heading\">Overview<\/h2><p>ChatDatabase provides comprehensive session management for the Chat API, handling CRUD operations, user isolation, and automatic session expiration. Supports persistent conversation storage with 24-hour session lifespans.<\/p><h2 class=\"wp-block-heading\">Purpose<\/h2><p>Centralizes all database operations for chat sessions, enabling multi-turn conversations with conversation history persistence, user-scoped access control, and automatic cleanup of expired sessions.<\/p><h2 class=\"wp-block-heading\">Database Schema<\/h2><h3 class=\"wp-block-heading\">Table Structure<\/h3><p><strong>Table Name<\/strong>: <code>wp_datamachine_chat_sessions<\/code><\/p><p><strong>Columns<\/strong>:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">sql<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-sql\"><code class=\"language-sql\">CREATE TABLE wp_datamachine_chat_sessions (\n    session_id VARCHAR(50) NOT NULL,              -- UUID4 session identifier\n    user_id BIGINT(20) UNSIGNED NOT NULL,         -- WordPress user ID\n    messages LONGTEXT NOT NULL,                   -- JSON array of conversation messages\n    metadata LONGTEXT NULL,                       -- JSON object for session metadata\n    provider VARCHAR(50) NULL,                    -- AI provider (anthropic, openai, google, grok, openrouter)\n    model VARCHAR(100) NULL,                      -- AI model identifier (e.g., claude-3-5-sonnet-20241022)\n    created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,\n    updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,\n    expires_at DATETIME NULL,                     -- Auto-cleanup timestamp (24 hours from creation)\n    PRIMARY KEY (session_id),\n    KEY user_id (user_id),\n    KEY created_at (created_at),\n    KEY expires_at (expires_at)\n);<\/code><\/pre><\/div><p><strong>Indexes<\/strong>:<\/p><ul class=\"wp-block-list\"><li>Primary key on <code>session_id<\/code> for direct session lookup<\/li><li>Index on <code>user_id<\/code> for user-scoped queries<\/li><li>Index on <code>created_at<\/code> for chronological ordering<\/li><li>Index on <code>expires_at<\/code> for efficient cleanup queries<\/li><\/ul><p><strong>Character Set<\/strong>: Uses WordPress database charset and collation<\/p><hr class=\"wp-block-separator\"\/><h2 class=\"wp-block-heading\">Core Methods<\/h2><h3 class=\"wp-block-heading\">Table Management<\/h3><h4 class=\"wp-block-heading\">create_table()<\/h4><p>Create chat sessions table using WordPress dbDelta for safe table creation\/updates.<\/p><p><strong>Signature<\/strong>:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">public static function create_table(): void<\/code><\/pre><\/div><p><strong>Behavior<\/strong>:<\/p><ul class=\"wp-block-list\"><li>Uses <code>dbDelta()<\/code> for safe table creation (handles existing tables)<\/li><li>Creates indexes for efficient querying<\/li><li>Logs table creation via <code>datamachine_log<\/code> action<\/li><li>Called during plugin activation<\/li><\/ul><p><strong>Example<\/strong>:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">use DataMachineCoreDatabaseChatChat as ChatDatabase;\n\n\/\/ During plugin activation\nChatDatabase::create_table();<\/code><\/pre><\/div><p><strong>Usage<\/strong>: Automatic during plugin activation, safe to call multiple times<\/p><hr class=\"wp-block-separator\"\/><h4 class=\"wp-block-heading\">table_exists()<\/h4><p>Check if chat sessions table exists in database.<\/p><p><strong>Signature<\/strong>:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">public static function table_exists(): bool<\/code><\/pre><\/div><p><strong>Returns<\/strong>: True if table exists, false otherwise<\/p><p><strong>Example<\/strong>:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">if (ChatDatabase::table_exists()) {\n    \/\/ Table ready for use\n} else {\n    ChatDatabase::create_table();\n}<\/code><\/pre><\/div><hr class=\"wp-block-separator\"\/><h4 class=\"wp-block-heading\">get_table_name()<\/h4><p>Get full table name with WordPress prefix.<\/p><p><strong>Signature<\/strong>:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">public static function get_table_name(): string<\/code><\/pre><\/div><p><strong>Returns<\/strong>: Full table name (e.g., <code>wp_datamachine_chat_sessions<\/code>)<\/p><p><strong>Example<\/strong>:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">$table = ChatDatabase::get_table_name();\n\/\/ Returns: &quot;wp_datamachine_chat_sessions&quot; (or custom prefix)<\/code><\/pre><\/div><hr class=\"wp-block-separator\"\/><h3 class=\"wp-block-heading\">Session CRUD Operations<\/h3><h4 class=\"wp-block-heading\">create_session()<\/h4><p>Create new chat session for user.<\/p><p><strong>Signature<\/strong>:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">public function create_session(int $user_id, array $metadata = []): string<\/code><\/pre><\/div><p><strong>Parameters<\/strong>:<\/p><ul class=\"wp-block-list\"><li><code>$user_id<\/code> (int) &#8211; WordPress user ID<\/li><li><code>$metadata<\/code> (array) &#8211; Optional session metadata (default: empty array)<\/li><\/ul><p><strong>Returns<\/strong>: Session ID (UUID4) or empty string on failure<\/p><p><strong>Default Values<\/strong>:<\/p><ul class=\"wp-block-list\"><li><code>session_id<\/code>: Generated UUID4<\/li><li><code>messages<\/code>: Empty JSON array (<code>[]<\/code>)<\/li><li><code>metadata<\/code>: JSON-encoded metadata array<\/li><li><code>provider<\/code>: NULL<\/li><li><code>model<\/code>: NULL<\/li><li><code>expires_at<\/code>: 24 hours from creation time (GMT)<\/li><\/ul><p><strong>Example<\/strong>:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">$chat_db = new ChatDatabase();\n\n$session_id = $chat_db-&gt;create_session(\n    get_current_user_id(),\n    [&#039;created_by&#039; =&gt; &#039;chat_interface&#039;, &#039;version&#039; =&gt; &#039;1.0&#039;]\n);\n\nif ($session_id) {\n    \/\/ Session created successfully\n    \/\/ Use $session_id for subsequent operations\n}<\/code><\/pre><\/div><p><strong>Logging<\/strong>:<\/p><ul class=\"wp-block-list\"><li>Success: Debug log with session_id and user_id<\/li><li>Failure: Error log with user_id and database error<\/li><\/ul><hr class=\"wp-block-separator\"\/><h4 class=\"wp-block-heading\">get_session()<\/h4><p>Retrieve session data with automatic expiration checking.<\/p><p><strong>Signature<\/strong>:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">public function get_session(string $session_id): ?array<\/code><\/pre><\/div><p><strong>Parameters<\/strong>:<\/p><ul class=\"wp-block-list\"><li><code>$session_id<\/code> (string) &#8211; Session UUID<\/li><\/ul><p><strong>Returns<\/strong>: Session data array or null if not found\/expired<\/p><p><strong>Returned Array Structure<\/strong>:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">[\n    &#039;session_id&#039; =&gt; &#039;uuid-string&#039;,\n    &#039;user_id&#039; =&gt; 123,\n    &#039;messages&#039; =&gt; [  \/\/ Decoded from JSON\n        [&#039;role&#039; =&gt; &#039;user&#039;, &#039;content&#039; =&gt; &#039;Hello&#039;],\n        [&#039;role&#039; =&gt; &#039;assistant&#039;, &#039;content&#039; =&gt; &#039;Hi there!&#039;]\n    ],\n    &#039;metadata&#039; =&gt; [  \/\/ Decoded from JSON\n        &#039;message_count&#039; =&gt; 2,\n        &#039;last_activity&#039; =&gt; &#039;2024-01-01 12:00:00&#039;\n    ],\n    &#039;provider&#039; =&gt; &#039;anthropic&#039;,\n    &#039;model&#039; =&gt; &#039;claude-3-5-sonnet-20241022&#039;,\n    &#039;created_at&#039; =&gt; &#039;2024-01-01 10:00:00&#039;,\n    &#039;updated_at&#039; =&gt; &#039;2024-01-01 12:00:00&#039;,\n    &#039;expires_at&#039; =&gt; &#039;2024-01-02 10:00:00&#039;\n]<\/code><\/pre><\/div><p><strong>Expiration Handling<\/strong>:<\/p><ul class=\"wp-block-list\"><li>Checks <code>expires_at<\/code> timestamp against current time<\/li><li>Automatically deletes expired sessions<\/li><li>Returns null for expired sessions<\/li><\/ul><p><strong>JSON Decoding<\/strong>:<\/p><ul class=\"wp-block-list\"><li><code>messages<\/code> field decoded to PHP array<\/li><li><code>metadata<\/code> field decoded to PHP array<\/li><li>Invalid JSON defaults to empty array<\/li><\/ul><p><strong>Example<\/strong>:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">$chat_db = new ChatDatabase();\n\n$session = $chat_db-&gt;get_session(&#039;uuid-abc-123&#039;);\n\nif ($session) {\n    $messages = $session[&#039;messages&#039;];\n    $user_id = $session[&#039;user_id&#039;];\n    \/\/ Continue conversation\n} else {\n    \/\/ Session not found or expired\n    \/\/ Create new session\n}<\/code><\/pre><\/div><p><strong>Security<\/strong>: No user isolation check in this method &#8211; caller must verify user_id matches current user<\/p><hr class=\"wp-block-separator\"\/><h4 class=\"wp-block-heading\">update_session()<\/h4><p>Update session with new messages and metadata.<\/p><p><strong>Signature<\/strong>:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">public function update_session(\n    string $session_id,\n    array $messages,\n    array $metadata = [],\n    string $provider = &#039;&#039;,\n    string $model = &#039;&#039;\n): bool<\/code><\/pre><\/div><p><strong>Parameters<\/strong>:<\/p><ul class=\"wp-block-list\"><li><code>$session_id<\/code> (string) &#8211; Session UUID<\/li><li><code>$messages<\/code> (array) &#8211; Complete messages array (replaces existing)<\/li><li><code>$metadata<\/code> (array) &#8211; Updated metadata (replaces existing)<\/li><li><code>$provider<\/code> (string) &#8211; AI provider (optional, only updated if non-empty)<\/li><li><code>$model<\/code> (string) &#8211; AI model (optional, only updated if non-empty)<\/li><\/ul><p><strong>Returns<\/strong>: True on success, false on failure<\/p><p><strong>Update Behavior<\/strong>:<\/p><ul class=\"wp-block-list\"><li><code>messages<\/code>: Always replaced with provided array (JSON-encoded)<\/li><li><code>metadata<\/code>: Always replaced with provided array (JSON-encoded)<\/li><li><code>provider<\/code>: Only updated if non-empty string provided<\/li><li><code>model<\/code>: Only updated if non-empty string provided<\/li><li><code>updated_at<\/code>: Automatically updated by database<\/li><\/ul><p><strong>Example<\/strong>:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">$chat_db = new ChatDatabase();\n\n\/\/ Get current session\n$session = $chat_db-&gt;get_session(&#039;uuid-abc-123&#039;);\n\n\/\/ Add new message to conversation\n$messages = $session[&#039;messages&#039;];\n$messages[] = [&#039;role&#039; =&gt; &#039;user&#039;, &#039;content&#039; =&gt; &#039;New message&#039;];\n\n\/\/ Update metadata\n$metadata = $session[&#039;metadata&#039;];\n$metadata[&#039;message_count&#039;] = count($messages);\n$metadata[&#039;last_activity&#039;] = gmdate(&#039;Y-m-d H:i:s&#039;);\n\n\/\/ Save updates\n$success = $chat_db-&gt;update_session(\n    &#039;uuid-abc-123&#039;,\n    $messages,\n    $metadata,\n    &#039;anthropic&#039;,\n    &#039;claude-sonnet-4&#039;\n);<\/code><\/pre><\/div><p><strong>Logging<\/strong>:<\/p><ul class=\"wp-block-list\"><li>Failure: Error log with session_id and database error<\/li><\/ul><p><strong>Important<\/strong>: Caller must retrieve existing messages\/metadata and merge changes &#8211; this method replaces entire arrays<\/p><hr class=\"wp-block-separator\"\/><h4 class=\"wp-block-heading\">delete_session()<\/h4><p>Delete session from database.<\/p><p><strong>Signature<\/strong>:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">public function delete_session(string $session_id): bool<\/code><\/pre><\/div><p><strong>Parameters<\/strong>:<\/p><ul class=\"wp-block-list\"><li><code>$session_id<\/code> (string) &#8211; Session UUID<\/li><\/ul><p><strong>Returns<\/strong>: True on success, false on failure<\/p><p><strong>Example<\/strong>:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">$chat_db = new ChatDatabase();\n\n$deleted = $chat_db-&gt;delete_session(&#039;uuid-abc-123&#039;);\n\nif ($deleted) {\n    \/\/ Session deleted successfully\n}<\/code><\/pre><\/div><p><strong>Logging<\/strong>:<\/p><ul class=\"wp-block-list\"><li>Success: Debug log with session_id<\/li><li>Failure: Error log with session_id and database error<\/li><\/ul><p><strong>Usage<\/strong>:<\/p><ul class=\"wp-block-list\"><li>Manual session termination<\/li><li>Automatic expiration cleanup (called by get_session)<\/li><li>User logout cleanup<\/li><\/ul><hr class=\"wp-block-separator\"\/><h3 class=\"wp-block-heading\">Maintenance<\/h3><h4 class=\"wp-block-heading\">cleanup_expired_sessions()<\/h4><p>Cleanup all expired sessions from database.<\/p><p><strong>Signature<\/strong>:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">public function cleanup_expired_sessions(): int<\/code><\/pre><\/div><p><strong>Returns<\/strong>: Number of deleted sessions<\/p><p><strong>Cleanup Logic<\/strong>:<\/p><ul class=\"wp-block-list\"><li>Deletes sessions where <code>expires_at IS NOT NULL AND expires_at &lt; NOW()<\/code><\/li><li>Uses GMT time for comparison<\/li><li>Batch deletion for efficiency<\/li><\/ul><p><strong>Example<\/strong>:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">$chat_db = new ChatDatabase();\n\n$deleted_count = $chat_db-&gt;cleanup_expired_sessions();\n\n\/\/ Result: 15 expired sessions deleted<\/code><\/pre><\/div><p><strong>Logging<\/strong>:<\/p><ul class=\"wp-block-list\"><li>Logs info message if any sessions deleted (includes count)<\/li><\/ul><p><strong>Recommended Schedule<\/strong>: Run via WordPress cron job (hourly or daily)<\/p><p><strong>Cron Setup Example<\/strong>:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">\/\/ Register cron event\nadd_action(&#039;init&#039;, function() {\n    if (!wp_next_scheduled(&#039;datamachine_cleanup_chat_sessions&#039;)) {\n        wp_schedule_event(time(), &#039;hourly&#039;, &#039;datamachine_cleanup_chat_sessions&#039;);\n    }\n});\n\n\/\/ Hook cleanup function\nadd_action(&#039;datamachine_cleanup_chat_sessions&#039;, function() {\n    $chat_db = new DataMachineCoreDatabaseChatChat();\n    $chat_db-&gt;cleanup_expired_sessions();\n});<\/code><\/pre><\/div><hr class=\"wp-block-separator\"\/><h2 class=\"wp-block-heading\">Integration with Chat API<\/h2><h3 class=\"wp-block-heading\">Chat Endpoint Usage<\/h3><p>The Chat API endpoint (<code>\/inc\/Api\/Chat\/Chat.php<\/code>) uses ChatDatabase for session management:<\/p><p><strong>Session Creation<\/strong>:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">\/\/ First message (no session_id provided)\n$chat_db = new ChatDatabase();\n$session_id = $chat_db-&gt;create_session(get_current_user_id());<\/code><\/pre><\/div><p><strong>Session Retrieval<\/strong>:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">\/\/ Subsequent messages (session_id provided)\n$session = $chat_db-&gt;get_session($session_id);\n\n\/\/ Verify user ownership\nif ($session[&#039;user_id&#039;] !== get_current_user_id()) {\n    return new WP_Error(&#039;session_access_denied&#039;, &#039;Access denied to this session&#039;, [&#039;status&#039; =&gt; 403]);\n}<\/code><\/pre><\/div><p><strong>Session Update<\/strong>:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">\/\/ After AI response\n$messages = $session[&#039;messages&#039;];\n$messages[] = [&#039;role&#039; =&gt; &#039;user&#039;, &#039;content&#039; =&gt; $user_message];\n$messages[] = [&#039;role&#039; =&gt; &#039;assistant&#039;, &#039;content&#039; =&gt; $ai_response];\n\n$metadata = [\n    &#039;message_count&#039; =&gt; count($messages),\n    &#039;last_activity&#039; =&gt; gmdate(&#039;Y-m-d H:i:s&#039;)\n];\n\n$chat_db-&gt;update_session($session_id, $messages, $metadata, $provider, $model);<\/code><\/pre><\/div><hr class=\"wp-block-separator\"\/><h2 class=\"wp-block-heading\">Security Features<\/h2><h3 class=\"wp-block-heading\">User Isolation<\/h3><p>Sessions are scoped to individual WordPress users:<\/p><ul class=\"wp-block-list\"><li><strong>Creation<\/strong>: Requires valid user_id<\/li><li><strong>Access<\/strong>: Caller must verify session user_id matches current user<\/li><li><strong>No Cross-User Access<\/strong>: Database queries don&#8217;t enforce this &#8211; API layer responsibility<\/li><\/ul><p><strong>Security Check Pattern<\/strong>:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">$session = $chat_db-&gt;get_session($session_id);\n\nif (!$session) {\n    return new WP_Error(&#039;session_not_found&#039;, &#039;Session not found or expired&#039;, [&#039;status&#039; =&gt; 404]);\n}\n\nif ($session[&#039;user_id&#039;] !== get_current_user_id()) {\n    return new WP_Error(&#039;session_access_denied&#039;, &#039;Access denied to this session&#039;, [&#039;status&#039; =&gt; 403]);\n}<\/code><\/pre><\/div><h3 class=\"wp-block-heading\">Automatic Expiration<\/h3><p>Sessions automatically expire after 24 hours:<\/p><ul class=\"wp-block-list\"><li><strong>Expiration Time<\/strong>: Set to <code>NOW() + 24 hours<\/code> at creation<\/li><li><strong>Cleanup<\/strong>: Automatic via <code>get_session()<\/code> and manual via <code>cleanup_expired_sessions()<\/code><\/li><li><strong>Purpose<\/strong>: Prevent stale session accumulation<\/li><\/ul><hr class=\"wp-block-separator\"\/><h2 class=\"wp-block-heading\">Data Storage Patterns<\/h2><h3 class=\"wp-block-heading\">Messages Array<\/h3><p><strong>Structure<\/strong>:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">[\n    [&#039;role&#039; =&gt; &#039;user&#039;, &#039;content&#039; =&gt; &#039;First user message&#039;],\n    [&#039;role&#039; =&gt; &#039;assistant&#039;, &#039;content&#039; =&gt; &#039;AI response&#039;, &#039;tool_calls&#039; =&gt; [...]],\n    [&#039;role&#039; =&gt; &#039;user&#039;, &#039;content&#039; =&gt; &#039;TOOL RESPONSE: ...&#039;],\n    [&#039;role&#039; =&gt; &#039;assistant&#039;, &#039;content&#039; =&gt; &#039;Final response&#039;]\n]<\/code><\/pre><\/div><p><strong>Storage<\/strong>: JSON-encoded LONGTEXT\n<strong>Retrieval<\/strong>: JSON-decoded to PHP array\n<strong>Validation<\/strong>: Invalid JSON defaults to empty array<\/p><h3 class=\"wp-block-heading\">Metadata Object<\/h3><p><strong>Common Fields<\/strong>:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">[\n    &#039;message_count&#039; =&gt; 10,\n    &#039;last_activity&#039; =&gt; &#039;2024-01-01 12:00:00&#039;,\n    &#039;created_by&#039; =&gt; &#039;chat_interface&#039;,\n    &#039;version&#039; =&gt; &#039;1.0&#039;,\n    &#039;custom_field&#039; =&gt; &#039;custom_value&#039;\n]<\/code><\/pre><\/div><p><strong>Storage<\/strong>: JSON-encoded LONGTEXT\n<strong>Flexibility<\/strong>: Arbitrary key-value pairs allowed\n<strong>Retrieval<\/strong>: JSON-decoded to PHP array<\/p><h3 class=\"wp-block-heading\">Provider and Model Tracking<\/h3><p><strong>Purpose<\/strong>: Track which AI provider\/model used for conversation\n<strong>Updates<\/strong>: Set during first AI call, can be updated on subsequent calls\n<strong>Nullable<\/strong>: Can be NULL if not yet set<\/p><hr class=\"wp-block-separator\"\/><h2 class=\"wp-block-heading\">Performance Considerations<\/h2><h3 class=\"wp-block-heading\">Indexes<\/h3><p>Optimized for common query patterns:<\/p><ul class=\"wp-block-list\"><li><strong>session_id (PRIMARY)<\/strong>: Direct session lookup (O(1))<\/li><li><strong>user_id<\/strong>: User session queries<\/li><li><strong>created_at<\/strong>: Chronological ordering<\/li><li><strong>expires_at<\/strong>: Efficient cleanup queries<\/li><\/ul><h3 class=\"wp-block-heading\">JSON Storage<\/h3><p><strong>Benefits<\/strong>:<\/p><ul class=\"wp-block-list\"><li>Flexible message structure<\/li><li>No schema changes needed for metadata additions<\/li><li>Efficient storage for variable-length arrays<\/li><\/ul><p><strong>Considerations<\/strong>:<\/p><ul class=\"wp-block-list\"><li>JSON decoding overhead (minimal for chat usage)<\/li><li>Not indexed (full messages not searchable)<\/li><li>Acceptable for conversation-scoped queries<\/li><\/ul><hr class=\"wp-block-separator\"\/><h2 class=\"wp-block-heading\">Usage Examples<\/h2><h3 class=\"wp-block-heading\">Complete Session Lifecycle<\/h3><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">use DataMachineCoreDatabaseChatChat as ChatDatabase;\n\n$chat_db = new ChatDatabase();\n$user_id = get_current_user_id();\n\n\/\/ 1. Create new session\n$session_id = $chat_db-&gt;create_session($user_id, [\n    &#039;created_by&#039; =&gt; &#039;rest_api&#039;,\n    &#039;version&#039; =&gt; &#039;1.0&#039;\n]);\n\n\/\/ 2. First message exchange\n$messages = [\n    [&#039;role&#039; =&gt; &#039;user&#039;, &#039;content&#039; =&gt; &#039;Create a pipeline&#039;]\n];\n\n$chat_db-&gt;update_session($session_id, $messages, [\n    &#039;message_count&#039; =&gt; 1,\n    &#039;last_activity&#039; =&gt; gmdate(&#039;Y-m-d H:i:s&#039;)\n]);\n\n\/\/ 3. Continue conversation\n$session = $chat_db-&gt;get_session($session_id);\n$messages = $session[&#039;messages&#039;];\n$messages[] = [&#039;role&#039; =&gt; &#039;assistant&#039;, &#039;content&#039; =&gt; &#039;I&#039;ll create a pipeline for you...&#039;];\n\n$chat_db-&gt;update_session($session_id, $messages, [\n    &#039;message_count&#039; =&gt; count($messages),\n    &#039;last_activity&#039; =&gt; gmdate(&#039;Y-m-d H:i:s&#039;)\n], &#039;anthropic&#039;, &#039;claude-sonnet-4&#039;);\n\n\/\/ 4. Session expires automatically after 24 hours\n\/\/ Or manual cleanup:\n$chat_db-&gt;cleanup_expired_sessions();<\/code><\/pre><\/div><h3 class=\"wp-block-heading\">User Session Management<\/h3><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">\/\/ Get all user sessions (custom query)\nglobal $wpdb;\n$table = ChatDatabase::get_table_name();\n\n$user_sessions = $wpdb-&gt;get_results($wpdb-&gt;prepare(\n    &quot;SELECT session_id, created_at, updated_at FROM {$table}\n     WHERE user_id = %d AND expires_at &gt; %s\n     ORDER BY updated_at DESC&quot;,\n    get_current_user_id(),\n    current_time(&#039;mysql&#039;, true)\n), ARRAY_A);\n\n\/\/ Display active sessions to user\nforeach ($user_sessions as $session_info) {\n    echo &quot;Session: {$session_info[&#039;session_id&#039;]} (Updated: {$session_info[&#039;updated_at&#039;]})n&quot;;\n}<\/code><\/pre><\/div><hr class=\"wp-block-separator\"\/><h2 class=\"wp-block-heading\">Related Components<\/h2><ul class=\"wp-block-list\"><li>Chat API Endpoint &#8211; REST API using ChatDatabase<\/li><li>AIConversationLoop &#8211; Conversation execution<\/li><li>Universal Engine Architecture &#8211; Shared AI infrastructure<\/li><li>Database Schema &#8211; Complete database documentation<\/li><\/ul><hr class=\"wp-block-separator\"\/><p><strong>Location<\/strong>: <code>\/inc\/Core\/Database\/Chat\/Chat.php<\/code>\n<strong>Namespace<\/strong>: <code>DataMachineCoreDatabaseChat<\/code>\n<strong>Table<\/strong>: <code>wp_datamachine_chat_sessions<\/code>\n<strong>Since<\/strong>: v0.2.0<\/p>","protected":false},"excerpt":{"rendered":"<p>Location: \/inc\/Core\/Database\/Chat\/Chat.php Since: v0.2.0 (Universal Engine Architecture) Namespace: DataMachineCoreDatabaseChat Table: wp_datamachine_chat_sessions Overview ChatDatabase provides comprehensive session management for the Chat API, handling CRUD operations, user isolation, and automatic session expiration&#8230;.<\/p>\n","protected":false},"featured_media":0,"template":"","meta":{"footnotes":""},"tags":[],"project":[506],"project_type":[484],"class_list":["post-4960","documentation","type-documentation","status-publish","hentry","project-core-system","project_type-wordpress-plugins"],"project_info":{"id":487,"name":"Data Machine","slug":"data-machine"},"project_type_info":{"id":484,"name":"WordPress Plugins","slug":"wordpress-plugins"},"_links":{"self":[{"href":"https:\/\/chubes.net\/wp-json\/wp\/v2\/documentation\/4960","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/chubes.net\/wp-json\/wp\/v2\/documentation"}],"about":[{"href":"https:\/\/chubes.net\/wp-json\/wp\/v2\/types\/documentation"}],"version-history":[{"count":3,"href":"https:\/\/chubes.net\/wp-json\/wp\/v2\/documentation\/4960\/revisions"}],"predecessor-version":[{"id":9302,"href":"https:\/\/chubes.net\/wp-json\/wp\/v2\/documentation\/4960\/revisions\/9302"}],"wp:attachment":[{"href":"https:\/\/chubes.net\/wp-json\/wp\/v2\/media?parent=4960"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/chubes.net\/wp-json\/wp\/v2\/tags?post=4960"},{"taxonomy":"project","embeddable":true,"href":"https:\/\/chubes.net\/wp-json\/wp\/v2\/project?post=4960"},{"taxonomy":"project_type","embeddable":true,"href":"https:\/\/chubes.net\/wp-json\/wp\/v2\/project_type?post=4960"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}