<?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>DEV Community: Kanha</title>
    <description>The latest articles on DEV Community by Kanha (@coderkanha47).</description>
    <link>https://dev.to/coderkanha47</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4193262%2Fcb1d5908-6741-40c2-997f-001922f954c9.jpg</url>
      <title>DEV Community: Kanha</title>
      <link>https://dev.to/coderkanha47</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/coderkanha47"/>
    <language>en</language>
    <item>
      <title>I Built an AI Expense Auditor: Vision LLM + Rule-Based Fraud Detection + Multi-Currency Payouts</title>
      <dc:creator>Kanha</dc:creator>
      <pubDate>Tue, 27 Oct 2026 07:50:27 +0000</pubDate>
      <link>https://dev.to/coderkanha47/i-built-an-ai-expense-auditor-vision-llm-rule-based-fraud-detection-multi-currency-payouts-4ikh</link>
      <guid>https://dev.to/coderkanha47/i-built-an-ai-expense-auditor-vision-llm-rule-based-fraud-detection-multi-currency-payouts-4ikh</guid>
      <description>&lt;p&gt;&lt;strong&gt;The Project&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sector Guard&lt;/strong&gt; — an AI-powered expense reimbursement platform. Employees upload receipts, a vision LLM extracts structured data, a rule-based fraud engine audits every claim, and monthly payouts are locked immutably.&lt;/p&gt;

&lt;p&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4mqpy85rr7vwnln9o2kj.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4mqpy85rr7vwnln9o2kj.png" alt=" " width="800" height="398"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Live: &lt;a href="https://sector-guard.vercel.app" rel="noopener noreferrer"&gt;Sector Guard&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GitHub: &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/CoderKanha47" rel="noopener noreferrer"&gt;
        CoderKanha47
      &lt;/a&gt; / &lt;a href="https://github.com/CoderKanha47/sector-guard" rel="noopener noreferrer"&gt;
        sector-guard
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Sector Guard v1.5&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;An AI-powered expense reimbursement auditing platform. Employees upload receipts, a hosted vision-language model extracts the data automatically, and a rule-based fraud engine catches policy violations before finance ever sees them.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Live demo:&lt;/strong&gt; &lt;a href="https://sector-guard.vercel.app/" rel="nofollow noopener noreferrer"&gt;https://sector-guard.vercel.app/&lt;/a&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Overview&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Sector Guard automates the expense reimbursement workflow that finance teams usually handle manually:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;An employee uploads a receipt (ride, food, or accommodation)&lt;/li&gt;
&lt;li&gt;A hosted vision-language model (Groq's Qwen 3.8 27B) extracts structured data — merchant, amount, currency, date, category, line items — with zero manual entry&lt;/li&gt;
&lt;li&gt;A rule-based fraud engine audits the expense against the employee's recent history, checking for policy violations, receipt-splitting fraud, and temporally impossible claims&lt;/li&gt;
&lt;li&gt;Each expense is scored, categorized (&lt;code&gt;APPROVED&lt;/code&gt; / &lt;code&gt;FLAGGED&lt;/code&gt; / &lt;code&gt;DENIED&lt;/code&gt;), and the employee's trust rating adjusts accordingly&lt;/li&gt;
&lt;li&gt;At month-end, approved expenses are aggregated and &lt;strong&gt;locked&lt;/strong&gt; into an immutable payout record — capped at the employee's monthly tier limit, with a category-wise (Travel /…&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/CoderKanha47/sector-guard" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Why I Built This&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Expense auditing is manual, slow, and error-prone in most companies. Someone stares at receipt images, types amounts into spreadsheets, checks policy rules by hand. I wanted to automate the full loop:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Receipt → Structured data (vision LLM, not OCR)&lt;/li&gt;
&lt;li&gt;Data → Audit decision (deterministic rules, explainable)&lt;/li&gt;
&lt;li&gt;Approved claims → Locked monthly payout (immutable, capped at tier limit)&lt;/li&gt;
&lt;li&gt;All other things could be queried (corporate overview, individual finances, normalized to USD).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Architecture&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Receipt Upload&lt;br&gt;
      ↓&lt;br&gt;
Groq Vision LLM (Qwen 3.8 27B) → Structured JSON&lt;br&gt;
      ↓&lt;br&gt;
Currency Converter (fixed rates, 21 Oct 2026) → USD normalization&lt;br&gt;
      ↓&lt;br&gt;
Fraud Engine (3 rules, risk score 0-100)&lt;br&gt;
      ↓&lt;br&gt;
Status: APPROVED / FLAGGED / DENIED /&lt;br&gt;
      ↓&lt;br&gt;
Prisma + Neon Postgres (serverless)&lt;br&gt;
      ↓&lt;br&gt;
Monthly Payout Close → Immutable record&lt;br&gt;
      ↓&lt;br&gt;
Company Summary (admin) / Employee Financial Summary&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Core Features&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;What It Does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Vision LLM extraction&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Receipt image → &lt;code&gt;{merchant, amount, currency, date, category, line_items[]}&lt;/code&gt; — no templates, no regex&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Fraud engine&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;3 rules: tier-limit breach, split-receipt detection, temporal conflict. Risk score → status. Plain-language explanations.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Trust rating&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Starts at 100. Clean audits +1, flags -5 to -15. Visible to admin.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Monthly payouts&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Approved expenses aggregated, capped at tier limit, categorized (Travel/Food/Stay/Other), locked immutable.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Company dashboard (admin)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Summary cards, employee ratings table, monthly trends chart (Recharts).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Employee portal&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Receipt folders by month, payout history, claimed/approved/paid in USD + original currency breakdown.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Rate limiting&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;29 receipts/day, atomic upsert + in-function semaphore (race-condition safe).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Auth&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Admin login + per-employee access codes (hashed). Employees scoped to own data.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;The Fraud Engine (Deterministic, Explainable)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/lib/engine/fraudCore.ts&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;calculateRiskScore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;receipt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;employee&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;history&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;RiskResult&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;score&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;reasons&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

  &lt;span class="c1"&gt;// Rule 1: Tier limit breach&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;monthlyTotal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;history&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;receipt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;employee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tierLimit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;reasons&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Monthly tier limit exceeded (&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;employee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tierLimit&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="c1"&gt;// Rule 2: Split receipt fraud&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;sameVendorSameDay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;history&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;receipt&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;b&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;a&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;amount&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="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;SINGLE_RECEIPT_LIMIT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;35&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;reasons&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Split-receipt pattern detected&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;// Rule 3: Temporal conflict&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;overlappingClaims&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;history&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;receipt&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;reasons&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Physically implausible overlapping claims&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="nx"&gt;score&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="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;70&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;DENIED&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;FLAGGED&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="s1"&gt;APPROVED&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;reasons&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;calculatedReimbursement&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;70&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;receipt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;amount&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;Why rule-based?&lt;/strong&gt; &lt;em&gt;Every flag has a clear, auditable reason. Compliance teams need "why," not "the model said so."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Currency Handling — The Pain Point I Didn't Expect&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Initially hardcoded INR→USD. Real receipts come in EUR, GBP, AED...&lt;br&gt;
Solution: Convert at write-time, not read-time.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/lib/currency/fixedRates.ts&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;FIXED_FX_RATES&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;USD&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="na"&gt;INR&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.0119&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="c1"&gt;// 1 INR = 0.0119 USD&lt;/span&gt;
  &lt;span class="na"&gt;EUR&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1.085&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;    &lt;span class="c1"&gt;// 1 EUR = 1.085 USD&lt;/span&gt;
  &lt;span class="na"&gt;GBP&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1.315&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;    &lt;span class="c1"&gt;// 1 GBP = 1.315 USD&lt;/span&gt;
  &lt;span class="na"&gt;AED&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.272&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;    &lt;span class="c1"&gt;// 1 AED = 0.272 USD&lt;/span&gt;
  &lt;span class="na"&gt;SGD&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.745&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;    &lt;span class="c1"&gt;// 1 SGD = 0.745 USD&lt;/span&gt;
  &lt;span class="c1"&gt;// ... rates as of 21 Oct 2026&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;convertToUSD&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;currency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;usdAmount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;rate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;CONVERTED&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;UNSUPPORTED&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;FIXED_FX_RATES&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;currency&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;rate&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;usdAmount&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;rate&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;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;UNSUPPORTED&lt;/span&gt;&lt;span class="dl"&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;usdAmount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;rate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rate&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;CONVERTED&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Result&lt;/strong&gt;: Fraud engine, payouts, summaries all work in USD. Original currency preserved. Unsupported currency = UNSUPPORTED status (currently not used — all test currencies covered).&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Choice&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Framework&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Next.js 16 (App Router)&lt;/td&gt;
&lt;td&gt;Server components, API routes, Vercel-native&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Database&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Neon (serverless Postgres)&lt;/td&gt;
&lt;td&gt;Scales to zero, works on Vercel&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ORM&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Prisma + @prisma/adapter-pg&lt;/td&gt;
&lt;td&gt;Required for serverless connection pooling&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AI&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Groq API (Qwen 3.8 27B Scout)&lt;/td&gt;
&lt;td&gt;Fast, free tier, vision support&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;FX&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Static rate table&lt;/td&gt;
&lt;td&gt;no external dependency&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Charts&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Recharts&lt;/td&gt;
&lt;td&gt;Lightweight, Tailwind-friendly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Auth&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;JWT (jose), httpOnly cookies&lt;/td&gt;
&lt;td&gt;Simple, no external dependency&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Hosting&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Vercel&lt;/td&gt;
&lt;td&gt;Zero-config for Next.js&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;What I Learned&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Vision LLMs &amp;gt; OCR for receipts. OCR gives text; vision LLM gives structure. Prompt design matters more than model choice.&lt;/li&gt;
&lt;li&gt;Never trust LLM output. The fraud engine's validation layer caught hallucinated totals and impossible dates.&lt;/li&gt;
&lt;li&gt;Convert currency at ingestion. One USD column everywhere downstream &amp;gt; CASE WHEN chaos in every query.&lt;/li&gt;
&lt;li&gt;Serverless rate limiting needs a semaphore. Vercel functions run concurrently. DB counter alone races.&lt;/li&gt;
&lt;li&gt;Admin dashboard = aggregation that you have already. No new table required; just query the table differently from Expense/Audit/Monthly Payout.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Demo Walkthrough&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open &lt;a href="https://sector-guard.vercel.app" rel="noopener noreferrer"&gt;Sector Guard&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Click admin tab&lt;/li&gt;
&lt;li&gt;Login: password abc&lt;/li&gt;
&lt;li&gt;Explore:
Company Summary - summary cards, employee ratings table, monthly trends chart,
Employees - list, create, edit, delete (access codes are hashed)
Payouts - monthly records, category breakdowns
Click an employee → Financial Summary → claimed/approved/paid in USD + original currency breakdown&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;What's Next&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automated payout approval (admin one-click → paidAt)&lt;/li&gt;
&lt;li&gt;Email/Slack notifications on payout close&lt;/li&gt;
&lt;li&gt;Configurable fraud rules per department&lt;/li&gt;
&lt;li&gt;E2E tests (Playwright)&lt;/li&gt;
&lt;li&gt;Dark mode toggle&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Feedback, issues, and PRs welcome. If you're building AI-powered finance tools or vision LLM pipelines, let's connect.&lt;br&gt;
GitHub: &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/CoderKanha47" rel="noopener noreferrer"&gt;
        CoderKanha47
      &lt;/a&gt; / &lt;a href="https://github.com/CoderKanha47/sector-guard" rel="noopener noreferrer"&gt;
        sector-guard
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Sector Guard v1.5&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;An AI-powered expense reimbursement auditing platform. Employees upload receipts, a hosted vision-language model extracts the data automatically, and a rule-based fraud engine catches policy violations before finance ever sees them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Live demo:&lt;/strong&gt; &lt;a href="https://sector-guard.vercel.app/" rel="nofollow noopener noreferrer"&gt;https://sector-guard.vercel.app/&lt;/a&gt;&lt;/p&gt;




&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Overview&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;Sector Guard automates the expense reimbursement workflow that finance teams usually handle manually:&lt;/p&gt;


&lt;ol&gt;

&lt;li&gt;An employee uploads a receipt (ride, food, or accommodation)&lt;/li&gt;

&lt;li&gt;A hosted vision-language model (Groq's Qwen 3.8 27B) extracts structured data — merchant, amount, currency, date, category, line items — with zero manual entry&lt;/li&gt;

&lt;li&gt;A rule-based fraud engine audits the expense against the employee's recent history, checking for policy violations, receipt-splitting fraud, and temporally impossible claims&lt;/li&gt;

&lt;li&gt;Each expense is scored, categorized (&lt;code&gt;APPROVED&lt;/code&gt; / &lt;code&gt;FLAGGED&lt;/code&gt; / &lt;code&gt;DENIED&lt;/code&gt;), and the employee's trust rating adjusts accordingly&lt;/li&gt;

&lt;li&gt;At month-end, approved expenses are aggregated and &lt;strong&gt;locked&lt;/strong&gt; into an immutable payout record — capped at the employee's monthly tier limit, with a category-wise (Travel /…&lt;/li&gt;

&lt;/ol&gt;&lt;/div&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/CoderKanha47/sector-guard" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


</description>
      <category>ai</category>
      <category>python</category>
      <category>fullstack</category>
      <category>postgres</category>
    </item>
  </channel>
</rss>
