feat: free-tier credit system + Syttende Mai access for Google users

- FreeTier.php: credit check/deduct/reset engine with hourly rate limit
- bootstrap.php: dbnmDb() singleton, dbnToolsIsFreeTier(), credit gate helpers
- index.php: store tier=free|approved in session from SSO JWT
- All 7 API endpoints: credit gate (402/429) + X-Credits-Remaining header
- layout.php: credit meta tag, JS balance var, Syttende Mai banner (05-17 only)
- tools.js: credit badge in topbar, 402 modal, 429 toast, dbnUpdateCredits()
- barnevernet.js + deep-research.js: wire 402/429 handling for NDJSON streams
- tools.css: styles for credit badge, no-credits modal, rate-limit toast

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-16 21:05:08 +02:00
parent 568314c554
commit 8b77acb828
15 changed files with 464 additions and 2 deletions
+3
View File
@@ -6,6 +6,8 @@ require_once __DIR__ . '/../includes/DeepResearchAgent.php';
dbnToolsRequireMethod('POST');
dbnToolsRequireAuth();
$ftUid = dbnToolsFreeTierCheck('deep-research');
$ftRemaining = dbnToolsFreeTierDeduct($ftUid, 'deep-research');
// Stream-friendly response — defeat output buffering so the user's browser
// receives progress events while the agent runs (can take 60-180s for
@@ -19,6 +21,7 @@ ob_implicit_flush(true);
header('Content-Type: application/x-ndjson; charset=utf-8');
header('Cache-Control: no-store');
header('X-Accel-Buffering: no');
if ($ftRemaining >= 0) { header('X-Credits-Remaining: ' . $ftRemaining); }
$language = 'en';
$startTime = microtime(true);