BEGIN; ALTER TABLE conversation ADD COLUMN runtime_type varchar(32) NOT NULL DEFAULT 'legacy_voicechat' CHECK (runtime_type IN ('legacy_voicechat', 'volc_hardware_agent')); CREATE INDEX conversation_runtime_status_idx ON conversation (runtime_type, status, created_at DESC); CREATE TABLE hardware_agent_device_binding ( id uuid PRIMARY KEY DEFAULT gen_random_uuid(), public_id uuid NOT NULL UNIQUE DEFAULT gen_random_uuid(), tenant_id uuid NOT NULL REFERENCES tenant(id), device_id uuid NOT NULL, provider varchar(40) NOT NULL DEFAULT 'volcengine', product_key varchar(200), provider_device_ref varchar(200), credential_ref varchar(500), bot_id varchar(200) NOT NULL, transport varchar(32) NOT NULL DEFAULT 'high_quality' CHECK (transport IN ('high_quality', 'low_load')), status varchar(24) NOT NULL DEFAULT 'ACTIVE' CHECK (status IN ('ACTIVE', 'DISABLED', 'REVOKED')), created_at timestamptz NOT NULL DEFAULT now(), updated_at timestamptz NOT NULL DEFAULT now(), CONSTRAINT hardware_agent_binding_device_tenant_fk FOREIGN KEY (device_id, tenant_id) REFERENCES device (id, tenant_id), CONSTRAINT hardware_agent_binding_device_key UNIQUE (device_id) ); CREATE INDEX hardware_agent_binding_tenant_status_idx ON hardware_agent_device_binding (tenant_id, status); CREATE TABLE hardware_agent_session ( id uuid PRIMARY KEY DEFAULT gen_random_uuid(), public_id uuid NOT NULL UNIQUE DEFAULT gen_random_uuid(), tenant_id uuid NOT NULL REFERENCES tenant(id), conversation_id uuid NOT NULL UNIQUE, provider varchar(40) NOT NULL DEFAULT 'volcengine', provider_session_ref varchar(200) NOT NULL UNIQUE, bot_id varchar(200) NOT NULL, transport varchar(32) NOT NULL CHECK (transport IN ('high_quality', 'low_load')), session_nonce_digest char(64) NOT NULL, config_digest char(64) NOT NULL, status varchar(32) NOT NULL CHECK (status IN ('READY', 'STARTING', 'ACTIVE', 'STOPPING', 'COMPLETED', 'FAILED', 'EXPIRED')), wait_for_session_update boolean NOT NULL DEFAULT true, provider_started_at timestamptz, provider_ended_at timestamptz, last_event_at timestamptz, last_event_sequence bigint NOT NULL DEFAULT 0 CHECK (last_event_sequence >= 0), created_at timestamptz NOT NULL DEFAULT now(), updated_at timestamptz NOT NULL DEFAULT now(), CONSTRAINT hardware_agent_session_conversation_tenant_fk FOREIGN KEY (conversation_id, tenant_id) REFERENCES conversation (id, tenant_id) ); CREATE INDEX hardware_agent_session_tenant_status_idx ON hardware_agent_session (tenant_id, status, updated_at DESC); CREATE TABLE hardware_agent_event ( id uuid PRIMARY KEY DEFAULT gen_random_uuid(), tenant_id uuid NOT NULL REFERENCES tenant(id), conversation_id uuid NOT NULL, event_id varchar(255) NOT NULL, sequence_no bigint NOT NULL CHECK (sequence_no > 0), event_type varchar(64) NOT NULL, occurred_at timestamptz NOT NULL, payload_digest char(64) NOT NULL, created_at timestamptz NOT NULL DEFAULT now(), CONSTRAINT hardware_agent_event_conversation_tenant_fk FOREIGN KEY (conversation_id, tenant_id) REFERENCES conversation (id, tenant_id), CONSTRAINT hardware_agent_event_key UNIQUE (tenant_id, event_id), CONSTRAINT hardware_agent_event_sequence_key UNIQUE (conversation_id, sequence_no) ); COMMENT ON COLUMN conversation.runtime_type IS 'legacy_voicechat uses platform-managed RTC/VoiceChat; volc_hardware_agent uses device-to-provider audio with platform control-plane sessions.'; COMMIT;