<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Jaber-Said</title>
    <description>The latest articles on Forem by Jaber-Said (@jaber-said).</description>
    <link>https://forem.com/jaber-said</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1013616%2F745c4de2-3c09-4e84-ac91-b16166bfdfde.png</url>
      <title>Forem: Jaber-Said</title>
      <link>https://forem.com/jaber-said</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/jaber-said"/>
    <language>en</language>
    <item>
      <title>SEO Isn’t Dead — It Just Got a Second Interface (How to Show Up in Google and AI Answers)</title>
      <dc:creator>Jaber-Said</dc:creator>
      <pubDate>Mon, 09 Mar 2026 02:53:09 +0000</pubDate>
      <link>https://forem.com/jaber-said/seo-isnt-dead-it-just-got-a-second-interface-how-to-show-up-in-google-and-ai-answers-17mo</link>
      <guid>https://forem.com/jaber-said/seo-isnt-dead-it-just-got-a-second-interface-how-to-show-up-in-google-and-ai-answers-17mo</guid>
      <description>&lt;p&gt;Search used to mean “10 blue links.” Now it’s also summaries, citations, map packs, “AI Overviews,” and chatbot-style answers. The good news: the fundamentals still work. The new news: you also need to help language models understand who you are (entity) and what you’re the best answer for (intent + evidence).&lt;/p&gt;

&lt;p&gt;This article covers:&lt;/p&gt;

&lt;p&gt;A practical, modern explanation of website SEO (with examples).&lt;/p&gt;

&lt;p&gt;How to analyze language models’ behavior when they recommend websites/services.&lt;/p&gt;

&lt;p&gt;A long, copy‑paste prompt you can give a coding agent in your editor to audit and implement SEO + AI visibility improvements.&lt;/p&gt;

&lt;p&gt;Part 1 — SEO for Websites (What matters in 2026, in plain terms)&lt;/p&gt;

&lt;p&gt;What SEO is (and why it still prints money)&lt;/p&gt;

&lt;p&gt;Search Engine Optimization (SEO) is the work of making your site easy for search engines to crawl, index, and rank for queries that matter to your business.&lt;/p&gt;

&lt;p&gt;Search engines generally do three things:&lt;/p&gt;

&lt;p&gt;Crawl: discover URLs by following links + sitemaps.&lt;/p&gt;

&lt;p&gt;Index: render + understand pages; store them in a searchable index.&lt;/p&gt;

&lt;p&gt;Rank: choose which indexed pages best match a query using relevance, quality, authority, UX, and more.&lt;/p&gt;

&lt;p&gt;If you improve crawlability + understanding + trust + usefulness, your rankings tend to follow.&lt;/p&gt;

&lt;p&gt;The core pillars of SEO (with concrete examples)&lt;/p&gt;

&lt;p&gt;1) Technical SEO (the “plumbing”)&lt;/p&gt;

&lt;p&gt;Technical SEO ensures your site can be discovered, rendered, and indexed correctly.&lt;/p&gt;

&lt;p&gt;Key checks:&lt;/p&gt;

&lt;p&gt;robots.txt + noindex: Don’t accidentally block important pages.&lt;/p&gt;

&lt;p&gt;Example disaster: a staging noindex tag ships to production → organic traffic falls off a cliff.&lt;/p&gt;

&lt;p&gt;XML sitemap: Helps crawlers find all indexable pages.&lt;/p&gt;

&lt;p&gt;Canonical URLs: Prevent duplicate URL variants (e.g., /?ref=…, trailing slashes, www vs non-www) from splitting signals.&lt;/p&gt;

&lt;p&gt;Mobile-first: Google primarily indexes mobile. Your mobile experience is not “nice-to-have.”&lt;/p&gt;

&lt;p&gt;Core Web Vitals: Speed + stability + responsiveness affect both rankings and conversions.&lt;/p&gt;

&lt;p&gt;HTTPS: baseline trust + security.&lt;/p&gt;

&lt;p&gt;Structured data (Schema.org): helps engines interpret meaning (Organization, LocalBusiness, Service, FAQPage, etc.).&lt;/p&gt;

&lt;p&gt;Example: A dental clinic adds LocalBusiness schema (address, hours, services). Result: richer SERP appearance and higher click-through rate (CTR) because searchers see instant trust signals.&lt;/p&gt;

&lt;p&gt;2) On-page SEO (make each page the best answer)&lt;/p&gt;

&lt;p&gt;On-page SEO is about aligning each page to search intent and making it the best, clearest answer.&lt;/p&gt;

&lt;p&gt;Search intent types:&lt;/p&gt;

&lt;p&gt;Informational: “how does solar energy work”&lt;/p&gt;

&lt;p&gt;Commercial investigation: “best solar panel installers 2026”&lt;/p&gt;

&lt;p&gt;Transactional: “buy solar panels online”&lt;/p&gt;

&lt;p&gt;Navigational: “BrandName login”&lt;/p&gt;

&lt;p&gt;If someone searches “roof replacement cost,” and your page only says “contact us,” that’s a mismatch.&lt;/p&gt;

&lt;p&gt;Modern on-page essentials:&lt;/p&gt;

&lt;p&gt;Unique title tags + meta descriptions (CTR matters even if meta descriptions aren’t a direct ranking factor).&lt;/p&gt;

&lt;p&gt;One clear H1, logical H2/H3 hierarchy.&lt;/p&gt;

&lt;p&gt;Depth that satisfies: process, pricing factors, FAQs, proof, next steps.&lt;/p&gt;

&lt;p&gt;Internal linking: connect related pages so authority and context flow through your site.&lt;/p&gt;

&lt;p&gt;Image optimization: descriptive filenames + alt text + modern formats + correct lazy-loading.&lt;/p&gt;

&lt;p&gt;Example: A plumbing company expands “Water Heater Installation” from 150 words to a real guide: tank vs tankless, sizing, permits, timeline, warranties, FAQs, reviews. They start ranking for dozens of long-tail queries and conversions rise because users trust the clarity.&lt;/p&gt;

&lt;p&gt;3) Off-page SEO (authority you don’t fully control)&lt;/p&gt;

&lt;p&gt;Off-page SEO is reputation and authority: backlinks, mentions, reviews, and brand demand.&lt;/p&gt;

&lt;p&gt;The rule: one strong link from a trusted industry site can beat 200 weak directory links.&lt;/p&gt;

&lt;p&gt;Practical strategies:&lt;/p&gt;

&lt;p&gt;Digital PR (original data, expert commentary)&lt;/p&gt;

&lt;p&gt;Partnerships + associations&lt;/p&gt;

&lt;p&gt;Linkable assets (calculators, benchmarks, definitive guides)&lt;/p&gt;

&lt;p&gt;Review growth (especially for local)&lt;/p&gt;

&lt;p&gt;Example: An accounting firm publishes a yearly deductions guide with original analysis. Local business publications cite it. The firm’s service pages rank better because the domain’s authority improves.&lt;/p&gt;

&lt;p&gt;4) Local SEO (if you serve geographic areas)&lt;/p&gt;

&lt;p&gt;Local visibility is its own game: Google Business Profile (GBP), reviews, citations, and location relevance.&lt;/p&gt;

&lt;p&gt;Local ranking factors:&lt;/p&gt;

&lt;p&gt;Relevance: do you match the query?&lt;/p&gt;

&lt;p&gt;Distance: proximity to searcher/service area&lt;/p&gt;

&lt;p&gt;Prominence: authority + reviews + mentions + links&lt;/p&gt;

&lt;p&gt;Example: A pest control company creates a city page that’s actually local (local pests, local codes, local case studies). It beats competitors using templated “find/replace city name” pages.&lt;/p&gt;

&lt;p&gt;5) Content strategy (stop blogging randomly)&lt;/p&gt;

&lt;p&gt;Random posts are content calories; strategy is nutrition.&lt;/p&gt;

&lt;p&gt;A good plan:&lt;/p&gt;

&lt;p&gt;Map content to the buyer journey (awareness → consideration → decision).&lt;/p&gt;

&lt;p&gt;Build topic clusters (pillar page + supporting articles interlinked).&lt;/p&gt;

&lt;p&gt;Refresh top pages quarterly (update stats, expand sections, merge thin/overlapping pages).&lt;/p&gt;

&lt;p&gt;6) Measurement (SEO without measurement is guesswork)&lt;/p&gt;

&lt;p&gt;Tools:&lt;/p&gt;

&lt;p&gt;Google Search Console: queries, CTR, indexing, Core Web Vitals&lt;/p&gt;

&lt;p&gt;Analytics (GA4 or privacy-focused alternatives): engagement + conversion&lt;/p&gt;

&lt;p&gt;Metrics that matter:&lt;/p&gt;

&lt;p&gt;Impressions (visibility)&lt;/p&gt;

&lt;p&gt;CTR (appeal)&lt;/p&gt;

&lt;p&gt;Conversions (business value)&lt;/p&gt;

&lt;p&gt;Index coverage (technical health)&lt;/p&gt;

&lt;p&gt;Example: Add FAQ schema + improve title → impressions +40%, CTR 2.1% → 3.8%, leads +30% in two months.&lt;/p&gt;

&lt;p&gt;Part 2 — Optimizing for AI Language Models (GEO) + How to Analyze Model Recommendations&lt;/p&gt;

&lt;p&gt;When users ask ChatGPT/Claude/Copilot/Perplexity/Google AI Overviews “who’s best for X,” these systems may recommend providers and cite sources. That’s Generative Engine Optimization (GEO): improving the likelihood you’re mentioned, recommended, or cited.&lt;/p&gt;

&lt;p&gt;How LLM-based systems “know” and recommend sites&lt;/p&gt;

&lt;p&gt;Most real-world assistants combine:&lt;/p&gt;

&lt;p&gt;Training knowledge (static; has a cutoff; not reliably up-to-date)&lt;/p&gt;

&lt;p&gt;Retrieval / live search (RAG) (pulls current pages, then summarizes/cites)&lt;/p&gt;

&lt;p&gt;Knowledge graphs / trusted datasets (entities, facts, relationships)&lt;/p&gt;

&lt;p&gt;If a system uses retrieval, traditional SEO directly increases the chance your pages get pulled as evidence.&lt;/p&gt;

&lt;p&gt;GEO fundamentals (what actually helps)&lt;/p&gt;

&lt;p&gt;1) Entity clarity (make it easy to identify your business)&lt;/p&gt;

&lt;p&gt;LLMs handle “entities” better than “vibes.” Ensure consistent:&lt;/p&gt;

&lt;p&gt;business name&lt;/p&gt;

&lt;p&gt;service categories&lt;/p&gt;

&lt;p&gt;location/service area&lt;/p&gt;

&lt;p&gt;phone/address&lt;/p&gt;

&lt;p&gt;about/credentials&lt;/p&gt;

&lt;p&gt;sameAs links (social profiles)&lt;/p&gt;

&lt;p&gt;This consistency should appear across:&lt;/p&gt;

&lt;p&gt;your site (footer, contact, about)&lt;/p&gt;

&lt;p&gt;GBP, major directories, association listings&lt;/p&gt;

&lt;p&gt;reputable third-party mentions&lt;/p&gt;

&lt;p&gt;2) “Answer-shaped” content (AI loves direct answers)&lt;/p&gt;

&lt;p&gt;LLMs and retrieval systems extract best from:&lt;/p&gt;

&lt;p&gt;clear declarative statements near the top (“We provide X in Y since Z”)&lt;/p&gt;

&lt;p&gt;FAQs and Q&amp;amp;A sections&lt;/p&gt;

&lt;p&gt;lists, tables, comparisons&lt;/p&gt;

&lt;p&gt;specific claims with constraints (“Plans start at $150/month for up to 5,000 sq ft…”)&lt;br&gt;
(Don’t invent numbers. Be precise and honest.)&lt;/p&gt;

&lt;p&gt;3) Structured data (schema) as machine-readable reinforcement&lt;/p&gt;

&lt;p&gt;Schema doesn’t guarantee rankings, but it strengthens understanding and can unlock rich results and citations.&lt;/p&gt;

&lt;p&gt;4) Diverse, credible third-party presence&lt;/p&gt;

&lt;p&gt;AI systems trust what the web “agrees” on. Earn mentions in:&lt;/p&gt;

&lt;p&gt;reputable reviews and directories (industry-specific is best)&lt;/p&gt;

&lt;p&gt;local press / trade journals&lt;/p&gt;

&lt;p&gt;podcasts (transcripts get indexed)&lt;/p&gt;

&lt;p&gt;community discussions where you genuinely help (not spam)&lt;/p&gt;

&lt;p&gt;5) “Recommendation queries” strategy&lt;/p&gt;

&lt;p&gt;Identify prompts users ask AI:&lt;/p&gt;

&lt;p&gt;“Best [service] in [city]?”&lt;/p&gt;

&lt;p&gt;“Who should I hire for [problem]?”&lt;/p&gt;

&lt;p&gt;“What does [service] cost in [location]?”&lt;br&gt;
Then create pages that answer these directly (and earn mentions in listicles that rank for them).&lt;/p&gt;

&lt;p&gt;How to analyze AI language models when they recommend your website&lt;/p&gt;

&lt;p&gt;You can’t treat LLM recommendations like classic rank tracking. You need a repeatable evaluation harness.&lt;/p&gt;

&lt;p&gt;A) Build a query test set (your “AI visibility benchmark”)&lt;/p&gt;

&lt;p&gt;Create 30–100 prompts that mirror real buyers. Mix:&lt;/p&gt;

&lt;p&gt;short: “best commercial plumber in Austin”&lt;/p&gt;

&lt;p&gt;long: “I manage an office building; recurring drain backups; what should I do and who do you recommend?”&lt;/p&gt;

&lt;p&gt;comparison: “French drain vs sump pump”&lt;/p&gt;

&lt;p&gt;trust: “licensed/insured [service] near me”&lt;/p&gt;

&lt;p&gt;pricing: “how much does X cost in Y?”&lt;/p&gt;

&lt;p&gt;Run them across:&lt;/p&gt;

&lt;p&gt;multiple models (ChatGPT, Claude, Perplexity, Copilot, etc.)&lt;/p&gt;

&lt;p&gt;multiple locations (VPN or location settings if relevant)&lt;/p&gt;

&lt;p&gt;multiple times (variance is real)&lt;/p&gt;

&lt;p&gt;Record: whether you’re mentioned, how you’re described, and what sources are cited.&lt;/p&gt;

&lt;p&gt;B) Separate “model memory” from “retrieval”&lt;/p&gt;

&lt;p&gt;For each query, test:&lt;/p&gt;

&lt;p&gt;with browsing/retrieval on (if available)&lt;/p&gt;

&lt;p&gt;with browsing off (if possible)&lt;/p&gt;

&lt;p&gt;If you only appear with retrieval on, SEO + citations are your lever.&lt;br&gt;
If you appear without retrieval, brand/entity presence in training data and common corpora is likely influencing it (a slower, PR-like game).&lt;/p&gt;

&lt;p&gt;C) Audit the citations (this is the actionable part)&lt;/p&gt;

&lt;p&gt;When the model cites sources:&lt;/p&gt;

&lt;p&gt;Are your pages cited?&lt;/p&gt;

&lt;p&gt;Are third-party pages mentioning you cited? (Often the real driver for “best X” queries.)&lt;/p&gt;

&lt;p&gt;Are citations accurate and current?&lt;/p&gt;

&lt;p&gt;Are you missing from “best of” pages that dominate results?&lt;/p&gt;

&lt;p&gt;This tells you whether to focus on:&lt;/p&gt;

&lt;p&gt;improving your page to rank higher (traditional SEO), or&lt;/p&gt;

&lt;p&gt;getting included in the sources that AI systems already trust (PR/directories/reviews).&lt;/p&gt;

&lt;p&gt;D) Check for brand/entity confusion&lt;/p&gt;

&lt;p&gt;Common failure modes:&lt;/p&gt;

&lt;p&gt;inconsistent name variants (“Acme Co.” vs “Acme Group LLC”)&lt;/p&gt;

&lt;p&gt;mismatched addresses/phone numbers across directories&lt;/p&gt;

&lt;p&gt;unclear service area boundaries&lt;/p&gt;

&lt;p&gt;multiple similar brands&lt;/p&gt;

&lt;p&gt;Fixing entity clarity often improves both local SEO and AI recommendation confidence.&lt;/p&gt;

&lt;p&gt;E) Evaluate answer quality (not just mentions)&lt;/p&gt;

&lt;p&gt;Even if you’re cited, ask:&lt;/p&gt;

&lt;p&gt;Did the model describe your services correctly?&lt;/p&gt;

&lt;p&gt;Did it invent features you don’t have? (hallucination risk)&lt;/p&gt;

&lt;p&gt;Did it list wrong contact info?&lt;/p&gt;

&lt;p&gt;If yes, you need:&lt;/p&gt;

&lt;p&gt;clearer “facts” on your site (About, Contact, Service pages)&lt;/p&gt;

&lt;p&gt;schema reinforcement&lt;/p&gt;

&lt;p&gt;consistent third-party listings&lt;/p&gt;

&lt;p&gt;and sometimes “myth-busting” FAQ content (e.g., “Do you offer 24/7 emergency service?”)&lt;/p&gt;

&lt;p&gt;F) Instrument your own product (if you run an assistant/chat on your site)&lt;/p&gt;

&lt;p&gt;If your site has an AI assistant that recommends your services, analyze it like any other system:&lt;/p&gt;

&lt;p&gt;Log user intents (anonymized), top questions, and drop-off points.&lt;/p&gt;

&lt;p&gt;Evaluate retrieval quality (what pages were fetched, were they relevant, were they fresh).&lt;/p&gt;

&lt;p&gt;Add guardrails: “don’t claim pricing unless from pricing page,” “always cite the contact page for phone/address,” etc.&lt;/p&gt;

&lt;p&gt;Use a golden set of test questions and run regression tests after content changes.&lt;/p&gt;

&lt;p&gt;Part 3 — Using an AI Coding Agent to Implement SEO at Scale (safely)&lt;/p&gt;

&lt;p&gt;AI agents inside editors (Cursor/Windsurf/Cline) can do real work: crawl the repo, detect frameworks, add sitemaps, implement schema, optimize metadata, and generate reports.&lt;/p&gt;

&lt;p&gt;To keep this from turning into a “helpful raccoon in your attic” situation:&lt;/p&gt;

&lt;p&gt;Require diffs and avoid silent sweeping rewrites&lt;/p&gt;

&lt;p&gt;Work in a branch&lt;/p&gt;

&lt;p&gt;Run lint/tests/build&lt;/p&gt;

&lt;p&gt;Validate schema with structured-data testing tools&lt;/p&gt;

&lt;p&gt;Run Lighthouse/WebPageTest for before/after&lt;/p&gt;

&lt;p&gt;Appendix — Copy/Paste Prompt for Your AI Coding Agent&lt;/p&gt;

&lt;p&gt;Below is a long, framework-agnostic master prompt you can paste into your coding agent. It instructs the agent to (1) analyze first, (2) implement improvements phase-by-phase, and (3) generate an SEO_AUDIT_REPORT.md.&lt;/p&gt;

&lt;p&gt;Note: I kept it intentionally exhaustive. If your agent tends to be overly “creative,” consider adding: “Do not rewrite UI components unless necessary; prefer minimal diffs; show a file-by-file plan before edits.”&lt;/p&gt;

&lt;h1&gt;
  
  
  COMPREHENSIVE SEO AUDIT AND OPTIMIZATION — MASTER PROMPT
&lt;/h1&gt;

&lt;p&gt;You are an expert SEO engineer and web performance specialist. Your task is to perform a complete, exhaustive SEO audit and optimization of this entire project. You have full permission to read, analyze, modify, create, and delete files as needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  IMPORTANT RULES
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Work through each phase sequentially. Do NOT skip ahead.&lt;/li&gt;
&lt;li&gt;For EVERY check, first verify whether it is already implemented before making changes.&lt;/li&gt;
&lt;li&gt;If something is already correctly implemented, log it as "✅ ALREADY IN PLACE" and move on.&lt;/li&gt;
&lt;li&gt;If something is missing or incorrectly implemented, fix it and log it as "🔧 IMPLEMENTED" with a brief description of what you changed.&lt;/li&gt;
&lt;li&gt;If something cannot be implemented due to the current tech stack or project constraints, log it as "⚠️ REQUIRES MANUAL ACTION" and explain what needs to be done and why you couldn't do it.&lt;/li&gt;
&lt;li&gt;Do NOT break existing functionality. If a change risks breaking something, note it and ask before proceeding.&lt;/li&gt;
&lt;li&gt;After completing ALL phases, generate a final summary report as a markdown file called &lt;code&gt;SEO_AUDIT_REPORT.md&lt;/code&gt; in the project root.&lt;/li&gt;
&lt;li&gt;Preserve all existing design, styling, branding, and visual appearance. SEO changes should be structural and content-meta level, not visual redesigns.&lt;/li&gt;
&lt;li&gt;All changes must follow the conventions and patterns already established in the codebase (naming conventions, file organization, component patterns, styling approach).&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  PHASE 0: PROJECT DISCOVERY AND ANALYSIS
&lt;/h2&gt;

&lt;p&gt;Before making ANY changes, perform a thorough analysis and document your findings.&lt;/p&gt;

&lt;h3&gt;
  
  
  0.1 — Technology Stack Analysis
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Identify the framework (React, Next.js, Nuxt.js, Vue, Angular, Astro, SvelteKit, WordPress, plain HTML/CSS/JS, PHP, Django, Ruby on Rails, Gatsby, Remix, Eleventy, Hugo, or other).&lt;/li&gt;
&lt;li&gt;Identify the rendering strategy: Static Site Generation (SSG), Server-Side Rendering (SSR), Client-Side Rendering (CSR), Incremental Static Regeneration (ISR), or hybrid.&lt;/li&gt;
&lt;li&gt;Identify the CSS approach (Tailwind, CSS Modules, Styled Components, SCSS/SASS, plain CSS, etc.).&lt;/li&gt;
&lt;li&gt;Identify the package manager (npm, yarn, pnpm, bun).&lt;/li&gt;
&lt;li&gt;Identify any CMS or headless CMS integration (Contentful, Strapi, Sanity, WordPress headless, etc.).&lt;/li&gt;
&lt;li&gt;Identify the hosting/deployment platform if detectable (Vercel, Netlify, AWS, traditional hosting, Docker, etc.).&lt;/li&gt;
&lt;li&gt;Identify any existing SEO-related packages, plugins, or configurations already installed.&lt;/li&gt;
&lt;li&gt;Identify the routing system and how pages/routes are structured.&lt;/li&gt;
&lt;li&gt;Identify if there is an existing sitemap, robots.txt, or manifest file.&lt;/li&gt;
&lt;li&gt;Identify any analytics or tracking already in place (Google Analytics, Google Tag Manager, etc.).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  0.2 — Site Architecture Analysis
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Map out every page/route in the project. List them all.&lt;/li&gt;
&lt;li&gt;Identify the page hierarchy and navigation structure.&lt;/li&gt;
&lt;li&gt;Identify which pages are service pages, blog/content pages, landing pages, utility pages (privacy policy, terms, contact, about, 404, etc.).&lt;/li&gt;
&lt;li&gt;Identify any dynamic routes and how they generate pages.&lt;/li&gt;
&lt;li&gt;Identify the internal linking structure between pages.&lt;/li&gt;
&lt;li&gt;Note any orphaned pages (pages with no internal links pointing to them).&lt;/li&gt;
&lt;li&gt;Note any broken internal links.&lt;/li&gt;
&lt;li&gt;Count total pages and categorize them by type.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  0.3 — Current SEO State Assessment
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Check every page for existing title tags, meta descriptions, Open Graph tags, Twitter Card tags.&lt;/li&gt;
&lt;li&gt;Check for existing structured data/Schema.org markup on any page.&lt;/li&gt;
&lt;li&gt;Check for existing canonical tags.&lt;/li&gt;
&lt;li&gt;Check for existing hreflang tags (if multilingual).&lt;/li&gt;
&lt;li&gt;Check for existing robots meta tags on individual pages.&lt;/li&gt;
&lt;li&gt;Check if a sitemap.xml exists and if it's comprehensive.&lt;/li&gt;
&lt;li&gt;Check if robots.txt exists and if it's correctly configured.&lt;/li&gt;
&lt;li&gt;Check for an existing favicon and web app manifest.&lt;/li&gt;
&lt;li&gt;Check image alt text coverage across all pages.&lt;/li&gt;
&lt;li&gt;Check heading hierarchy (H1, H2, H3) on every page.&lt;/li&gt;
&lt;li&gt;Check for any existing performance optimization (image optimization, lazy loading, code splitting, etc.).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  0.4 — Content Analysis
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;For each page, identify the primary topic/keyword intent.&lt;/li&gt;
&lt;li&gt;Note pages with thin content (fewer than 300 words of meaningful text on service/content pages).&lt;/li&gt;
&lt;li&gt;Note pages with duplicate or near-duplicate content.&lt;/li&gt;
&lt;li&gt;Note pages with missing or generic headings.&lt;/li&gt;
&lt;li&gt;Identify the business name, industry, services offered, and target location(s) from the existing content.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Document ALL findings from Phase 0 before proceeding. This becomes the baseline for your audit.&lt;/p&gt;




&lt;h2&gt;
  
  
  PHASE 1: TECHNICAL SEO FIXES
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1.1 — Meta Tags and Head Configuration
&lt;/h3&gt;

&lt;p&gt;For EVERY page/route in the project:&lt;/p&gt;

&lt;p&gt;Title Tags:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ensure every page has a unique, descriptive  tag.&lt;/li&gt;
&lt;li&gt;Title should be 50-60 characters maximum.&lt;/li&gt;
&lt;li&gt;Title should include the primary keyword for that page naturally.&lt;/li&gt;
&lt;li&gt;Title should include the brand name, typically at the end separated by a pipe or dash.&lt;/li&gt;
&lt;li&gt;Homepage title should lead with the primary value proposition or brand + primary service + location.&lt;/li&gt;
&lt;li&gt;No two pages should share the same title tag.&lt;/li&gt;
&lt;li&gt;Implement using the appropriate method for the framework.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Meta Descriptions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ensure every page has a unique meta description.&lt;/li&gt;
&lt;li&gt;Length: 120-155 characters.&lt;/li&gt;
&lt;li&gt;Should accurately describe the page content.&lt;/li&gt;
&lt;li&gt;Should include primary keyword naturally.&lt;/li&gt;
&lt;li&gt;Should include a compelling reason to click.&lt;/li&gt;
&lt;li&gt;No two pages should share the same meta description.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Canonical Tags:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Every page must have a self-referencing canonical tag with a full absolute URL.&lt;/li&gt;
&lt;li&gt;Ensure canonical URLs are consistent (www vs non-www, trailing slash or no trailing slash).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Viewport / Charset / Language:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ensure viewport meta exists.&lt;/li&gt;
&lt;li&gt;Ensure UTF-8 charset is present and early in .&lt;/li&gt;
&lt;li&gt;Ensure  is correct; implement hreflang if multilingual.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Robots Meta:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ensure indexable pages are not noindexed.&lt;/li&gt;
&lt;li&gt;Ensure pages that should not be indexed (thank-you, internal search, admin, staging) are noindexed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  1.2 — Open Graph and Social Tags
&lt;/h3&gt;

&lt;p&gt;For every public page:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;og:title, og:description, og:type, og:url, og:image (absolute), og:site_name, og:locale&lt;/li&gt;
&lt;li&gt;Twitter:card summary_large_image, twitter:title/description/image&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  1.3 — Robots.txt
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Create or fix robots.txt in public/static.&lt;/li&gt;
&lt;li&gt;Do not block CSS/JS/images.&lt;/li&gt;
&lt;li&gt;Include Sitemap: https://[DOMAIN]/sitemap.xml&lt;/li&gt;
&lt;li&gt;Only disallow routes that truly should not be indexed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  1.4 — XML Sitemap
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Implement a sitemap mechanism appropriate to the framework.&lt;/li&gt;
&lt;li&gt;Include all public, indexable pages; exclude noindex/redirect/auth pages.&lt;/li&gt;
&lt;li&gt;Include lastmod if available.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  1.5 — URL Structure + Redirects
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Enforce clean, lowercase, hyphenated URLs.&lt;/li&gt;
&lt;li&gt;If changing URLs, add 301 redirects and avoid chains/loops.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  1.6 — 404/Error Handling
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Ensure proper 404 page and correct HTTP status.&lt;/li&gt;
&lt;li&gt;Fix broken internal links.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  1.7 — HTTPS/Mixed Content
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Ensure internal assets and links use HTTPS; fix mixed content.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  PHASE 2: ON-PAGE SEO OPTIMIZATION
&lt;/h2&gt;

&lt;h3&gt;
  
  
  2.1 — Heading Hierarchy
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Exactly one H1 per page.&lt;/li&gt;
&lt;li&gt;Logical H2/H3 hierarchy; no heading tags used purely for styling.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2.2 — Semantic HTML + Accessibility Basics
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;header/nav/main/article/section/footer usage where appropriate.&lt;/li&gt;
&lt;li&gt;Labels for form controls; buttons are , links are &lt;a&gt;.&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Add skip-to-content link if missing.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2.3 — Image Optimization
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Ensure alt attributes exist (decorative alt="").&lt;/li&gt;
&lt;li&gt;Use modern formats and responsive images where supported.&lt;/li&gt;
&lt;li&gt;Lazy-load below-the-fold; never lazy-load LCP/hero images.&lt;/li&gt;
&lt;li&gt;Ensure width/height or aspect-ratio to prevent CLS.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2.4 — Internal Linking
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Ensure key pages have multiple internal links pointing to them.&lt;/li&gt;
&lt;li&gt;Use descriptive anchor text.&lt;/li&gt;
&lt;li&gt;Add breadcrumbs if site hierarchy warrants it (and add schema if implemented).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2.5 — Content Quality Checks
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Flag thin/duplicate/placeholder content.&lt;/li&gt;
&lt;li&gt;Do NOT write new body copy; log manual content needs.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  PHASE 3: STRUCTURED DATA / SCHEMA.ORG (JSON-LD)
&lt;/h2&gt;

&lt;p&gt;Implement where applicable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Organization or LocalBusiness site-wide&lt;/li&gt;
&lt;li&gt;WebSite (and SearchAction only if site search exists)&lt;/li&gt;
&lt;li&gt;WebPage per page (and BreadcrumbList where relevant)&lt;/li&gt;
&lt;li&gt;Service schema on service pages&lt;/li&gt;
&lt;li&gt;FAQPage schema where FAQs exist&lt;/li&gt;
&lt;li&gt;BlogPosting on articles&lt;/li&gt;
&lt;li&gt;Optional: Review/AggregateRating, Product, HowTo, Video, Person, JobPosting, Event, Course as relevant&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use real business data from the site; if missing, add placeholders and flag manual action.&lt;/p&gt;




&lt;h2&gt;
  
  
  PHASE 4: PERFORMANCE (CORE WEB VITALS)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Optimize LCP: preload hero/LCP images; avoid lazy-loading; reduce render-blocking.&lt;/li&gt;
&lt;li&gt;Prevent CLS: dimensions for media; font-display swap; reserve space for banners.&lt;/li&gt;
&lt;li&gt;Improve INP: reduce long tasks; defer 3rd-party scripts; split bundles.&lt;/li&gt;
&lt;li&gt;Optimize fonts: self-host WOFF2, subset, preload 1-2 critical files, reduce weights.&lt;/li&gt;
&lt;li&gt;Ensure caching/compression where configurable; otherwise flag hosting actions.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  PHASE 5: ACCESSIBILITY (SEO-RELEVANT)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;ARIA labels for icon-only controls&lt;/li&gt;
&lt;li&gt;Keyboard navigation&lt;/li&gt;
&lt;li&gt;aria-current for active nav&lt;/li&gt;
&lt;li&gt;Flag contrast issues without redesigning branding&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  PHASE 6: PWA + ENHANCEMENTS
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;manifest.json/site.webmanifest + icons + theme-color meta&lt;/li&gt;
&lt;li&gt;favicon set (flag manual asset creation if missing)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  PHASE 7: INTERNATIONAL SEO (IF APPLICABLE)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;hreflang + correct lang attributes + consistent language URL strategy&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  PHASE 8: AI / LLM VISIBILITY OPTIMIZATION
&lt;/h2&gt;

&lt;h3&gt;
  
  
  8.1 — Answer-Friendly Structure
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Add clear declarative summary sentences early on key pages.&lt;/li&gt;
&lt;li&gt;Ensure FAQ sections exist on service pages (flag content needs if missing).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  8.2 — Entity Clarity
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Consistent name/services/location/contact across site + schema.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  8.3 — llms.txt
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Create /llms.txt in public/static with business summary, services, areas, contact, and key pages.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  8.4 — Reinforce Structured Data
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Ensure applicable schema types are implemented cleanly.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  8.5 — AI-Style Query Coverage
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Flag recommendations for sections answering conversational queries like cost, timelines, what to expect, how to choose a provider.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  PHASE 9: FINAL REPORT
&lt;/h2&gt;

&lt;p&gt;Create &lt;code&gt;SEO_AUDIT_REPORT.md&lt;/code&gt; in the project root including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;stack + routing findings&lt;/li&gt;
&lt;li&gt;implemented vs already-in-place vs manual items per phase&lt;/li&gt;
&lt;li&gt;content recommendations&lt;/li&gt;
&lt;li&gt;page-by-page meta table (title/description/canonical/OG image)&lt;/li&gt;
&lt;li&gt;schema summary&lt;/li&gt;
&lt;li&gt;sitemap/robots/https status&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Begin now with Phase 0.&lt;/p&gt;

&lt;p&gt;Closing thought (the “don’t be weird” rule)&lt;/p&gt;

&lt;p&gt;The best SEO/GEO strategy is not trickery—it’s clarity, usefulness, and credibility made easy for machines to parse. If your site is the most helpful answer and it’s technically accessible, both Google and AI systems have a much easier time recommending you.&lt;/p&gt;

&lt;p&gt;Jaber Said&lt;/p&gt;

</description>
      <category>seo</category>
      <category>webdev</category>
      <category>digitalmarketing</category>
    </item>
    <item>
      <title>Securing AI-Powered Applications: A Comprehensive Guide to Protecting Your LLM-Integrated Web App</title>
      <dc:creator>Jaber-Said</dc:creator>
      <pubDate>Thu, 19 Feb 2026 03:53:29 +0000</pubDate>
      <link>https://forem.com/jaber-said/securing-ai-powered-applications-a-comprehensive-guide-to-protecting-your-llm-integrated-web-app-38h9</link>
      <guid>https://forem.com/jaber-said/securing-ai-powered-applications-a-comprehensive-guide-to-protecting-your-llm-integrated-web-app-38h9</guid>
      <description>&lt;h1&gt;
  
  
  Securing AI-Powered Applications: A Comprehensive Guide to Protecting Your LLM-Integrated Web App
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;Lessons learned from implementing security measures for Promptimizer, an AI Prompt Enhancement Tool&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;The rise of Large Language Models (LLMs) has opened incredible possibilities for web applications, but it has also introduced a new frontier of security challenges. When I developed &lt;strong&gt;Promptimizer&lt;/strong&gt; (an AI prompt enhancement tool at &lt;a href="https://www.promptimizer.top" rel="noopener noreferrer"&gt;promptimizer.top&lt;/a&gt;), I quickly realized that securing an application that interfaces with AI models requires a multi-layered approach.&lt;/p&gt;

&lt;p&gt;In this article, I'll share the comprehensive security measures implemented to protect the application from common threats like abuse, cost explosions, prompt injection attacks, and unauthorized access. Whether you're building a chatbot, an AI writing assistant, or any LLM-powered application, these strategies will help you build a more secure and resilient system.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Unique Security Challenges of AI Applications
&lt;/h2&gt;

&lt;p&gt;Applications that integrate LLMs face distinct security challenges that traditional web applications don't typically encounter:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cost Vulnerabilities&lt;/strong&gt;: Every API call to an LLM costs money. Malicious users can exploit this by making excessive requests or requesting extremely long outputs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Prompt Injection Attacks&lt;/strong&gt;: Users can craft inputs designed to manipulate the AI's behavior, extract system prompts, or bypass safety measures.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Model Parameter Manipulation&lt;/strong&gt;: Clients can send modified parameters (like setting &lt;code&gt;max_tokens&lt;/code&gt; to 100,000) that dramatically increase costs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Abuse and DoS&lt;/strong&gt;: Without proper limits, bad actors can overwhelm your API endpoints.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Authentication Bypass&lt;/strong&gt;: Client-side authentication can be easily circumvented.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's dive into how we addressed each of these challenges.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Creating a Security Utilities Module
&lt;/h2&gt;

&lt;p&gt;The foundation of our security implementation is a dedicated security utilities module. This centralizes all security-related functions and makes them easier to maintain and audit.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/lib/security.js&lt;/span&gt;

&lt;span class="c1"&gt;// In-memory rate limit store (for production, use Redis or similar)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rateLimitStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;blockedIPs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Rate limit configuration&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;RATE_LIMIT_CONFIG&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Chat endpoint specific (more restrictive due to AI costs)&lt;/span&gt;
  &lt;span class="na"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;windowMs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// 1 minute window&lt;/span&gt;
    &lt;span class="na"&gt;maxRequests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// max requests per window&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="c1"&gt;// Failed attempt tracking (for brute force prevention)&lt;/span&gt;
  &lt;span class="na"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;windowMs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// 15 minute window&lt;/span&gt;
    &lt;span class="na"&gt;maxAttempts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// max failed attempts before temporary block&lt;/span&gt;
    &lt;span class="na"&gt;blockDurationMs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// 30 minute block&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key Insight&lt;/strong&gt;: We use different rate limits for different endpoints. The chat endpoint has stricter limits because each request costs money, while authentication failures trigger progressive blocking.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Rate Limiting: Protecting Against Abuse
&lt;/h2&gt;

&lt;p&gt;Rate limiting is your first line of defense against abuse. Our implementation tracks requests per IP address within rolling time windows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;checkRateLimit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;identifier&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;RATE_LIMIT_CONFIG&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;windowStart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;windowMs&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Check if IP is blocked&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;blockedIPs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;identifier&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;allowed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;remaining&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;resetTime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;RATE_LIMIT_CONFIG&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;blockDurationMs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;blocked&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Get or create entry for this identifier&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;entry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;rateLimitStore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;identifier&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;entry&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;windowStart&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;windowStart&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;entry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;windowStart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;failedAttempts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;failedAttempts&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Calculate remaining requests&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;remaining&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;maxRequests&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resetTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;windowStart&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;windowMs&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;maxRequests&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;allowed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;remaining&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;resetTime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;blocked&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;allowed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;remaining&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;remaining&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;resetTime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;blocked&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Implementation Tips&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;X-Forwarded-For&lt;/code&gt; and similar headers to get the real client IP behind CDNs&lt;/li&gt;
&lt;li&gt;Include rate limit information in response headers so legitimate users know their limits&lt;/li&gt;
&lt;li&gt;For production, use Redis or a similar distributed store to share rate limit state across multiple server instances&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  3. Detecting Prompt Injection Attacks
&lt;/h2&gt;

&lt;p&gt;Prompt injection is a unique threat to LLM applications. Attackers craft inputs designed to override your system instructions or extract sensitive information.&lt;/p&gt;

&lt;p&gt;We implemented pattern-based detection to identify common attack vectors:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SUSPICIOUS_PATTERNS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="c1"&gt;// Prompt injection attempts&lt;/span&gt;
  &lt;span class="sr"&gt;/ignore&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;all&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;)?(&lt;/span&gt;&lt;span class="sr"&gt;previous|above|prior&lt;/span&gt;&lt;span class="se"&gt;)\s&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;instructions&lt;/span&gt;&lt;span class="se"&gt;?&lt;/span&gt;&lt;span class="sr"&gt;|prompts&lt;/span&gt;&lt;span class="se"&gt;?&lt;/span&gt;&lt;span class="sr"&gt;|rules&lt;/span&gt;&lt;span class="se"&gt;?)&lt;/span&gt;&lt;span class="sr"&gt;/i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="sr"&gt;/disregard&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;all&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;)?(&lt;/span&gt;&lt;span class="sr"&gt;previous|above|prior&lt;/span&gt;&lt;span class="se"&gt;)\s&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;instructions&lt;/span&gt;&lt;span class="se"&gt;?&lt;/span&gt;&lt;span class="sr"&gt;|prompts&lt;/span&gt;&lt;span class="se"&gt;?&lt;/span&gt;&lt;span class="sr"&gt;|rules&lt;/span&gt;&lt;span class="se"&gt;?)&lt;/span&gt;&lt;span class="sr"&gt;/i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="sr"&gt;/forget&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;all&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;)?(&lt;/span&gt;&lt;span class="sr"&gt;previous|above|prior&lt;/span&gt;&lt;span class="se"&gt;)\s&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;instructions&lt;/span&gt;&lt;span class="se"&gt;?&lt;/span&gt;&lt;span class="sr"&gt;|prompts&lt;/span&gt;&lt;span class="se"&gt;?&lt;/span&gt;&lt;span class="sr"&gt;|rules&lt;/span&gt;&lt;span class="se"&gt;?)&lt;/span&gt;&lt;span class="sr"&gt;/i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="sr"&gt;/you&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+are&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+now&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;a|an&lt;/span&gt;&lt;span class="se"&gt;)\s&lt;/span&gt;&lt;span class="sr"&gt;+/i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="sr"&gt;/act&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+as&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+if&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+you&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+are/i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="sr"&gt;/pretend&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;that&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;)?&lt;/span&gt;&lt;span class="sr"&gt;you&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+are/i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="sr"&gt;/jailbreak/i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="sr"&gt;/DAN&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;*mode/i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="sr"&gt;/developer&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+mode/i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

  &lt;span class="c1"&gt;// Attempting to extract system prompts&lt;/span&gt;
  &lt;span class="sr"&gt;/reveal&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;your|the&lt;/span&gt;&lt;span class="se"&gt;)\s&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;system&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;)?&lt;/span&gt;&lt;span class="sr"&gt;prompt/i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="sr"&gt;/show&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;me&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;)?(&lt;/span&gt;&lt;span class="sr"&gt;your|the&lt;/span&gt;&lt;span class="se"&gt;)\s&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;system&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;)?&lt;/span&gt;&lt;span class="sr"&gt;prompt/i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="sr"&gt;/what&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;is|are&lt;/span&gt;&lt;span class="se"&gt;)\s&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;your|the&lt;/span&gt;&lt;span class="se"&gt;)\s&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;system&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;)?&lt;/span&gt;&lt;span class="sr"&gt;prompt/i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

  &lt;span class="c1"&gt;// Code execution attempts&lt;/span&gt;
  &lt;span class="sr"&gt;/eval&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;*&lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="sr"&gt;/i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="sr"&gt;/process&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sr"&gt;env/i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="sr"&gt;/__proto__/i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Important Note&lt;/strong&gt;: Pattern matching isn't foolproof. Sophisticated attackers can craft inputs that bypass these filters. Use this as one layer of defense, not your only protection.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Model and Parameter Validation
&lt;/h2&gt;

&lt;p&gt;One of the most dangerous vulnerabilities in LLM applications is allowing clients to specify arbitrary model parameters. A malicious user could set &lt;code&gt;max_tokens: 1000000&lt;/code&gt; and drain your API credits in minutes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Model Whitelisting
&lt;/h3&gt;

&lt;p&gt;Only allow specific, approved models:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ALLOWED_MODELS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;meta-llama/Llama-3.3-70B-Instruct&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;deepseek-ai/DeepSeek-V3.1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gpt-4o-mini&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;validateModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;model&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;valid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Model is required&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;normalizedModel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isAllowed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ALLOWED_MODELS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;allowed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;allowed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;normalizedModel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;isAllowed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;valid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Invalid model specified&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;valid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;normalizedModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Token Limit Enforcement
&lt;/h3&gt;

&lt;p&gt;Define maximum token limits per model and enforce them server-side:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MODEL_TOKEN_LIMITS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;meta-llama/Llama-3.3-70B-Instruct&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;max&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4096&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2048&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;deepseek-ai/DeepSeek-V3.1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;max&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8192&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4096&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gpt-4o-mini&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;max&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4096&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2048&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;max&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4096&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2048&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;validateTokenParams&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;modelLimits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;MODEL_TOKEN_LIMITS&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;MODEL_TOKEN_LIMITS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;temperature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;temperature&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;max_tokens&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;max_tokens&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="nx"&gt;modelLimits&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="nx"&gt;modelLimits&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;max&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;top_p&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;top_p&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;frequency_penalty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;frequency_penalty&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;presence_penalty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;presence_penalty&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The Fix&lt;/strong&gt;: Our application originally had &lt;code&gt;max_tokens: 100000&lt;/code&gt; in the client-side store. We changed this to &lt;code&gt;2048&lt;/code&gt; as the default and enforced server-side limits.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Securing the API Route
&lt;/h2&gt;

&lt;p&gt;With our validation utilities in place, securing the API route becomes straightforward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/app/api/chat/route.js&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;OpenAI&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;openai&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;getClientIP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;checkRateLimit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;incrementRateLimit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;validateModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;validateMessages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;validateTokenParams&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;logSecurityEvent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;createRateLimitHeaders&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;RATE_LIMIT_CONFIG&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/lib/security&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MAX_BODY_SIZE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 1MB&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;clientIP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getClientIP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// 1. Check rate limit&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rateLimitInfo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;checkRateLimit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;clientIP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;RATE_LIMIT_CONFIG&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;rateLimitInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;allowed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;logSecurityEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;rateLimitInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;blocked&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;IP_BLOCKED&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;RATE_LIMITED&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;remaining&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;rateLimitInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;remaining&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;rateLimitInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;blocked&lt;/span&gt;
          &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Your IP has been temporarily blocked due to suspicious activity.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
          &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Too many requests. Please wait before trying again.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;retryAfter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ceil&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;rateLimitInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resetTime&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="p"&gt;}),&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;429&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Retry-After&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ceil&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rateLimitInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resetTime&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
          &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nf"&gt;createRateLimitHeaders&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rateLimitInfo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;chat&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// 2. Increment rate limit counter&lt;/span&gt;
  &lt;span class="nf"&gt;incrementRateLimit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;clientIP&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// 3. Check request size&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;contentLength&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;content-length&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contentLength&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contentLength&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;MAX_BODY_SIZE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Request body too large&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;413&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// 4. Parse and validate inputs&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Validate model&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;modelValidation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;validateModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;modelValidation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;valid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;modelValidation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Validate messages&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;messagesValidation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;validateMessages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;messagesValidation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;valid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;messagesValidation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Validate and constrain token parameters&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;validatedOptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;validateTokenParams&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;modelValidation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// 5. Make the API call with validated parameters&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;completion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;modelValidation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;messagesValidation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;temperature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;validatedOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;temperature&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;max_tokens&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;validatedOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;max_tokens&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="c1"&gt;// ... other validated parameters&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;completion&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Log internally but don't expose details to client&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;API Error:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;clientIP&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;An error occurred. Please try again.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  6. Server-Side Authentication
&lt;/h2&gt;

&lt;p&gt;Client-side authentication is inherently insecure — any password stored in localStorage or exposed via &lt;code&gt;NEXT_PUBLIC_&lt;/code&gt; environment variables can be easily bypassed.&lt;/p&gt;

&lt;p&gt;We implemented server-side authentication with HTTP-only cookies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/app/api/auth/route.js&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;cookies&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next/headers&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;crypto&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;getClientIP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;recordFailedAuthAttempt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;resetFailedAuthAttempts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;blockedIPs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/lib/security&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SESSION_VALIDITY_MS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 24 hours&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sessions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Use Redis in production&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;clientIP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getClientIP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Check if IP is blocked&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;blockedIPs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;clientIP&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Your IP has been temporarily blocked.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;429&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="c1"&gt;// Use server-side password (not exposed to client)&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;correctPassword&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SITE_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;correctPassword&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Reset failed attempts&lt;/span&gt;
    &lt;span class="nf"&gt;resetFailedAuthAttempts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;clientIP&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Create session&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sessionToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;randomBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hex&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;sessions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sessionToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;createdAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="na"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;clientIP&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="c1"&gt;// Set secure HTTP-only cookie&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cookieStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;cookies&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;cookieStore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;session_token&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sessionToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;httpOnly&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;secure&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NODE_ENV&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;production&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;sameSite&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;strict&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;maxAge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SESSION_VALIDITY_MS&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Record failed attempt (blocks IP after 5 failures)&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isBlocked&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;recordFailedAuthAttempt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;clientIP&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Invalid credentials&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;blocked&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;isBlocked&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key Security Features&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Password is stored server-side only (&lt;code&gt;SITE_PASSWORD&lt;/code&gt;), not exposed to client&lt;/li&gt;
&lt;li&gt;HTTP-only cookies prevent JavaScript access (XSS protection)&lt;/li&gt;
&lt;li&gt;Brute force protection with IP blocking&lt;/li&gt;
&lt;li&gt;Session tokens are cryptographically random&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  7. Content Security Policy and Security Headers
&lt;/h2&gt;

&lt;p&gt;Security headers provide an additional layer of protection against common web vulnerabilities:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// next.config.mjs&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nextConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/:path*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="c1"&gt;// Prevent clickjacking&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;X-Frame-Options&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SAMEORIGIN&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;

          &lt;span class="c1"&gt;// Prevent MIME type sniffing&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;X-Content-Type-Options&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;nosniff&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;

          &lt;span class="c1"&gt;// Enable XSS filter&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;X-XSS-Protection&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1; mode=block&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;

          &lt;span class="c1"&gt;// Referrer policy&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Referrer-Policy&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;strict-origin-when-cross-origin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;

          &lt;span class="c1"&gt;// Permissions policy&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Permissions-Policy&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
              &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;camera=(), microphone=(), geolocation=(), payment=(), usb=()&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;

          &lt;span class="c1"&gt;// Content Security Policy&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Security-Policy&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
              &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;default-src 'self'&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;script-src 'self' 'unsafe-inline' https://www.googletagmanager.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;style-src 'self' 'unsafe-inline'&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;img-src 'self' data: blob: https:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;connect-src 'self' https://api.friendli.ai&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;frame-ancestors 'self'&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;form-action 'self'&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;object-src 'none'&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;; &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  8. Secure Error Handling
&lt;/h2&gt;

&lt;p&gt;How you handle errors can expose or protect your application. Never expose internal details to clients:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Good: Generic error messages&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;An error occurred. Please try again.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Bad: Exposing internal details&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Database connection failed: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Always log detailed errors server-side for debugging while returning generic messages to clients.&lt;/p&gt;




&lt;h2&gt;
  
  
  Security Checklist for LLM Applications
&lt;/h2&gt;

&lt;p&gt;Here's a quick checklist you can use when securing your AI-powered application:&lt;/p&gt;

&lt;h3&gt;
  
  
  API Security
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Implement rate limiting per IP/user&lt;/li&gt;
&lt;li&gt;[ ] Validate all inputs server-side&lt;/li&gt;
&lt;li&gt;[ ] Whitelist allowed models&lt;/li&gt;
&lt;li&gt;[ ] Enforce token limits server-side&lt;/li&gt;
&lt;li&gt;[ ] Limit request body size&lt;/li&gt;
&lt;li&gt;[ ] Use secure error handling (no internal details exposed)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Authentication
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Use server-side authentication&lt;/li&gt;
&lt;li&gt;[ ] Store passwords securely (not in client-side code)&lt;/li&gt;
&lt;li&gt;[ ] Use HTTP-only cookies for sessions&lt;/li&gt;
&lt;li&gt;[ ] Implement brute force protection&lt;/li&gt;
&lt;li&gt;[ ] Set session expiration times&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Headers &amp;amp; CSP
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Set X-Frame-Options&lt;/li&gt;
&lt;li&gt;[ ] Set X-Content-Type-Options&lt;/li&gt;
&lt;li&gt;[ ] Set Content-Security-Policy&lt;/li&gt;
&lt;li&gt;[ ] Set Referrer-Policy&lt;/li&gt;
&lt;li&gt;[ ] Set Permissions-Policy&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Monitoring
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Log security events (failed auth, rate limits, suspicious patterns)&lt;/li&gt;
&lt;li&gt;[ ] Set up alerts for anomalies&lt;/li&gt;
&lt;li&gt;[ ] Monitor API usage and costs&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Production Considerations
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Use Redis for distributed rate limiting&lt;/li&gt;
&lt;li&gt;[ ] Use a database for session management&lt;/li&gt;
&lt;li&gt;[ ] Consider adding CAPTCHA for authentication&lt;/li&gt;
&lt;li&gt;[ ] Implement API key authentication for additional security&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Securing AI-powered applications requires a defense-in-depth approach. The strategies I've shared — rate limiting, input validation, prompt injection detection, parameter enforcement, server-side authentication, and security headers — work together to create multiple layers of protection.&lt;/p&gt;

&lt;p&gt;The threat landscape for LLM applications is still evolving. As new attack vectors emerge, it's essential to stay informed, regularly audit your security measures, and be prepared to adapt.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Remember&lt;/strong&gt;: Security is not a one-time implementation but an ongoing process. Start with these fundamentals, monitor your application for anomalies, and continuously improve your defenses.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;If you found this article helpful, check out &lt;a href="https://www.promptimizer.top" rel="noopener noreferrer"&gt;Promptimizer&lt;/a&gt; to see these security measures in action. Feel free to reach out with questions or share your own experiences securing AI applications!&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;#Security #AI #LLM #WebSecurity #NextJS #PromptEngineering #Cybersecurity #ApplicationSecurity&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Author&lt;/strong&gt;: &lt;a href="https://jaber.dev/" rel="noopener noreferrer"&gt;Jaber Said&lt;/a&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>ai</category>
      <category>llm</category>
      <category>websecurity</category>
    </item>
    <item>
      <title>I Stopped Writing Prompts as Plain Text — Here's What I Do Instead</title>
      <dc:creator>Jaber-Said</dc:creator>
      <pubDate>Fri, 13 Feb 2026 15:16:14 +0000</pubDate>
      <link>https://forem.com/jaber-said/i-stopped-writing-prompts-as-plain-text-heres-what-i-do-instead-l6h</link>
      <guid>https://forem.com/jaber-said/i-stopped-writing-prompts-as-plain-text-heres-what-i-do-instead-l6h</guid>
      <description>&lt;p&gt;I've been doing a lot of prompt engineering lately, and I hit a wall that I think many developers will recognize.&lt;br&gt;
My prompts started looking like messy config files. A system role at the top, then task instructions, then constraints, then output formatting rules, then few-shot examples. Every time I wanted to test a small change — like swapping the persona or adjusting one constraint — I was duplicating the entire prompt and carefully editing one section. It felt like editing a monolithic codebase with no modules.&lt;br&gt;
So I started thinking about prompts the way we think about code: modular, composable, reusable.&lt;br&gt;
What if each section of a prompt was an independent block? What if you could toggle a block on or off to A/B test its impact? What if your "output format" block could be shared across 20 different prompts?&lt;br&gt;
That idea turned into a tool I've been building called Prompt Builder. It's a block-based editor where prompts are assembled from draggable, reusable components instead of written as a wall of text.&lt;br&gt;
I'm curious whether other devs have felt this friction or if I'm solving a problem that only exists at a certain scale of prompt complexity. What does your prompt workflow look like?&lt;/p&gt;

&lt;h1&gt;
  
  
  promptengineering #ai #productivity #webdev
&lt;/h1&gt;

</description>
    </item>
    <item>
      <title>Bring Your Website to Life: A Complete Guide to Animated Icons and Motion Effects</title>
      <dc:creator>Jaber-Said</dc:creator>
      <pubDate>Thu, 22 Jan 2026 23:36:18 +0000</pubDate>
      <link>https://forem.com/jaber-said/bring-your-website-to-life-a-complete-guide-to-animated-icons-and-motion-effects-4di</link>
      <guid>https://forem.com/jaber-said/bring-your-website-to-life-a-complete-guide-to-animated-icons-and-motion-effects-4di</guid>
      <description>&lt;p&gt;Transform static interfaces into engaging, memorable experiences with the magic of motion.&lt;/p&gt;

&lt;p&gt;Every great website tells a story, but the truly memorable ones make you feel something. They don't just display content—they breathe, move, and respond. The secret? Thoughtful animation and motion design.&lt;/p&gt;

&lt;p&gt;If you've ever landed on a website and thought, "This feels alive," chances are animated icons and subtle motion effects played a significant role. These micro-interactions create a sense of polish and professionalism that static designs simply cannot achieve. In this guide, I'll walk you through why animated icons matter, where to find the best resources, and how to implement them in your projects—regardless of which framework you're using.&lt;/p&gt;

&lt;p&gt;Why Animation Matters More Than You Think&lt;/p&gt;

&lt;p&gt;Animation isn't just decoration. When done right, it serves critical purposes in user experience design. Motion guides attention, helping users understand where to look and what actions to take. It provides feedback, confirming that a button was clicked or a form was submitted. It creates continuity between states, making transitions feel natural rather than jarring. And perhaps most importantly, it injects personality into your brand, transforming a forgettable interface into something distinctly yours.&lt;/p&gt;

&lt;p&gt;Consider a simple loading indicator. A static spinner tells users to wait, but an elegantly animated icon tells them the system is actively working on their request. That subtle difference builds trust and reduces perceived wait times. The same principle applies throughout your interface—every animated element is an opportunity to communicate care and attention to detail.&lt;/p&gt;

&lt;p&gt;The Best Resources for Animated Icons&lt;/p&gt;

&lt;p&gt;Finding high-quality animated icons used to require either significant design skills or expensive licenses. Today, the ecosystem has exploded with incredible free and premium options. Here are the resources I personally rely on for projects.&lt;/p&gt;

&lt;p&gt;General Purpose Animation Libraries&lt;/p&gt;

&lt;p&gt;Lucide Animated at lucide-animated.com offers a beautifully crafted collection of animated icons based on the popular Lucide icon set. These are lightweight, customizable, and perfect for modern web applications. The animations feel intentional rather than gratuitous, which is exactly what you want for professional projects.&lt;/p&gt;

&lt;p&gt;Animate UI provides comprehensive documentation and examples at animate-ui.com/docs/icons. What sets this resource apart is its focus on integration—you'll find clear guidance on implementing these animations within component-based architectures.&lt;/p&gt;

&lt;p&gt;LordIcon at lordicon.com/icons/system/regular has been a go-to resource for years. Their icons come with multiple animation styles for each design, allowing you to choose between subtle hover effects and more elaborate triggered animations. The system regular collection alone covers most common interface needs.&lt;/p&gt;

&lt;p&gt;AnimatedIcons.co offers a minimalistic collection at animatedicons.co/icons/minimalistic?type=free. If your design aesthetic leans toward clean and simple, these icons will feel right at home. Their free tier is generous enough for most projects.&lt;/p&gt;

&lt;p&gt;Icons8 at icons8.com/icons/all provides an enormous library that extends far beyond animated options. When you need variety and scale, this is where you'll find it. Their search and filtering tools make finding exactly what you need surprisingly painless.&lt;/p&gt;

&lt;p&gt;UseAnimations invites you to explore their collection at useanimations.com/#explore. These Lottie-based animations are particularly smooth and render beautifully across devices. The interactive preview makes it easy to evaluate each icon before committing.&lt;/p&gt;

&lt;p&gt;Framework-Specific Solutions&lt;/p&gt;

&lt;p&gt;Modern web development often means working within specific frameworks, and animated icon support varies significantly between them. Fortunately, dedicated resources exist for each major ecosystem.&lt;/p&gt;

&lt;p&gt;Svelte developers should explore movingicons.dev, which provides animated icons designed specifically for Svelte's reactive paradigm. The integration feels native, and the performance overhead is minimal.&lt;/p&gt;

&lt;p&gt;Vue.js projects benefit from the collection at imfenghuang.github.io/icons. These icons slot seamlessly into Vue's component model, complete with props for controlling animation states and timing.&lt;/p&gt;

&lt;p&gt;Angular applications can leverage the icons at icons.ajitpanigrahi.com. Angular's particular approach to change detection and rendering is accounted for, ensuring animations perform well even in complex applications.&lt;/p&gt;

&lt;p&gt;Flutter developers haven't been forgotten either. The flutter_lucide_animated package on pub.dev brings the Lucide animated icons to mobile and desktop Flutter applications with full platform optimization.&lt;/p&gt;

&lt;p&gt;Implementation Best Practices&lt;/p&gt;

&lt;p&gt;Having access to great animated icons is only half the battle. How you implement them determines whether your site feels polished or chaotic. Start by establishing an animation budget—not every icon needs to animate, and overusing motion can overwhelm users or harm performance. Reserve animations for moments that genuinely benefit from them, such as state changes, loading indicators, and interactive feedback.&lt;/p&gt;

&lt;p&gt;Consider timing carefully. Most interface animations should complete within 200 to 500 milliseconds. Faster than that feels abrupt; slower feels sluggish. Match your animation timing to the action's importance—a page transition might warrant a longer, more elaborate animation, while a button hover should be nearly instantaneous.&lt;/p&gt;

&lt;p&gt;Respect user preferences by implementing the prefers-reduced-motion media query. Some users experience motion sickness or simply find animations distracting. Providing a reduced-motion alternative isn't just thoughtful—it's increasingly expected and may be required for accessibility compliance in some contexts.&lt;/p&gt;

&lt;p&gt;The Magic Touch&lt;/p&gt;

&lt;p&gt;There's something almost magical about a website that responds to your every action with graceful, purposeful motion. It creates an emotional connection that static designs struggle to achieve. The resources I've shared here give you everything you need to bring that magic to your own projects.&lt;/p&gt;

&lt;p&gt;Start small. Add an animated icon to your navigation or incorporate a subtle loading animation. Notice how it changes the feel of your interface. Then build from there, always asking whether each animation serves the user or merely serves your desire to show off. The best animated interfaces feel inevitable—so natural that users would miss them if they were gone.&lt;/p&gt;

&lt;p&gt;Your website deserves to breathe. These tools will help you give it life.&lt;/p&gt;

&lt;p&gt;Happy animating! If you found this guide helpful, consider bookmarking these resources and sharing with other developers looking to elevate their interfaces.&lt;/p&gt;

&lt;p&gt;Jaber Said&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>frontend</category>
      <category>uxdesign</category>
      <category>uidesign</category>
    </item>
    <item>
      <title>Where AI Is Actually Taking Software Development Careers</title>
      <dc:creator>Jaber-Said</dc:creator>
      <pubDate>Mon, 12 Jan 2026 02:43:40 +0000</pubDate>
      <link>https://forem.com/jaber-said/where-ai-is-actually-taking-software-development-careers-1aae</link>
      <guid>https://forem.com/jaber-said/where-ai-is-actually-taking-software-development-careers-1aae</guid>
      <description>&lt;p&gt;The real story is messier—and more interesting—than "robots taking our jobs"&lt;/p&gt;

&lt;p&gt;If you've spent any time on tech Twitter or LinkedIn lately, you've probably seen two equally confident camps: one insisting AI will replace most developers within five years, the other dismissing the whole thing as hype. Both are wrong, and the emerging research tells a more nuanced story worth understanding.&lt;/p&gt;

&lt;p&gt;I've been digging through the latest evidence—randomized trials, labor market data, developer surveys, and productivity studies—to get a clearer picture of where things actually stand as of early 2026. Here's what I found.&lt;/p&gt;

&lt;p&gt;The Core Insight: It's About Task Shifts, Not Job Elimination&lt;/p&gt;

&lt;p&gt;A software engineering role isn't a single thing. It's a bundle of tasks: writing boilerplate, debugging, designing systems, reviewing code, responding to incidents, aligning with stakeholders. AI doesn't uniformly affect all of these. It compresses some dramatically while elevating the importance of others.&lt;/p&gt;

&lt;p&gt;The pattern that keeps emerging: as generation gets easier, verification becomes the bottleneck.&lt;/p&gt;

&lt;p&gt;This matters because it changes what makes an engineer valuable. The ability to produce a first draft of code quickly is becoming commoditized. The ability to know whether that code is correct, secure, maintainable, and aligned with business goals? That's becoming the scarce resource.&lt;/p&gt;

&lt;p&gt;What the Research Actually Shows&lt;/p&gt;

&lt;p&gt;Here's where things get interesting—and complicated.&lt;/p&gt;

&lt;p&gt;Productivity gains are real but context-dependent. OECD reviews of experimental studies report gains ranging from around 5% to over 25%, depending on the task and setting. That sounds great until you see the caveats.&lt;/p&gt;

&lt;p&gt;The METR randomized trial flipped the script. Researchers studied experienced open-source developers working on issues in their own repositories—not artificial tasks, but real work on codebases they knew well. The result? Developers using early-2025 AI tools were approximately 19% slower than those without them. Even more striking: the developers themselves believed they were faster.&lt;/p&gt;

&lt;p&gt;This isn't necessarily a contradiction. It suggests that AI tools excel at certain task types (greenfield code, unfamiliar domains, boilerplate) while potentially adding friction in others (complex debugging, deeply familiar codebases, nuanced refactoring). Context matters enormously.&lt;/p&gt;

&lt;p&gt;Verification debt is becoming a recognized risk category. A widely-covered January 2026 survey found that many developers don't always verify AI-generated code before committing it—even while expressing low trust in that code's correctness. This is how technical debt accumulates at scale. Organizations are producing code faster than they can confidently validate it.&lt;/p&gt;

&lt;p&gt;The Labor Market Signals&lt;/p&gt;

&lt;p&gt;The Federal Reserve Bank of Dallas published research in early January 2026 showing that young workers' employment has dropped in occupations with high AI exposure. Meanwhile, experienced engineers who can own systems end-to-end—design, ship, operate, govern—are often seeing their leverage increase as raw output becomes cheaper.&lt;/p&gt;

&lt;p&gt;This creates a potential squeeze: entry-level pathways may tighten in some segments as teams use AI to raise baseline expectations, while senior roles that require judgment and accountability become more valuable.&lt;/p&gt;

&lt;p&gt;What Actually Determines Whether AI Helps or Hurts Your Career&lt;/p&gt;

&lt;p&gt;Several variables will shape how this plays out for individual engineers:&lt;/p&gt;

&lt;p&gt;Demand expansion versus efficiency capture. If AI lowers the cost of building software enough, more software gets built—that's a tailwind for the profession. But in cost-cutting cycles, companies might deliver the same roadmap with fewer hires. Both dynamics can coexist across different market segments.&lt;/p&gt;

&lt;p&gt;Tooling maturity. We're moving from copilots to more agentic workflows. This shifts value toward orchestration, guardrails, and monitoring—roles that didn't exist five years ago.&lt;/p&gt;

&lt;p&gt;Governance and regulation. Security incidents, IP concerns, and regulatory attention can slow adoption in some areas while increasing demand for compliance-ready engineering in others.&lt;/p&gt;

&lt;p&gt;Verification capacity. Organizations with strong testing discipline, code review culture, evaluation harnesses, and observability infrastructure will capture more value from AI speed than those without.&lt;/p&gt;

&lt;p&gt;Three Plausible Scenarios for 2026–2028&lt;/p&gt;

&lt;p&gt;Scenario A: Augmentation dominates. AI assists most development steps, but humans remain firmly in the loop for judgment, integration, and accountability. The profession expands as software becomes cheaper to build.&lt;/p&gt;

&lt;p&gt;Scenario B: Efficiency wave tightens entry. Teams raise baseline productivity expectations and reduce junior hiring in certain segments. Mid-to-senior engineers benefit; career ladders become harder to climb from the bottom.&lt;/p&gt;

&lt;p&gt;Scenario C: Governance backlash. High-profile security or IP incidents trigger increased controls. Demand grows for engineers who specialize in secure development lifecycles, auditability, and private AI deployment patterns.&lt;/p&gt;

&lt;p&gt;None of these are mutually exclusive. Different industries, companies, and geographies will likely experience different mixes.&lt;/p&gt;

&lt;p&gt;Career Moves That Work Across Scenarios&lt;/p&gt;

&lt;p&gt;After reviewing all of this, a few strategies seem robustly valuable regardless of which scenario dominates:&lt;/p&gt;

&lt;p&gt;Become AI-native and verification-native. Use the tools for speed, then systematically validate with tests, reviews, security checks, and evaluations. Both halves matter.&lt;/p&gt;

&lt;p&gt;Move up the stack. Architecture decisions, reliability engineering, cost and performance optimization, and domain-specific constraints remain scarce skills that AI assists but doesn't replace.&lt;/p&gt;

&lt;p&gt;Own outcomes, not output. Measure your value by time-to-impact, incident rate, and maintainability—not lines of code or pull requests merged.&lt;/p&gt;

&lt;p&gt;Learn the emerging bottleneck roles. Platform engineering, developer experience, security engineering, data governance, and AI product engineering are all areas where demand seems likely to grow as AI reshapes workflows.&lt;/p&gt;

&lt;p&gt;The Bottom Line&lt;/p&gt;

&lt;p&gt;The most useful mental model isn't "AI will replace developers" or "AI is just hype." It's this: AI is reshaping the task portfolio of software engineering faster than job descriptions or hiring practices have adapted.&lt;/p&gt;

&lt;p&gt;The skills that got you here may not be the skills that keep you relevant. But the skills that will matter—judgment, verification, systems thinking, ownership of outcomes—are learnable. They're also, for now, distinctly human.&lt;/p&gt;

&lt;p&gt;The engineers who thrive will be the ones who treat AI as a tool for leverage rather than a threat to resist or a magic wand to trust blindly. That's always been true of every powerful technology. This one just moves faster.&lt;/p&gt;

&lt;p&gt;Research sources reviewed for this analysis include studies and data from METR, OECD, DORA/Google Cloud, Stack Overflow's 2025 Developer Survey, the Federal Reserve Bank of Dallas, the U.S. Bureau of Labor Statistics, and the World Economic Forum's Future of Jobs Report 2025.&lt;/p&gt;

&lt;p&gt;Jaber Said&lt;/p&gt;

</description>
      <category>ai</category>
      <category>softwaredevelopment</category>
      <category>careeradvice</category>
      <category>futureofwork</category>
    </item>
    <item>
      <title>🚀 I Built a Block-Based AI Prompt Builder with Next.js and Supabase - Here's What I Learned</title>
      <dc:creator>Jaber-Said</dc:creator>
      <pubDate>Wed, 01 Oct 2025 14:57:53 +0000</pubDate>
      <link>https://forem.com/jaber-said/i-built-a-block-based-ai-prompt-builder-with-nextjs-and-supabase-heres-what-i-learned-1ne1</link>
      <guid>https://forem.com/jaber-said/i-built-a-block-based-ai-prompt-builder-with-nextjs-and-supabase-heres-what-i-learned-1ne1</guid>
      <description>&lt;p&gt;The Problem That Started It All&lt;br&gt;
If you're like me, you've probably got AI prompts scattered across:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Random text files&lt;/li&gt;
&lt;li&gt;Notion pages&lt;/li&gt;
&lt;li&gt;Apple Notes&lt;/li&gt;
&lt;li&gt;That one Google Doc from 3 months ago&lt;/li&gt;
&lt;li&gt;Slack DMs to yourself&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And every time you need to tweak a prompt, you're playing copy-paste gymnastics, losing track of what worked and what didn't.&lt;br&gt;
So I built Prompt Builder - a block-based workspace for composing, organizing, and sharing AI prompts. Think of it as Notion blocks meet prompt engineering.&lt;br&gt;
🎯 What It Does&lt;br&gt;
Instead of managing prompts as walls of text, you build them from draggable blocks:&lt;br&gt;
[Block 1: Context] → [Block 2: Instructions] → [Block 3: Examples] → [Block 4: Output Format]&lt;/p&gt;

&lt;p&gt;Each block has its own controls:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;👁️ Toggle visibility (test variations without deleting)&lt;/li&gt;
&lt;li&gt;🏷️ Wrap with custom tags&lt;/li&gt;
&lt;li&gt;🎙️ Voice input with transcription&lt;/li&gt;
&lt;li&gt;📋 Individual copy/paste/clear&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The killer feature? Live preview shows your combined prompt in real-time with character count.&lt;br&gt;
🛠️ The Tech Stack&lt;br&gt;
Here's what powers it:&lt;/p&gt;

&lt;p&gt;`// Core Stack&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Next.js 14 (App Router)&lt;/li&gt;
&lt;li&gt;Supabase (Database + Auth)&lt;/li&gt;
&lt;li&gt;Stripe (Payments)&lt;/li&gt;
&lt;li&gt;Tailwind CSS + shadcn/ui&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;// State Management&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Zustand (Editor state)&lt;/li&gt;
&lt;li&gt;TanStack Query (Server state)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;// Key Libraries&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;@dnd-kit (Drag &amp;amp; drop)&lt;/li&gt;
&lt;li&gt;react-textarea-autosize (Auto-expanding textareas)&lt;/li&gt;
&lt;li&gt;sonner (Notifications)&lt;/li&gt;
&lt;li&gt;next-themes (Dark mode)`&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🏗️ Architecture Decisions&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Block Storage Strategy
I store blocks as JSONB in Supabase for maximum flexibility:
&lt;code&gt;CREATE TABLE prompts (
id UUID PRIMARY KEY,
user_id UUID REFERENCES auth.users,
name TEXT,
blocks JSONB,
created_at TIMESTAMPTZ
);&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Share Links Without Auth
Users can share prompts instantly without signing up. I generate unique IDs with nanoid and store them in a public table:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;// Generate shareable link&lt;br&gt;
const shareId = nanoid(10);&lt;br&gt;
await supabase&lt;br&gt;
  .from('shared_prompts')&lt;br&gt;
  .insert({ &lt;br&gt;
    id: shareId, &lt;br&gt;
    content: blocks,&lt;br&gt;
    expires_at: proUser ? expiryDate : null &lt;br&gt;
  });&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Real-time Preview Performance
Instead of re-rendering everything on each keystroke, I use:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;React.memo on block components&lt;/li&gt;
&lt;li&gt;Debounced preview updates&lt;/li&gt;
&lt;li&gt;Virtualization for long block lists with @tanstack/react-virtual&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💡 Cool Features I'm Proud Of&lt;br&gt;
Voice Input with Translation (Pro)&lt;br&gt;
&lt;code&gt;// Simplified implementation&lt;br&gt;
const transcript = await speechToText(audioBlob, sourceLanguage);&lt;br&gt;
const translated = proUser &lt;br&gt;
  ? await translateText(transcript, targetLanguage)&lt;br&gt;
  : transcript;&lt;br&gt;
updateBlockContent(blockId, translated);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Drag &amp;amp; Drop with @dnd-kit&lt;br&gt;
&lt;code&gt;&amp;lt;DndContext onDragEnd={handleDragEnd}&amp;gt;&lt;br&gt;
  &amp;lt;SortableContext items={blocks}&amp;gt;&lt;br&gt;
    {blocks.map(block =&amp;gt; (&lt;br&gt;
      &amp;lt;SortableBlock key={block.id} {...block} /&amp;gt;&lt;br&gt;
    ))}&lt;br&gt;
  &amp;lt;/SortableContext&amp;gt;&lt;br&gt;
&amp;lt;/DndContext&amp;gt;&lt;/code&gt;&lt;br&gt;
Variables System (Pro)&lt;br&gt;
Users can create reusable templates with variables:&lt;br&gt;
Hello {{name}}, regarding {{topic}}...&lt;/p&gt;

&lt;p&gt;📊 Current Status&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ MVP launched at promptbuilder.space&lt;/li&gt;
&lt;li&gt;🎉 No signup required to test&lt;/li&gt;
&lt;li&gt;💰 Free tier: 3 prompts, 5 blocks/prompt, 10 share links&lt;/li&gt;
&lt;li&gt;🚀 Pro unlocks: unlimited everything + exports + custom tags + variables&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🤔 Lessons Learned&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Start with sharing: Making sharing work without auth was complex but worth it for adoption&lt;/li&gt;
&lt;li&gt;JSONB is your friend: For flexible content structures, JSONB beats normalized tables&lt;/li&gt;
&lt;li&gt;Preview performance matters: Users expect instant feedback - optimize aggressively&lt;/li&gt;
&lt;li&gt;Stripe is still king: For SaaS billing, nothing beats Stripe's developer experience&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;🎯 What's Next?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; Team workspaces&lt;/li&gt;
&lt;li&gt; Prompt marketplace&lt;/li&gt;
&lt;li&gt; API access&lt;/li&gt;
&lt;li&gt; Chrome extension&lt;/li&gt;
&lt;li&gt; More AI model integrations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💭 Question for the Community&lt;br&gt;
What features would make YOU switch from your current prompt management solution?&lt;br&gt;
I'm especially curious about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Export formats you'd want&lt;/li&gt;
&lt;li&gt;Collaboration features&lt;/li&gt;
&lt;li&gt;Integration needs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Try it out (no signup needed): promptbuilder.space&lt;br&gt;
Drop your thoughts below or roast my implementation choices - I'm here for all of it! 🔥&lt;/p&gt;

&lt;p&gt;P.S. - If you're building something similar or want to chat about the technical decisions, my DMs are open!&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvnbd2b16nfm5z1o2mm64.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvnbd2b16nfm5z1o2mm64.png" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>buildinpublic</category>
    </item>
    <item>
      <title>"You are no longer limited by what you know; rather, you are only limited by what you can think to ask."</title>
      <dc:creator>Jaber-Said</dc:creator>
      <pubDate>Mon, 25 Aug 2025 18:27:30 +0000</pubDate>
      <link>https://forem.com/jaber-said/you-are-no-longer-limited-by-what-you-know-rather-you-are-only-limited-by-what-you-can-think-to-2nbk</link>
      <guid>https://forem.com/jaber-said/you-are-no-longer-limited-by-what-you-know-rather-you-are-only-limited-by-what-you-can-think-to-2nbk</guid>
      <description>&lt;p&gt;"You are no longer limited by what you know; rather, you are only limited by what you can think to ask."&lt;/p&gt;

&lt;p&gt;This quote perfectly captures the seismic shift we're experiencing as software engineers in the age of AI. 🚀 For generations, our value was deeply rooted in the knowledge we held—mastery of languages, frameworks, and algorithms. But with powerful language models at our fingertips, the game has fundamentally changed.&lt;/p&gt;

&lt;p&gt;Think about it: the entire repository of human knowledge is now accessible through a simple prompt. The bottleneck is no longer a lack of information, but a lack of imagination. AI is poised to significantly change the role of software engineers, automating mundane tasks and allowing us to focus on more complex and creative work.[1] This elevates our role from implementers to architects and problem-solvers, using AI as a tool to streamline our tasks.&lt;/p&gt;

&lt;p&gt;This transformation is leading to faster development cycles, higher-quality software, and more time for innovation. By automating routine tasks, AI boosts productivity and frees us up to focus on higher-level problem-solving, like architectural planning and strategic decision-making.&lt;/p&gt;

&lt;p&gt;Of course, this doesn't mean our technical skills are obsolete. On the contrary, finding the right balance between leveraging AI tools and maintaining our core technical competencies is essential. However, the emphasis is shifting from rote memorization to creative problem-solving and, most importantly, the art of asking the right questions. The ability to craft effective prompts is key to unlocking the full potential of AI.&lt;/p&gt;

&lt;p&gt;So, I leave you with this question: What is the most creative or complex question you've asked an AI that has unlocked a truly innovative solution? 🤔&lt;/p&gt;

&lt;p&gt;Jaber Said&lt;/p&gt;

&lt;p&gt;hashtag#AI hashtag#SoftwareEngineering hashtag#FutureOfTech hashtag#LanguageModels hashtag#Innovation&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Figmlj8xy4uzmdofj109x.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Figmlj8xy4uzmdofj109x.jpeg" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Future of Tech Jobs: Key Insights from the 2025 WEF Report</title>
      <dc:creator>Jaber-Said</dc:creator>
      <pubDate>Thu, 20 Mar 2025 06:43:23 +0000</pubDate>
      <link>https://forem.com/jaber-said/future-of-tech-jobs-key-insights-from-the-2025-wef-report-1fhi</link>
      <guid>https://forem.com/jaber-said/future-of-tech-jobs-key-insights-from-the-2025-wef-report-1fhi</guid>
      <description>&lt;p&gt;🚀 Future of Tech Jobs: Key Insights from the 2025 WEF Report 🚀&lt;/p&gt;

&lt;p&gt;The Future of Jobs Report 2025 by the World Economic Forum outlines transformative trends reshaping the tech landscape. Here’s what technical professionals need to know:&lt;/p&gt;

&lt;p&gt;🔥 Top Trends Impacting Tech Roles&lt;br&gt;
AI &amp;amp; Automation Dominate:&lt;/p&gt;

&lt;p&gt;86% of employers say AI and information processing technologies will transform businesses by 2030.&lt;/p&gt;

&lt;p&gt;Fastest-growing roles: AI/ML Specialists, Big Data Engineers, Cybersecurity Experts, and Software Developers.&lt;/p&gt;

&lt;p&gt;Declining roles: Data Entry Clerks, Administrative Assistants, and legacy IT support roles.&lt;/p&gt;

&lt;p&gt;Human-Machine Collaboration:&lt;/p&gt;

&lt;p&gt;By 2030, tasks will be nearly evenly split between humans, machines, and hybrid collaboration.&lt;/p&gt;

&lt;p&gt;Focus on augmentation (enhancing human skills) over outright replacement.&lt;/p&gt;

&lt;p&gt;Skills in Demand:&lt;/p&gt;

&lt;p&gt;Technical: AI/ML, cybersecurity, IoT, blockchain, and quantum computing.&lt;/p&gt;

&lt;p&gt;Human-Centric: Resilience, creative thinking, and systems thinking.&lt;/p&gt;

&lt;p&gt;📈 Critical Skills to Future-Proof Your Career&lt;br&gt;
Top 3 Fastest-Growing Skills:&lt;/p&gt;

&lt;p&gt;AI &amp;amp; Big Data&lt;/p&gt;

&lt;p&gt;Networks &amp;amp; Cybersecurity&lt;/p&gt;

&lt;p&gt;Technological Literacy&lt;/p&gt;

&lt;p&gt;Soft Skills:&lt;/p&gt;

&lt;p&gt;Leadership, adaptability, and curiosity are now non-negotiable for tech leaders.&lt;br&gt;
🌱 Green Tech &amp;amp; Sustainability&lt;br&gt;
Roles like Renewable Energy Engineers and Environmental Data Scientists are surging.&lt;/p&gt;

&lt;p&gt;Demand for environmental stewardship skills enters the top 10 for the first time.&lt;/p&gt;

&lt;p&gt;💡 Actionable Takeaways&lt;br&gt;
Upskill Relentlessly: 59% of workers globally will need reskilling by 2030. Prioritize certifications in AI, cloud, and cybersecurity.&lt;/p&gt;

&lt;p&gt;Embrace Hybrid Roles: Combine technical expertise with cross-disciplinary skills (e.g., AI ethics, sustainable tech).&lt;/p&gt;

&lt;p&gt;Leverage DEI: Companies with diverse teams are 4x more likely to tap into new talent pools.&lt;/p&gt;

&lt;p&gt;🔗 Stay Ahead:&lt;br&gt;
Dive into emerging tools like GenAI (prompt engineering, AI-augmented coding) and decentralized systems.&lt;/p&gt;

&lt;p&gt;👉 Question for You: Which skill are you prioritizing to stay competitive in the next 5 years?&lt;/p&gt;

&lt;h1&gt;
  
  
  FutureOfWork #AI #TechCareers #Cybersecurity #MachineLearning #Innovation
&lt;/h1&gt;

&lt;p&gt;(Source: World Economic Forum, Future of Jobs Report 2025)&lt;/p&gt;

&lt;p&gt;Jaber Said&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.weforum.org/publications/the-future-of-jobs-report-2025/" rel="noopener noreferrer"&gt;https://www.weforum.org/publications/the-future-of-jobs-report-2025/&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Enhancing AI Model Outcomes Through Dynamic Chain-of-Thought Framework: A Systematic Approach</title>
      <dc:creator>Jaber-Said</dc:creator>
      <pubDate>Tue, 29 Oct 2024 23:04:26 +0000</pubDate>
      <link>https://forem.com/jaber-said/enhancing-ai-model-outcomes-through-dynamic-chain-of-thought-framework-a-systematic-approach-2886</link>
      <guid>https://forem.com/jaber-said/enhancing-ai-model-outcomes-through-dynamic-chain-of-thought-framework-a-systematic-approach-2886</guid>
      <description>&lt;h1&gt;
  
  
  Dynamic Problem Solving Framework to Improve Model Outcomes (COT)
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Executive Summary
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;Dynamic Problem-Solving Framework&lt;/strong&gt; presents an innovative approach to improving AI model outcomes through structured thinking and systematic evaluation. This framework implements &lt;strong&gt;Chain-of-Thought (CoT) methodology&lt;/strong&gt;, enhanced with dynamic reflection mechanisms and quality metrics, to achieve more reliable and accurate problem-solving results.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In the evolving landscape of AI and machine learning, the quality of model outputs heavily depends on the framework used to guide their thinking process. This repository introduces a comprehensive framework that combines structured problem-solving with continuous evaluation and adaptation mechanisms.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Features
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Structured Thinking Process
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Implements tagged sections for organized thought progression.&lt;/li&gt;
&lt;li&gt;Utilizes a &lt;strong&gt;20-step budget system&lt;/strong&gt; for efficient problem management.&lt;/li&gt;
&lt;li&gt;Incorporates &lt;strong&gt;formal mathematical notation&lt;/strong&gt; when needed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Dynamic Evaluation System
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Real-time &lt;strong&gt;quality scoring&lt;/strong&gt; (0.0-1.0).&lt;/li&gt;
&lt;li&gt;Immediate feedback loops for &lt;strong&gt;approach adjustment&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Systematic &lt;strong&gt;reflection points&lt;/strong&gt; throughout the process.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Adaptive Problem-Solving
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Flexible backtracking&lt;/strong&gt; mechanisms.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multiple solution exploration&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Continuous &lt;strong&gt;approach refinement&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Technical Implementation
&lt;/h2&gt;

&lt;p&gt;The framework employs XML-style tags for different aspects of the problem-solving process:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;thinking&amp;gt;&lt;/code&gt; for initial problem analysis.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;step&amp;gt;&lt;/code&gt; for sequential solution development.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;reflect&amp;gt;&lt;/code&gt; for progress evaluation.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;reward&amp;gt;&lt;/code&gt; for quality scoring.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;verify&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;confirm&amp;gt;&lt;/code&gt; for solution validation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Applications and Benefits
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Enhanced accuracy&lt;/strong&gt; in complex problem-solving.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Improved transparency&lt;/strong&gt; in decision-making processes.&lt;/li&gt;
&lt;li&gt;Systematic approach to &lt;strong&gt;solution verification&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Adaptable to &lt;strong&gt;various domains&lt;/strong&gt; and problem types.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This framework represents a significant advancement in structured problem-solving methodologies, offering a robust approach to improving AI model outcomes through systematic thinking and continuous evaluation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;Visit the repository at &lt;a href="https://github.com/Jaber-Saed/Dynamic-Problem-Solving-Framework-To-Improve-Model-Outcomes--COT-" rel="noopener noreferrer"&gt;GitHub Repository&lt;/a&gt; to explore the implementation details and documentation.&lt;/p&gt;

</description>
      <category>promptengineering</category>
      <category>aimodeloptimization</category>
      <category>structuredthinking</category>
      <category>problemsolvingframework</category>
    </item>
    <item>
      <title>Fortifying Your Digital Fortress: The Art of API Security</title>
      <dc:creator>Jaber-Said</dc:creator>
      <pubDate>Thu, 18 Jul 2024 14:39:49 +0000</pubDate>
      <link>https://forem.com/jaber-said/fortifying-your-digital-fortress-the-art-of-api-security-1ae2</link>
      <guid>https://forem.com/jaber-said/fortifying-your-digital-fortress-the-art-of-api-security-1ae2</guid>
      <description>&lt;p&gt;In the ever-evolving landscape of web development, APIs serve as the vital bridges connecting different software systems. But as these bridges become more crucial, they also become prime targets for cyber attacks. Welcome to the world of API security – where vigilance meets innovation in the quest to protect our digital ecosystems.&lt;/p&gt;

&lt;p&gt;The HTTPS Revolution: Encryption on the Move&lt;/p&gt;

&lt;p&gt;Imagine sending a postcard with your bank details versus a sealed, tamper-proof envelope. That's the difference between HTTP and HTTPS. By implementing HTTPS, we encrypt data in transit, turning our API communications into those secure envelopes. It's not just a good practice; it's the foundation of API security.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Express.js HTTPS setup 

const https = require('https'); 
const fs = require('fs');

const options = { 
      key: fs.readFileSync('path/to/key.pem'), 
      cert: fs.readFileSync('path/to/cert.pem')
       };`

https.createServer(options, app).listen(443);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Authentication: The Digital Bouncer&lt;/p&gt;

&lt;p&gt;Think of authentication as the bouncer at an exclusive club. JSON Web Tokens (JWTs) have become the VIP passes of the API world. They're compact, self-contained, and can carry a wealth of user information securely.4&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
const jwt = require('jsonwebtoken');

app.post('/login', (req, res) =&amp;gt; { 
        // Verify user credentials 
     const token = jwt.sign({ userId: user.id }, 'your-secret-key', { expiresIn: '1h' });       res.json({ token });
 });

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Authorization: The Velvet Rope of Access Control&lt;/p&gt;

&lt;p&gt;Once inside the club, authorization determines which areas you can access. Role-Based Access Control (RBAC) is like having different colored wristbands at a festival – each color grants access to different stages.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function checkRole(role) { 
   return (req, res, next) =&amp;gt; { 
       if (req.user.role !== role) { 
           return res.status(403).send('Access denied'); 
       } next(); 
       } 
}

app.get('/vip-area', checkRole('vip'), (req, res) =&amp;gt; { 
    res.send('Welcome to the VIP area!'); 
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Input Validation: The Art of Paranoia&lt;/p&gt;

&lt;p&gt;In the world of APIs, trust no one. Every input is a potential threat. Input validation is like having a meticulous inspector checking every package before it enters your system.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const { body, validationResult } = require('express-validator');

app.post('/user', [
      body('username').isLength({ min: 5 }).withMessage('Username must be at least 5 characters long'), 
          body('email').isEmail().withMessage('Invalid email format'), 
], (req, res) =&amp;gt; { 
     const errors = validationResult(req); 
     if (!errors.isEmpty()) {
         return res.status(400).json({ errors: errors.array() }); 
       } 
 // Process valid input 
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rate Limiting: The Traffic Controller&lt;/p&gt;

&lt;p&gt;Imagine if everyone tried to enter a store at once during a sale. Chaos, right? Rate limiting is your digital crowd control, ensuring your API doesn't get overwhelmed by too many requests.&lt;/p&gt;

&lt;p&gt;`const rateLimit = require("express-rate-limit");&lt;/p&gt;

&lt;p&gt;const apiLimiter = rateLimit({ &lt;br&gt;
    windowMs: 15  60  1000, // 15 minutes &lt;br&gt;
    max: 100, // limit each IP to 100 requests per windowMs &lt;br&gt;
    message: "Too many requests, please try again later." &lt;br&gt;
});&lt;/p&gt;

&lt;p&gt;app.use("/api/", apiLimiter);`&lt;/p&gt;

&lt;p&gt;Logging and Monitoring: The Watchful Eye&lt;/p&gt;

&lt;p&gt;In the realm of API security, knowledge is power. Comprehensive logging and monitoring are like having a team of vigilant security cameras and alert guards, always watching for suspicious activity.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const winston = require('winston');

const logger = winston.createLogger({ 
   level: 'info', 
     format: winston.format.json(), 
   transports: [ 
      new winston.transports.File({ filename: 'error.log', level: 'error' }), 
      new winston.transports.Console({ format: winston.format.simple() }) 
    ] 
});

app.use((req, res, next) =&amp;gt; {
   logger.info(${req.method} ${req.url}); 
    next();
 });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Conclusion: The Never-Ending Battle&lt;/p&gt;

&lt;p&gt;Securing an API is not a one-time task but an ongoing process. It's a chess game where the pieces are constantly evolving. By implementing these security measures, you're not just protecting data; you're safeguarding trust, ensuring privacy, and fortifying the foundations of our interconnected digital world.&lt;/p&gt;

&lt;p&gt;Remember, in the realm of API security, paranoia is not just acceptable – it's essential. Stay vigilant, stay updated, and may your APIs be forever unbreached!&lt;/p&gt;

&lt;p&gt;Jaber Said&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Understanding Command Line Execution and Environment Configuration</title>
      <dc:creator>Jaber-Said</dc:creator>
      <pubDate>Mon, 15 Jul 2024 07:52:40 +0000</pubDate>
      <link>https://forem.com/jaber-said/understanding-command-line-execution-and-environment-configuration-1hd5</link>
      <guid>https://forem.com/jaber-said/understanding-command-line-execution-and-environment-configuration-1hd5</guid>
      <description>&lt;p&gt;Introduction&lt;/p&gt;

&lt;p&gt;In the world of software development, the command line is a powerful tool that allows developers to execute scripts, run programs, and manage files and processes efficiently. One of the common challenges encountered by developers, especially when working with multiple programming languages and tools, is understanding how to correctly execute commands and configure the environment for smooth operations. This article delves into the mechanics of command line execution, focusing on the differences between using the Python module system and directly invoking executables, and provides insights into environment configuration.&lt;/p&gt;

&lt;p&gt;Command Line Basics&lt;/p&gt;

&lt;p&gt;The command line, also known as the terminal or shell, is an interface where users can type commands to perform specific tasks. Commands are typically executed in a sequence, where each command is interpreted and executed by the shell. For example, in a Windows environment, the Command Prompt or PowerShell can be used, while macOS and Linux users often use the Terminal.&lt;/p&gt;

&lt;p&gt;Executing Python Modules&lt;/p&gt;

&lt;p&gt;Python is a versatile programming language that allows for modular programming. Python scripts and modules can be executed directly from the command line using the Python interpreter. A common command to run a Python script is:&lt;/p&gt;

&lt;p&gt;python script.py&lt;/p&gt;

&lt;p&gt;However, Python also allows the execution of modules using the -m flag:&lt;/p&gt;

&lt;p&gt;python -m module_name&lt;/p&gt;

&lt;p&gt;or using the Python launcher in Windows:&lt;/p&gt;

&lt;p&gt;py -m module_name&lt;/p&gt;

&lt;p&gt;Why Use -m to Run Modules?&lt;/p&gt;

&lt;p&gt;When you use the -m flag, Python locates the specified module in the Python environment and runs it as a script. This method has several advantages:&lt;/p&gt;

&lt;p&gt;Module Lookup: Python searches for the module in the standard library and installed packages, ensuring the correct module is executed.&lt;/p&gt;

&lt;p&gt;Environment Management: It uses the current Python environment, respecting virtual environments and avoiding conflicts with other Python installations.&lt;/p&gt;

&lt;p&gt;Convenience: It simplifies running modules that are not standalone scripts, leveraging Python’s module system for execution.&lt;/p&gt;

&lt;p&gt;Direct Command Execution&lt;/p&gt;

&lt;p&gt;Directly executing a command, such as running an executable file, requires the command to be recognized by the operating system. For example:&lt;/p&gt;

&lt;p&gt;aider --model gemini/gemini-1.5-pro-latest --browser&lt;/p&gt;

&lt;p&gt;If the shell responds with:&lt;/p&gt;

&lt;p&gt;'aider' is not recognized as an internal or external command, operable program or batch file.&lt;/p&gt;

&lt;p&gt;it means the executable is not found in the system’s PATH.&lt;/p&gt;

&lt;p&gt;Understanding PATH&lt;/p&gt;

&lt;p&gt;The PATH is an environment variable that tells the operating system where to look for executable files. When you type a command, the shell searches the directories listed in the PATH variable to find the corresponding executable.&lt;/p&gt;

&lt;p&gt;Configuring PATH&lt;/p&gt;

&lt;p&gt;To ensure an executable can be run from any location in the command line, its directory must be added to the PATH. Here’s how to add a directory to the PATH in Windows:&lt;/p&gt;

&lt;p&gt;Open Environment Variables: Search for "Edit the system environment variables" in the Start menu and open it.&lt;/p&gt;

&lt;p&gt;Access PATH Variable: In the System Properties window, click on "Environment Variables". Under "System variables", find and select the PATH variable, then click "Edit".&lt;/p&gt;

&lt;p&gt;Add Directory: Click "New" and add the directory where the executable is located. Click "OK" to save the changes.&lt;/p&gt;

&lt;p&gt;Best Practices for Command Line Execution&lt;/p&gt;

&lt;p&gt;Use Virtual Environments: When working with Python, use virtual environments to manage dependencies and avoid conflicts.&lt;/p&gt;

&lt;p&gt;Leverage -m for Modules: Use the -m flag to run Python modules, ensuring the correct environment and module lookup.&lt;/p&gt;

&lt;p&gt;Manage PATH Carefully: Regularly review and manage your PATH variable to avoid clutter and conflicts, only adding necessary directories.&lt;/p&gt;

&lt;p&gt;Consistency: Maintain consistency in your command line practices to streamline workflows and reduce errors.&lt;/p&gt;

&lt;p&gt;Conclusion&lt;/p&gt;

&lt;p&gt;Understanding how the command line executes commands and how environment variables like PATH influence this process is crucial for efficient software development. Using the -m flag to run Python modules and properly configuring the PATH can save time and prevent common issues. By adopting these best practices, developers can enhance their productivity and maintain cleaner, more manageable development environments.&lt;/p&gt;

&lt;p&gt;Jaber Said&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Muslim Prayer Times Extension for Visual Studio Code</title>
      <dc:creator>Jaber-Said</dc:creator>
      <pubDate>Sat, 13 Jul 2024 12:48:53 +0000</pubDate>
      <link>https://forem.com/jaber-said/muslim-prayer-times-extension-for-visual-studio-code-17a3</link>
      <guid>https://forem.com/jaber-said/muslim-prayer-times-extension-for-visual-studio-code-17a3</guid>
      <description>&lt;p&gt;Introducing the Muslim Prayer Times Extension for Visual Studio Code&lt;br&gt;
Are you a Muslim developer looking to stay on top of your prayer times while coding? We've got great news for you! The Muslim Prayer Times extension for Visual Studio Code is here to help you balance your work and religious obligations seamlessly.&lt;br&gt;
This powerful extension brings prayer time reminders directly into your coding environment, ensuring you never miss a prayer while immersed in your projects. Here's what makes it special:&lt;/p&gt;

&lt;p&gt;Location-based accuracy: Get precise prayer times based on your exact location.&lt;br&gt;
At-a-glance information: View prayer times and countdown to the next prayer right in your VS Code sidebar.&lt;br&gt;
Customizable notifications: Receive gentle reminders when it's time to pray.&lt;br&gt;
Azan sound option: Enable the beautiful call to prayer sound for a more immersive experience.&lt;br&gt;
Flexible time formats: Choose between 12-hour and 24-hour displays to suit your preference.&lt;br&gt;
Language options: View prayer names in your preferred language.&lt;br&gt;
Easy setup: Simple configuration allows you to set your location and preferences quickly.&lt;/p&gt;

&lt;p&gt;Whether you're working on a complex project or debugging code, this extension ensures that your spiritual well-being remains a priority. It's the perfect tool for Muslim developers who want to maintain their prayer schedule without interrupting their workflow.&lt;br&gt;
Ready to enhance your coding and spiritual experience? Install the Muslim Prayer Times extension for Visual Studio Code today and bring harmony to your development process!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=JaberSaid.muslim-prayer-times" rel="noopener noreferrer"&gt;https://marketplace.visualstudio.com/items?itemName=JaberSaid.muslim-prayer-times&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  MuslimDevelopers #VSCode #PrayerTimes #ProductivityTools
&lt;/h1&gt;

&lt;p&gt;Jaber Said&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftb29z34nxfee7ehkmxg0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftb29z34nxfee7ehkmxg0.png" alt=" " width="800" height="391"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
