- Shop: subscription perks shown once (each card repeated them, «۳ سوال در روز» twice), plans as selectable rows with one big buy button, prices as «۷۹۸ هزار تومان», a single clear status card for subscribers. Checkout inside the Bazaar app offers «کارتِ بانکی» (default) or «کافهبازار» for packs with a SKU; «بهزودی در بازار» is gone. The gateway opens in the phone browser; status refreshes on return. - Back button: every back-able level (open sheet, pushed screen, non-home tab, shop list) owns exactly one history entry created right after the tap; back closes the sheet, then the screen, then returns to Home, then leaves the app. (A re-pushed trap is skipped by Chrome's history intervention.) - Sound: AudioContext unlocked on the first touch (it was created after a network wait, which WebView/Safari keep muted); softer notes, option tick, finish fanfare, streak whoosh. Haptics through the new TadrisinoAndroid.vibrate bridge when the APK has it, navigator.vibrate otherwise. - Streak: animated flame with lit / at-risk (grey) / frozen (ice) states on Home and the streak screen, a companion reminder when the streak is at risk or frozen, and a full-screen «روزِ پیاپی» celebration after the first lesson of the day (needs backend 9024c6b: streak.activeToday / lost). - Lessons: intro/example text with inline «۱. … ۲. …» renders as a numbered list (2,250 of 4,469 texts). - Quiz: duplicate React key on the answer bubble fixed. - android/MainActivity.kt: vibrate bridge and mediaPlaybackRequiresUserGesture=false. Not built; needs the next APK from the signing owner. Checked in headless Chrome against the local backend (shop as a subscriber with the Bazaar bridge stubbed, back sequences, quiz → streak celebration, frozen state). Not checked on a real phone or in the APK. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
اپِ اندرویدِ تدریسینو (پوستهی WebView + پرداختِ بازار)
همان سایتِ math.tadrisino2.ir داخلِ یک WebView. تنها کدِ بومی پرداختِ درونبرنامهایِ
کافهبازار است (کتابخانهی Poolakey)، چون بازار برای اپی که در آن منتشر میشود پرداختِ
محصولِ دیجیتال را فقط از راهِ خودش میپذیرد. باقیِ اپ همان فرانتِ وب است و با دیپلویِ
فرانت بهروز میشود، بیآنکه نسخهی تازهی اپ لازم باشد.
⚠️ این پروژه هنوز یک بار هم build نشده. روی ماشینی نوشته شد که Android SDK نداشت (۲۰۲۶-۱۰-۰۳). APIِ Poolakey از README خودِ کتابخانه است. اولین کار: باز کردن در Android Studio، build، و یک خریدِ واقعی روی گوشی.
پیش از build — سه چیز از پیشخانِ بازار (سنیور / حسابِ شرکت)
| چه | کجا گذاشته میشود | وضعیت |
|---|---|---|
| اسمِ پکیج | applicationId در app/build.gradle.kts |
com.tadrisino.app حدس است؛ تأیید نشده |
| کلیدِ RSAِ عمومیِ اپ | BAZAAR_RSA_KEY در app/build.gradle.kts |
ندارد؛ بدونِ آن خرید شروع نمیشود |
| SKUِ هر بسته (محصولِ مصرفشدنی) | پنلِ ادمینِ بکاند: /admin/subscription/plan/ ← «Bazaar sku» |
هیچکدام تعریف نشده |
قیمتِ هر محصول در پیشخانِ بازار باید با قیمتِ همان بسته در ادمین یکی باشد؛ سرور مبلغ را از بازار نمیخواند.
build
- Android Studio ← Open ← همین پوشهی
android/. Studio خودش Gradle wrapper را میسازد. Build ← Generate Signed App Bundle / APK، با کلیدِ امضای شرکت. کلیدِ امضا را گم نکنید: بدونِ همان کلید هیچ نسخهی بعدی روی بازار بهروزرسانی نمیشود.- نصب روی گوشیای که کافهبازار دارد و با حسابِ تست وارد شده.
جریانِ خرید (برای عیبیابی)
فرانت POST /api/subscription/purchase {planId, paymentMethod:"bazaar"} → orderId, bazaarSku
فرانت TadrisinoAndroid.bazaarPurchase(sku, orderId)
اپ Poolakey.purchaseProduct(sku, payload=orderId) → purchaseToken
اپ رویدادِ «tadrisino:bazaar» {orderId, purchaseToken}
فرانت POST /api/payment/bazaar/verify {orderId, purchaseToken} ← سرور از بازار میپرسد
فرانت TadrisinoAndroid.bazaarConsume(token) ← تا همان بسته دوباره خریدنی باشد
اگر پول رفت ولی تأییدِ سرور نرسید، کاربر دوباره «پرداخت» میزند: فرانت همان سفارش را میفرستد
و اپ توکنِ ماندهٔ همان سفارش را از getPurchasedProducts پیدا میکند.
قرارداد سمتِ وب: src/lib/bazaar.ts. سمتِ سرور: payment/bazaar.py و docs/operations.mdِ بکاند.