mirror of
https://github.com/OpenSquawk/OpenSquawk
synced 2026-08-07 01:55:51 +08:00
feat(server): per-user AI usage tracking, cost alerting, and endpoint hardening
Usage tracking: - new UsageEvent collection records every STT/TTS/LLM call per user with provider, model, volume (audio seconds, characters, tokens) and an estimated USD cost; self-hosted providers (Speaches/Piper) and cache hits record at $0 - pricing table for whisper-1, tts-1, gpt-5-nano & co. in server/utils/usage.ts - weekly KPI mail gains an "AI-Nutzung & Kosten" section: weekly and rolling 30-day cost, per-kind breakdown, top 5 users by cost - quota alert mail when rolling 30-day cost exceeds USAGE_ALERT_USD (default $5), at most once per calendar month (UsageAlertDelivery) Hardening: - /api/atc/say now requires an authenticated session (middleware exemption removed); useFlightLabAudio sends the bearer token - /api/service/tools/latency requires auth (was a public LLM endpoint) - per-user rate limits: PTT 20/min, say 60/min, latency 5/min - cron endpoints (waitlist-drip, weekly-kpi-report) require a shared secret via ?secret= or x-cron-secret (CRON_SECRET, falls back to KPI_CRON_SECRET); allowed with a warning while unset so existing deployments keep working - PTT records the actual transcribed audio duration for billing accuracy Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,9 @@
|
||||
import { createError } from 'h3'
|
||||
import { getOpenAIClient } from '../../../utils/openai'
|
||||
import { getServerRuntimeConfig } from '../../../utils/runtimeConfig'
|
||||
import { requireUserSession } from '../../../utils/auth'
|
||||
import { enforceRateLimit } from '../../../utils/rateLimit'
|
||||
import { recordUsage } from '../../../utils/usage'
|
||||
|
||||
const SYSTEM_PROMPT =
|
||||
'Check if the pilot readback contains ALL of: Frankfurt or EDDF, FL320, and 120.8 MHz. ' +
|
||||
@@ -10,7 +13,10 @@ const SYSTEM_PROMPT =
|
||||
const READBACK =
|
||||
'Lufthanser four seven eight cleared fra via NORDA1A, climb 5000 feet, expect flight level tree too zero, dep 120 decimal 8, squawk 4213.';
|
||||
|
||||
export default defineEventHandler(async () => {
|
||||
export default defineEventHandler(async (event) => {
|
||||
const user = await requireUserSession(event)
|
||||
enforceRateLimit(event, 'tools-latency', String(user._id), 5)
|
||||
|
||||
const client = getOpenAIClient()
|
||||
const { llmModel } = getServerRuntimeConfig()
|
||||
const model = llmModel || 'chatgpt-5-nano'
|
||||
@@ -32,6 +38,16 @@ export default defineEventHandler(async () => {
|
||||
const validResult = Number.isInteger(parsed) && parsed >= 0 && parsed <= 2 ? parsed : null
|
||||
const latencyMs = Date.now() - started
|
||||
|
||||
await recordUsage({
|
||||
user: String(user._id),
|
||||
kind: 'llm',
|
||||
provider: 'openai',
|
||||
model,
|
||||
endpoint: '/api/service/tools/latency',
|
||||
inputTokens: response.usage?.prompt_tokens,
|
||||
outputTokens: response.usage?.completion_tokens,
|
||||
})
|
||||
|
||||
return {
|
||||
result: validResult,
|
||||
raw,
|
||||
|
||||
Reference in New Issue
Block a user