<?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: gxlbfc</title>
    <description>The latest articles on DEV Community by gxlbfc (@gxlbfc_d039fe229d0c50aa9e).</description>
    <link>https://dev.to/gxlbfc_d039fe229d0c50aa9e</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%2F3988567%2Fcc556ab2-c2ce-415c-bae9-1d3cb056b4dc.png</url>
      <title>DEV Community: gxlbfc</title>
      <link>https://dev.to/gxlbfc_d039fe229d0c50aa9e</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gxlbfc_d039fe229d0c50aa9e"/>
    <language>en</language>
    <item>
      <title>I Started Using an AI Closet Before Buying Clothes — Here’s What It Can and Can’t Tell You</title>
      <dc:creator>gxlbfc</dc:creator>
      <pubDate>Mon, 29 Jun 2026 08:45:00 +0000</pubDate>
      <link>https://dev.to/gxlbfc_d039fe229d0c50aa9e/i-started-using-an-ai-closet-before-buying-clothes-heres-what-it-can-and-cant-tell-you-55hf</link>
      <guid>https://dev.to/gxlbfc_d039fe229d0c50aa9e/i-started-using-an-ai-closet-before-buying-clothes-heres-what-it-can-and-cant-tell-you-55hf</guid>
      <description>&lt;p&gt;I used to shop in one of two ways:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;I saw an outfit on someone else and tried to recreate it.&lt;/li&gt;
&lt;li&gt;I found one item I liked and convinced myself I would somehow build outfits around it later.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Both methods produced the same result: a wardrobe full of individually nice pieces that did not always work together — or feel like me.&lt;/p&gt;

&lt;p&gt;So I added a step before buying anything:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I test the style direction with AI first.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not the exact size. Not the fabric quality. Not whether a particular pair of trousers will pinch at the waist.&lt;/p&gt;

&lt;p&gt;I use AI virtual try-on to answer a simpler question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Is this style worth exploring on me before I spend money on it?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That distinction matters, because AI can be surprisingly useful as a visual filter — and very misleading if you treat it like a fitting room.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aiclotheschanger.me/closet/fashion-lab" rel="noopener noreferrer"&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%2Fwj40fdakciqgi7mejiz7.webp" alt="A fashion closet with multiple style directions" width="800" height="1200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The shift: test a direction, not a product
&lt;/h2&gt;

&lt;p&gt;The biggest improvement came when I stopped asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Would this exact jacket look good on me?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;and started asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Do I actually like myself in this silhouette, palette, and level of formality?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The first question is difficult for AI. It requires accurate sizing, construction, material behavior, and product fidelity.&lt;/p&gt;

&lt;p&gt;The second question is much more realistic. It is about visual direction.&lt;/p&gt;

&lt;p&gt;For example, an “old money” look is not just one camel coat. It is a combination of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;restrained neutral colors&lt;/li&gt;
&lt;li&gt;clean tailoring&lt;/li&gt;
&lt;li&gt;longer, quieter silhouettes&lt;/li&gt;
&lt;li&gt;low-contrast accessories&lt;/li&gt;
&lt;li&gt;polished rather than trend-heavy styling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://aiclotheschanger.me/closet/fashion-lab/modern-aesthetics/old-money" rel="noopener noreferrer"&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%2F8erkv3wc41y9wdwgulpk.webp" alt="Old money outfit with camel coat, cream knit and pleated skirt" width="800" height="1200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If I like that complete direction on myself, I can shop more intelligently. I may not buy the exact AI-generated outfit, but I now know that camel, cream, soft knitwear, straight tailoring, and brown leather are useful signals.&lt;/p&gt;

&lt;p&gt;That is already more valuable than adding another random “nice top” to a cart.&lt;/p&gt;

&lt;h2&gt;
  
  
  My 10-minute pre-shopping test
&lt;/h2&gt;

&lt;p&gt;Here is the workflow I use.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Start with one neutral photo
&lt;/h3&gt;

&lt;p&gt;I use the same clear, front-facing photo for every test:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;natural standing pose&lt;/li&gt;
&lt;li&gt;arms not covering the torso&lt;/li&gt;
&lt;li&gt;even lighting&lt;/li&gt;
&lt;li&gt;most of the body visible&lt;/li&gt;
&lt;li&gt;no oversized coat hiding the original silhouette&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Keeping the person photo fixed is important. If the pose, camera angle, and lighting change every time, I end up comparing photographs instead of comparing clothes.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Test several clearly different style lanes
&lt;/h3&gt;

&lt;p&gt;I do not begin with ten versions of almost the same outfit. I choose directions that are far enough apart to teach me something.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;minimal casual&lt;/li&gt;
&lt;li&gt;denim casual&lt;/li&gt;
&lt;li&gt;polished office wear&lt;/li&gt;
&lt;li&gt;old money&lt;/li&gt;
&lt;li&gt;date night&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is not to crown one permanent personal aesthetic. Most people need more than one.&lt;/p&gt;

&lt;p&gt;The useful question is: &lt;strong&gt;Which directions feel natural, and which feel like a costume?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aiclotheschanger.me/closet/urban-streetwear/everyday-street/minimal-casual" rel="noopener noreferrer"&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%2Fd5hyjx3ll8av66p39hxx.webp" alt="Minimal casual outfit in soft neutral colors" width="800" height="1200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Look for repeated signals
&lt;/h3&gt;

&lt;p&gt;One AI image means very little. Repeated preferences are more useful.&lt;/p&gt;

&lt;p&gt;After several tests, I write down what keeps working:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do I prefer a defined waist or a straighter silhouette?&lt;/li&gt;
&lt;li&gt;Do warm neutrals suit the overall impression better than cool grey?&lt;/li&gt;
&lt;li&gt;Do I like sharp shoulders or softer layers?&lt;/li&gt;
&lt;li&gt;Do ankle-length trousers feel better than wide, floor-length shapes?&lt;/li&gt;
&lt;li&gt;Do high necklines make the look feel refined or restrictive?&lt;/li&gt;
&lt;li&gt;Do I consistently prefer low-contrast outfits?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These observations turn a vague reaction — “I like it” — into a shopping filter.&lt;/p&gt;

&lt;p&gt;Instead of searching for “cute work clothes,” I can look for:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;warm-neutral blazer, softly structured shoulder, single-breasted, hip length&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is a much better starting point.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Separate admiration from identification
&lt;/h3&gt;

&lt;p&gt;This was the most useful lesson.&lt;/p&gt;

&lt;p&gt;There are outfits I love looking at but do not want to wear.&lt;/p&gt;

&lt;p&gt;AI makes that difference obvious because it moves the outfit from a model, mood board, or product page onto something closer to my own visual context.&lt;/p&gt;

&lt;p&gt;Sometimes the reaction is immediate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“Beautiful, but not me.”&lt;/li&gt;
&lt;li&gt;“I like the color, not the silhouette.”&lt;/li&gt;
&lt;li&gt;“This works only because of the styling.”&lt;/li&gt;
&lt;li&gt;“I would wear this if the jacket were shorter.”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is not a failed result. That is the result.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aiclotheschanger.me/closet/career-professional/smart-casual/office-lady" rel="noopener noreferrer"&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%2Fr0l6vitp5xmi7zrf42o6.webp" alt="Polished office outfit in cream and blush neutrals" width="800" height="1200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What AI can tell you
&lt;/h2&gt;

&lt;p&gt;Used carefully, AI virtual try-on can help with four things.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Whether a color direction is worth testing in real life
&lt;/h3&gt;

&lt;p&gt;It can give a rough sense of whether an outfit feels harmonious, heavy, washed out, too severe, or surprisingly balanced.&lt;/p&gt;

&lt;p&gt;This is not professional color analysis. Screens, lighting, image processing, and the model itself can all shift colors.&lt;/p&gt;

&lt;p&gt;But it can tell me whether “more warm beige” is a promising direction before I order four beige items.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Whether a silhouette feels like you
&lt;/h3&gt;

&lt;p&gt;AI is useful for comparing broad shapes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;cropped versus long outerwear&lt;/li&gt;
&lt;li&gt;fitted versus relaxed&lt;/li&gt;
&lt;li&gt;structured versus draped&lt;/li&gt;
&lt;li&gt;high-waisted versus low-rise&lt;/li&gt;
&lt;li&gt;minimal versus heavily layered&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Again, it is directional. It does not know the actual garment measurements or how the fabric behaves on your body.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Whether a style works with your existing identity
&lt;/h3&gt;

&lt;p&gt;Clothing is not only about body shape. Hair, posture, personal energy, work environment, and how formal you like to feel all matter.&lt;/p&gt;

&lt;p&gt;Seeing yourself near a style can expose whether you enjoy wearing it or only enjoy the idea of it.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. What is missing from your wardrobe
&lt;/h3&gt;

&lt;p&gt;If several successful looks depend on the same type of item — perhaps a cream blazer, straight-leg denim, or a simple dark evening dress — that repeated item may be a genuine wardrobe gap.&lt;/p&gt;

&lt;p&gt;That is much more actionable than buying whatever happens to be trending.&lt;/p&gt;

&lt;h2&gt;
  
  
  What AI cannot tell you
&lt;/h2&gt;

&lt;p&gt;This is the part every virtual try-on article should include.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Your correct size
&lt;/h3&gt;

&lt;p&gt;A generated image is not a measurement tool. It cannot reliably tell you whether a real garment will button, pull, gap, or need tailoring.&lt;/p&gt;

&lt;p&gt;Always use the retailer’s measurements, garment dimensions, reviews, and return policy.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Fabric quality
&lt;/h3&gt;

&lt;p&gt;AI can render beautiful wool, silk, denim, or linen. That says nothing about the item arriving at your door.&lt;/p&gt;

&lt;p&gt;It cannot detect thin lining, scratchy knitwear, weak seams, cheap hardware, or fabric that becomes transparent in daylight.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Real drape and movement
&lt;/h3&gt;

&lt;p&gt;A still image cannot tell you what happens when you sit, walk, lift your arms, or wear the garment for six hours.&lt;/p&gt;

&lt;p&gt;This is especially important for fitted dresses, trousers, occasion wear, and anything made from stiff or very light fabric.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Exact color
&lt;/h3&gt;

&lt;p&gt;Product photography is already affected by lighting and editing. AI adds another interpretation layer.&lt;/p&gt;

&lt;p&gt;Treat color as a family — warm cream, muted blue, deep burgundy — rather than an exact match.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Whether the real item is well made
&lt;/h3&gt;

&lt;p&gt;AI can help decide whether a design direction makes sense. It cannot inspect construction.&lt;/p&gt;

&lt;p&gt;That still requires product details, close-up photos, material composition, customer reviews, and sometimes seeing the item in person.&lt;/p&gt;

&lt;h2&gt;
  
  
  The buying checklist I use now
&lt;/h2&gt;

&lt;p&gt;Before purchasing, I separate the decision into two passes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pass 1: visual direction
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Does the color family work?&lt;/li&gt;
&lt;li&gt;Does the overall silhouette feel natural on me?&lt;/li&gt;
&lt;li&gt;Can I name at least three occasions where I would wear it?&lt;/li&gt;
&lt;li&gt;Does it work with pieces I already own?&lt;/li&gt;
&lt;li&gt;Am I attracted to the outfit, or only to the model and photography?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI can help here.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pass 2: physical reality
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Are the garment measurements right?&lt;/li&gt;
&lt;li&gt;Is the fabric appropriate for the season and use?&lt;/li&gt;
&lt;li&gt;Do reviews mention shrinking, pilling, transparency, or poor construction?&lt;/li&gt;
&lt;li&gt;Can I move comfortably in this cut?&lt;/li&gt;
&lt;li&gt;Is the return policy reasonable?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI cannot answer these questions.&lt;/p&gt;

&lt;p&gt;I only buy when both passes make sense.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the AI closet fits
&lt;/h2&gt;

&lt;p&gt;I built &lt;a href="https://aiclotheschanger.me/" rel="noopener noreferrer"&gt;Dressora&lt;/a&gt; around this style-first workflow.&lt;/p&gt;

&lt;p&gt;Instead of requiring people to find and upload a clothing image for every experiment, the &lt;a href="https://aiclotheschanger.me/closet/gallery" rel="noopener noreferrer"&gt;AI Closet&lt;/a&gt; includes ready-made directions such as minimal casual, office wear, old money, Y2K, denim, date-night looks, wedding outfits, Hanfu, streetwear, and fantasy styles.&lt;/p&gt;

&lt;p&gt;You can start broad, notice what works, and then narrow down.&lt;/p&gt;

&lt;p&gt;For a specific garment you found elsewhere, you can switch to the &lt;a href="https://aiclotheschanger.me/ai-clothes-changer" rel="noopener noreferrer"&gt;AI clothes changer&lt;/a&gt; and upload your own outfit reference.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aiclotheschanger.me/closet/occasions/special-moments/date-night" rel="noopener noreferrer"&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%2Fs7zyc9pqhakscpdgbumv.webp" alt="Burgundy date-night dress with a cream blazer" width="800" height="1200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The important part is not generating the most impressive picture.&lt;/p&gt;

&lt;p&gt;It is reducing uncertainty before spending money.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thought
&lt;/h2&gt;

&lt;p&gt;AI virtual try-on did not replace shopping for me. It inserted a useful pause before shopping.&lt;/p&gt;

&lt;p&gt;It helps me move from:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“That outfit looks great.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;to:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“I like the warm palette and long outer layer, but I need a straighter skirt and a less formal shoe.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is a better question to take into a store, a product page, or a tailor.&lt;/p&gt;

&lt;p&gt;Use AI to explore style, eliminate weak ideas, and build a more specific shopping list.&lt;/p&gt;

&lt;p&gt;Then use measurements, materials, reviews, and real-world try-on to make the final decision.&lt;/p&gt;

&lt;p&gt;That is the boundary where AI becomes genuinely helpful — without pretending it knows more than it does.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Building an AI Clothes Changer: provider abstraction, async jobs, and a credit system that won't lose money</title>
      <dc:creator>gxlbfc</dc:creator>
      <pubDate>Wed, 17 Jun 2026 08:16:53 +0000</pubDate>
      <link>https://dev.to/gxlbfc_d039fe229d0c50aa9e/building-an-ai-clothes-changer-provider-abstraction-async-jobs-and-a-credit-system-that-wont-2cc1</link>
      <guid>https://dev.to/gxlbfc_d039fe229d0c50aa9e/building-an-ai-clothes-changer-provider-abstraction-async-jobs-and-a-credit-system-that-wont-2cc1</guid>
      <description>&lt;p&gt;I recently launched &lt;a href="https://aiclotheschanger.me/" rel="noopener noreferrer"&gt;Dressora&lt;/a&gt;, an AI clothes changer that swaps outfits onto a single photo for virtual try-on. The product side is fun, but the parts I actually sweated over were the boring backend bits: orchestrating multiple AI providers, handling long-running generation jobs, and building a credit system that never double-charges or loses money. Here's what I learned.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Next.js 15&lt;/strong&gt; (App Router) + React 19 + TypeScript&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PostgreSQL + Drizzle ORM&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloudflare R2&lt;/strong&gt; for media storage&lt;/li&gt;
&lt;li&gt;Multiple AI image/video providers behind one interface&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  1. Don't marry a single AI provider
&lt;/h2&gt;

&lt;p&gt;AI providers change pricing, rate limits, and quality constantly. Hardcoding one is a trap. I put everything behind a small factory:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getProvider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;evolink&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;task&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;provider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createTask&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;aspectRatio&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each provider implements the same interface (&lt;code&gt;createTask&lt;/code&gt;, &lt;code&gt;handleCallback&lt;/code&gt;, status mapping). Swapping or adding a provider is a new file, not a refactor. When one provider had an outage, switching the default was a one-line env change.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Generation is async — embrace callbacks
&lt;/h2&gt;

&lt;p&gt;AI generation takes 10s–minutes. Blocking a request is a non-starter. The flow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;generate()&lt;/code&gt; — create a DB record, &lt;strong&gt;freeze credits&lt;/strong&gt;, call the provider with a callback URL&lt;/li&gt;
&lt;li&gt;Provider processes and hits my webhook when done&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;handleCallback()&lt;/code&gt; — download the result, re-upload to R2, mark complete, &lt;strong&gt;settle credits&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The frontend just polls a lightweight status endpoint. The webhook is the source of truth.&lt;/p&gt;

&lt;p&gt;A gotcha: &lt;strong&gt;always re-upload the provider's output to your own storage.&lt;/strong&gt; Provider URLs expire. Downloading and pushing to R2 on completion saved me from dead links later.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. The credit system was the hardest part
&lt;/h2&gt;

&lt;p&gt;Money + concurrency + async failures = the scariest combination. The pattern that worked: &lt;strong&gt;freeze → settle / release.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On request: &lt;code&gt;freeze(credits)&lt;/code&gt; — move credits to a "held" state&lt;/li&gt;
&lt;li&gt;On success: &lt;code&gt;settle()&lt;/code&gt; — actually consume them&lt;/li&gt;
&lt;li&gt;On failure/timeout: &lt;code&gt;release()&lt;/code&gt; — give them back
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;freeze  -&amp;gt; hold created, balance reserved
settle  -&amp;gt; hold consumed (success)
release -&amp;gt; hold returned (failure)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way a failed generation never costs the user, and a user can't fire 10 concurrent jobs with credits for one. I also did &lt;strong&gt;FIFO consumption across credit packages&lt;/strong&gt; so credits with the nearest expiry get used first — fairer for users and simpler for accounting.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Lessons
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Put external dependencies behind interfaces &lt;em&gt;before&lt;/em&gt; you think you need to.&lt;/li&gt;
&lt;li&gt;For async jobs, design the failure path first (release credits, retry, timeout) — the happy path is easy.&lt;/li&gt;
&lt;li&gt;Re-host anything an external API generates.&lt;/li&gt;
&lt;li&gt;A "frozen" intermediate state for credits/money is worth the extra table.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want to see the end result, it's live at &lt;a href="https://aiclotheschanger.me/" rel="noopener noreferrer"&gt;aiclotheschanger.me&lt;/a&gt;. Happy to answer questions about the architecture in the comments.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>architecture</category>
      <category>saas</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
