<?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: Dakshata </title>
    <description>The latest articles on DEV Community by Dakshata  (@thedakshata).</description>
    <link>https://dev.to/thedakshata</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%2F2153584%2F9694d03b-4425-4641-841a-e363603f46ef.jpg</url>
      <title>DEV Community: Dakshata </title>
      <link>https://dev.to/thedakshata</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/thedakshata"/>
    <language>en</language>
    <item>
      <title>LazyLora — Open-Weight Intent, Durable Escalation, Zero Babysitting</title>
      <dc:creator>Dakshata </dc:creator>
      <pubDate>Thu, 22 Oct 2026 19:38:36 +0000</pubDate>
      <link>https://dev.to/thedakshata/lazylora-open-weight-intent-durable-escalation-zero-babysitting-2noj</link>
      <guid>https://dev.to/thedakshata/lazylora-open-weight-intent-durable-escalation-zero-babysitting-2noj</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week3-2026-10-19"&gt;Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;On a busy ward a coordinator used to send the same shift text to six people, wait, chase the ones who didn’t reply, then escalate by phone. The replies were never clean. “yeah sure”, “nah booked”, “what time again?”. Keyword rules broke. Someone had to stay online.I built the thing that stays online instead. &lt;br&gt;
LazyLore is a small FastAPI service that fans out shift offers, understands messy caregiver replies with a local open-weight model, claims the first valid accept under a lock, and escalates to voice if nobody answers. The humans only start it. The rest runs while they do something else.&lt;/p&gt;

&lt;p&gt;Who gets to be lazier?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Coordinators stop manually texting and chasing people&lt;/li&gt;
&lt;li&gt;Caregivers can reply casually instead of using rigid keywords&lt;/li&gt;
&lt;li&gt;The system keeps running even if the model or Temporal is temporarily down (graceful fallback)&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Piece&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Fan-out&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Sends SMS notifications to every caregiver with the matching role.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Intent&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Uses local Gemma (&lt;code&gt;gemma2:2b&lt;/code&gt; via Ollama) to classify responses as &lt;code&gt;ACCEPT&lt;/code&gt;, &lt;code&gt;DECLINE&lt;/code&gt;, or &lt;code&gt;UNKNOWN&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Claim&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The first valid acceptance wins; an &lt;code&gt;asyncio&lt;/code&gt; lock prevents multiple caregivers from claiming the same request.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Escalation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A Temporal workflow waits for a specified interval, then places phone calls if the request is still pending.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Fallback&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;If Ollama or Temporal is unavailable, the service degrades gracefully instead of crashing.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/lLoOd3qhYMU" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Running it locally
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr2wt5pfj8w1q9k5ull3o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr2wt5pfj8w1q9k5ull3o.png" alt="VS Code showing the project, the running terminals, and the passing pytest output" width="800" height="553"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The project in VS Code. The terminal list on the right shows the Temporal server (&lt;code&gt;temporal&lt;/code&gt;), the API (&lt;code&gt;uv&lt;/code&gt;), and two PowerShell tabs for sending requests and running tests.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The setup is three pieces running side by side:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Temporal server:&lt;/strong&gt; &lt;code&gt;temporal server start-dev&lt;/code&gt; starts a local server and a web UI at &lt;code&gt;localhost:8233&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The API:&lt;/strong&gt; &lt;code&gt;uv run uvicorn app.api:create_app --factory --reload --port 8000&lt;/code&gt;. The Temporal worker starts inside it, so there is no separate worker to run.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ollama:&lt;/strong&gt; it runs in the background after installation, and the app uses it to classify replies. You don't need a terminal for it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The other two PowerShell tabs are for sending test requests with &lt;code&gt;Invoke-RestMethod&lt;/code&gt; and running the tests.&lt;/p&gt;

&lt;p&gt;At the bottom of the screenshot is the test run (&lt;code&gt;uv run pytest -v&lt;/code&gt;): all 5 tests pass in under 3 seconds. They cover the intent parser, including accept, decline, unknown, fallback on error, and messy replies like "yeah sure I can take it".&lt;br&gt;
Local run is three terminals: Ollama, Temporal worker, FastAPI. One curl starts the fan-out. Natural-language replies claim the shift. After the demo delay the worker escalates if nobody claimed it.&lt;/p&gt;
&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/the-matrixneo" rel="noopener noreferrer"&gt;
        the-matrixneo
      &lt;/a&gt; / &lt;a href="https://github.com/the-matrixneo/LazyLora" rel="noopener noreferrer"&gt;
        LazyLora
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;LazyLore (with Local Open-Weight AI)&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;A Python FastAPI microservice that fills open caregiver shifts by fanning out SMS (and escalating to voice), accepting the first valid claim, and handling race conditions safely.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Hacktoberfest 2026 – Week 3 “Slow and Steady”&lt;/strong&gt;&lt;br&gt;
The service now uses a &lt;strong&gt;local open-weight model&lt;/strong&gt; (via Ollama) to understand messy real-world replies instead of brittle keyword matching. This means:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;messages never leave your machine&lt;/li&gt;
&lt;li&gt;Zero ongoing LLM API cost&lt;/li&gt;
&lt;li&gt;Works fully offline once the model is pulled&lt;/li&gt;
&lt;li&gt;Handles natural language (“yeah sure”, “nah I’m booked”, “what time again?”) so coordinators can be lazy&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Quick Start (with open-weight model)&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;1. Install &amp;amp; start Ollama&lt;/h3&gt;
&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;curl -fsSL https://ollama.com/install.sh &lt;span class="pl-k"&gt;|&lt;/span&gt; sh
ollama serve          &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; leave this running&lt;/span&gt;
ollama pull gemma2:2b &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; or phi3:mini / llama3.2:1b&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;2. Install project dependencies&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;&lt;code&gt;uv sync&lt;/code&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;3. Run the API&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;&lt;code&gt;uv run uvicorn app.api:create_app --factory --reload&lt;/code&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;4. Test the intent classifier&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;&lt;code&gt;uv run pytest tests/test_intent.py&lt;/code&gt;…&lt;/p&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/the-matrixneo/LazyLora" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Core files:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;app/intent.py&lt;/code&gt; — zero shot Gemma classifier, temperature 0, falls back to UNKNOWN&lt;br&gt;
&lt;code&gt;app/workflows.py + worker.py&lt;/code&gt; — Temporal escalation with retries&lt;br&gt;
app/api.py — fan-out, claim lock, Temporal start with &lt;code&gt;asyncio&lt;/code&gt; fallback.&lt;/p&gt;
&lt;h2&gt;
  
  
  How I built it
&lt;/h2&gt;
&lt;h3&gt;
  
  
  The idea
&lt;/h3&gt;

&lt;p&gt;When a shift opens, LazyLora texts every caregiver with the right role. The first person to reply "yes" gets the shift. If nobody claims it in time, it escalates to phone calls. I wanted this to be reliable, so I used Temporal for the waiting and escalation instead of a plain timer.&lt;/p&gt;
&lt;h3&gt;
  
  
  Architecture
&lt;/h3&gt;

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

&lt;p&gt;Everything the app owns runs in &lt;strong&gt;one Python process&lt;/strong&gt; (FastAPI + uvicorn). Around it are two local services: a Temporal dev server and Ollama. As the image below shows that a Fan-out → natural-language accept → first claim wins → second request rejected&lt;br&gt;
All intent classification runs locally with Gemma via Ollama.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsmc0m6n80axlr2kzbl0e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsmc0m6n80axlr2kzbl0e.png" alt="Fan-out → natural-language accept → first claim wins → second request rejected&lt;br&gt;
All intent classification runs locally with Gemma via Ollama." width="800" height="516"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Piece&lt;/th&gt;
&lt;th&gt;Job&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;FastAPI routes&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;POST /shifts/{id}/fanout&lt;/code&gt; opens a shift, &lt;code&gt;POST /messages/inbound&lt;/code&gt; receives replies, &lt;code&gt;GET /health&lt;/code&gt; checks the service&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;In-memory store&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Holds shifts, caregivers, and fanouts, loaded from &lt;code&gt;sample_data.json&lt;/code&gt; on startup&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Claim lock&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;One &lt;code&gt;asyncio.Lock&lt;/code&gt; per shift, so only one caregiver can claim it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Intent parser&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Sends each reply to a local model (gemma2:2b via Ollama) and returns ACCEPT, DECLINE, or UNKNOWN. If the model is down, it falls back to UNKNOWN instead of crashing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Notifier&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;send_sms&lt;/code&gt; and &lt;code&gt;place_phone_call&lt;/code&gt;. These are mocked for the demo, so no real messages are sent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Temporal server&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Stores the workflow and its timer outside the app, so the timer survives restarts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Temporal worker&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Runs the escalation workflow and activity. It starts inside the API process&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  Project layout
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LazyLora/
├── app/
│   ├── api.py        # routes, claim lock, worker startup
│   ├── database.py   # in-memory store + sample data loader
│   ├── intent.py     # reply classification (Ollama)
│   ├── models.py     # InboundMessage, ShiftFanout, statuses
│   ├── notifier.py   # mocked SMS and phone calls
│   └── workflow.py   # Temporal workflow + activity
├── tests/
│   └── test_intent.py
├── worker.py         
└── sample_data.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Step 1: Open a shift and text the caregivers
&lt;/h3&gt;

&lt;p&gt;The fanout endpoint is &lt;strong&gt;idempotent&lt;/strong&gt;, so posting the same shift twice never texts anyone twice. It saves the shift as &lt;code&gt;PENDING&lt;/code&gt; and starts a Temporal workflow named &lt;code&gt;escalate-{shift_id}&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@router.post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/shifts/{shift_id}/fanout&lt;/span&gt;&lt;span class="sh"&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;def&lt;/span&gt; &lt;span class="nf"&gt;fanout_shift&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;shift_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_db&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;shift&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shifts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;shift_id&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;shift&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;HTTPException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;detail&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Shift &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;shift_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; not found&lt;/span&gt;&lt;span class="sh"&gt;"&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;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fanouts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;shift_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;already_fanout&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;caregivers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_caregivers_by_role&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;shift&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;role_required&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;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;caregivers&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;send_sms&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="n"&gt;phone&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;New shift available. Reply &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;yes&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; to claim.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fanouts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;shift_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;ShiftFanout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;shift_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;shift_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ShiftFanoutStatus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PENDING&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;contacted_caregiver_ids&lt;/span&gt;&lt;span class="o"&gt;=&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;id&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;caregivers&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="n"&gt;client&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;Client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;localhost:7233&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start_workflow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;ShiftEscalationWorkflow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;shift_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;escalate-&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;shift_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;task_queue&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;shift-escalation&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fanout_initiated&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Let the first "yes" win
&lt;/h3&gt;

&lt;p&gt;Replies don't have to match a keyword. "yes I can take it" and "yes put me down" both get classified as ACCEPT. Then a lock makes sure only one person claims the shift, even if replies arrive at nearly the same time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;lock&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;_get_claim_lock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fanout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shift_id&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;with&lt;/span&gt; &lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Re-check inside the lock: someone may have claimed while we waited
&lt;/span&gt;    &lt;span class="n"&gt;fanout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fanouts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fanout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shift_id&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;fanout&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;fanout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;ShiftFanoutStatus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PENDING&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;shift_already_claimed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;fanout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ShiftFanoutStatus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CLAIMED&lt;/span&gt;
    &lt;span class="n"&gt;fanout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;claimed_by&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;caregiver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fanouts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fanout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shift_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fanout&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Escalate with a durable timer
&lt;/h3&gt;

&lt;p&gt;The workflow sleeps, then runs an activity. If the shift is still &lt;code&gt;PENDING&lt;/code&gt;, it places phone calls. If someone claimed it, it does nothing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@workflow.defn&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ShiftEscalationWorkflow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nd"&gt;@workflow.run&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;shift_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;workflow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;timedelta&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;seconds&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  &lt;span class="c1"&gt;# 10 minutes in real use
&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;workflow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute_activity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;escalate_shift_activity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;shift_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;start_to_close_timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;timedelta&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;seconds&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;retry_policy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;RetryPolicy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maximum_attempts&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&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;
  
  
  Step 4: Run the worker inside the API
&lt;/h3&gt;

&lt;p&gt;My first version ran the worker as a separate process. Because the data lives in memory, that worker had its own empty copy and never found the shift, so the escalation silently did nothing. Starting the worker in FastAPI's lifespan fixed it, since both now share the same data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@asynccontextmanager&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;lifespan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;FastAPI&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;load_sample_data&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;client&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;Client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;localhost:7233&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;worker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Worker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;task_queue&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;shift-escalation&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;workflows&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ShiftEscalationWorkflow&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;activities&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;escalate_shift_activity&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;worker_task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="k"&gt;yield&lt;/span&gt;
    &lt;span class="n"&gt;worker_task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cancel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_app&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;FastAPI&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FastAPI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lifespan&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;lifespan&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;include_router&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="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Run it yourself
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;temporal&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;start-dev&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;uv&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;uvicorn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;app.api:create_app&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--factory&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--reload&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--port&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;8000&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;uv&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;pytest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-v&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How the flow works
&lt;/h2&gt;

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

&lt;p&gt;The diagram has one starting point and two paths that run at the same time. Here's how to read it, top to bottom.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. A shift opens (the blue box at the top)
&lt;/h3&gt;

&lt;p&gt;A request hits &lt;code&gt;POST /shifts/{id}/fanout&lt;/code&gt;. The app first checks that the shift exists and hasn't already been sent out, so sending the same request twice never texts people twice. Then it finds every caregiver with the required role (for example, an LPN) and sends each of them an SMS.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. The shift is marked PENDING and a timer starts
&lt;/h3&gt;

&lt;p&gt;The app saves the shift as &lt;code&gt;PENDING&lt;/code&gt; and starts a &lt;strong&gt;Temporal workflow&lt;/strong&gt; with a timer. From here the diagram splits into two paths that run at once.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. The claim path (green box, left)
&lt;/h3&gt;

&lt;p&gt;When a caregiver replies, the app:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Checks that the phone number belongs to a known caregiver.&lt;/li&gt;
&lt;li&gt;Sends the text to a small &lt;strong&gt;local language model (Ollama, gemma2:2b)&lt;/strong&gt;, which labels it as accept, decline, or unknown. That means "yes I can take it" and "yes put me down" both work, with no exact keyword needed.&lt;/li&gt;
&lt;li&gt;If it's an accept, takes a &lt;strong&gt;per-shift lock&lt;/strong&gt; and checks the shift is still open.&lt;/li&gt;
&lt;li&gt;The first caregiver through the lock gets the shift (&lt;code&gt;CLAIMED&lt;/code&gt;). Anyone else gets &lt;code&gt;shift_already_claimed&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The lock matters because two people can reply at nearly the same moment. Without it, both could be booked for the same shift.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. The escalation path (purple box, right)
&lt;/h3&gt;

&lt;p&gt;At the same time, Temporal is counting down a &lt;strong&gt;durable timer&lt;/strong&gt; (30 seconds in my demo, 10 minutes for real use). When it ends, an activity checks the shift:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Still &lt;code&gt;PENDING&lt;/code&gt;? It places a phone call to each matching caregiver and marks the shift &lt;code&gt;ESCALATED&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Already claimed? It does nothing and returns &lt;code&gt;already_claimed_or_missing&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why Temporal for the timer?
&lt;/h3&gt;

&lt;p&gt;A plain &lt;code&gt;sleep&lt;/code&gt; inside the app disappears if the server crashes or restarts. Temporal stores the timer outside the app, so the escalation still fires after a restart. That's the main reason I used it here.&lt;/p&gt;

&lt;h3&gt;
  
  
  What I fixed
&lt;/h3&gt;

&lt;p&gt;My first version ran the Temporal worker as a separate process. The app kept its data in memory, so that worker had its own empty copy and never found the shift. Escalation silently did nothing.&lt;/p&gt;

&lt;p&gt;Here is what that looked like in the Temporal UI. The workflow list shows the escalation workflow as &lt;strong&gt;Completed&lt;/strong&gt;, which looks healthy at first glance:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frh5fi1itfgcho3bhgwwc.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%2Frh5fi1itfgcho3bhgwwc.jpeg" alt="Temporal workflow detail showing the result already_claimed_or_missing and a 10 minute timer" width="799" height="388"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The workflow ran and finished, so Temporal reported success. Nothing here hints at a problem.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Opening the workflow shows the real result. The activity returned &lt;code&gt;already_claimed_or_missing&lt;/code&gt; even though nobody had claimed the shift. The worker could not see the shift at all, so it skipped the phone calls. The timeline also shows the original 10-minute timer, which is why I later shortened it to 30 seconds for demos:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1pzxoutxs1jvpumkti1f.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%2F1pzxoutxs1jvpumkti1f.jpeg" alt="Temporal UI workflow list showing one completed ShiftEscalationWorkflow" width="800" height="371"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Result: &lt;code&gt;already_claimed_or_missing&lt;/code&gt;. The workflow completed, but the escalation never happened.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The lesson: a Completed workflow only means the code ran without crashing, not that it did the right thing. Always check the result.&lt;/p&gt;

&lt;p&gt;The fix was to start the worker inside the API's startup so both share the same data. After that, the same flow returned &lt;code&gt;escalated_to_1_caregivers&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;Closed intent APIs would have required keys, bills, and shipping private caregiver messages off box. A local open-weight model keeps the data on the machine, costs nothing after the first pull, and still works offline. Temporal does the same for time. A plain sleep is fine until the process restarts. A workflow survives the restart. The combination of local model for understanding, durable workflow for waiting is what lets the system actually replace the human loop instead of just assisting it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Lazy Payoff
&lt;/h2&gt;

&lt;p&gt;Before: manual texts, keyword failures, phone chases, someone watching the channel.&lt;/p&gt;

&lt;p&gt;After: one POST starts the fan-out. Replies are understood. The first accept claims the shift under a lock. If silence continues, Temporal escalates. The coordinator’s job shrinks to “start it and, if they want, look later.”&lt;br&gt;
That is the whole point of the theme. Build the thing that keeps working so the people can stop.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Gemma&lt;/strong&gt;: Local &lt;code&gt;gemma2:2b&lt;/code&gt; via Ollama classifies messy caregiver SMS into ACCEPT / DECLINE / UNKNOWN with temperature 0 and graceful UNKNOWN fallback.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Temporal&lt;/strong&gt;: Shift escalation is a Temporal workflow (sleep → activity with retries). Survives worker restarts; falls back to asyncio if Temporal is unavailable.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>opensource</category>
      <category>hacktoberfest</category>
    </item>
    <item>
      <title>Red Flags in the Ledger - hf26 Challenge</title>
      <dc:creator>Dakshata </dc:creator>
      <pubDate>Tue, 13 Oct 2026 08:25:29 +0000</pubDate>
      <link>https://dev.to/thedakshata/red-flags-in-the-ledger-hf26-challenge-36d9</link>
      <guid>https://dev.to/thedakshata/red-flags-in-the-ledger-hf26-challenge-36d9</guid>
      <description>&lt;h1&gt;
  
  
  TinyGuard AI — Simple AI Powered Expense Anomaly Detector
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week2-2026-10-12"&gt;Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;TinyGuard AI is a lightweight, AI-powered anomaly detection tool that helps users spot unusual expenses and suspicious-looking transactions in their CSV data.&lt;/p&gt;

&lt;p&gt;Small businesses, freelancers, and independent professionals often manage their expenses using spreadsheets. Manually reviewing every transaction can be tedious, and unusual amounts can easily go unnoticed.&lt;/p&gt;

&lt;p&gt;TinyGuard AI makes this process simpler. Upload a CSV file, select numerical features, and let the application analyze the data.&lt;/p&gt;

&lt;p&gt;It currently includes two separate AI-powered analysis sections:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Isolation Forest:&lt;/strong&gt; Detects unusual patterns in numerical transaction data without requiring labelled training examples.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TabPFN:&lt;/strong&gt; Demonstrates tabular classification by predicting Normal/Review categories using a separate synthetic, labelled training dataset.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The application also provides visualizations, a results table, and downloadable analysis results.&lt;/p&gt;

&lt;p&gt;The idea is simple: make useful AI-based data analysis accessible without requiring users to build their own machine learning pipeline.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Who would pay for it?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Freelancers, small businesses, independent consultants, and bookkeeping teams could benefit from a simple tool that helps them review expense data faster. A future version could offer recurring CSV analysis, automated reports, and integrations with accounting workflows.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk71kv4d4ewlbph4ik35s.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%2Fk71kv4d4ewlbph4ik35s.jpeg" alt="TabPFN Prediction Results: Displays the model's classification output for the selected numerical features, showcasing the integration of TabPFN into TinyGuard AI." width="800" height="404"&gt;&lt;/a&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fiuyum0ofqwpq9c5nxlr7.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%2Fiuyum0ofqwpq9c5nxlr7.jpeg" alt="TabPFN Predictions: Demonstrates TabPFN-based classification of transactions into Normal and Review categories using a labelled training dataset." width="799" height="397"&gt;&lt;/a&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjroiygxq9fqkdnw0ajek.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%2Fjroiygxq9fqkdnw0ajek.jpeg" alt="Isolation Forest Predictions: Detects unusual patterns in uploaded expense data and highlights potentially anomalous transactions." width="799" height="392"&gt;&lt;/a&gt;&lt;/p&gt;

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


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/the-matrixneo" rel="noopener noreferrer"&gt;
        the-matrixneo
      &lt;/a&gt; / &lt;a href="https://github.com/the-matrixneo/spill_the_tea" rel="noopener noreferrer"&gt;
        spill_the_tea
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;TinyGuard AI&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;A beginner-friendly web app that detects unusual records in CSV files using machine learning.&lt;/p&gt;
&lt;p&gt;Built with &lt;strong&gt;Streamlit&lt;/strong&gt;, &lt;strong&gt;Pandas&lt;/strong&gt;, and &lt;strong&gt;Scikit-learn's Isolation Forest&lt;/strong&gt;.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Quick Start&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;1. Create &amp;amp; activate a virtual environment&lt;/h3&gt;
&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Windows&lt;/span&gt;
py -m venv .venv
.venv&lt;span class="pl-cce"&gt;\S&lt;/span&gt;cripts&lt;span class="pl-cce"&gt;\a&lt;/span&gt;ctivate

&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; macOS / Linux&lt;/span&gt;
python3 -m venv .venv
&lt;span class="pl-c1"&gt;source&lt;/span&gt; .venv/bin/activate&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;2. Install dependencies&lt;/h3&gt;

&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;pip install -r requirements.txt&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;3. Run the app&lt;/h3&gt;

&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;streamlit run app.py&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;The app opens at &lt;strong&gt;&lt;a href="http://localhost:8501" rel="nofollow noopener noreferrer"&gt;http://localhost:8501&lt;/a&gt;&lt;/strong&gt; in your browser.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;How to Use&lt;/h2&gt;

&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;Upload any CSV file (or use the included &lt;code&gt;sample_expenses.csv&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Select the numeric columns you want to analyze.&lt;/li&gt;
&lt;li&gt;Adjust the anomaly ratio slider if needed.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Analyze Data&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Review the results and download the annotated CSV.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;/div&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;spill_the_tea/
├── app.py                 # Main application
├── requirements.txt       # Python dependencies
├── sample_expenses.csv    # Sample data for testing
└── README.md              # This file
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

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

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Python 3.10+&lt;/li&gt;
&lt;li&gt;See &lt;code&gt;requirements.txt&lt;/code&gt; for…&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/the-matrixneo/spill_the_tea" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;I built TinyGuard AI using Python and Streamlit, with a focus on keeping the application lightweight, accessible, and easy to run locally.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tech stack:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Python&lt;/strong&gt; — core application logic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Streamlit&lt;/strong&gt; — interactive web interface.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pandas&lt;/strong&gt; — CSV processing and data manipulation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scikit-learn&lt;/strong&gt; — Isolation Forest anomaly detection.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TabPFN by Prior Labs&lt;/strong&gt; — tabular machine learning classification.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Matplotlib&lt;/strong&gt; — data visualization.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The application has two independent analysis pipelines. Isolation Forest identifies unusual observations, while TabPFN demonstrates classification using labelled synthetic training data. Keeping these pipelines separate makes their different purposes clear.&lt;/p&gt;

&lt;p&gt;I also designed the interface with a soft pink and ivory aesthetic, including CSV upload, feature selection, result visualization, and downloadable outputs.&lt;/p&gt;

&lt;p&gt;TabPFN's model weights are accessed through the required Prior Labs authentication and licensing process. The current implementation is designed as a small-data prototype and runs on CPU.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;Open innovation makes it possible for individual developers and small teams to experiment with powerful machine learning tools without building every component from scratch.&lt;/p&gt;

&lt;p&gt;For TinyGuard AI, open-source libraries such as Pandas, Scikit-learn, Matplotlib, and Streamlit provided the foundation for data processing, anomaly detection, visualization, and the application interface.&lt;br&gt;
Integrating TabPFN gave me an opportunity to explore a specialized tabular machine learning model alongside a conventional anomaly detection approach.&lt;/p&gt;

&lt;p&gt;Instead of depending entirely on a closed, general-purpose AI API, I could build around tools designed for specific tasks, understand how the components work together, and customize the application for a practical use case.&lt;/p&gt;

&lt;h2&gt;
  
  
  My First User
&lt;/h2&gt;

&lt;p&gt;One of the first things I wanted to validate with TinyGuard AI was whether someone could upload an expense CSV and understand the results without needing a machine learning background.&lt;br&gt;
The idea is genuinely useful: instead of manually scanning rows of expenses, users can get a quick overview of unusual transactions through Isolation Forest, with a separate TabPFN classification demo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What could be improved next?&lt;/strong&gt; I'd want clearer explanations of why a transaction was flagged, an easier way to compare the two models, and testing against real, appropriately labelled data before relying on the results for financial decisions.&lt;/p&gt;

&lt;p&gt;For me, the most valuable next step would be making the flagged transactions easier to investigate, rather than simply showing predictions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Prior Labs — Best Use of TabPFN:&lt;/strong&gt; Uses TabPFN for a separate tabular classification demonstration alongside Isolation Forest anomaly detection.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Show your love and support !!!&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>ai</category>
      <category>mcp</category>
    </item>
    <item>
      <title>Cross-Origin Resource Sharing</title>
      <dc:creator>Dakshata </dc:creator>
      <pubDate>Wed, 30 Apr 2025 18:55:19 +0000</pubDate>
      <link>https://dev.to/thedakshata/cross-origin-resource-sharing-278l</link>
      <guid>https://dev.to/thedakshata/cross-origin-resource-sharing-278l</guid>
      <description>&lt;p&gt;&lt;strong&gt;What is (CORS) Cross-Origin Resource Sharing ?&lt;/strong&gt;&lt;br&gt;
In simple words, is a mechanism for integrating applications.For example, your application may use your browser to pull videos from a video platform API, use fonts from a public font library, or display weather data from a national weather database. CORS allows the client browser to check with the third-party servers if the request is authorized before any data transfers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What does "other-domain" means?&lt;/strong&gt;&lt;br&gt;
means the URL being accessed differs from the location that the JavaScript is running from, by having:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a different scheme (HTTP or HTTPS)&lt;/li&gt;
&lt;li&gt;a different domain &lt;/li&gt;
&lt;li&gt;a different port&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why do we need CORS?&lt;/strong&gt;&lt;br&gt;
This is a worst-case scenario, where everything is wide open. But it still exemplifies what a CORS attack looks like. In fact, in 2016, &lt;em&gt;Facebook&lt;/em&gt; was found to be vulnerable to such a CORS attack.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;One domain + port combination cannot read the response to a request from&lt;br&gt;
 a different domain + port combination.&lt;/p&gt;
&lt;/blockquote&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%2Fcdn.comparitech.com%2Fwp-content%2Fuploads%2F2021%2F03%2FCORS1.jpg" 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%2Fcdn.comparitech.com%2Fwp-content%2Fuploads%2F2021%2F03%2FCORS1.jpg" width="511" height="338"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to allow CORS in react.js?&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Using &lt;code&gt;proxy&lt;/code&gt; in &lt;code&gt;package.json&lt;/code&gt; file.&lt;/li&gt;
&lt;li&gt;Add the API part to &lt;code&gt;package.json&lt;/code&gt; file.&lt;/li&gt;
&lt;li&gt;Then make request :-
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;React.useEffect(() =&amp;gt; {
    axios
        .get('api/profile/')
        .then(function (response) {
            console.log(response);
        })
        .catch(function (error) {
            console.log(error);
        });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How to prevent CORS-based attacks?&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Specify the allowed origins &lt;/li&gt;
&lt;li&gt;Only allow trusted sites&lt;/li&gt;
&lt;li&gt;Don’t whitelist “null”&lt;/li&gt;
&lt;li&gt;Implement proper server-side security policies&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For more information and installation visit - &lt;a href="https://www.npmjs.com/package/cors" rel="noopener noreferrer"&gt;www.npmjs.com&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;ⓢⓗⓞⓦ ⓛⓞⓥⓔ ⓐⓝⓓ ⓢⓤⓟⓟⓞⓡⓣ&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>react</category>
      <category>learning</category>
      <category>interview</category>
    </item>
    <item>
      <title>SAYONARA 2024</title>
      <dc:creator>Dakshata </dc:creator>
      <pubDate>Tue, 07 Jan 2025 12:20:29 +0000</pubDate>
      <link>https://dev.to/thedakshata/sayonara-2024-1385</link>
      <guid>https://dev.to/thedakshata/sayonara-2024-1385</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/newyear"&gt;2025 New Year Writing challenge&lt;/a&gt;: Retro’ing and Debugging 2024.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;New year — a new chapter, new verse, or just the same old story? Ultimately we write it. The choice is ours&lt;/em&gt;. &lt;br&gt;
                                             — Alex Morritt&lt;/p&gt;

&lt;p&gt;2O24 has been the great year for me, as I stepped into college to pursue my bachelor's degree in computer science and engineering. Missing those school days a lot 🫠. Anyway, I got to learn and experience many futuristic things. Yes!! I participated in Girl Script Summer of Code (GSsoc'24), Hacktoberfest and got selected for Social Winter of Code 2024 ⛄  as a Contributor. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fmedia1.tenor.com%2Fimages%2F770fd323aac976f24841a71d9cda49c0%2Ftenor.gif" class="article-body-image-wrapper"&gt;&lt;img width="468" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fmedia1.tenor.com%2Fimages%2F770fd323aac976f24841a71d9cda49c0%2Ftenor.gif" height="498"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;h2&gt;Girl Script Summer Of Code 2024 🚀&lt;/h2&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Participating in Girl Script Summer of Code 2024 (GSsoC '24) has been an incredible experience that allowed me to grow as a developer while contributing to impactful open-source projects.&lt;/p&gt;

&lt;p&gt;Achievements 🌟&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;7 Pull Requests Merged: Tackled diverse issues across multiple &lt;br&gt;
repositories, focusing on solving real-world problems.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ranked 177: Among thousands of contributors, I’m proud to have made &lt;br&gt;
meaningful contributions that earned me this rank.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;h2&gt;Hacktoberfest 🌱&lt;/h2&gt;

&lt;p&gt;I had the privilege of participating in Hacktoberfest 2024, and it was an amazing experience that challenged me to push my limits while contributing to meaningful open-source projects.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Achievements 🌟&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Completed All 4 Levels: I successfully submitted the required pull requests, earning the recognition of completing all levels of Hacktoberfest.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Early Pegasus Badge: I earned the Early Pegasus Badge by contributing early and actively throughout the month, demonstrating my commitment to open-source.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Last but not the least I think that this is just the beginning. The world of open-source is boundless, and I am excited to continue my journey by contributing, learning, and collaborating on projects. I’m interested in exploring new technologies, refining my skills, and making a lasting impact in the open-source community.&lt;/p&gt;

&lt;p&gt;Ⓢⓗⓞⓦ ⓛⓞⓥⓔ💖 ⓐⓝⓓ ⓢⓤⓟⓟⓞⓡⓣ 🙌&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>newyearchallenge</category>
      <category>career</category>
      <category>devresolutions2024</category>
    </item>
    <item>
      <title>BLOCKCHAIN the emerging trend</title>
      <dc:creator>Dakshata </dc:creator>
      <pubDate>Sun, 05 Jan 2025 18:09:15 +0000</pubDate>
      <link>https://dev.to/thedakshata/blockchain-the-emerging-trend-2f1e</link>
      <guid>https://dev.to/thedakshata/blockchain-the-emerging-trend-2f1e</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/newyear"&gt;2025 New Year Writing challenge&lt;/a&gt;: Predicting 2025.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Blockchain?&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;“Bumble” are rewarded for making successful matches whether it’s dating to freelancing to Ola and Flipkart.&lt;/em&gt; &lt;br&gt;
In a simple language, Blockchain is secure digital Technology that creates an unchangeable record of transactions. The global blockchain technology market size was valued at USD 17.46 billion in 2023 and is expected to grow at a compound annual growth rate (CAGR) of 87.7% from 2023 to 2030. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Trend Analysis&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;It has got &lt;em&gt;Advance Privacy&lt;/em&gt; Feature which is the biggest concern in today's era.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Transparency&lt;/em&gt; which is the most important factor to grow at rapid pace.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Suitable Environment&lt;/em&gt; which made it easier to get accepted by countries like Switzerland and Singapore.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Easy Adoption&lt;/em&gt;, &lt;strong&gt;BaaS&lt;/strong&gt; (Blockchain-as-a-Service) enables companies to deploy blockchain Technology without complex infrastructure, easier to handle.&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Specific Tools&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Development Frameworks:-&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;1.Truffle Suite&lt;br&gt;
 2.Hardhat &lt;br&gt;
 3.Embark&lt;br&gt;
 4.Quorum&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Programming Languages:-&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;1.Solidity&lt;br&gt;
 2.Rust&lt;br&gt;
 3.Go&lt;br&gt;
 4.JavaScript &lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Companies that use this Technoloy are &lt;strong&gt;HSBC, VISA, SIEMENS, Walmart, EHIHAD Airways, British Airways&lt;/strong&gt; ...and many more.&lt;/p&gt;

&lt;p&gt;Show love💖 and support!!🙌   &lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>newyearchallenge</category>
      <category>future</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>Girl in Tech</title>
      <dc:creator>Dakshata </dc:creator>
      <pubDate>Thu, 02 Jan 2025 18:37:35 +0000</pubDate>
      <link>https://dev.to/thedakshata/girl-in-tech-40d0</link>
      <guid>https://dev.to/thedakshata/girl-in-tech-40d0</guid>
      <description>&lt;p&gt;&lt;code&gt;GIRL IN TECH&lt;/code&gt;&lt;br&gt;
Its Vibrant Community of Girl's 👧 who are passionate about Tech/STEM. Its not just about women in Tech, it's about women building Tech. &lt;br&gt;
&lt;strong&gt;Non-Profit Community for Girls who want to excel in their life.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We need diversity of experiences, Perspective, and stories to build a community. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It's important to ensure that the Technology being built serves each and every person.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To build it, is to ensure we have diversity within the coders creating that Technology. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Here what you can expect:-&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Support from Other girls from different part of India&lt;/li&gt;
&lt;li&gt;Internship/Jobs Alert.&lt;/li&gt;
&lt;li&gt;Guidance from Senior's.&lt;/li&gt;
&lt;li&gt;Monthly Coffee Chats.&lt;/li&gt;
&lt;li&gt;Text + Video Resources. &lt;/li&gt;
&lt;li&gt;Info about latest Events/Scholarships
.....and &lt;strong&gt;Much more&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Started back in June 2024 by Manik. Grown to a community of 1200+ girls. 1.2k Newsletter subscriber. Having Phenomenal results in GHC Scholarship, Codess Cafe.&lt;br&gt;
It's not just a community it's an Emotion where everyone connects and build network. &lt;/p&gt;

&lt;p&gt;Do Visit [&lt;a href="https://www.linkedin.com/company/girls-in-tech-community/posts/?feedView=all" rel="noopener noreferrer"&gt;https://www.linkedin.com/company/girls-in-tech-community/posts/?feedView=all&lt;/a&gt;]&lt;/p&gt;

&lt;p&gt;Show your Love💖 and Support🙌!!!&lt;/p&gt;

</description>
      <category>wecoded</category>
      <category>womenintech</category>
      <category>community</category>
    </item>
    <item>
      <title>Social Winter of Code 2025</title>
      <dc:creator>Dakshata </dc:creator>
      <pubDate>Thu, 05 Dec 2024 13:36:35 +0000</pubDate>
      <link>https://dev.to/thedakshata/social-winter-of-code-2025-3gjn</link>
      <guid>https://dev.to/thedakshata/social-winter-of-code-2025-3gjn</guid>
      <description>&lt;h2&gt;
  
  
  Here are the things you should know about SWOC-2025
&lt;/h2&gt;

&lt;h2&gt;
  
  
  What is SWOC?
&lt;/h2&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%2Fjj7t1x23n7tdkzyzvj3n.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjj7t1x23n7tdkzyzvj3n.jpeg" alt="Social Winter of Code" width="598" height="514"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Social Winter of Code is an open-source program Which aims to bring students into the world of open-source development and see the power of unified problem-solving in real time. Social Winter of Code is the 2 month long open-source program. Highly Preferred to those who are new into world of coding.
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why Should you participate?
&lt;/h2&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%2F1e91kg2fgr3dly64adv4.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1e91kg2fgr3dly64adv4.jpeg" alt="Participate" width="800" height="361"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You will be guided on various topics like Web &amp;amp; App development, Frontend/Backend, Web3, Blockchain, Artificial Intelligence, Machine Learning, Personal Branding. Moreover, there are many giveaways, you can also get Swags. You even get contributor Badge to showoff you peers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What Pre-Requisite Knowledge Required?
&lt;/h2&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%2Fvjtp9m1qwkqxk5sjfvlx.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%2Fvjtp9m1qwkqxk5sjfvlx.png" alt="Git Hub" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you can have basic Knowledge of Git and GitHub or Git Desktop that would be good. Like basic commands &lt;code&gt;git push&lt;/code&gt;, &lt;code&gt;git commit&lt;/code&gt;,&lt;code&gt;git pull&lt;/code&gt;,&lt;code&gt;git status&lt;/code&gt;. But no problem if you don't know. You will get to know about them in this programme.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Ways to Contribute?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;There are many ways to contribute to SWOC, and you don't need to be a coding wizard at all. In fact, there are several ways to participate that don’t involve coding at all.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Writing: Contribute by writing or improving documentation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Graphic Design: Create graphics, icons, and other visual elements that projects may need.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;In real open source, you have the right to control your own destiny. - Linus Torvalds&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I will encourage you to register and participate in this wonderful Open-source Programme ➡️&lt;a href="https://dev.tourl"&gt;https://socialwinterofcode.devfolio.co/?ref=8ecbd3b2f6&lt;/a&gt;&lt;br&gt;
You Can also join Discord Channel and ask your doubts to mentors, project admins➡️&lt;a href="https://dev.tourl"&gt;https://discord.gg/bAMqtfsX&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Keep Learning, Keep Growing❄️⛄💙!! Yes, don't forget to share with your friends. &lt;/p&gt;

</description>
      <category>opensource</category>
      <category>learning</category>
      <category>github</category>
      <category>coding</category>
    </item>
  </channel>
</rss>
