feat: add LLM cost tracking with budget enforcement and admin dashboard
- New Cost_Tracker class: logs every API call (model, tokens, cost), enforces monthly budgets with hard-stop mode, provides aggregated reporting - New llm_costs database table with indexes on created_at, model, operation - Modified LLM class: call_openrouter_with_usage() extracts token usage from OpenRouter responses; budget gate checks before each API call - Admin settings: monthly budget (USD), enforcement mode (disabled/warn/hard-stop), cost log retention period - Admin cost dashboard: budget progress bar, daily cost chart (Chart.js), per-model and per-operation breakdowns, recent API call log - PHPUnit tests: 16 tests covering cost calculation, pricing lookups, budget enforcement logic, and model validation - Updated ARCHITECTURE.md with new table schema, data flow, and key decisions - Updated CONVENTIONS.md with "how to add cost tracking for a new operation" - Version bump to 2.4.0 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
9
includes/class-peptide-news-rest-api.php
Normal file → Executable file
9
includes/class-peptide-news-rest-api.php
Normal file → Executable file
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
declare( strict_types=1 );
|
||||
/**
|
||||
* REST API endpoints for external analytics access.
|
||||
*
|
||||
@@ -22,7 +23,7 @@ class Peptide_News_Rest_API {
|
||||
/**
|
||||
* Register REST routes.
|
||||
*/
|
||||
public function register_routes() {
|
||||
public function register_routes(): void {
|
||||
|
||||
// Public: list articles.
|
||||
register_rest_route( self::API_NAMESPACE, '/articles', array(
|
||||
@@ -83,7 +84,7 @@ class Peptide_News_Rest_API {
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_date_range_args() {
|
||||
private function get_date_range_args(): array {
|
||||
return array(
|
||||
'start_date' => array(
|
||||
'default' => gmdate( 'Y-m-d', strtotime( '-30 days' ) ),
|
||||
@@ -216,7 +217,7 @@ class Peptide_News_Rest_API {
|
||||
* @param string $source_url The source URL (used to extract domain-based publisher names).
|
||||
* @return string Cleaned text.
|
||||
*/
|
||||
private function strip_source_suffix( $text, $source, $source_url = '' ) {
|
||||
private function strip_source_suffix( string $text, string $source, string $source_url = '' ): string {
|
||||
if ( empty( $text ) ) {
|
||||
return $text;
|
||||
}
|
||||
@@ -387,7 +388,7 @@ class Peptide_News_Rest_API {
|
||||
*
|
||||
* @since 2.1.0
|
||||
*/
|
||||
public static function ajax_delete_articles() {
|
||||
public static function ajax_delete_articles(): void {
|
||||
check_ajax_referer( 'peptide_news_admin', 'nonce' );
|
||||
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
|
||||
Reference in New Issue
Block a user