a199891a3c
Deploy to VPS / deploy (push) Has been cancelled
Two production-grade hardening additions and one cost optimisation. FLUXAI AUTONOMY RESTORED (api/chat) - Brings back the multi-step agentic flow that the system prompt was always designed for. The "temporarily removed maxSteps" comment is gone — replaced with the AI SDK 6 equivalent stopWhen: stepCountIs(5). - Cap at 5 chained tool calls per turn bounds latency + LLM cost. - maxDuration raised 30s → 60s to absorb tool-chain runs. - Result: one user prompt now triggers, e.g. search_installations → energy_savings_calculator → show_case_study → schedule_consultation in a single turn — exactly the SPIN methodology in the prompt. RATE LIMITING (src/lib/rateLimit.ts + api/chat) - Token-bucket per IP: 30 messages burst, sustained 30/minute. Trips to 429 with Retry-After + X-RateLimit-Remaining headers when abused. - IP extracted from x-forwarded-for (Nginx already passes this). - In-memory Map with 10-min GC of stale buckets — no Redis dep. If we scale to multiple replicas later, swap the Map for Upstash. - Protects the OpenAI quota from someone hammering the chat endpoint. IMAGE PIPELINE (src/lib/imageOptimizer.ts) - sharp-based optimizer: auto-orient (EXIF), cap at 2560px long side, re-encode WebP@85, content-hash filename. Re-uploads with same content reuse the same hash; new content gets a new URL — perfect cache invalidation without header tricks. - Opt-in via optimize=1 form/query param on /api/assets POST. - Hero CMS and Site Settings uploads turn it on automatically (those are user-facing brand assets where compression matters most). - App/news/parts uploads remain untouched (editors may be uploading CAD drawings, datasheets, etc. that shouldn't be transcoded). - Falls back gracefully to a no-op for unsupported formats (SVG, GIF, videos, anything sharp can't decode) so it never breaks an upload. DOCKERFILE - Adds vips/vips-dev for sharp on Alpine + --include=optional so the @img/sharp-linuxmusl-x64 prebuilt is downloaded - Explicitly copies node_modules/sharp + node_modules/@img to the runner stage (Next.js trace can miss conditional deps). NO DB SCHEMA CHANGES.
56 lines
1.3 KiB
JSON
56 lines
1.3 KiB
JSON
{
|
|
"name": "flux-srl",
|
|
"version": "0.1.0",
|
|
"private": true,
|
|
"scripts": {
|
|
"dev": "next dev",
|
|
"build": "next build",
|
|
"start": "next start",
|
|
"lint": "eslint"
|
|
},
|
|
"dependencies": {
|
|
"@ai-sdk/openai": "^3.0.41",
|
|
"@ai-sdk/react": "^3.0.118",
|
|
"@prisma/adapter-pg": "^7.5.0",
|
|
"@prisma/client": "^7.5.0",
|
|
"@react-three/drei": "^10.7.7",
|
|
"@react-three/fiber": "^9.5.0",
|
|
"@types/nodemailer": "^7.0.11",
|
|
"ai": "^6.0.116",
|
|
"bcryptjs": "^3.0.3",
|
|
"clsx": "^2.1.1",
|
|
"framer-motion": "^12.35.2",
|
|
"jose": "^6.2.1",
|
|
"lucide-react": "^0.577.0",
|
|
"next": "16.1.6",
|
|
"next-intl": "^4.8.3",
|
|
"nodemailer": "^8.0.2",
|
|
"pg": "^8.20.0",
|
|
"qrcode": "^1.5.4",
|
|
"react": "19.2.4",
|
|
"react-dom": "19.2.4",
|
|
"resend": "^6.9.3",
|
|
"sharp": "^0.34.5",
|
|
"speakeasy": "^2.0.0",
|
|
"tailwind-merge": "^3.5.0",
|
|
"three": "^0.183.2",
|
|
"zod": "^4.3.6",
|
|
"zustand": "^5.0.11"
|
|
},
|
|
"devDependencies": {
|
|
"@tailwindcss/postcss": "^4",
|
|
"@types/bcryptjs": "^3.0.0",
|
|
"@types/node": "^25",
|
|
"@types/pg": "^8.18.0",
|
|
"@types/qrcode": "^1.5.6",
|
|
"@types/react": "^19",
|
|
"@types/react-dom": "^19",
|
|
"@types/speakeasy": "^2.0.10",
|
|
"eslint": "^10",
|
|
"eslint-config-next": "16.1.6",
|
|
"prisma": "^7.5.0",
|
|
"tailwindcss": "^4",
|
|
"typescript": "^5"
|
|
}
|
|
}
|