<?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: Junzi Xu</title>
    <description>The latest articles on DEV Community by Junzi Xu (@junzi2026).</description>
    <link>https://dev.to/junzi2026</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%2F4148431%2F7aec8e61-21e6-41ba-8e1b-efdff331b954.png</url>
      <title>DEV Community: Junzi Xu</title>
      <link>https://dev.to/junzi2026</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/junzi2026"/>
    <language>en</language>
    <item>
      <title>An observed coupon is not a verified coupon: auditing timestamps and CSV exports in Python</title>
      <dc:creator>Junzi Xu</dc:creator>
      <pubDate>Tue, 29 Sep 2026 03:32:12 +0000</pubDate>
      <link>https://dev.to/junzi2026/an-observed-coupon-is-not-a-verified-coupon-auditing-timestamps-and-csv-exports-in-python-5hm</link>
      <guid>https://dev.to/junzi2026/an-observed-coupon-is-not-a-verified-coupon-auditing-timestamps-and-csv-exports-in-python-5hm</guid>
      <description>&lt;p&gt;&lt;em&gt;Disclosure: This article and the accompanying code were prepared with AI assistance. The described tests were run locally; coupon redemption was not tested.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A discount page can remain online after its campaign ends. A source observation therefore needs its own timestamp, independently from any stated expiry. Missing expiry must stay unknown, rather than becoming a promise of indefinite validity.&lt;/p&gt;

&lt;h2&gt;
  
  
  A small offline audit
&lt;/h2&gt;

&lt;p&gt;The example project is &lt;a href="https://github.com/junzigo/esim-offer-audit-kit" rel="noopener noreferrer"&gt;eSIM Offer Audit Kit&lt;/a&gt;. Its dated historical fixture comes from my &lt;a href="https://getesimdeals.com/" rel="noopener noreferrer"&gt;eSIM deals website&lt;/a&gt;. It contains no customer accounts or activation QR codes. The fixture is an example, not a list of currently valid coupons.&lt;/p&gt;

&lt;p&gt;After downloading the repository, run these commands from its directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; unittest &lt;span class="nt"&gt;-v&lt;/span&gt;
python audit.py observations.json &lt;span class="nt"&gt;--csv&lt;/span&gt; audit.csv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The CLI uses Python's standard library and performs no network calls. Each output row preserves a source URL and collection time and adds review flags.&lt;/p&gt;

&lt;h2&gt;
  
  
  Observation age and offer expiry are different
&lt;/h2&gt;

&lt;p&gt;Age in hours is calculated as:&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;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nf"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;offer&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;fetched_at&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])).&lt;/span&gt;&lt;span class="nf"&gt;total_seconds&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;3600&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A negative age is a clock or data problem, not a fresh record. The configurable 30-hour default is an editorial recheck policy, not the provider's validity period. Timezone-free timestamps are rejected to avoid silently interpreting them as local time.&lt;/p&gt;

&lt;p&gt;The flags distinguish several cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;future_timestamp&lt;/code&gt;: collection time is later than the audit time.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;stale_observation&lt;/code&gt;: the observation exceeds the configured review interval.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;expiry_unknown&lt;/code&gt;: no explicit expiry is recorded.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;expired&lt;/code&gt;: a recorded expiry is at or before the audit time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unknown expiry stays a review flag. It never becomes evidence that an offer lasts forever.&lt;/p&gt;

&lt;h2&gt;
  
  
  CSV quoting is not formula protection
&lt;/h2&gt;

&lt;p&gt;Another boundary is spreadsheets. CSV quoting alone does not stop a formula from being evaluated when someone opens a file. The exporter prefixes an apostrophe when text begins with &lt;code&gt;=&lt;/code&gt;, &lt;code&gt;+&lt;/code&gt;, &lt;code&gt;-&lt;/code&gt; or &lt;code&gt;@&lt;/code&gt;, including when those characters are preceded by whitespace:&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;csv_safe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;value&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="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"'"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lstrip&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;startswith&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;=&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;+&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;-&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;@&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a defensive export step, not a guarantee across every spreadsheet application's import settings. Inspect imports as text when handling untrusted data.&lt;/p&gt;

&lt;p&gt;The regression tests exercise formula-prefix handling alongside stale observations, malformed source URL shapes, explicit expiry and missing expiry.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this audit cannot prove
&lt;/h2&gt;

&lt;p&gt;The output deliberately has no "verified coupon" column. HTTPS URL syntax does not prove domain ownership, a percentage does not establish a comparable final price, and a downloaded source hash does not establish a successful checkout.&lt;/p&gt;

&lt;p&gt;Manual review still needs plan eligibility, destination, device compatibility, subscription terms and final payment. An automated check should identify what needs review without claiming evidence it never collected.&lt;/p&gt;

</description>
      <category>python</category>
    </item>
  </channel>
</rss>
