<?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: Mayuresh Smita Suresh</title>
    <description>The latest articles on DEV Community by Mayuresh Smita Suresh (@mayu2008).</description>
    <link>https://dev.to/mayu2008</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%2F3571903%2Ffce1104c-74aa-424e-9521-7195968d0ad0.jpeg</url>
      <title>DEV Community: Mayuresh Smita Suresh</title>
      <link>https://dev.to/mayu2008</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mayu2008"/>
    <language>en</language>
    <item>
      <title>Building GenAI-Powered Applications with PHP and CodeIgniter 4. A Complete Guide</title>
      <dc:creator>Mayuresh Smita Suresh</dc:creator>
      <pubDate>Thu, 30 Jul 2026 02:48:54 +0000</pubDate>
      <link>https://dev.to/mayu2008/building-genai-powered-applications-with-php-and-codeigniter-4-a-complete-guide-5ba2</link>
      <guid>https://dev.to/mayu2008/building-genai-powered-applications-with-php-and-codeigniter-4-a-complete-guide-5ba2</guid>
      <description>&lt;p&gt;Generative AI has largely become a Python-and-JavaScript conversation, but there's no technical reason PHP should sit this out. CodeIgniter 4 — lightweight, fast-booting, and still powering a huge number of production apps — is perfectly capable of integrating LLMs cleanly. This guide walks through a full, production-minded implementation: configuration, a reusable service layer, streaming responses, error handling, a basic RAG setup, security considerations, and testing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Why CodeIgniter 4 for GenAI&lt;/li&gt;
&lt;li&gt;Project Setup &amp;amp; Configuration&lt;/li&gt;
&lt;li&gt;Building a Robust GenAI Service Layer&lt;/li&gt;
&lt;li&gt;Controller &amp;amp; Routes&lt;/li&gt;
&lt;li&gt;Frontend Integration (Form + Streaming)&lt;/li&gt;
&lt;li&gt;Adding a Simple RAG Pipeline&lt;/li&gt;
&lt;li&gt;Error Handling &amp;amp; Retries&lt;/li&gt;
&lt;li&gt;Security &amp;amp; Rate Limiting&lt;/li&gt;
&lt;li&gt;Caching Strategy&lt;/li&gt;
&lt;li&gt;Testing the Integration&lt;/li&gt;
&lt;li&gt;Deployment Considerations&lt;/li&gt;
&lt;li&gt;Real-World Use Cases&lt;/li&gt;
&lt;li&gt;Wrapping Up&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  1. Why CodeIgniter 4 for GenAI
&lt;/h2&gt;

&lt;p&gt;CodeIgniter 4 has a few things going for it here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Built-in HTTP client&lt;/strong&gt; (&lt;code&gt;CURLRequest&lt;/code&gt;) — no need for Guzzle or heavy SDKs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Service container&lt;/strong&gt; (&lt;code&gt;Config\Services&lt;/code&gt;) — makes it trivial to swap providers (Anthropic, OpenAI, local models) behind one interface.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fast boot time&lt;/strong&gt; — matters if you're calling this from lightweight microservices or queued workers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mature caching layer&lt;/strong&gt; — useful for reducing redundant LLM calls, which are often the most expensive part of the stack.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of this requires abandoning your existing MVC structure. The LLM is just another external API — CI4 already knows how to talk to those.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Project Setup &amp;amp; Configuration
&lt;/h2&gt;

&lt;p&gt;Install a fresh CI4 project if you don't already have one:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
bash
composer create-project codeigniter4/appstarter genai-ci4-app
cd genai-ci4-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>php</category>
      <category>codeigniter</category>
    </item>
    <item>
      <title>Building a Zoho CRM AI Chatbot with Airbyte: Architecture for Anomaly Detection and Causal Analysis</title>
      <dc:creator>Mayuresh Smita Suresh</dc:creator>
      <pubDate>Thu, 23 Jul 2026 04:29:24 +0000</pubDate>
      <link>https://dev.to/mayu2008/building-a-zoho-crm-ai-chatbot-with-airbyte-architecture-for-anomaly-detection-and-causal-analysis-52om</link>
      <guid>https://dev.to/mayu2008/building-a-zoho-crm-ai-chatbot-with-airbyte-architecture-for-anomaly-detection-and-causal-analysis-52om</guid>
      <description>&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%2Fj4r2f24pwgqw031s1jj6.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fj4r2f24pwgqw031s1jj6.jpeg" alt=" " width="600" height="479"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Building a Zoho CRM Chatbot with Airbyte: Architecture for Anomaly Detection and Causal Analysis
&lt;/h2&gt;

&lt;p&gt;Most "chat with your CRM" tools stop at natural language querying — you ask a question, it runs a lookup, you get an answer. That's useful, but it's not decision intelligence. The harder and more valuable problem is: &lt;em&gt;why&lt;/em&gt; did this metric move, and what will happen if we don't act on it?&lt;/p&gt;

&lt;p&gt;This article walks through an architecture for a Zoho CRM chatbot that goes past simple Q&amp;amp;A into anomaly detection and causal analysis — using Airbyte as the data movement layer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Airbyte as the Ingestion Layer
&lt;/h2&gt;

&lt;p&gt;Zoho CRM's native API is capable, but building a custom sync pipeline for every object (Leads, Deals, Contacts, Activities, Custom Modules) means handling pagination, rate limits, schema drift, and incremental sync logic yourself. Airbyte solves this with a pre-built Zoho CRM connector that handles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Incremental syncs&lt;/strong&gt; using Zoho's modified-time cursors, so you're not re-pulling the full dataset on every run&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Schema normalization&lt;/strong&gt; into a consistent format regardless of custom fields your Zoho instance has added&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Destination flexibility&lt;/strong&gt; — you can land data in Postgres, Snowflake, BigQuery, or a data lake without rewriting extraction logic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This matters because your chatbot and analysis layer are only as good as the freshness and structure of the underlying data. Airbyte turns "get Zoho data into a warehouse" into a configuration problem, not an engineering project.&lt;/p&gt;

&lt;h2&gt;
  
  
  High-Level Architecture
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Zoho CRM API
    │
    ▼
Airbyte (Zoho CRM Source Connector)
    │
    ▼
Data Warehouse (Postgres / Snowflake / BigQuery)
    │
    ├──► Semantic Layer (business-friendly metric definitions)
    │
    ├──► Anomaly Detection Service (statistical + ML models)
    │
    ├──► Causal Analysis Engine (root-cause chain builder)
    │
    └──► Chat Interface (LLM + retrieval + tool calls)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each layer has a distinct job, and keeping them separate is what makes the system maintainable as your Zoho instance grows more custom modules and fields over time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 1: Ingestion with Airbyte
&lt;/h2&gt;

&lt;p&gt;Set up the Zoho CRM connector with these core streams:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Leads&lt;/code&gt;, &lt;code&gt;Deals&lt;/code&gt;, &lt;code&gt;Contacts&lt;/code&gt;, &lt;code&gt;Accounts&lt;/code&gt; — the core CRM entities&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Activities&lt;/code&gt; and &lt;code&gt;Tasks&lt;/code&gt; — for behavioral/engagement signals&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Custom_Modules&lt;/code&gt; — if your Zoho instance has non-standard objects (common in sales-heavy configurations)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Configure sync frequency based on how time-sensitive your alerting needs to be. Hourly syncs are usually sufficient for CRM data — deal stages and lead statuses don't need real-time streaming for most use cases, and hourly batches keep your warehouse costs predictable.&lt;/p&gt;

&lt;p&gt;Land raw data in a staging schema first, untouched. Transform into cleaned, typed tables using dbt or a similar tool downstream. This separation means a Zoho schema change never corrupts your analysis layer — you fix the transformation, not the whole pipeline.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 2: Semantic Layer
&lt;/h2&gt;

&lt;p&gt;Before any AI touches the data, define your business metrics once, in one place: what counts as a "won deal," how "pipeline velocity" is calculated, what a "stalled lead" means for your sales process. This layer exists so the chatbot and the anomaly detector agree on definitions — without it, you'll get an alert that contradicts what the chatbot tells a user five minutes later, which destroys trust fast.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 3: Anomaly Detection
&lt;/h2&gt;

&lt;p&gt;This is where the system starts doing real work instead of just reporting numbers. Two approaches, used together:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Statistical baseline detection&lt;/strong&gt; — rolling averages and standard deviation bands per metric (deal close rate, average deal size, lead response time). Flag anything outside expected bounds. Cheap, explainable, and a good first line of defense.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Model-based detection&lt;/strong&gt; — for patterns too subtle for simple thresholds, such as a slow multi-week decline in lead quality from a specific source that wouldn't trip a single-day anomaly check. This is where a lightweight time-series model earns its keep over pure rule-based thresholds.&lt;/p&gt;

&lt;p&gt;Every anomaly gets written back to the warehouse with metadata: which metric, which segment (region, rep, product line), severity, and timestamp. This log is what your causal engine and chatbot both draw from.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 4: Causal Analysis
&lt;/h2&gt;

&lt;p&gt;This is the differentiator over a plain BI dashboard. When an anomaly fires — say, deal close rate dropped 15% this week — the causal engine's job is to trace &lt;em&gt;which upstream factor&lt;/em&gt; explains it, rather than leaving a human to dig through pivot tables.&lt;/p&gt;

&lt;p&gt;A practical approach:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Build a metric dependency graph ahead of time (e.g., close rate depends on lead source quality, rep activity volume, deal stage duration).&lt;/li&gt;
&lt;li&gt;When an anomaly fires on a downstream metric, walk the graph and check each upstream node for its own anomaly in the same window.&lt;/li&gt;
&lt;li&gt;Rank candidate causes by correlation strength and time-lag alignment, not just co-occurrence.&lt;/li&gt;
&lt;li&gt;Present the top 1-3 candidates with supporting evidence, not a single definitive answer — causal inference from observational CRM data is probabilistic, and the chatbot should represent it that way.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This step is what turns "close rate dropped" into "close rate dropped, most likely tied to a spike in leads from Channel X starting Tuesday" — the difference between a notification and an insight.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 5: Chat Interface
&lt;/h2&gt;

&lt;p&gt;The chatbot sits on top of everything below it — it should never touch raw Zoho data directly. Its job is to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Translate a natural language question into a query against the semantic layer&lt;/li&gt;
&lt;li&gt;Pull relevant anomaly and causal-chain records when a question relates to "why" something happened&lt;/li&gt;
&lt;li&gt;Generate a response grounded in retrieved data, not model memory — this is critical for numeric accuracy&lt;/li&gt;
&lt;li&gt;Route report or alert requests to a scheduling layer rather than answering ad hoc&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use retrieval-augmented generation here, not fine-tuning: the underlying CRM data changes daily, and RAG lets the chatbot stay current without retraining anything.&lt;/p&gt;

&lt;h2&gt;
  
  
  Alerts and Reports
&lt;/h2&gt;

&lt;p&gt;Once anomaly detection and causal analysis exist as services, alerts and reports become a thin layer on top:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Alerts&lt;/strong&gt; — push anomaly events above a severity threshold to Slack/email/webhook, including the top causal candidate if one was found&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reports&lt;/strong&gt; — scheduled summaries pulling from the same semantic layer the chatbot uses, so numbers in a Monday report and numbers the chatbot gives on Tuesday never disagree&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Practical Notes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Start with 3-4 core metrics, not full coverage. Anomaly detection tuned across every possible Zoho field produces noise, not insight, and noisy alerts get ignored within a week.&lt;/li&gt;
&lt;li&gt;Keep the causal dependency graph human-editable. Automatically inferring causal structure from correlation alone is unreliable — let domain knowledge define the graph, and let data confirm or flag deviations within it.&lt;/li&gt;
&lt;li&gt;Log every chatbot answer alongside the underlying query and data snapshot used to generate it. This audit trail matters both for debugging wrong answers and for any enterprise buyer who will ask "how do I know this is accurate."&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Closing Thought
&lt;/h2&gt;

&lt;p&gt;The gap between a basic "chat with your CRM" tool and a genuinely useful decision-intelligence system isn't the chat interface — it's the layers underneath it: clean ingestion, a shared semantic definition of your metrics, real anomaly detection, and a causal engine that can explain &lt;em&gt;why&lt;/em&gt;, not just &lt;em&gt;what&lt;/em&gt;. Airbyte handles the unglamorous but essential first step reliably, which frees up the harder engineering effort for the layers that actually create value.&lt;/p&gt;

</description>
      <category>zoho</category>
      <category>crm</category>
      <category>ai</category>
      <category>airbyte</category>
    </item>
    <item>
      <title>Building AI Agents for Social Media with TypeScript and Hono.js</title>
      <dc:creator>Mayuresh Smita Suresh</dc:creator>
      <pubDate>Sun, 19 Jul 2026 12:07:20 +0000</pubDate>
      <link>https://dev.to/mayu2008/building-ai-agents-for-social-media-with-typescript-and-honojs-4lgp</link>
      <guid>https://dev.to/mayu2008/building-ai-agents-for-social-media-with-typescript-and-honojs-4lgp</guid>
      <description>&lt;p&gt;Everyone's talking about AI agents right now, but most tutorials stop at "call an LLM in a loop." If you actually want an agent that runs unattended — fetches data, thinks about it, writes content, and publishes it — you need a real backend, not just a prompt. This post walks through the architecture I use for exactly that: a scheduled agent that finds fresh data, drafts social posts with Claude, and publishes them, built entirely on &lt;strong&gt;Hono.js&lt;/strong&gt; running on &lt;strong&gt;Cloudflare Workers&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I'll use "post finance news to LinkedIn/Reddit" as the running example, but the pattern generalizes to any "watch → think → act → publish" agent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Hono.js for agent backends
&lt;/h2&gt;

&lt;p&gt;Hono is a small, fast web framework that runs on Cloudflare Workers, Deno, Bun, and Node. For agent workloads specifically, three things make it a good fit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Native Cloudflare Cron Triggers&lt;/strong&gt; — agents that run on a schedule don't need a separate job scheduler or a always-on server.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Edge runtime, near-zero cold start&lt;/strong&gt; — your agent wakes up, does its work, and disappears. You pay for execution, not idle uptime.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Middleware model&lt;/strong&gt; — auth, logging, and rate-limiting for your own agent's admin routes come for free.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The architecture
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cron Trigger (Hono on Cloudflare Workers)
   │
   ├── 1. Fetch step   → pull raw data from an external API
   ├── 2. Reasoning step → Claude API decides what's worth posting
   ├── 3. Generation step → Claude API drafts platform-specific copy
   ├── 4. Dedup check   → Postgres/Neon, skip anything already posted
   └── 5. Publish step  → social API (or a unified posting provider)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each step is a plain async function. No agent framework, no hidden state machine — just a pipeline you can read top to bottom and unit test.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up the project
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm create hono@latest social-agent
&lt;span class="nb"&gt;cd &lt;/span&gt;social-agent
npm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pick the &lt;code&gt;cloudflare-workers&lt;/code&gt; template when prompted. Then add what we need:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @anthropic-ai/sdk drizzle-orm @neondatabase/serverless
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 1: The cron trigger
&lt;/h2&gt;

&lt;p&gt;In &lt;code&gt;wrangler.toml&lt;/code&gt;, define when the agent wakes up:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[triggers]&lt;/span&gt;
&lt;span class="py"&gt;crons&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"0 * * * 1-5"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c"&gt;# hourly, weekdays only&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In your Hono app, handle the &lt;code&gt;scheduled&lt;/code&gt; event separately from HTTP routes:&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Hono&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="s1"&gt;hono&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&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;Hono&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fetch&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;scheduled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;event&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ScheduledEvent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;env&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="na"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ExecutionContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;waitUntil&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;runAgentCycle&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="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;code&gt;ctx.waitUntil&lt;/code&gt; is important — it tells the Worker runtime to keep the instance alive until your async work finishes, even though there's no HTTP response to wait on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Fetch fresh data
&lt;/h2&gt;

&lt;p&gt;Keep this step dumb. It should return structured data, not decide anything.&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="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;RawEvent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;payload&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="nx"&gt;unknown&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&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;fetchLatestEvents&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;Env&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;RawEvent&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;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;res&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;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.example.com/events?window=today&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;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;Authorization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Bearer &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;SOURCE_API_KEY&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="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;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Source fetch failed: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&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;res&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;events&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3: Let Claude decide what's worth posting
&lt;/h2&gt;

&lt;p&gt;This is the part people skip and regret. Don't auto-draft a post for every single item — have the model triage first. It's cheaper, and it keeps your feed from looking like a bot dump.&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Anthropic&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@anthropic-ai/sdk&lt;/span&gt;&lt;span class="dl"&gt;'&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;triageEvents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;events&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;RawEvent&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;Env&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;anthropic&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;Anthropic&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;apiKey&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;ANTHROPIC_API_KEY&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;message&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;anthropic&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="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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;claude-sonnet-4-6&lt;/span&gt;&lt;span class="dl"&gt;'&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="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;system&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;You triage events for social media worthiness. Only flag items with a genuinely interesting angle — a surprise, a pattern, a number that stands out. Return strict JSON, no prose.&lt;/span&gt;&lt;span class="dl"&gt;'&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="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;'&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;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="nx"&gt;events&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="nx"&gt;text&lt;/span&gt; &lt;span class="o"&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="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;c&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;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)?.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="k"&gt;return&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;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&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="nl"&gt;angle&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Asking for "strict JSON, no prose" up front saves you a fragile regex-strip step later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Generate platform-specific copy
&lt;/h2&gt;

&lt;p&gt;LinkedIn and Reddit have different norms — LinkedIn rewards a confident, analytical voice; Reddit punishes anything that reads like marketing copy. Generate both in one call, but prompt for the difference explicitly rather than reusing one draft everywhere.&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="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;draftPosts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;RawEvent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;angle&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="nx"&gt;env&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="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;anthropic&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;Anthropic&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;apiKey&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;ANTHROPIC_API_KEY&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;message&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;anthropic&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="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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;claude-sonnet-4-6&lt;/span&gt;&lt;span class="dl"&gt;'&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="mi"&gt;800&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;system&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Write two versions of a post about this event.
LinkedIn: 80-150 words, analytical tone, one soft mention of relevant context, no hashtag spam.
Reddit: framed as a discussion starter, no promotional language, ends with a genuine question.
Return JSON: { "linkedin": "...", "reddit": "..." }`&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="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;'&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="s2"&gt;`Event: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;\nAngle: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;angle&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;\nData: &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="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;payload&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="p"&gt;})&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&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="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;c&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;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)?.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;{}&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="k"&gt;return&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;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;linkedin&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="nl"&gt;reddit&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 5: Dedup with Postgres
&lt;/h2&gt;

&lt;p&gt;Nothing kills credibility faster than posting the same thing twice because a cron overlapped. Use Neon's serverless driver — it works over HTTP, which matters on Workers since you don't have a persistent TCP connection.&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;neon&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="s1"&gt;@neondatabase/serverless&lt;/span&gt;&lt;span class="dl"&gt;'&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;alreadyPosted&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;Env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;eventId&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sql&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;neon&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;DATABASE_URL&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;rows&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;sql&lt;/span&gt;&lt;span class="s2"&gt;`SELECT 1 FROM posted_events WHERE event_id = &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;eventId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="p"&gt;}&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;markPosted&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;Env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;eventId&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="nx"&gt;platform&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="nx"&gt;postId&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sql&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;neon&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;DATABASE_URL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;sql&lt;/span&gt;&lt;span class="s2"&gt;`
    INSERT INTO posted_events (event_id, platform, post_id, posted_at)
    VALUES (&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;eventId&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="nx"&gt;platform&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="nx"&gt;postId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, now())
  `&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 6: Publish
&lt;/h2&gt;

&lt;p&gt;You have two real options here:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Native platform APIs.&lt;/strong&gt; LinkedIn requires an approved Company Page and &lt;code&gt;w_member_social&lt;/code&gt; scope; Reddit requires its own OAuth app and respects strict rate limits. Both are doable but slow to set up the first time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A unified posting provider&lt;/strong&gt; (e.g. Ayrshare) that abstracts multiple platforms behind one API. Much faster to ship an MVP with — worth it if you're validating the idea before investing in native integrations.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;platform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;linkedin&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;reddit&lt;/span&gt;&lt;span class="dl"&gt;'&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="kr"&gt;string&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;Env&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;res&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;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.ayrshare.com/api/post&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;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&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="na"&gt;Authorization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Bearer &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;AYRSHARE_API_KEY&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&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="s1"&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="na"&gt;body&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;post&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="na"&gt;platforms&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;platform&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;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;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Publish failed on &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;platform&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="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Wiring it together
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;runAgentCycle&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;Env&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;events&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;fetchLatestEvents&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;flagged&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;triageEvents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;events&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="k"&gt;for &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;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;angle&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;flagged&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="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;alreadyPosted&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;id&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;events&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;e&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;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&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;linkedin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reddit&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="nf"&gt;draftPosts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;angle&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;li&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;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;linkedin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;linkedin&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="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;markPosted&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;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;linkedin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;li&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// Reddit: hold for human review instead of auto-publishing — see note below&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;queueForReview&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;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reddit&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;
  
  
  The guardrail that actually matters
&lt;/h2&gt;

&lt;p&gt;Automating the fetch → draft pipeline is safe. Automating the &lt;strong&gt;publish&lt;/strong&gt; step to Reddit is not, at least not at first. Most active subreddits have strict self-promotion rules, and an account that posts on a predictable schedule with promotional undertones gets flagged as a bot fast — sometimes shadowbanned entirely. Two things fix this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Human-in-the-loop for Reddit specifically.&lt;/strong&gt; Queue the draft (Slack, email, a simple admin route in the same Hono app) and require a manual approve before it publishes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep the language descriptive, not advisory.&lt;/strong&gt; For anything finance-adjacent, "revenue beat estimates by X%" is commentary; "you should buy this" edges into advice you don't want to be on the hook for.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;LinkedIn is more forgiving of a consistent posting cadence, so it's the safer platform to fully automate first.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to go from here
&lt;/h2&gt;

&lt;p&gt;This same skeleton — cron trigger, fetch, triage, generate, dedup, publish — works for far more than finance news. Swap the fetch step for GitHub releases, product reviews, conference CFPs, or your own product's usage metrics, and you have a different agent with the same reliability guarantees.&lt;/p&gt;

&lt;p&gt;The part worth getting right early is the triage step. An agent that posts about &lt;em&gt;everything&lt;/em&gt; is just noise with extra steps; an agent that only speaks up when there's a genuine angle is the one people actually follow.&lt;/p&gt;

&lt;p&gt;If you're building something similar, I'd love to hear what you're automating — drop it in the comments.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>aiagents</category>
      <category>honojs</category>
    </item>
    <item>
      <title>Honoured to receive Google AI Badge. Awarded for publishing a top Google AI post. Thank you Dev team.</title>
      <dc:creator>Mayuresh Smita Suresh</dc:creator>
      <pubDate>Fri, 20 Mar 2026 05:37:17 +0000</pubDate>
      <link>https://dev.to/mayu2008/honoured-to-receive-google-ai-badge-awarded-for-publishing-a-top-google-ai-post-thank-you-dev-1c56</link>
      <guid>https://dev.to/mayu2008/honoured-to-receive-google-ai-badge-awarded-for-publishing-a-top-google-ai-post-thank-you-dev-1c56</guid>
      <description></description>
    </item>
    <item>
      <title>mcpnest.cloud 
Calling all dev to support my new platform, I am building a robust platform to deploy any MCP easily and manage it and scale it easy. Please join the waitlist your support matters a lot. Thank you.</title>
      <dc:creator>Mayuresh Smita Suresh</dc:creator>
      <pubDate>Wed, 11 Mar 2026 07:00:34 +0000</pubDate>
      <link>https://dev.to/mayu2008/mcpnestcloud-calling-all-dev-to-support-my-new-platform-i-am-building-a-robust-platform-to-4ndn</link>
      <guid>https://dev.to/mayu2008/mcpnestcloud-calling-all-dev-to-support-my-new-platform-i-am-building-a-robust-platform-to-4ndn</guid>
      <description></description>
    </item>
    <item>
      <title>https://mcpnest.cloud 
Calling all dev to support my new platform, I am building a robust platform to deploy any MCP easily and manage it and scale it easy. Please join the waitlist your support matters a lot. Thank you.</title>
      <dc:creator>Mayuresh Smita Suresh</dc:creator>
      <pubDate>Wed, 11 Mar 2026 07:00:02 +0000</pubDate>
      <link>https://dev.to/mayu2008/httpsmcpnestcloud-calling-all-dev-to-support-my-new-platform-i-am-building-a-robust-platform-4o9i</link>
      <guid>https://dev.to/mayu2008/httpsmcpnestcloud-calling-all-dev-to-support-my-new-platform-i-am-building-a-robust-platform-4o9i</guid>
      <description>&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
        &lt;div class="c-embed__cover"&gt;
          &lt;a href="https://mcpnest.cloud/" class="c-link align-middle" rel="noopener noreferrer"&gt;
            &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmcpnest.cloud%2FMCPNest-logo.png" height="800" class="m-0" width="800"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="c-embed__body"&gt;
        &lt;h2 class="fs-xl lh-tight"&gt;
          &lt;a href="https://mcpnest.cloud/" rel="noopener noreferrer" class="c-link"&gt;
            MCPNest | Deploy MCP Servers Instantly
          &lt;/a&gt;
        &lt;/h2&gt;
          &lt;p class="truncate-at-3"&gt;
            Deploy, scale, and manage your Model Context Protocol servers in minutes.
          &lt;/p&gt;
        &lt;div class="color-secondary fs-s flex items-center"&gt;
            &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmcpnest.cloud%2Ficon.ico%3Ficon.7e10ef02.ico" width="16" height="16"&gt;
          mcpnest.cloud
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


</description>
    </item>
    <item>
      <title>Why MCP servers deployments are so hard?</title>
      <dc:creator>Mayuresh Smita Suresh</dc:creator>
      <pubDate>Tue, 10 Mar 2026 13:39:06 +0000</pubDate>
      <link>https://dev.to/mayu2008/why-mcp-servers-deployments-are-so-hard-27ho</link>
      <guid>https://dev.to/mayu2008/why-mcp-servers-deployments-are-so-hard-27ho</guid>
      <description></description>
      <category>ai</category>
      <category>devops</category>
      <category>llm</category>
      <category>mcp</category>
    </item>
    <item>
      <title>MILP From Scratch in Pure Rust — No Dependencies, Full Branch and Bound</title>
      <dc:creator>Mayuresh Smita Suresh</dc:creator>
      <pubDate>Wed, 04 Mar 2026 18:33:49 +0000</pubDate>
      <link>https://dev.to/mayu2008/milp-from-scratch-in-pure-rust-no-dependencies-full-branch-and-bound-2a01</link>
      <guid>https://dev.to/mayu2008/milp-from-scratch-in-pure-rust-no-dependencies-full-branch-and-bound-2a01</guid>
      <description>&lt;p&gt;If you’ve ever seen terms like &lt;em&gt;linear programming&lt;/em&gt;, &lt;em&gt;integer optimisation&lt;/em&gt;, or &lt;em&gt;Branch and Bound&lt;/em&gt; and felt lost — this post is for you.&lt;/p&gt;

&lt;p&gt;We’ll build a &lt;strong&gt;complete MILP solver in pure Rust&lt;/strong&gt; (zero external crates) that solves a real factory planning problem. Every term is explained from scratch. The code compiles and runs today.&lt;/p&gt;

&lt;p&gt;By the end you’ll understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What MILP is and why it’s hard&lt;/li&gt;
&lt;li&gt;The full mathematical formulation&lt;/li&gt;
&lt;li&gt;What Branch and Bound actually does (with the real tree output)&lt;/li&gt;
&lt;li&gt;Why this matters for quantum optimisation&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Problem: A Furniture Factory
&lt;/h2&gt;

&lt;p&gt;A furniture factory makes two products:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Product&lt;/th&gt;
&lt;th&gt;Profit&lt;/th&gt;
&lt;th&gt;Machine hrs needed&lt;/th&gt;
&lt;th&gt;Wood units needed&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Table (x₁)&lt;/td&gt;
&lt;td&gt;£50 each&lt;/td&gt;
&lt;td&gt;3 hrs&lt;/td&gt;
&lt;td&gt;4 units&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chair (x₂)&lt;/td&gt;
&lt;td&gt;£30 each&lt;/td&gt;
&lt;td&gt;2 hrs&lt;/td&gt;
&lt;td&gt;3 units&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Available resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Machine hours:&lt;/strong&gt; 120 total&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wood:&lt;/strong&gt; 160 units total&lt;/li&gt;
&lt;li&gt;Market demand caps: max 30 tables, max 40 chairs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Question: How many tables and chairs to make to maximise profit?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can’t make 16.7 tables. They must be whole numbers. That’s the key challenge — and it’s what makes this MILP.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Is MILP? (Every Word Explained)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Linear&lt;/strong&gt; → All relationships are proportional. Profit scales linearly with units. &lt;code&gt;profit = 50 × tables + 30 × chairs&lt;/code&gt; — no powers, no curves, just straight lines.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Programming&lt;/strong&gt; → Old term for “optimisation”. Nothing to do with coding.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Integer&lt;/strong&gt; → Some variables must be whole numbers. You can’t produce 2.5 tables or hire 0.7 people.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mixed&lt;/strong&gt; → Some variables can be continuous (e.g. temperature, weight, price) while others must be integer (units, people, machines). Our problem has &lt;em&gt;all&lt;/em&gt; integer variables, but MILP handles both.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why is it hard?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Pure LP (without integers) is solvable in polynomial time — milliseconds even for massive problems. The moment you add integer constraints, the problem becomes &lt;strong&gt;NP-hard&lt;/strong&gt;. You can’t just solve equations — you need to search through combinations. A factory with 100 products has more valid integer combinations than atoms in the universe.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Mathematics
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Decision Variables
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;x₁ = number of Tables to produce  (integer, ≥ 0)
x₂ = number of Chairs to produce  (integer, ≥ 0)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are what the solver decides. Everything else is fixed input.&lt;/p&gt;

&lt;h3&gt;
  
  
  Objective Function
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Maximise:  Z = 50·x₁ + 30·x₂
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every table adds £50 to profit. Every chair adds £30. We want Z as large as possible.&lt;/p&gt;

&lt;h3&gt;
  
  
  Constraints
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;3·x₁ + 2·x₂  ≤  120     ← machine hours: can't exceed 120 total
4·x₁ + 3·x₂  ≤  160     ← wood: can't exceed 160 units
      x₁      ≤   30     ← market can only absorb 30 tables
           x₂ ≤   40     ← market can only absorb 40 chairs
x₁, x₂       ≥    0     ← can't produce negative quantities
x₁, x₂       ∈   ℤ⁺    ← must be whole numbers (the "Integer" in MILP)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Matrix Form
&lt;/h3&gt;

&lt;p&gt;Solvers work with matrices. Written as &lt;code&gt;A·x ≤ b&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;     A           x      b
[ 3  2 ]   [ x₁ ]   [ 120 ]
[ 4  3 ] · [ x₂ ] ≤ [ 160 ]

Objective vector c = [50, 30]
Maximise cᵀ·x  subject to  A·x ≤ b,  lb ≤ x ≤ ub,  x ∈ ℤ
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What Does the Feasible Region Look Like?
&lt;/h3&gt;

&lt;p&gt;Plot x₁ on the x-axis, x₂ on the y-axis. Each constraint is a line. The &lt;strong&gt;feasible region&lt;/strong&gt; is the polygon where all constraints are satisfied simultaneously. The optimal solution always sits at a corner (vertex) of this polygon.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;x₂ (Chairs)
40 |---.
   |    \   ← demand cap x₂ ≤ 40
   |     \
   |      ◆ ← OPTIMAL: (30, 13), Profit = £1890
   |      .\
   |      . \  ← Wood: 4x₁ + 3x₂ = 160
   |      .  \
   |      .   \__ Machine: 3x₁ + 2x₂ = 120
   |___________ x₁ (Tables)
   0           30
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  The Algorithm: Branch and Bound
&lt;/h2&gt;

&lt;p&gt;This is how every serious MILP solver works at its core.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: LP Relaxation
&lt;/h3&gt;

&lt;p&gt;First, forget the integer constraint. Solve as pure LP (allowing fractions). This gives the &lt;strong&gt;upper bound&lt;/strong&gt; — the best profit achievable if fractions were allowed.&lt;/p&gt;

&lt;p&gt;For our problem, LP relaxation gives: x₁ = 30, x₂ = 13.33, profit = £1,900.&lt;/p&gt;

&lt;p&gt;But x₂ = 13.33 is fractional. We can’t make 13.33 chairs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Branch
&lt;/h3&gt;

&lt;p&gt;Pick the fractional variable (x₂ = 13.33). Split into two sub-problems:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Branch A: x₂ ≤ 13   (round down)
Branch B: x₂ ≥ 14   (round up)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Push both onto the search stack. Now solve each one’s LP relaxation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Bound
&lt;/h3&gt;

&lt;p&gt;For each sub-problem, the LP relaxation gives an upper bound. If that upper bound is worse than the best integer solution found so far — &lt;strong&gt;prune the branch&lt;/strong&gt; (don’t explore further). This is what makes B&amp;amp;B efficient.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Repeat
&lt;/h3&gt;

&lt;p&gt;Keep branching on fractional variables, pruning hopeless branches, until every branch is either pruned or yields an integer solution.&lt;/p&gt;

&lt;h3&gt;
  
  
  Our Actual Search Tree (from the code output)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Node  1] depth=0  LP=1900.0 → BRANCH x₂=13.33 (≤13 | ≥14)
[Node  2] depth=1  LP=1895.0 → BRANCH x₁=29.5  (≤29 | ≥30)
[Node  3] depth=2  → INFEASIBLE, pruned
[Node  4] depth=2  LP=1890.0 → BRANCH x₂=14.67 (≤14 | ≥15)
[Node  5] depth=3  LP=1887.5 → BRANCH x₁=28.75 (≤28 | ≥29)
[Node  6] depth=4  → INFEASIBLE, pruned
[Node  7] depth=4  LP=1880.0 → ✓ INTEGER (x1=28, x2=16) ★ £1880
[Node  8] depth=3  LP=1870.0 ≤ best=1880 → PRUNED
[Node  9] depth=1  LP=1890.0 → ✓ INTEGER (x1=30, x2=13) ★ £1890
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Only &lt;strong&gt;9 nodes&lt;/strong&gt; to find the global optimum. Without B&amp;amp;B, brute force would check 30×40 = 1,200 combinations. For larger problems (1,000 variables), B&amp;amp;B reduces billions of checks to thousands.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Rust Code
&lt;/h2&gt;

&lt;p&gt;Pure Rust. Zero external dependencies. The full solver from scratch.&lt;/p&gt;

&lt;h3&gt;
  
  
  Data Structures
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="cd"&gt;/// The LP problem in standard form: Maximise c·x subject to A·x ≤ b&lt;/span&gt;
&lt;span class="nd"&gt;#[derive(Clone,&lt;/span&gt; &lt;span class="nd"&gt;Debug)]&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;LpProblem&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;          &lt;span class="c1"&gt;// objective coefficients&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;     &lt;span class="c1"&gt;// constraint matrix&lt;/span&gt;
    &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;          &lt;span class="c1"&gt;// rhs of constraints&lt;/span&gt;
    &lt;span class="n"&gt;lb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;         &lt;span class="c1"&gt;// lower bounds per variable&lt;/span&gt;
    &lt;span class="n"&gt;ub&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;         &lt;span class="c1"&gt;// upper bounds per variable&lt;/span&gt;
    &lt;span class="n"&gt;n_vars&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cd"&gt;/// One node in the Branch and Bound search tree.&lt;/span&gt;
&lt;span class="cd"&gt;/// Each node represents a sub-problem with tightened bounds.&lt;/span&gt;
&lt;span class="nd"&gt;#[derive(Clone,&lt;/span&gt; &lt;span class="nd"&gt;Debug)]&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;BbNode&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;lb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;    &lt;span class="c1"&gt;// current lower bounds (tightened by branching)&lt;/span&gt;
    &lt;span class="n"&gt;ub&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;    &lt;span class="c1"&gt;// current upper bounds (tightened by branching)&lt;/span&gt;
    &lt;span class="n"&gt;depth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;    &lt;span class="c1"&gt;// depth in tree (for logging)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  LP Relaxation Solver (Coordinate Ascent)
&lt;/h3&gt;

&lt;p&gt;For each node we solve the LP relaxation — the same problem but without integer constraints.&lt;/p&gt;

&lt;p&gt;We use &lt;strong&gt;coordinate ascent&lt;/strong&gt;: move each variable as far as possible in its profit-improving direction while staying feasible. For small bounded problems like ours, this converges to the exact LP optimum.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;solve_lp_relaxation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prob&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;LpProblem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;ub&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;LpResult&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prob&lt;/span&gt;&lt;span class="py"&gt;.n_vars&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// Start at lower bounds (always feasible when b ≥ 0)&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lb&lt;/span&gt;&lt;span class="nf"&gt;.to_vec&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_iter&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;10_000&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;improved&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;dir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prob&lt;/span&gt;&lt;span class="py"&gt;.c&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;           &lt;span class="c1"&gt;// gradient: improving direction for x[i]&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;dir&lt;/span&gt;&lt;span class="nf"&gt;.abs&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mf"&gt;1e-10&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="c1"&gt;// Find how far we can move x[i] before hitting a constraint&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;step&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;dir&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nf"&gt;max_step_up&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prob&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ub&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;    &lt;span class="c1"&gt;// move up&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="nf"&gt;max_step_down&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prob&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;// move down&lt;/span&gt;
            &lt;span class="p"&gt;};&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;step&lt;/span&gt;&lt;span class="nf"&gt;.abs&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mf"&gt;1e-9&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;step&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;dot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;prob&lt;/span&gt;&lt;span class="py"&gt;.c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;dot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;prob&lt;/span&gt;&lt;span class="py"&gt;.c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;1e-10&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;improved&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&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="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="n"&gt;step&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c1"&gt;// revert if no improvement&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;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;improved&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;  &lt;span class="c1"&gt;// converged&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nn"&gt;LpResult&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Optimal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;dot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;prob&lt;/span&gt;&lt;span class="py"&gt;.c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;x&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;code&gt;max_step_up&lt;/code&gt; computes the maximum safe step by checking each constraint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;max_step_up&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prob&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;LpProblem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ub&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;max_step&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ub&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;            &lt;span class="c1"&gt;// can't exceed upper bound&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;bk&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;prob&lt;/span&gt;&lt;span class="py"&gt;.b&lt;/span&gt;&lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.enumerate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;a_ki&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prob&lt;/span&gt;&lt;span class="py"&gt;.a&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;a_ki&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mf"&gt;1e-10&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;lhs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;dot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;prob&lt;/span&gt;&lt;span class="py"&gt;.a&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;step&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bk&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;lhs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;a_ki&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;       &lt;span class="c1"&gt;// slack / coefficient = max safe step&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;step&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;max_step&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;max_step&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;step&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="n"&gt;max_step&lt;/span&gt;&lt;span class="nf"&gt;.max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.0&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;
  
  
  Branch and Bound
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;branch_and_bound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prob&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;LpProblem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;integer_vars&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MilpSolution&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;best_obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;NEG_INFINITY&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;best_x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;None&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BbNode&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;BbNode&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;lb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;prob&lt;/span&gt;&lt;span class="py"&gt;.lb&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                                               &lt;span class="n"&gt;ub&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;prob&lt;/span&gt;&lt;span class="py"&gt;.ub&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;depth&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="k"&gt;while&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="nf"&gt;.pop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="c1"&gt;// 1. Solve LP relaxation for this node&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lp_obj&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lp_x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="nf"&gt;solve_lp_relaxation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prob&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="py"&gt;.lb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="py"&gt;.ub&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nn"&gt;LpResult&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Infeasible&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;         &lt;span class="c1"&gt;// prune: infeasible&lt;/span&gt;
            &lt;span class="nn"&gt;LpResult&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Optimal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&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. Prune if LP bound can't beat current best&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;lp_obj&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;best_obj&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;1e-6&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// 3. Find most fractional integer variable (closest fraction to 0.5)&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;branch_var&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;integer_vars&lt;/span&gt;&lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.enumerate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="nf"&gt;.filter&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;is_int&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="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;is_int&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;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;frac&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lp_x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nf"&gt;.fract&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                &lt;span class="n"&gt;frac&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mf"&gt;1e-6&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;frac&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mf"&gt;1e-6&lt;/span&gt;
            &lt;span class="p"&gt;})&lt;/span&gt;
            &lt;span class="nf"&gt;.min_by&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&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;let&lt;/span&gt; &lt;span class="n"&gt;fi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lp_x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nf"&gt;.fract&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.abs&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;fj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lp_x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nf"&gt;.fract&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.abs&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                &lt;span class="n"&gt;fi&lt;/span&gt;&lt;span class="nf"&gt;.partial_cmp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;fj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;})&lt;/span&gt;
            &lt;span class="nf"&gt;.map&lt;/span&gt;&lt;span class="p"&gt;(|(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;branch_var&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nb"&gt;None&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="c1"&gt;// All integer vars are integral → valid integer solution!&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;lp_obj&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;best_obj&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;best_obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lp_obj&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                    &lt;span class="n"&gt;best_x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lp_x&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="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vi&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;floor_v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lp_x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;vi&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nf"&gt;.floor&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;ceil_v&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lp_x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;vi&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="c1"&gt;// Child 1: x[vi] ≤ floor (round down branch)&lt;/span&gt;
                &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;ub2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="py"&gt;.ub&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                &lt;span class="n"&gt;ub2&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;vi&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ub2&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;vi&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="n"&gt;floor_v&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BbNode&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;lb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="py"&gt;.lb&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;ub&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ub2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;depth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="py"&gt;.depth&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="c1"&gt;// Child 2: x[vi] ≥ ceil (round up branch)&lt;/span&gt;
                &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;lb2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="py"&gt;.lb&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                &lt;span class="n"&gt;lb2&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;vi&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lb2&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;vi&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="n"&gt;ceil_v&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BbNode&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;lb&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;lb2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ub&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="py"&gt;.ub&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;depth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="py"&gt;.depth&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="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;best_x&lt;/span&gt;&lt;span class="nf"&gt;.map&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;MilpSolution&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;objective&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;best_obj&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                   &lt;span class="n"&gt;nodes_explored&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Defining the Problem
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;prob&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;LpProblem&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;50.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;30.0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;        &lt;span class="c1"&gt;// objective: max 50x₁ + 30x₂&lt;/span&gt;
        &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;3.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="c1"&gt;// 3x₁ + 2x₂ ≤ 120  (machine hours)&lt;/span&gt;
            &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;4.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;3.0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;      &lt;span class="c1"&gt;// 4x₁ + 3x₂ ≤ 160  (wood supply)&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;120.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;160.0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;      &lt;span class="c1"&gt;// rhs&lt;/span&gt;
        &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="mf"&gt;0.0&lt;/span&gt;  &lt;span class="p"&gt;],&lt;/span&gt;      &lt;span class="c1"&gt;// lower bounds: x₁, x₂ ≥ 0&lt;/span&gt;
        &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;30.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="mf"&gt;40.0&lt;/span&gt; &lt;span class="p"&gt;],&lt;/span&gt;      &lt;span class="c1"&gt;// upper bounds: x₁ ≤ 30, x₂ ≤ 40&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;integer_vars&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;vec!&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="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;   &lt;span class="c1"&gt;// both must be integers&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;solution&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;branch_and_bound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;prob&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;integer_vars&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;
  
  
  Output
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;╔══════════════════════════════════════════════════════════╗
║     MILP Solver — Pure Rust, Zero Dependencies          ║
║     Factory Production Planning (Branch and Bound)      ║
╚══════════════════════════════════════════════════════════╝

BRANCH AND BOUND TREE:
──────────────────────────────────────────────────────────
  [Node   1] depth=0 obj=1900.0 → BRANCH x2=13.333 (≤13 | ≥14)
  [Node   2] depth=1 obj=1895.0 → BRANCH x1=29.500 (≤29 | ≥30)
  [Node   3] depth=2 → INFEASIBLE, pruned
  [Node   4] depth=2 obj=1890.0 → BRANCH x2=14.667 (≤14 | ≥15)
  [Node   5] depth=3 obj=1887.5 → BRANCH x1=28.750 (≤28 | ≥29)
  [Node   6] depth=4 → INFEASIBLE, pruned
  [Node   7] depth=4 obj=1880.0 → ✓ INTEGER (x1=28, x2=16)  ★ £1880
  [Node   8] depth=3 LP=1870.0 ≤ best=1880.0 → PRUNED
  [Node   9] depth=1 obj=1890.0 → ✓ INTEGER (x1=30, x2=13)  ★ £1890

╔══════════════════════════════════════════════════════════╗
║               ✅ OPTIMAL SOLUTION                       ║
╠══════════════════════════════════════════════════════════╣
║  Tables  (x₁) :    30 units                            ║
║  Chairs  (x₂) :    13 units                            ║
║  Max Profit   : £1890                                   ║
╠══════════════════════════════════════════════════════════╣
║  Machine hrs  : 116 / 120  (96.7% utilised)            ║
║  Wood used    : 159 / 160  (99.4% utilised)            ║
║  B&amp;amp;B Nodes    :    9 explored                          ║
╠══════════════════════════════════════════════════════════╣
║  CONSTRAINT CHECK:                                      ║
║  3(30)+2(13) = 116 ≤ 120  ✓                            ║
║  4(30)+3(13) = 159 ≤ 160  ✓                            ║
║  x₁=30 ≤ 30  ✓                                         ║
║  x₂=13 ≤ 40  ✓                                         ║
╚══════════════════════════════════════════════════════════╝

WHY NOT A SIMPLER GUESS?
──────────────────────────────────────────────────────────
  All tables (30, 0)         profit=£1500  ✓
  All chairs (0, 40)         profit=£1200  ✓
  Equal split (20, 20)       profit=£1600  ✓
  Optimal (30, 13)           profit=£1890  ✓  ← solver wins
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The solver found &lt;strong&gt;£1,890&lt;/strong&gt; — significantly better than every naive guess, and it verified all constraints automatically.&lt;/p&gt;




&lt;h2&gt;
  
  
  Running It
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo new milp_solver
&lt;span class="c"&gt;# paste main.rs (link below)&lt;/span&gt;
cargo run &lt;span class="nt"&gt;--release&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No &lt;code&gt;Cargo.toml&lt;/code&gt; dependencies needed. Pure Rust standard library only.&lt;/p&gt;




&lt;h2&gt;
  
  
  Key Terms — Quick Reference
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Term&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Decision variable&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;What the solver decides (x₁, x₂)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Objective function&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;What you’re maximising or minimising (Z = 50x₁ + 30x₂)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Constraint&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A rule the solution must satisfy (3x₁ + 2x₂ ≤ 120)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Feasible region&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;All points satisfying every constraint&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;LP relaxation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Same problem without integer constraint — gives upper bound&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Branch&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Split a fractional variable into two sub-problems&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Bound&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Prune branches whose LP bound can’t beat the current best&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Prune&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Discard a branch — guaranteed to not contain the optimum&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Integer solution&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;All integer variables have whole-number values&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Why This Matters for Quantum Computing
&lt;/h2&gt;

&lt;p&gt;Classical MILP solvers (HiGHS, Gurobi, OR-Tools) handle problems up to roughly 10,000–100,000 variables well. Beyond that, Branch and Bound’s exponential tree becomes intractable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quantum optimisation&lt;/strong&gt; attacks this differently. Instead of sequentially searching the B&amp;amp;B tree, quantum algorithms explore combinations simultaneously via superposition. But to feed problems to a quantum computer, you need to convert them to &lt;strong&gt;QUBO&lt;/strong&gt; (Quadratic Unconstrained Binary Optimisation):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MILP → convert integer vars to binary → add constraint penalties → QUBO
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once in QUBO form, quantum algorithms like &lt;strong&gt;QAOA&lt;/strong&gt; or quantum-inspired algorithms like &lt;strong&gt;Simulated Bifurcation&lt;/strong&gt; can solve it — and they scale better on large, dense combinatorial problems where classical B&amp;amp;B degrades.&lt;/p&gt;

&lt;p&gt;This Rust implementation is the foundation. In the next post, we’ll convert this exact MILP into a QUBO matrix and run it through a Simulated Bifurcation solver — still in pure Rust.&lt;/p&gt;




&lt;h2&gt;
  
  
  What’s Next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Part 2:&lt;/strong&gt; QUBO conversion — turning this MILP into a matrix a quantum solver can eat&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 3:&lt;/strong&gt; Simulated Bifurcation in Rust — quantum-inspired solver from scratch, no hardware needed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 4:&lt;/strong&gt; Benchmarking against HiGHS on large-scale problems&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;I’m &lt;a href="https://tagnovate.com/mayuresh" rel="noopener noreferrer"&gt;Mayuresh&lt;/a&gt;, Founder &amp;amp; CTO at &lt;a href="https://ambicube.com" rel="noopener noreferrer"&gt;AmbiCube&lt;/a&gt;. Building quantum-classical optimisation infrastructure in Rust. My vision is to build world’s best schedule solution company, if anyone is interested in learning something real computer science then get in touch and help me. Follow for posts on Rust, quantum algorithms, and applied AI systems&lt;/em&gt;&lt;/p&gt;

</description>
      <category>algorithms</category>
      <category>computerscience</category>
      <category>rust</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>What do you think about my idea?</title>
      <dc:creator>Mayuresh Smita Suresh</dc:creator>
      <pubDate>Sun, 01 Mar 2026 14:11:57 +0000</pubDate>
      <link>https://dev.to/mayu2008/what-do-you-think-about-my-idea-3ne7</link>
      <guid>https://dev.to/mayu2008/what-do-you-think-about-my-idea-3ne7</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/mayu2008" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&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%2Fuser%2Fprofile_image%2F3571903%2Ffce1104c-74aa-424e-9521-7195968d0ad0.jpeg" alt="mayu2008"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/mayu2008/i-built-an-app-to-help-elderly-and-disabled-people-in-my-neighbourhood-90h" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;I built an app to help Elderly and Disabled people in my neighbourhood&lt;/h2&gt;
      &lt;h3&gt;Mayuresh Smita Suresh ・ Feb 28&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#devchallenge&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#weekendchallenge&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#showdev&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>devchallenge</category>
      <category>weekendchallenge</category>
      <category>showdev</category>
    </item>
    <item>
      <title>I built an app to help Elderly and Disabled people in my neighbourhood</title>
      <dc:creator>Mayuresh Smita Suresh</dc:creator>
      <pubDate>Sat, 28 Feb 2026 10:46:22 +0000</pubDate>
      <link>https://dev.to/mayu2008/i-built-an-app-to-help-elderly-and-disabled-people-in-my-neighbourhood-90h</link>
      <guid>https://dev.to/mayu2008/i-built-an-app-to-help-elderly-and-disabled-people-in-my-neighbourhood-90h</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/weekend-2026-02-28"&gt;DEV Weekend Challenge: Community&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  My grandmother couldn't change a lightbulb, neither can take her dog on walk and I live 200 miles away, I cant be there every time.
&lt;/h2&gt;

&lt;p&gt;Not because she was frail. Not because she lacked the will. But at 78, with arthritic hands and a second-floor flat with no elevator, climbing a stepladder to reach a ceiling fixture was genuinely dangerous. She lived alone. My family was two cities away. And she sat in a dim room for six days before she finally asked her neighbor — a stranger she'd shared a building with for three years — for help.&lt;/p&gt;

&lt;p&gt;Six days in a dim room. Because she didn't know if it was okay to ask.&lt;/p&gt;

&lt;p&gt;That's the problem NearbyHelp is built to solve. Not emergencies. Not disasters. The quiet, grinding, invisible difficulty of daily life for millions of elderly and disabled people who need small help — and have no idea who around them is willing to give it.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Community
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The community I built for is one that rarely gets built for: elderly individuals, disabled people, and anyone who lives alone and needs occasional help with day-to-day tasks that most of us take for granted.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We're talking about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An 80-year-old who needs someone to carry a heavy box down from a shelf&lt;/li&gt;
&lt;li&gt;A person with MS who needs a neighbor to pick up their prescription on the way back from the shops&lt;/li&gt;
&lt;li&gt;A visually impaired resident who needs help navigating a council form online&lt;/li&gt;
&lt;li&gt;Someone post-surgery who just needs their groceries picked up once&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These aren't crises. There's no ambulance to call. There's no app for this. There's just... the hope that someone nearby is kind enough, and that you're brave enough to ask.&lt;/p&gt;

&lt;p&gt;The second part of that equation — the willingness of neighbors to help — already exists in abundance. What's missing is the infrastructure to make that willingness &lt;em&gt;visible&lt;/em&gt;. Right now, the goodwill is there. It's just invisible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NearbyHelp makes it visible.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;NearbyHelp is a community-first web application where local volunteers register specific tasks they're willing to help with — and anyone nearby can open a map, see exactly who's available, how far away they are, and call them directly.&lt;/p&gt;

&lt;p&gt;The philosophy is deliberate simplicity: &lt;strong&gt;one volunteer, one skill offer, one pin on the map.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No social network. No messaging layer. No karma points. Just a live map of willing neighbors, searchable by task type, sorted by distance.&lt;/p&gt;

&lt;h3&gt;
  
  
  Core Features
&lt;/h3&gt;

&lt;p&gt;** Live Interactive Map**&lt;br&gt;
Built on &lt;code&gt;react-leaflet&lt;/code&gt;, the map shows every registered volunteer as a color-coded pin based on their task category. Tap a pin, see their name, what they can help with, and a direct call button. That's it. Designed specifically to be usable by elderly people on tablets — large tap targets, high contrast, no clutter.&lt;/p&gt;

&lt;p&gt;** Haversine Proximity Sorting**&lt;br&gt;
Every volunteer's distance from your location is calculated in real time using the Haversine formula — the same spherical geometry used in aviation navigation. It's not "roughly in your area." It's "0.4 km away." That specificity matters when you're deciding whether to ask someone for help.&lt;/p&gt;

&lt;p&gt;** AI Skill Categorization (Google Gemini)**&lt;br&gt;
Volunteers type what they can help with in plain English: &lt;em&gt;"I can help move furniture and do heavy lifting"&lt;/em&gt; or &lt;em&gt;"happy to help with tech stuff, phones, tablets, computers."&lt;/em&gt; Google's Gemini AI reads their natural language and maps it to a standardized tag: &lt;code&gt;MAINTENANCE&lt;/code&gt;, &lt;code&gt;TECH_HELP&lt;/code&gt;, &lt;code&gt;ERRANDS&lt;/code&gt;, &lt;code&gt;HOUSEWORK&lt;/code&gt;, &lt;code&gt;TRANSPORT&lt;/code&gt;, &lt;code&gt;COMPANIONSHIP&lt;/code&gt;. This means the map filter works reliably regardless of how different people describe the same task.&lt;/p&gt;

&lt;p&gt;** One-Tap Direct Call**&lt;br&gt;
Volunteers who opt in share a contact number. The app generates a native &lt;code&gt;tel:&lt;/code&gt; link — on mobile, one tap opens the phone dialer. No messaging, no waiting for a reply. Direct human contact, immediately.&lt;/p&gt;

&lt;p&gt;** Mobile-First List View**&lt;br&gt;
A swipeable overlay on mobile showing volunteers as cards sorted nearest-first. Built specifically because many of the people &lt;em&gt;looking&lt;/em&gt; for help are elderly tablet users who find maps cognitively harder to parse.&lt;/p&gt;

&lt;p&gt;** Secure by Default**&lt;br&gt;
Strict Row Level Security (RLS) in Supabase PostgreSQL. Users can only edit their own profiles. Volunteer visibility is opt-in. No one's location is stored with more precision than they choose to provide.&lt;/p&gt;


&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;🔴 &lt;strong&gt;Live App:&lt;/strong&gt; &lt;a href="https://nearbyhelp.vercel.app" rel="noopener noreferrer"&gt;https://nearbyhelp.vercel.app&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Sign in with Google, allow location access, and you'll see the map immediately populated with volunteers nearby. Use the filter panel to narrow by task type. On mobile, swipe up for the list view.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Screenshots:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The main map: color-coded pins by task category, live distance shown on each popup&lt;/em&gt;&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.amazonaws.com%2Fuploads%2Farticles%2F6s88fvrkg738kzpnx3c8.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%2F6s88fvrkg738kzpnx3c8.png" alt="screenshot 1" width="800" height="360"&gt;&lt;/a&gt;&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%2Frw8ycshv577ngymnemj2.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%2Frw8ycshv577ngymnemj2.png" alt="screenshot 2" width="800" height="444"&gt;&lt;/a&gt;&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%2Fqnh8j3lfqmdewzd2s6vf.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%2Fqnh8j3lfqmdewzd2s6vf.png" alt="screenshot 3" width="800" height="626"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/mayureshsmitasuresh/nearbyhelp" rel="noopener noreferrer"&gt;Github code&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;
&lt;h3&gt;
  
  
  The Stack
&lt;/h3&gt;

&lt;p&gt;Every technology choice was made with two users in mind simultaneously: the &lt;strong&gt;volunteer&lt;/strong&gt; (typically a younger, tech-comfortable neighbor) and the &lt;strong&gt;person seeking help&lt;/strong&gt; (often elderly, on a tablet, with limited tech confidence). The stack had to be fast to ship, reliable in production, and genuinely accessible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Next.js 14 (App Router)&lt;/strong&gt;&lt;br&gt;
React Server Components for near-instant page loads. The map page is a protected route — unauthenticated users are redirected cleanly. API routes handle the Gemini integration server-side so API keys never touch the client.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Supabase — the backbone of the whole thing&lt;/strong&gt;&lt;br&gt;
Supabase does three jobs here that would have taken three separate services otherwise:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Authentication&lt;/strong&gt; — Google OAuth, one provider, zero friction. First sign-in auto-creates a profile row via a PostgreSQL trigger. No separate user management.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database&lt;/strong&gt; — PostgreSQL with a custom &lt;code&gt;get_nearby_profiles&lt;/code&gt; function that does bounding-box pre-filtering before Haversine calculation, keeping queries fast even at scale.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Row Level Security&lt;/strong&gt; — Users can only update their own rows. Volunteer contact info is only exposed if they've explicitly opted in. Security is enforced at the database layer, not just the application layer.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The Supabase database trigger that auto-creates a profile on first Google login was one of the most satisfying pieces to build:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="k"&gt;REPLACE&lt;/span&gt; &lt;span class="k"&gt;FUNCTION&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;handle_new_user&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;RETURNS&lt;/span&gt; &lt;span class="k"&gt;TRIGGER&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="err"&gt;$$&lt;/span&gt;
&lt;span class="k"&gt;BEGIN&lt;/span&gt;
  &lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;profiles&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;display_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;avatar_url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;VALUES&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;NEW&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;NEW&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;raw_user_meta_data&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="s1"&gt;'full_name'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;NEW&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;raw_user_meta_data&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="s1"&gt;'avatar_url'&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="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="err"&gt;$$&lt;/span&gt; &lt;span class="k"&gt;LANGUAGE&lt;/span&gt; &lt;span class="n"&gt;plpgsql&lt;/span&gt; &lt;span class="k"&gt;SECURITY&lt;/span&gt; &lt;span class="k"&gt;DEFINER&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TRIGGER&lt;/span&gt; &lt;span class="n"&gt;on_auth_user_created&lt;/span&gt;
  &lt;span class="k"&gt;AFTER&lt;/span&gt; &lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;
  &lt;span class="k"&gt;FOR&lt;/span&gt; &lt;span class="k"&gt;EACH&lt;/span&gt; &lt;span class="k"&gt;ROW&lt;/span&gt; &lt;span class="k"&gt;EXECUTE&lt;/span&gt; &lt;span class="k"&gt;FUNCTION&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;handle_new_user&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Zero onboarding friction. Sign in, you exist in the database. Done.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Haversine Formula&lt;/strong&gt;&lt;br&gt;
I implemented Haversine in pure TypeScript rather than relying on a library. I wanted to understand every line of the distance logic, and it's satisfying code to read:&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;haversineDistance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;lat1&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;lng1&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;lat2&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;lng2&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="kr"&gt;number&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;R&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;6371&lt;/span&gt; &lt;span class="c1"&gt;// Earth's radius in km&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dLat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;toRad&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lat2&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;lat1&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;dLng&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;toRad&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lng2&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;lng1&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;a&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;sin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dLat&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;2&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;cos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;toRad&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lat1&lt;/span&gt;&lt;span class="p"&gt;))&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;cos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;toRad&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lat2&lt;/span&gt;&lt;span class="p"&gt;))&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;sin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dLng&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;R&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&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;atan2&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;sqrt&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="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sqrt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;a&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;Every volunteer card on the map shows their distance to two decimal places. &lt;em&gt;0.4 km away.&lt;/em&gt; That specificity was important to me — vague proximity ("nearby") doesn't give someone the confidence to reach out. Exact distance does.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Google Gemini AI — the quiet magic&lt;/strong&gt;&lt;br&gt;
The AI feature is invisible to users, which is exactly how it should be. Volunteers type naturally. Gemini reads it and returns a standardized category. Here's the API route:&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;// app/api/categorize/route.ts&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;TASK_TAGS&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="s1"&gt;ERRANDS&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;HOUSEWORK&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;MAINTENANCE&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;TECH_HELP&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;TRANSPORT&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;COMPANIONSHIP&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;OTHER&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;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`
  You are a community volunteer task categorizer.
  Given this offer: '&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;skillText&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;'
  Return ONLY one tag from: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;TASK_TAGS&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="s1"&gt;, &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;
  No explanation. Just the tag.
`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The constraint of returning &lt;em&gt;only one tag&lt;/em&gt; from a fixed enum was deliberate. I don't want AI creativity here — I want consistency. Every "I can drive you to appointments" maps to &lt;code&gt;TRANSPORT&lt;/code&gt;. Every "I'm good with computers" maps to &lt;code&gt;TECH_HELP&lt;/code&gt;. The map filter relies on this being reliable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;react-leaflet + Custom Pins&lt;/strong&gt;&lt;br&gt;
No Google Maps API key required. Leaflet is open source, fast, and renders beautifully on mobile. Custom SVG pins are color-coded by task category so you can read the map at a glance without reading any text — important for elderly users who may have reduced vision.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tailwind CSS v4&lt;/strong&gt;&lt;br&gt;
Glassmorphism-inspired UI with high contrast ratios throughout. WCAG AA compliance was a design constraint, not an afterthought. Every interactive element has a minimum 44×44px tap target for accessibility.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Architecture Decision I'm Most Proud Of
&lt;/h3&gt;

&lt;p&gt;I chose to put the Haversine calculation in JavaScript rather than SQL, but the &lt;em&gt;pre-filtering&lt;/em&gt; (bounding box) in a Supabase PostgreSQL function. This means:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The database returns a small, geographically bounded set of profiles (fast)&lt;/li&gt;
&lt;li&gt;JavaScript sorts them by exact spherical distance (precise)&lt;/li&gt;
&lt;li&gt;The client renders cards in perfect nearest-first order (useful)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It's a clean separation: database does what databases are good at (filtering large datasets quickly), JavaScript does what it's good at (precise calculation on a small set).&lt;/p&gt;

&lt;h3&gt;
  
  
  What Was Hard
&lt;/h3&gt;

&lt;p&gt;The mobile list view took longer than I expected. The UX challenge was real: elderly users navigating a swipeable overlay need smooth momentum scrolling, large text, and clear visual hierarchy. I went through four iterations before the swipe gesture felt natural enough that I'd be comfortable handing a tablet to my grandmother.&lt;/p&gt;

&lt;p&gt;The other challenge was the Supabase RLS policies. Getting the policies right — where anyone can read volunteer profiles, but only the authenticated owner can write to theirs, and contact info is only exposed with explicit opt-in — required careful thinking. I've documented the full policy setup in the repo README for anyone who wants to fork it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why This Community. Why Now.
&lt;/h2&gt;

&lt;p&gt;By 2030, 1 in 6 people in the world will be over 60. In many cities, over 30% of elderly people report feeling lonely. The infrastructure of community that used to exist — knowing your neighbors, looking out for each other — has eroded in modern urban life.&lt;/p&gt;

&lt;p&gt;The solution isn't a government program or an expensive subscription service. It's already living three doors down from you. It's your neighbor who said "let me know if you ever need anything" and meant it — but never got the call because nobody had a way to make asking feel natural and safe.&lt;/p&gt;

&lt;p&gt;NearbyHelp is that way.&lt;/p&gt;

&lt;p&gt;It's not built for crisis. It's built for Tuesday afternoon when the jar won't open and there's nobody to call.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built with Next.js 14, Supabase, Google Gemini AI, react-leaflet, and Tailwind CSS v4.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Live at &lt;a href="https://nearbyhelp.vercel.app" rel="noopener noreferrer"&gt;https://nearbyhelp.vercel.app&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>weekendchallenge</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Mathematical Optimisation in Rust: A Complete Guide to good_lp + HiGHS (Production Ready with Axum)</title>
      <dc:creator>Mayuresh Smita Suresh</dc:creator>
      <pubDate>Sat, 21 Feb 2026 10:26:27 +0000</pubDate>
      <link>https://dev.to/mayu2008/mathematical-optimisation-in-rust-a-complete-guide-to-goodlp-highs-production-ready-with-axum-4pnm</link>
      <guid>https://dev.to/mayu2008/mathematical-optimisation-in-rust-a-complete-guide-to-goodlp-highs-production-ready-with-axum-4pnm</guid>
      <description>&lt;p&gt;Modern backend systems often need to make &lt;strong&gt;optimal decisions under&lt;br&gt;
constraints&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Allocate limited resources&lt;/li&gt;
&lt;li&gt;  Minimize operational cost&lt;/li&gt;
&lt;li&gt;  Select optimal product mix&lt;/li&gt;
&lt;li&gt;  Plan logistics efficiently&lt;/li&gt;
&lt;li&gt;  Build smart pricing engines&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where &lt;strong&gt;mathematical optimization&lt;/strong&gt; becomes powerful.&lt;/p&gt;

&lt;p&gt;In Rust, two tools make this practical:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;good_lp&lt;/code&gt; → Modeling layer (DSL for optimization problems)&lt;/li&gt;
&lt;li&gt;  HiGHS → High-performance optimization solver&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;  Mathematical foundations&lt;/li&gt;
&lt;li&gt;  What &lt;code&gt;good_lp&lt;/code&gt; and HiGHS are&lt;/li&gt;
&lt;li&gt;  When to use them&lt;/li&gt;
&lt;li&gt;  Rust examples&lt;/li&gt;
&lt;li&gt;  Production-ready Axum backend integration&lt;/li&gt;
&lt;li&gt;  Scaling considerations&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  1. Mathematical Optimization (Concept)
&lt;/h2&gt;

&lt;p&gt;Optimization problems look like this:&lt;/p&gt;

&lt;p&gt;Minimize or Maximize:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;f(x)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Subject to:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;g1(x) ≤ b1
g2(x) = b2
x ∈ feasible set
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  x = decision variables&lt;/li&gt;
&lt;li&gt;  f(x) = objective function&lt;/li&gt;
&lt;li&gt;  g(x) = constraints&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  2. LP vs MIP
&lt;/h2&gt;
&lt;h2&gt;
  
  
  Linear Programming (LP)
&lt;/h2&gt;

&lt;p&gt;All expressions are linear.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;Maximize: 3x + 2y&lt;/p&gt;

&lt;p&gt;Subject to: x + y ≤ 10 x ≥ 0 y ≥ 0&lt;/p&gt;

&lt;p&gt;LP problems are solved efficiently using simplex or interior-point&lt;br&gt;
methods.&lt;/p&gt;


&lt;h2&gt;
  
  
  Mixed Integer Programming (MIP)
&lt;/h2&gt;

&lt;p&gt;Some variables must be integers or binary.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;x ∈ {0,1}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;MIP is NP-hard.&lt;/p&gt;

&lt;p&gt;Solvers use: - LP relaxation - Branch-and-bound - Cutting planes&lt;/p&gt;


&lt;h2&gt;
  
  
  3. What Is HiGHS?
&lt;/h2&gt;

&lt;p&gt;HiGHS is a high-performance open-source solver written in C++.&lt;/p&gt;

&lt;p&gt;It supports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Linear Programming (LP)&lt;/li&gt;
&lt;li&gt;  Mixed Integer Programming (MIP)&lt;/li&gt;
&lt;li&gt;  Quadratic Programming (QP)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;HiGHS is the computation engine.&lt;/p&gt;


&lt;h2&gt;
  
  
  4. What Is &lt;code&gt;good_lp&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;good_lp&lt;/code&gt; is a Rust modeling crate.&lt;/p&gt;

&lt;p&gt;It: - Builds constraint matrices - Translates to solver format - Calls&lt;br&gt;
backend solver (like HiGHS)&lt;/p&gt;

&lt;p&gt;It does not solve problems itself.&lt;/p&gt;

&lt;p&gt;Architecture:&lt;/p&gt;

&lt;p&gt;Rust Code → good_lp → HiGHS → Optimal Solution&lt;/p&gt;


&lt;h2&gt;
  
  
  5. Installation
&lt;/h2&gt;

&lt;p&gt;Cargo.toml:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[dependencies]&lt;/span&gt;
&lt;span class="py"&gt;good_lp&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"1.4"&lt;/span&gt;
&lt;span class="py"&gt;highs&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.8"&lt;/span&gt;
&lt;span class="py"&gt;axum&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.7"&lt;/span&gt;
&lt;span class="py"&gt;tokio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;features&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"full"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="py"&gt;serde&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"1.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;features&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"derive"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="py"&gt;serde_json&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"1.0"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  6. Basic Optimization Example
&lt;/h2&gt;

&lt;p&gt;Maximize: 3x + 2y&lt;/p&gt;

&lt;p&gt;Subject to: x + y ≤ 10&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;good_lp&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;variable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SolverModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default_solver&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;solve_lp&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nb"&gt;Box&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;dyn&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;error&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;vars&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;variables!&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vars&lt;/span&gt;&lt;span class="nf"&gt;.add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;variable&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="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vars&lt;/span&gt;&lt;span class="nf"&gt;.add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;variable&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="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;solution&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vars&lt;/span&gt;
        &lt;span class="nf"&gt;.maximise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;3.0&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;2.0&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.using&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;default_solver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mf"&gt;10.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.solve&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="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"x = {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;solution&lt;/span&gt;&lt;span class="nf"&gt;.value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"y = {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;solution&lt;/span&gt;&lt;span class="nf"&gt;.value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

    &lt;span class="nf"&gt;Ok&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;
  
  
  7. Production-Ready Axum Backend Example
&lt;/h2&gt;

&lt;p&gt;We now build a simple optimization API.&lt;/p&gt;

&lt;p&gt;It solves:&lt;/p&gt;

&lt;p&gt;Maximize: profit_a * A + profit_b * B&lt;/p&gt;

&lt;p&gt;Subject to: A + B ≤ limit A, B ∈ {0,1}&lt;/p&gt;




&lt;h2&gt;
  
  
  main.rs
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;axum&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="nn"&gt;routing&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Router&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Json&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;serde&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;Deserialize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Serialize&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;good_lp&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;variable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SolverModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default_solver&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;net&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;SocketAddr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;#[derive(Deserialize)]&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;OptimizeRequest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;profit_a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;profit_b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[derive(Serialize)]&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;OptimizeResponse&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;objective&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;optimize&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="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="n"&gt;Json&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;OptimizeRequest&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Json&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;OptimizeResponse&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;vars&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;variables!&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vars&lt;/span&gt;&lt;span class="nf"&gt;.add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;variable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.binary&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vars&lt;/span&gt;&lt;span class="nf"&gt;.add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;variable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.binary&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;solution&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vars&lt;/span&gt;
        &lt;span class="nf"&gt;.maximise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="py"&gt;.profit_a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="py"&gt;.profit_b&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.using&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;default_solver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="py"&gt;.limit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.solve&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;OptimizeResponse&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;solution&lt;/span&gt;&lt;span class="nf"&gt;.value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;solution&lt;/span&gt;&lt;span class="nf"&gt;.value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;objective&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;solution&lt;/span&gt;&lt;span class="nf"&gt;.eval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="py"&gt;.profit_a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="py"&gt;.profit_b&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;),&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="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[tokio::main]&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Router&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/optimize"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;optimize&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;addr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;SocketAddr&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(([&lt;/span&gt;&lt;span class="mi"&gt;127&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="mi"&gt;0&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="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Server running at http://{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nn"&gt;axum&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Server&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.serve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="nf"&gt;.into_make_service&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="k"&gt;.await&lt;/span&gt;
        &lt;span class="nf"&gt;.unwrap&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. Running the API
&lt;/h2&gt;

&lt;p&gt;Start server:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cargo run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Call endpoint:&lt;/p&gt;

&lt;p&gt;POST &lt;a href="http://localhost:3000/optimize" rel="noopener noreferrer"&gt;http://localhost:3000/optimize&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Body:&lt;/p&gt;

&lt;p&gt;{ "profit_a": 10, "profit_b": 6, "limit": 1 }&lt;/p&gt;

&lt;p&gt;Response:&lt;/p&gt;

&lt;p&gt;{ "a": 1, "b": 0, "objective": 10 }&lt;/p&gt;




&lt;h2&gt;
  
  
  9. Production Considerations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  Set solver time limits&lt;/li&gt;
&lt;li&gt;  Handle infeasible models gracefully&lt;/li&gt;
&lt;li&gt;  Log solver status&lt;/li&gt;
&lt;li&gt;  Separate optimization into service layer&lt;/li&gt;
&lt;li&gt;  Consider async worker if solve time is long&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  10. Scaling
&lt;/h2&gt;

&lt;p&gt;To scale:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Partition large problems&lt;/li&gt;
&lt;li&gt;  Avoid symmetry&lt;/li&gt;
&lt;li&gt;  Use soft constraints carefully&lt;/li&gt;
&lt;li&gt;  Monitor solver time&lt;/li&gt;
&lt;li&gt;  Use time limits for MIP&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Optimization is a powerful backend capability.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;good_lp&lt;/code&gt; provides clean modeling. HiGHS provides industrial-grade&lt;br&gt;
solving. Axum provides modern Rust web infrastructure.&lt;/p&gt;

&lt;p&gt;Together, they form a production-ready optimization backend stack.&lt;/p&gt;

&lt;p&gt;If your system needs:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Best possible decision under constraints
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Then mathematical optimization in Rust is the correct architectural&lt;br&gt;
choice.&lt;/p&gt;

&lt;p&gt;Please ask me any questions you have in your mind I’ll be happy to guide you through &lt;/p&gt;

&lt;p&gt;Thanks,&lt;br&gt;
Mayuresh&lt;br&gt;
&lt;a href="https://tagnovate.com/mayuresh" rel="noopener noreferrer"&gt;About me&lt;/a&gt;&lt;/p&gt;

</description>
      <category>algorithms</category>
      <category>backend</category>
      <category>rust</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Create A Powerful Mobile App - Rust as the Brain, Flutter as the Face</title>
      <dc:creator>Mayuresh Smita Suresh</dc:creator>
      <pubDate>Wed, 18 Feb 2026 13:43:53 +0000</pubDate>
      <link>https://dev.to/mayu2008/create-a-powerful-mobile-app-rust-as-the-brain-flutter-as-the-face-5bm1</link>
      <guid>https://dev.to/mayu2008/create-a-powerful-mobile-app-rust-as-the-brain-flutter-as-the-face-5bm1</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Design beautiful interfaces in Flutter. Run serious logic in Rust.&lt;br&gt;
Connect them like a pro.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Modern applications are evolving beyond simple UI rendering and API&lt;br&gt;
calls. Today's apps handle heavy data processing, encryption, offline&lt;br&gt;
computation, and performance‑critical operations. While Flutter is&lt;br&gt;
exceptional for building beautiful cross‑platform interfaces, it is not&lt;br&gt;
optimized for low‑level, high‑performance computation. That's where Rust&lt;br&gt;
fits perfectly.&lt;/p&gt;

&lt;p&gt;This article explains how to architect your application with Rust as the&lt;br&gt;
"brain" and Flutter as the "face," and how they communicate efficiently.&lt;/p&gt;


&lt;h2&gt;
  
  
  Architecture Philosophy
&lt;/h2&gt;

&lt;p&gt;Think of your app in two layers:&lt;/p&gt;

&lt;p&gt;Flutter → Presentation Layer (UI)\&lt;br&gt;
Rust → Core Logic Layer (Brain)&lt;/p&gt;

&lt;p&gt;Flutter handles: - UI rendering - Animations - Navigation - State&lt;br&gt;
management&lt;/p&gt;

&lt;p&gt;Rust handles: - Heavy computation - Data processing - Encryption -&lt;br&gt;
Parsing - Performance‑critical algorithms - Offline engines&lt;/p&gt;

&lt;p&gt;Flutter does not need to understand internal logic. It simply calls Rust&lt;br&gt;
functions and displays results. This separation keeps the system clean&lt;br&gt;
and maintainable.&lt;/p&gt;


&lt;h2&gt;
  
  
  Why Rust Works So Well
&lt;/h2&gt;

&lt;p&gt;Rust provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Near C‑level performance\&lt;/li&gt;
&lt;li&gt;  Memory safety without garbage collection\&lt;/li&gt;
&lt;li&gt;  Strong type guarantees\&lt;/li&gt;
&lt;li&gt;  Safe concurrency\&lt;/li&gt;
&lt;li&gt;  Cross‑platform compilation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unlike putting heavy computation inside Dart, Rust gives you predictable&lt;br&gt;
performance and control over memory behaviour. You can even reuse the&lt;br&gt;
same Rust core across Android, iOS, desktop, or backend systems.&lt;/p&gt;


&lt;h2&gt;
  
  
  How Flutter and Rust Communicate
&lt;/h2&gt;

&lt;p&gt;Flutter and Rust communicate using FFI (Foreign Function Interface).&lt;br&gt;
Instead of writing raw FFI manually, you can use &lt;code&gt;flutter_rust_bridge&lt;/code&gt;,&lt;br&gt;
which generates safe bindings between Dart and Rust.&lt;/p&gt;

&lt;p&gt;This eliminates: - Manual pointer management - Unsafe memory passing -&lt;br&gt;
Complex native glue code&lt;/p&gt;


&lt;h2&gt;
  
  
  Basic Setup
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1. Create a Rust Library
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo new core_engine &lt;span class="nt"&gt;--lib&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In &lt;code&gt;Cargo.toml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[lib]&lt;/span&gt;
&lt;span class="py"&gt;crate-type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"cdylib"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Add flutter_rust_bridge
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="py"&gt;flutter_rust_bridge&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"latest"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Write a Rust Function
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;lib.rs&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;flutter_rust_bridge&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;frb&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;#[frb]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;process_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Processed: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;input&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;
  
  
  4. Generate Bridge Code
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flutter_rust_bridge_codegen
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Call Rust from Flutter
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RustApi&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;processData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;input:&lt;/span&gt; &lt;span class="s"&gt;"Hello"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. Flutter calls Rust. Rust processes the logic. Flutter renders&lt;br&gt;
the result.&lt;/p&gt;




&lt;h2&gt;
  
  
  Streaming Data from Rust
&lt;/h2&gt;

&lt;p&gt;For long‑running tasks, streaming is important.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rust Side
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;flutter_rust_bridge&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;StreamSink&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;#[frb]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;compute_stream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sink&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;StreamSink&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;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;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;sink&lt;/span&gt;&lt;span class="nf"&gt;.add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Step {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&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;h3&gt;
  
  
  Flutter Side
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;computeStream&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&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;This allows background processing while keeping the UI smooth.&lt;/p&gt;




&lt;h2&gt;
  
  
  Recommended Project Structure
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;project_root/
│
├── flutter_app/
│   └── lib/
│
└── rust_core/
    ├── src/
    │   ├── lib.rs
    │   ├── logic.rs
    │   ├── services.rs
    │   └── models.rs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Keep UI concerns inside Flutter and business logic inside Rust. The Rust&lt;br&gt;
The core should be testable independently of Flutter.&lt;/p&gt;




&lt;h2&gt;
  
  
  Best Practices
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  Keep Flutter thin --- only UI and state.&lt;/li&gt;
&lt;li&gt;  Keep Rust pure --- no UI dependencies.&lt;/li&gt;
&lt;li&gt;  Avoid blocking calls --- use threads or streaming.&lt;/li&gt;
&lt;li&gt;  Design simple Rust APIs for Flutter to consume.&lt;/li&gt;
&lt;li&gt;  Test Rust independently via CLI before integrating.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  When This Architecture Makes Sense
&lt;/h2&gt;

&lt;p&gt;Use Flutter + Rust when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  You need high performance&lt;/li&gt;
&lt;li&gt;  You process large datasets&lt;/li&gt;
&lt;li&gt;  You require strong memory safety&lt;/li&gt;
&lt;li&gt;  You build offline‑first applications&lt;/li&gt;
&lt;li&gt;  You need shared core logic across platforms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For simple CRUD apps, this may be unnecessary. But for performance‑heavy&lt;br&gt;
systems, this separation is powerful.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Flutter builds beautiful experiences. Rust builds powerful systems.&lt;/p&gt;

&lt;p&gt;Together, they allow you to create applications that are fast, stable,&lt;br&gt;
scalable, and maintainable, with a clear separation between&lt;br&gt;
presentation and logic.&lt;/p&gt;

&lt;p&gt;If you're building something beyond just screens, consider making Rust&lt;br&gt;
Your brain and Flutter your face.&lt;/p&gt;

&lt;p&gt;Mayuresh Smita Suresh&lt;br&gt;
&lt;a href="https://tagnovate.com/mayuresh" rel="noopener noreferrer"&gt;My work&lt;/a&gt;&lt;/p&gt;

</description>
      <category>rust</category>
      <category>flutter</category>
      <category>mobile</category>
      <category>softwaredevelopment</category>
    </item>
  </channel>
</rss>
