<?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: Zhuang Hua</title>
    <description>The latest articles on DEV Community by Zhuang Hua (@zhuanghua).</description>
    <link>https://dev.to/zhuanghua</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%2F4212047%2Fc29156ea-b5bb-471c-85d0-fec74f832005.png</url>
      <title>DEV Community: Zhuang Hua</title>
      <link>https://dev.to/zhuanghua</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/zhuanghua"/>
    <language>en</language>
    <item>
      <title>Overlays Are Not Accessibility, and Scanners Are Not Compliance Certificates</title>
      <dc:creator>Zhuang Hua</dc:creator>
      <pubDate>Sat, 31 Oct 2026 05:19:24 +0000</pubDate>
      <link>https://dev.to/zhuanghua/overlays-are-not-accessibility-and-scanners-are-not-compliance-certificates-11a6</link>
      <guid>https://dev.to/zhuanghua/overlays-are-not-accessibility-and-scanners-are-not-compliance-certificates-11a6</guid>
      <description>&lt;p&gt;Disclosure: I'm the indie maker of A11yKeeper, so this is a soft promo, but the point stands without it.&lt;/p&gt;

&lt;p&gt;If you build sites for clients, you've probably been asked: "Can we just add that accessibility widget and be done?" Short answer: no. Overlays are not accessibility. They patch the surface, can clash with screen readers, and don't fix the underlying markup, keyboard flow, or content problems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scanners are not certificates
&lt;/h2&gt;

&lt;p&gt;Automated checks are genuinely useful, but they catch only part of WCAG. Many criteria (meaningful alt text, logical focus order, clear error messages, cognitive load) need a human to judge. So a clean scan result does &lt;strong&gt;not&lt;/strong&gt; certify anyone as ADA compliant, and no automated tool can honestly say a site is "compliant". Be wary of anyone who claims otherwise.&lt;/p&gt;

&lt;h2&gt;
  
  
  What agencies actually need for client reports
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A clear list of detected issues mapped to WCAG success criteria&lt;/li&gt;
&lt;li&gt;Severity and where on the page each issue lives&lt;/li&gt;
&lt;li&gt;Honest wording: "automated findings" plus a manual review checklist, not a compliance badge&lt;/li&gt;
&lt;li&gt;Progress over time, so clients see fixes landing&lt;/li&gt;
&lt;li&gt;Reports that carry your agency's branding, not someone else's&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Where A11yKeeper fits
&lt;/h2&gt;

&lt;p&gt;I built A11yKeeper as a small, honest scanning tool for agencies: white-label WCAG 2.2 scans you can hand to clients, with plain-language reports. It's a starting point for the audit conversation, not a replacement for manual testing. There's a founding agency offer at 50% off if you want to try it: &lt;a href="https://a11ykeeper.com" rel="noopener noreferrer"&gt;https://a11ykeeper.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Whatever tools you use, be upfront with clients about what automation can and can't tell them. Thanks for reading!&lt;/p&gt;

</description>
      <category>a11y</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Why per-seat e-signature pricing is expensive for small teams (and an envelope-based alternative)</title>
      <dc:creator>Zhuang Hua</dc:creator>
      <pubDate>Sat, 31 Oct 2026 05:18:20 +0000</pubDate>
      <link>https://dev.to/zhuanghua/why-per-seat-e-signature-pricing-is-expensive-for-small-teams-and-an-envelope-based-alternative-bic</link>
      <guid>https://dev.to/zhuanghua/why-per-seat-e-signature-pricing-is-expensive-for-small-teams-and-an-envelope-based-alternative-bic</guid>
      <description>&lt;p&gt;I build small tools, and one thing that kept bugging me was how e-signature pricing is shaped. Most of it is per seat, which makes sense for a 500-person sales org and much less for a 4-person team that sends a handful of contracts a month.&lt;/p&gt;

&lt;h2&gt;
  
  
  The per-seat problem
&lt;/h2&gt;

&lt;p&gt;Say you're a small agency or a freelancer collective. Maybe one person sends most documents, and others occasionally need to. With per-seat pricing you either pay for everyone who &lt;em&gt;might&lt;/em&gt; send, or you share a login (which usually breaks the terms).&lt;/p&gt;

&lt;p&gt;For reference, as of Oct 31, 2026, DocuSign's published annual-billing plans are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Standard: $30 per user per month&lt;/li&gt;
&lt;li&gt;Business Pro: $45 per user per month&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a team of 5 on Standard, that's $150/month, whether you send 2 documents or 200.&lt;/p&gt;

&lt;h2&gt;
  
  
  The envelope-pricing alternative
&lt;/h2&gt;

&lt;p&gt;The other model is paying for what you actually send. That's what I went with when building FairSign:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;About $0.30 per envelope&lt;/li&gt;
&lt;li&gt;5 free envelopes to try it&lt;/li&gt;
&lt;li&gt;Up to 10 signers per envelope&lt;/li&gt;
&lt;li&gt;No seat license, so your whole team can send without extra per-user cost&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you send 20 envelopes in a month, that's roughly $6. Quiet month, tiny bill. Busy month, it scales with you.&lt;/p&gt;

&lt;h2&gt;
  
  
  When per-seat still wins
&lt;/h2&gt;

&lt;p&gt;To be fair: if you send thousands of documents, need deep integrations, or have heavy compliance and workflow needs, a bigger platform may be worth it. Envelope pricing suits low-to-moderate volume and small teams best.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaway
&lt;/h2&gt;

&lt;p&gt;Before you commit to an annual per-seat plan, count how many documents you really send and how many people really send them. The math is sometimes surprising.&lt;/p&gt;

&lt;p&gt;If you want to try the envelope model, FairSign is at &lt;a href="https://fairsign.ai" rel="noopener noreferrer"&gt;https://fairsign.ai&lt;/a&gt;. Five free envelopes, no card games. I'd love feedback from other indie folks.&lt;/p&gt;

</description>
      <category>saas</category>
      <category>startup</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How to schedule Shopify sale prices so they actually end on time (without leaving variants discounted)</title>
      <dc:creator>Zhuang Hua</dc:creator>
      <pubDate>Sat, 31 Oct 2026 02:37:24 +0000</pubDate>
      <link>https://dev.to/zhuanghua/how-to-schedule-shopify-sale-prices-so-they-actually-end-on-time-without-leaving-variants-4d</link>
      <guid>https://dev.to/zhuanghua/how-to-schedule-shopify-sale-prices-so-they-actually-end-on-time-without-leaving-variants-4d</guid>
      <description>&lt;p&gt;I build a small Shopify app, and the problem I hear about most isn't "how do I start a sale." It's "why is my sale still running on Tuesday?"&lt;/p&gt;

&lt;p&gt;Starting a sale is easy. Ending it cleanly — across every product, every variant, with the original prices restored exactly — is where things go sideways. This post covers why that happens and a checklist you can use whether or not you ever use a tool for it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem: sales are easy to start, hard to end
&lt;/h2&gt;

&lt;p&gt;On Shopify, a "sale price" is usually just two fields on each variant:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Price&lt;/strong&gt; — what the customer pays&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compare-at price&lt;/strong&gt; — the crossed-out "was" price&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To run a sale, you lower &lt;code&gt;price&lt;/code&gt; and set &lt;code&gt;compare-at&lt;/code&gt; to the old price. To end it, you reverse that. Simple on one product. Messy on fifty products with sizes and colors.&lt;/p&gt;

&lt;p&gt;Here's what tends to go wrong:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Hand edits don't scale to variants
&lt;/h3&gt;

&lt;p&gt;A T-shirt with 4 sizes × 3 colors is 12 variants. Editing the product-level view and forgetting that one variant has a different price is very easy. Bulk editor helps, but it's still manual, and manual means someone has to be awake and at a laptop when the sale ends.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Stuck sale prices
&lt;/h3&gt;

&lt;p&gt;The sale was supposed to end Sunday at midnight. Nobody remembered, or someone reverted &lt;em&gt;most&lt;/em&gt; of the products. Now a handful of variants are still discounted days later — and you often find out from a customer, or from your margin report.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Lost compare-at prices
&lt;/h3&gt;

&lt;p&gt;This one hurts more quietly. If you overwrite &lt;code&gt;compare-at&lt;/code&gt; during the sale and don't record what it was before, you can't restore it accurately. Some products had a permanent compare-at (e.g., an MSRP) before your sale even started. Wipe that out and your "normal" listing looks different after the sale than it did before.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Time zones and "midnight"
&lt;/h3&gt;

&lt;p&gt;"Ends at midnight" — whose midnight? Your store's time zone, your own, or your customers'? If you announced a time in an email, the prices should change at that time in the zone you announced.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Overlapping sales
&lt;/h3&gt;

&lt;p&gt;A product in both the "Black Friday" collection and a "Clearance" sale. Which price wins? What gets restored when one ends but the other hasn't?&lt;/p&gt;

&lt;h2&gt;
  
  
  A checklist for timed Shopify sales
&lt;/h2&gt;

&lt;p&gt;Use this before, during, and after any sale.&lt;/p&gt;

&lt;h3&gt;
  
  
  Before the sale
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] &lt;strong&gt;Export a snapshot&lt;/strong&gt; of current &lt;code&gt;price&lt;/code&gt; and &lt;code&gt;compare-at&lt;/code&gt; for every variant in scope (CSV export from Products works). This is your undo button.&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;List the scope explicitly&lt;/strong&gt;: which products, which collections, and whether &lt;em&gt;all&lt;/em&gt; variants are included.&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;Note existing compare-at values.&lt;/strong&gt; Decide whether the sale should overwrite them or leave them alone.&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;Write down start and end times with a time zone.&lt;/strong&gt; Match your store's time zone setting (Settings → General).&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;Check for overlaps&lt;/strong&gt; with other running or scheduled sales.&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;Decide on rounding&lt;/strong&gt; (e.g., 20% off then round to .99) so prices don't land on odd numbers like $23.47.&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;Line up marketing&lt;/strong&gt; (emails, banners, social posts) with the exact same end time.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  When the sale starts
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Spot-check a few products &lt;strong&gt;at the variant level&lt;/strong&gt;, not just the product overview.&lt;/li&gt;
&lt;li&gt;[ ] Check the storefront in a private window — the theme should show the crossed-out compare-at price.&lt;/li&gt;
&lt;li&gt;[ ] Confirm the collection or discount banner points to the right products.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  When the sale ends
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Restore prices from your snapshot — &lt;strong&gt;every variant&lt;/strong&gt;, not just the default.&lt;/li&gt;
&lt;li&gt;[ ] Restore the original compare-at values (including ones that existed before the sale).&lt;/li&gt;
&lt;li&gt;[ ] Remove sale banners, badges, and announcement bars.&lt;/li&gt;
&lt;li&gt;[ ] Spot-check again: search the admin for products with a compare-at higher than price that &lt;em&gt;shouldn't&lt;/em&gt; have one.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  After the sale
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Keep the snapshot file for a while in case something surfaces later.&lt;/li&gt;
&lt;li&gt;[ ] Write down what went wrong so the next sale has fewer surprises.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Automate the boring, risky part
&lt;/h2&gt;

&lt;p&gt;You can do all of the above by hand. Lots of merchants do. But the riskiest step — reverting every variant at an exact time — is also the most boring one, and that's exactly the kind of thing that's worth automating.&lt;/p&gt;

&lt;p&gt;That's why I built &lt;strong&gt;SaleGuard&lt;/strong&gt;. It lets you schedule a sale with a start and end time, applies prices across the variants you pick, saves the original price and compare-at values, and restores them when the sale ends. The goal is simple: the sale ends when you said it would, and your catalog goes back to exactly how it was.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🛍️ Shopify App Store: &lt;a href="https://apps.shopify.com/saleguard-flash-sale-editor" rel="noopener noreferrer"&gt;https://apps.shopify.com/saleguard-flash-sale-editor&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🌐 Website: &lt;a href="https://getsaleguard.com" rel="noopener noreferrer"&gt;https://getsaleguard.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;▶️ Short demo: &lt;a href="https://youtu.be/8PM7dKO3Lq4" rel="noopener noreferrer"&gt;https://youtu.be/8PM7dKO3Lq4&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;No pressure — even if you never install anything, steal the checklist. The "export a snapshot first" habit alone will save you a bad Monday.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;Timed sales fail at the edges: the forgotten variant, the overwritten compare-at, the midnight nobody agreed on. Make a snapshot, be explicit about scope and time zone, verify at the variant level, and restore from your snapshot instead of from memory.&lt;/p&gt;

&lt;p&gt;If you run Shopify sales and have a horror story (or a better process), I'd genuinely love to hear it in the comments — it directly shapes what I build next.&lt;/p&gt;

</description>
      <category>shopify</category>
      <category>ecommerce</category>
      <category>indiehackers</category>
      <category>startup</category>
    </item>
    <item>
      <title>What does an e-signature actually cost? Why I built FairSign to charge at cost</title>
      <dc:creator>Zhuang Hua</dc:creator>
      <pubDate>Fri, 30 Oct 2026 23:03:37 +0000</pubDate>
      <link>https://dev.to/zhuanghua/what-does-an-e-signature-actually-cost-why-i-built-fairsign-to-charge-at-cost-5ce6</link>
      <guid>https://dev.to/zhuanghua/what-does-an-e-signature-actually-cost-why-i-built-fairsign-to-charge-at-cost-5ce6</guid>
      <description>&lt;p&gt;If you send a handful of contracts a month, seat-based e-signature plans can work out to &lt;strong&gt;several dollars per signature&lt;/strong&gt;. The actual cost of an envelope (storage, email delivery, audit trail, PDF processing) is far lower.&lt;/p&gt;

&lt;h2&gt;
  
  
  What goes into one envelope
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Storing the PDF and the signed copy&lt;/li&gt;
&lt;li&gt;Sending emails to each signer&lt;/li&gt;
&lt;li&gt;Recording an audit trail (who signed, when, from where)&lt;/li&gt;
&lt;li&gt;Producing the final signed PDF and completion certificate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of these needs a per-seat subscription at small volume.&lt;/p&gt;

&lt;h2&gt;
  
  
  How FairSign prices it
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;FairSign&lt;/strong&gt; (&lt;a href="https://fairsign.ai" rel="noopener noreferrer"&gt;https://fairsign.ai&lt;/a&gt;) charges at cost:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;5 envelopes free&lt;/strong&gt;, then &lt;strong&gt;about $0.30 per envelope&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Up to 10 signers&lt;/strong&gt; per envelope&lt;/li&gt;
&lt;li&gt;No seats or bundles. Each envelope comes with a &lt;strong&gt;receipt that shows what it cost&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Upload a PDF, place the signature fields, add signers, send. It works in the browser today.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Send your first envelope free:&lt;/strong&gt; &lt;a href="https://fairsign.ai/documents" rel="noopener noreferrer"&gt;https://fairsign.ai/documents&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Comparing it with DocuSign or another tool? Tell me in the comments what you'd need to switch. It shapes what I build next.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Side note: we're also testing a Google Forms → PDF add-on. If that's useful to you, there's an optional waitlist at forms.usefairsign.com.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>saas</category>
      <category>productivity</category>
      <category>startup</category>
      <category>webdev</category>
    </item>
    <item>
      <title>I built a Shopify app that restores sale prices on time (before BFCM)</title>
      <dc:creator>Zhuang Hua</dc:creator>
      <pubDate>Fri, 30 Oct 2026 22:51:19 +0000</pubDate>
      <link>https://dev.to/zhuanghua/i-built-a-shopify-app-that-restores-sale-prices-on-time-before-bfcm-1pim</link>
      <guid>https://dev.to/zhuanghua/i-built-a-shopify-app-that-restores-sale-prices-on-time-before-bfcm-1pim</guid>
      <description>&lt;p&gt;BFCM is when sale prices get stuck.&lt;/p&gt;

&lt;p&gt;I built &lt;strong&gt;SaleGuard&lt;/strong&gt; for Shopify merchants who schedule sales by the minute: it snapshots every original price and compare-at price first, changes the real product price for the sale window, then restores and checks each variant when the sale ends. Prices you edit by hand mid-sale are kept and listed in the report.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Free plan includes snapshot + restore&lt;/li&gt;
&lt;li&gt;Starter $9.99/mo · Pro $19.99/mo (Shopify Billing)&lt;/li&gt;
&lt;li&gt;Only 2 permissions; no customer data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Install on Shopify:&lt;br&gt;
&lt;a href="https://apps.shopify.com/saleguard-flash-sale-editor" rel="noopener noreferrer"&gt;https://apps.shopify.com/saleguard-flash-sale-editor&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Site / demo: &lt;a href="https://getsaleguard.com" rel="noopener noreferrer"&gt;https://getsaleguard.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'm an independent developer (not affiliated with Shopify). Feedback welcome — especially if you've been burned by a sale that didn't end cleanly.&lt;/p&gt;

</description>
      <category>shopify</category>
      <category>ecommerce</category>
      <category>saas</category>
      <category>webdev</category>
    </item>
    <item>
      <title>I built a free WCAG 2.2 checker that's honest about what automated scans miss</title>
      <dc:creator>Zhuang Hua</dc:creator>
      <pubDate>Wed, 28 Oct 2026 06:33:18 +0000</pubDate>
      <link>https://dev.to/zhuanghua/i-built-a-free-wcag-22-checker-thats-honest-about-what-automated-scans-miss-3740</link>
      <guid>https://dev.to/zhuanghua/i-built-a-free-wcag-22-checker-thats-honest-about-what-automated-scans-miss-3740</guid>
      <description>&lt;p&gt;Agencies get asked "is our site accessible?" all the time. Most answers are either vague ("we follow WCAG") or a five-figure manual audit.&lt;/p&gt;

&lt;p&gt;I built something in between: &lt;strong&gt;&lt;a href="https://a11ykeeper.com" rel="noopener noreferrer"&gt;A11yKeeper&lt;/a&gt;&lt;/strong&gt; — paste a URL, it runs axe-core across that page plus up to 9 linked pages (~1 min), groups issues by severity, and gives a plain-English fix for each.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I tried to get right
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;It says clearly that a clean scan ≠ accessible. Deque's 2021 data puts automated detection at ~57% of issues by volume; every report ends with what a human still has to check (keyboard, screen reader, content).&lt;/li&gt;
&lt;li&gt;No overlay, nothing injected into your site.&lt;/li&gt;
&lt;li&gt;3 free scans/day, no signup to see results.&lt;/li&gt;
&lt;li&gt;Agencies can put their own name on a white-label PDF for clients.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On the W3C's deliberately broken demo site it found &lt;strong&gt;353 issues across 10 pages&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Founding agencies
&lt;/h2&gt;

&lt;p&gt;I'm looking for 5 founding agencies to shape scheduled re-checks and read-only client links — &lt;strong&gt;50% off for as long as they stay subscribed&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Would love feedback on false positives or confusing fix text: &lt;a href="https://a11ykeeper.com" rel="noopener noreferrer"&gt;https://a11ykeeper.com&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Independent developer. Not a compliance certificate — a triage list.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>a11y</category>
      <category>buildinpublic</category>
      <category>tools</category>
    </item>
  </channel>
</rss>
