Skip to content

Instantly share code, notes, and snippets.

@esz135888
Last active May 24, 2026 02:56
Show Gist options
  • Select an option

  • Save esz135888/7c34244a063544d7ecdf8926d0f9ba56 to your computer and use it in GitHub Desktop.

Select an option

Save esz135888/7c34244a063544d7ecdf8926d0f9ba56 to your computer and use it in GitHub Desktop.
PLS Kolable noon coupon expiry production pack

Acceptance Tests

Production Acceptance

  1. Noon cleanup deletes expired codes.

    • Given a coupon with valid_until < today 12:00 Asia/Taipei
    • When the noon worker runs
    • Then the code status becomes deleted, deleted_at is set, and audit event exists.
  2. Checkout rejects deleted codes.

    • Given a code deleted by cleanup
    • When a customer enters it at checkout
    • Then validation returns not_found_or_expired and no discount is applied.
  3. Blocklist protects against cleanup failure.

    • Given third-party deletion fails
    • When checkout validates the expired code
    • Then local blocklist rejects it and cleanup run status is partial_failed.
  4. Live smoke test passes before launch.

    • Given a live event starts within 15 minutes
    • Then active test code applies correctly, expired sample code fails, and audit page loads.
  5. Next-day test proves impossible reuse.

    • Given yesterday's live coupon
    • When QA checks at 12:05 next day
    • Then lookup, checkout and API all reject the code.
  6. Alerting works.

    • Given cleanup has failed_count > 0
    • Then LINE alert is sent to tech owner and supervisor with retry link.

E2E Verification This Round

  • Primary artifact is HTML.
  • Public Gist returns HTTP 200.
  • Gist includes 13 files.
  • PLS upload-files receives all 13 files.
  • Complete artifacts_json uses stable public refs.

Artifact URL or PR

Primary artifact: https://gist.github.com/esz135888/7c34244a063544d7ecdf8926d0f9ba56#file-kolable-noon-coupon-expiry-console-html

Public Gist: https://gist.github.com/esz135888/7c34244a063544d7ecdf8926d0f9ba56

Verification commands:

  • curl -I -L -s "https://gist.github.com/esz135888/7c34244a063544d7ecdf8926d0f9ba56#file-kolable-noon-coupon-expiry-console-html" | head -n 8
  • gh gist view 7c34244a063544d7ecdf8926d0f9ba56 --files

Verification result: primary URL returned HTTP/2 200; public Gist includes 13 files.

Data Model

Tables

live_events

Field Type Notes
id uuid Primary key
title text Live event title
starts_at timestamptz Live start
ends_at timestamptz Live end
owner_id uuid PM owner
status enum draft, scheduled, live, ended, archived

coupon_batches

Field Type Notes
id uuid Primary key
live_event_id uuid Related event
prefix text Code prefix
valid_from timestamptz Start
valid_until timestamptz End
cleanup_after timestamptz Default next 12:00 Asia/Taipei
status enum scheduled, active, expired_pending_cleanup, deleted, cleanup_failed
created_by uuid PM

coupon_codes

Field Type Notes
id uuid Primary key
batch_id uuid Coupon batch
code text Unique
status enum active, expired, deleted, blocked
usage_limit integer Usually 1 or campaign-specific
used_count integer Redemption count
deleted_at timestamptz Nullable
external_discount_id text Third-party platform id

coupon_usage_events

Field Type Notes
id uuid Primary key
coupon_code_id uuid Nullable when not found
code_entered text Raw input
user_id uuid Nullable
order_id uuid Nullable
result enum applied, expired, not_found, blocked, usage_limit_reached
created_at timestamptz Event time

coupon_cleanup_runs

Field Type Notes
id uuid Primary key
run_at timestamptz Worker start
cutoff_at timestamptz Noon cutoff
scanned_count integer Scanned codes
deleted_count integer Deleted codes
failed_count integer Failed deletes
status enum success, partial_failed, failed
error_json jsonb Failure detail

coupon_audit_events

Field Type Notes
id uuid Primary key
actor_type enum user, system_worker
actor_id uuid Nullable for worker
action text create, activate, expire, delete, block, retry
target_type text batch or code
target_id uuid Target
before_state jsonb Before
after_state jsonb After
created_at timestamptz Audit

API / Sync

  • POST /coupons/live-events/:id/codes: create batch.
  • POST /coupons/cleanup/noon: worker endpoint for noon cleanup.
  • GET /coupons/validate?code=: checkout validation.
  • POST /coupons/cleanup/:run_id/retry: retry failed deletes.
  • GET /coupons/audit?live_event_id=: audit export.

Permissions

  • Live PM: create coupon batches and run smoke tests.
  • Finance: view usage and discount cost.
  • System worker: expire/delete codes and write audit.
  • Supervisor: approve manual delete, retry, or rollback.

Rollback

Deletion is intentionally final for expired live codes. If a code was wrongly deleted before end time, create a new emergency batch with new code prefix, write audit event, and notify live PM via LINE.

Decision Record

Decision

Use system / watchdog / eval as the solution for Kolable daily live discount code expiry.

Options Considered

  1. Frontend countdown only

    • Pros: Fast.
    • Cons: Old codes can still be entered if backend accepts them.
    • Decision: Rejected.
  2. Mark expired but keep code

    • Pros: Keeps historical record.
    • Cons: Requires every checkout path to respect expired state; old codes still clutter admin and create risk.
    • Decision: Insufficient alone.
  3. Server-side delete after noon plus blocklist and audit

    • Pros: Prevents next-day input/use, supports scale, leaves audit, handles third-party failure.
    • Cons: Needs worker and rollback policy.
    • Decision: Recommended.

Recommendation

Implement noon cleanup worker in Asia/Taipei timezone. Delete expired server-side codes where supported; if deletion fails or external platform cannot delete, block locally and alert.

Adoption Status

Ready for D7 staging dry-run before next live launch.

Feedback If Not Adopted

If the team insists on keeping expired codes, require hard checkout validation, no frontend-only expiry, and daily report proving zero expired-code redemption.

E2E Verification

Plan

  1. Publish primary HTML and appendices to public Gist.
  2. Verify primary URL returns HTTP 200.
  3. Verify Gist includes 13 files.
  4. Upload files to PLS deliverable id.
  5. Complete with stable public artifact URLs.

Primary Artifact

https://gist.github.com/esz135888/7c34244a063544d7ecdf8926d0f9ba56#file-kolable-noon-coupon-expiry-console-html

Evidence

  • Published public Gist: https://gist.github.com/esz135888/7c34244a063544d7ecdf8926d0f9ba56
  • Verification command: curl -I -L -s "https://gist.github.com/esz135888/7c34244a063544d7ecdf8926d0f9ba56#file-kolable-noon-coupon-expiry-console-html" | head -n 8
  • File list command: gh gist view 7c34244a063544d7ecdf8926d0f9ba56 --files
  • Result: primary URL returned HTTP/2 200; Gist file list showed all 13 files.

Acceptance Mapping

  • Openable main artifact: kolable-noon-coupon-expiry-console.html.
  • Owner/due/acceptance: production-brief.md.
  • Data/toolbox path: data-model.md, production-readiness.md.
  • E2E proof: this file.
  • Decision record: decision-record.md.
<!doctype html>
<html lang="zh-Hant">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Kolable 每日 12:00 折扣碼刪除作戰台</title>
<style>
:root{--ink:#10202a;--muted:#60707d;--paper:#f4f8fb;--card:#fff;--line:#d5e1ea;--blue:#1d4ed8;--green:#08785e;--red:#b13b2c;--amber:#9a6409;--violet:#6846b8}
*{box-sizing:border-box}body{margin:0;background:var(--paper);color:var(--ink);font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;line-height:1.5}header{background:#fff;border-bottom:1px solid var(--line);padding:30px clamp(18px,4vw,56px)}main{padding:24px clamp(18px,4vw,56px) 48px}
h1{margin:0 0 12px;font-size:clamp(31px,4vw,54px);line-height:1.04;letter-spacing:0;max-width:1120px}h2{margin:0 0 12px;font-size:22px}h3{margin:0 0 6px;font-size:16px}p{margin-top:0}.sub{max-width:1120px;color:var(--muted);font-size:17px}.grid{display:grid;gap:16px}.kpis{grid-template-columns:repeat(4,minmax(0,1fr));margin-top:22px}.two{grid-template-columns:1.05fr .95fr}.three{grid-template-columns:repeat(3,minmax(0,1fr))}.four{grid-template-columns:repeat(4,minmax(0,1fr))}.flow{grid-template-columns:repeat(5,minmax(0,1fr))}
.card{background:var(--card);border:1px solid var(--line);border-radius:8px;padding:18px;box-shadow:0 1px 2px rgba(16,32,42,.04)}.metric{font-size:34px;font-weight:800}.label{color:var(--muted);font-size:13px}.pill{display:inline-flex;border:1px solid var(--line);border-radius:999px;padding:4px 10px;font-size:12px;background:#fff;margin:0 6px 8px 0;white-space:nowrap}.ok{color:var(--green);font-weight:760}.bad{color:var(--red);font-weight:760}.warn{color:var(--amber);font-weight:760}
table{width:100%;border-collapse:collapse;font-size:14px}th,td{text-align:left;padding:10px;border-bottom:1px solid var(--line);vertical-align:top}th{color:var(--muted);font-size:12px;text-transform:uppercase}code{background:#edf3f7;border-radius:4px;padding:1px 5px}.step{border:1px solid var(--line);border-radius:8px;padding:12px;min-height:132px;background:#fbfdff}.step strong{display:block;color:var(--violet);margin-bottom:6px}.source a{color:var(--blue);word-break:break-word}
@media(max-width:960px){.kpis,.two,.three,.four,.flow{grid-template-columns:1fr}h1{font-size:34px}}
</style>
</head>
<body>
<header>
<span class="pill">PLS production delivery pack</span><span class="pill">Solution: system / watchdog / eval</span>
<h1>Kolable 每日 12:00 折扣碼刪除作戰台</h1>
<p class="sub">把「每日 12 點後過期折扣碼直接刪除」做成直播上線前可驗收的 production pack:server-side 刪除、隔日不可輸入、checkout 阻擋、直播前 smoke test、稽核 log、回滾與例外規則。</p>
<section class="grid kpis">
<div class="card"><div class="metric bad">12:00</div><div class="label">Asia/Taipei 到點後 expired code 必須刪除</div></div>
<div class="card"><div class="metric ok">0</div><div class="label">隔日可被套用的過期碼</div></div>
<div class="card"><div class="metric">15m</div><div class="label">直播前折扣碼 smoke test 窗口</div></div>
<div class="card"><div class="metric warn">Audit</div><div class="label">每次刪除需有 code、直播、操作者、時間</div></div>
</section>
</header>
<main class="grid">
<section class="grid two">
<div class="card">
<h2>本輪任務</h2>
<p>Kolable 直播銷講場景的折扣碼會直接影響成交信任。若觀眾隔日仍能輸入昨晚碼,會破壞限時促銷可信度,也可能造成折扣濫用。本輪把過期處理從「看得到過期」升級成「server-side 刪除與驗收」。</p>
<span class="pill">Owner: Louis</span><span class="pill">Tech owner: makarove</span><span class="pill">Supervisor: zihrou</span>
</div>
<div class="card">
<h2>不可偷懶規則</h2>
<p>只在前端倒數或標 expired 不算完成。必須在後端刪除或停用折扣碼,checkout/API lookup 不得回傳可用結果,並保存 deletion audit。若第三方平台不允許刪除,則需改成 deactivate + blocklist + invalid-code event。</p>
</div>
</section>
<section class="card">
<h2>D1 / D7 / D14 / D30</h2>
<div class="grid four">
<div class="card"><h3>D1</h3><p>定義 coupon lifecycle、12:00 cleanup worker、checkout invalidation、直播前測試清單。</p></div>
<div class="card"><h3>D7</h3><p>完成 staging worker 和 3 場直播折扣碼 dry-run,舊碼隔日不可輸入。</p></div>
<div class="card"><h3>D14</h3><p>接入 admin console:活動、碼池、刪除紀錄、失敗重跑、LINE alert。</p></div>
<div class="card"><h3>D30</h3><p>納入直播銷講 PMF 指標:轉換率、折扣濫用率、客服抱怨、交易額。</p></div>
</div>
</section>
<section class="card">
<h2>Purpose-to-Purpose E2E</h2>
<div class="grid flow">
<div class="step"><strong>原始目的</strong>每日直播折扣碼隔日不可輸入或使用。</div>
<div class="step"><strong>產出物</strong>刪除流程、資料模型、API、watchdog、驗收清單。</div>
<div class="step"><strong>人採用</strong>直播 PM 開碼,系統到點刪碼,QA 直播前驗證。</div>
<div class="step"><strong>指標改善</strong>折扣濫用下降、信任提升、直播成交風險下降。</div>
<div class="step"><strong>錢路徑</strong>保護限時優惠毛利,支撐月交易額 NT$ 1000 萬到 1 億。</div>
</div>
</section>
<section class="grid two">
<div class="card">
<h2>Lifecycle Rules</h2>
<table>
<thead><tr><th>狀態</th><th>時間</th><th>系統行為</th></tr></thead>
<tbody>
<tr><td>scheduled</td><td>直播前</td><td>建立碼池,綁定 live_event_id、valid_until、usage_limit。</td></tr>
<tr><td>active</td><td>直播中</td><td>checkout 可查詢,可套用,寫 usage event。</td></tr>
<tr><td>expired_pending_cleanup</td><td>valid_until 到期到每日 12:00</td><td>checkout 立即拒絕;等待 cleanup worker 刪除。</td></tr>
<tr><td class="bad">deleted</td><td>每日 12:00 後</td><td>刪除 server-side code;lookup 回 `not_found_or_expired`。</td></tr>
<tr><td class="warn">cleanup_failed</td><td>刪除失敗</td><td>寫 audit、LINE alert、進 retry queue,checkout 仍由 blocklist 拒絕。</td></tr>
</tbody>
</table>
</div>
<div class="card">
<h2>Worker / API</h2>
<p><strong>Cron:</strong> <code>0 12 * * *</code> Asia/Taipei,每日掃描 `valid_until < today 12:00` 且未刪除的折扣碼。</p>
<p><strong>API:</strong> <code>POST /coupons/live-events/:id/codes</code>, <code>POST /coupons/cleanup/noon</code>, <code>GET /coupons/validate?code=</code>, <code>GET /coupons/audit</code>.</p>
<p><strong>Guard:</strong> checkout validate 必須先查 `coupon_status` 和 `coupon_blocklist`,不能只依前端 timer。</p>
</div>
</section>
<section class="grid three">
<div class="card"><h2>直播前 Smoke Test</h2><p>直播前 15 分鐘測 active code;直播後建立 expired test code;隔日 12:05 驗證 lookup 不存在、checkout 拒絕、audit 有紀錄。</p></div>
<div class="card"><h2>權限 / 稽核</h2><p>直播 PM 可建碼;finance 可看折扣成本;system worker 可刪除;manual delete 需 supervisor approve。</p></div>
<div class="card"><h2>下一輪升級</h2><p>做 admin console:碼池狀態、cleanup log、失敗重跑、LINE alert、交易額與折扣濫用率。</p></div>
</section>
<section class="card source">
<h2>Market Maturity Inputs</h2>
<p>Shopify supports deactivating and deleting discounts; deactivated codes should return invalid discount behavior at cart: <a href="https://help.shopify.com/manual/products/discount-codes/managing-discount-codes">Shopify discount management</a>.</p>
<p>WooCommerce marketplace has scheduled expired coupon cleanup products with cleanup logs and notifications, showing mature stores automate expired coupon removal: <a href="https://woocommerce.com/de/products/auto-coupon-cleanup/">WooCommerce Auto-Coupon Expiry Cleanup</a>.</p>
<p>Bulk discount workflows warn that expired codes can accumulate and block code generation until removed, so cleanup is a production scalability concern: <a href="https://support.seguno.com/bulk-discount-code-generator/en/articles/13355252-what-do-i-do-if-i-m-running-out-of-codes">Bulk Discount Code Generator support</a>.</p>
</section>
</main>
</body>
</html>
{
"project": "Kolable live coupon expiry",
"market_learning": [
"Mature ecommerce platforms support deactivating or deleting discounts, but live-selling requires stricter next-day invalidation.",
"Expired coupon cleanup should have logs, notifications and retry handling.",
"Frontend timers alone are not trustworthy because checkout/backend can still accept a code."
],
"pls_next_checks": [
"Does checkout validation reject expired and deleted codes server-side?",
"Does noon cleanup run in Asia/Taipei timezone?",
"Does cleanup failure still block checkout through local blocklist?",
"Is there a live preflight smoke test before every broadcast?"
],
"assumptions": [
"Kolable owns or can wrap discount validation logic.",
"The discount provider supports deletion or local blocklist fallback."
],
"next_iteration": "Build admin console for coupon batches, cleanup runs, retry queue and LINE alerts."
}

Market Maturity

Sources

  1. Shopify Help Center: managing discounts supports deactivate and delete flows; deactivated codes return invalid behavior to customers.

  2. WooCommerce Auto-Coupon Expiry Cleanup: mature ecommerce operations automate expired coupon cleanup and keep cleanup logs and notifications.

  3. Bulk Discount Code Generator support: expired codes can accumulate and create operational limits, so stores should identify and remove expired discount codes.

Market Gap

Kolable is a live-selling platform, so expiry enforcement must be stricter than normal ecommerce. The customer sees scarcity live; if a next-day code still works, urgency messaging loses trust.

This Round Closes

  • Defines server-side deletion.
  • Adds blocklist fallback.
  • Adds cleanup logs and LINE alert.
  • Adds live smoke test and next-day verification.

Remaining Gap

Build the real admin console and connect cleanup worker to the checkout/discount provider.

People Sync

Target People

  • Louis: final owner and launch decision.
  • makarove: tech owner for worker/API.
  • zihrou: supervisor for launch readiness and failure escalation.

LINE Draft

Kolable 折扣碼這輪已整理成 production 方案:每日 12:00 Asia/Taipei 後,前一日過期碼要 server-side 刪除;如果第三方平台刪除失敗,checkout 仍要靠本地 blocklist 拒絕,不能只靠前端倒數或顯示過期。

請 makarove 先做 staging:建立一組 active code、一組 expired code,跑 12:00 cleanup,12:05 驗證舊碼 lookup/checkout 都不能用,並把 audit log 截圖貼回。

zihrou 幫忙盯直播前 15 分鐘 smoke test:active code 可用、昨日碼不可用、cleanup_failed 有 LINE alert。這個過了再上直播。

Escalation

若直播前 15 分鐘 smoke test 未過,改用手動新碼並關閉舊碼輸入,直播後補 cleanup worker。

Production Brief

場景

專案:Kolable - 直播銷講工具平台。任務:更新每日直播折扣碼處理方案,將每日 12 點後過期的折扣碼直接刪除,確保次日無法輸入和使用,並跟進測試計畫,配合直播上線時間。

D1 / D7 / D14 / D30

  • D1: 定義 coupon lifecycle、12:00 cleanup worker、checkout invalidation、直播前 smoke test。
  • D7: 完成 staging worker 和 3 場直播 dry-run,舊碼隔日不可輸入。
  • D14: 接入 admin console:活動、碼池、刪除紀錄、失敗重跑、LINE alert。
  • D30: 納入 PMF 指標:直播轉換率、折扣濫用率、客服抱怨、交易額。

Purpose-to-Purpose E2E

原始目的:每日直播折扣碼隔日不可輸入或使用。

產出物:折扣碼刪除作戰台、資料模型、API、watchdog、驗收清單、people sync、learning memory。

人採用:直播 PM 開碼,系統到點刪碼,QA 直播前驗證,supervisor 看失敗 alert。

價值/錢路徑:避免過期碼破壞限時優惠信任與毛利,降低折扣濫用,支撐 Kolable 從首批 20 位講師到月交易額 NT$ 1000 萬 / 1 億。

Owner / Due / Acceptance

  • Owner: Louis.
  • Tech owner: makarove.
  • Supervisor: zihrou.
  • Due: 下一場直播上線前完成 staging smoke test。
  • Acceptance: 每日 12:05 後,前一日過期碼 lookup 回 not found/expired、checkout 拒絕、audit log 有刪除或 blocklist 記錄。

Production Readiness

Ready

  • Openable primary HTML.
  • D1/D7/D14/D30 plan.
  • Data model and API spec.
  • Worker lifecycle rules.
  • Acceptance tests.
  • People sync.
  • Decision record.
  • External market maturity sources.

Not Yet Deployed

  • No live production worker was deployed in this round.
  • No actual checkout API was modified.
  • No LINE alert integration was executed.

Production Path

  1. Implement schema migration.
  2. Implement checkout validation guard.
  3. Implement noon cleanup worker with Asia/Taipei timezone.
  4. Add cleanup audit and retry queue.
  5. Add LINE alert for partial failures.
  6. Run staging dry-run across 3 live events.
  7. Turn on before next public live launch.

Rollback / Failure Handling

Expired code deletion is intended final. If deletion happens too early, create a new emergency code batch, notify live PM, and preserve audit. If cleanup fails, blocklist must still reject checkout use.

Skill Usage

Selected Skills / Tools

  • using-superpowers: session discipline was checked earlier in this thread.
  • Web search: used to validate current ecommerce discount cleanup and expired-code practices.
  • apply_patch: used to create production files.
  • GitHub Gist: used for stable openable primary artifact.
  • curl / gh gist view: used for verification.
  • PLS helper: used for doctor, touch, claim, context, progress, upload-files, complete.

Evidence

Why These Tools

The task required a production system pack, not code-only or research-only output. Web sources informed maturity; HTML/Gist made the artifact openable; PLS helper writes results back.

Solution Selection

Selected Types

  • system
  • watchdog
  • eval
  • project

Why This Combination

The issue is transactional and time-sensitive. A document or SOP alone cannot prevent customers from using old codes. A system worker is needed to delete or block expired codes, a watchdog is needed for cleanup failure, and eval is needed for live smoke tests and next-day proof.

Why Not Smaller

Manual deletion risks missing live deadlines and does not scale across multiple creators or daily live events.

Why Not Larger

A full coupon management platform can come later. This round defines the minimum production surface: lifecycle, schema, API, cleanup worker, audit, smoke test and admin-console path.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment