Adding Groq‑Powered AI Summaries to the ISO‑27001 Dashboard with Daily Usage Limits A developer added server-side Groq-powered AI summaries to an ISO-27001 compliance dashboard, moving the Groq API key out of the client bundle and into server-only environment variables to fix a 401 Unauthorized leak. A usage-counter middleware backed by a new ai_usage table enforces a per-day token quota (AI_DAILY_LIMIT, set to 2000) and returns a quota-exhausted error instead of letting requests hit Groq's 429 rate limit. The summaries are generated through Next.js 13 server actions and surfaced via AiButton and AiText components without a full page reload. TL;DR: Integrated server‑side Groq calls to generate daily AI summaries for each analysis page, added a usage‑counter middleware and UI components AiButton , AiText . This keeps API keys secret, enforces a per‑day quota, and surfaces results without a full page reload. The ISO‑27001 dashboard lets auditors view controls, policies, and daily logs. A recurring request from the team was to get an AI‑generated summary of each analysis /analisis/ id that highlighted gaps and suggested next steps. Two technical blockers surfaced: The symptom was a broken “Generate Summary” button that either threw a 401 Unauthorized key exposed or let anyone hammer the endpoint until the quota was exhausted, resulting in 429 Too Many Requests from Groq. My first attempt was a client‑side fetch from components/ai-button.tsx : js // early prototype removed const resp = await fetch "https://api.groq.com/openai/v1/chat/completions", { method: "POST", headers: { Authorization: Bearer ${process.env.NEXT PUBLIC GROQ KEY} }, body: JSON.stringify payload , } ; Issues: NEXT PUBLIC GROQ KEY leaked into the bundle, visible in Chrome dev tools. localhost:3000 . I also tried wrapping the fetch in a Next.js API route pages/api/ai.ts but hit the same quota‑blow problem because the route lacked any persistence of usage counts. Result: the button either failed with a 401 or kept consuming tokens until the daily budget was spent, after which every call returned a 429. Added the Groq key to .env.example never committed the real value : + GROQ API KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxx + AI DAILY LIMIT=2000 token budget per day The production .env now contains the real key, and the code only accesses it via process.env.GROQ API KEY on the server. lib/ai.ts Created a thin wrapper around the Groq client that also tracks daily usage: js // lib/ai.ts import { Groq } from "groq-sdk"; import { db } from "@/lib/db"; export const groq = new Groq { apiKey: process.env.GROQ API KEY } ; export const aiEnabled = process.env.GROQ API KEY == undefined; export const dailyLimit = Number process.env.AI DAILY LIMIT ?? 0 ; / Returns true if we have quota left for today / export async function canUseAi : Promise