Fix cost-tracker SELECT against canonical schema (v0.15.1)

The cost-preview probe in get_avg_tokens_for_stages() referenced
input_tokens/output_tokens/timestamp, which don't exist. Canonical
columns are prompt_tokens/completion_tokens/created_at. Empty-result
fallback was masking the failure functionally, but the wpdb debug
notice was visibly leaking to every admin visit of the AI Models tab.

Adds regression tests that assert $wpdb->last_error after the call,
so the next schema drift won't be masked the same way.

Bug present since v0.11.0 (2026-04-23).

Agent-Session: engineer-prautoblogger cost-tracker-schema-mismatch
This commit is contained in:
peptiderepo
2026-05-14 16:40:51 +08:00
parent 96f0248d81
commit 0bac52d268
4 changed files with 153 additions and 11 deletions

View File

@@ -235,19 +235,19 @@ class PRAutoBlogger_Cost_Tracker {
);
}
$cutoff_time = time() - ( $days * DAY_IN_SECONDS );
$stage_list = implode( ',', array_map( array( $wpdb, 'prepare' ), array_fill( 0, count( $stages ), '%s' ), $stages ) );
$table_name = $wpdb->prefix . 'prautoblogger_generation_log';
$cutoff_datetime = gmdate( 'Y-m-d H:i:s', time() - ( $days * DAY_IN_SECONDS ) );
$stage_list = implode( ',', array_map( array( $wpdb, 'prepare' ), array_fill( 0, count( $stages ), '%s' ), $stages ) );
$table_name = $wpdb->prefix . 'prautoblogger_generation_log';
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Prepared stage list via array_map + prepare
$query = $wpdb->prepare(
"SELECT AVG(input_tokens) as avg_input,
AVG(output_tokens) as avg_output,
"SELECT AVG(prompt_tokens) as avg_prompt,
AVG(completion_tokens) as avg_completion,
COUNT(*) as sample_count
FROM $table_name
WHERE stage IN ( $stage_list )
AND timestamp >= %d",
$cutoff_time
AND created_at >= %s",
$cutoff_datetime
);
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- phpcs pragma above
@@ -262,8 +262,8 @@ class PRAutoBlogger_Cost_Tracker {
}
return array(
'avg_prompt_tokens' => (float) ( $result['avg_input'] ?? 0 ),
'avg_completion_tokens' => (float) ( $result['avg_output'] ?? 0 ),
'avg_prompt_tokens' => (float) ( $result['avg_prompt'] ?? 0 ),
'avg_completion_tokens' => (float) ( $result['avg_completion'] ?? 0 ),
'sample_size' => (int) ( $result['sample_count'] ?? 0 ),
);
}