|
@@ -0,0 +1,164 @@
|
|
|
+# Sendy Mail List Spec
|
|
|
+
|
|
|
+Using rails to get member groups from kdan cloud.
|
|
|
+
|
|
|
+Using gem Sequel to access sendy mysql db
|
|
|
+
|
|
|
+# Features
|
|
|
+1. To create list
|
|
|
+ * prefix: [ZCR]
|
|
|
+ * manually enter description
|
|
|
+
|
|
|
+2. To add subscriber into list
|
|
|
+ * member_center
|
|
|
+ * from\_application (member.from\_application)
|
|
|
+ * comfirmed (member.confirmed\_at)
|
|
|
+ * location (member.identity.location)
|
|
|
+ * language (member.identity.language)
|
|
|
+ * iap_service
|
|
|
+ * app\_series (receipt.product.app.app_series)
|
|
|
+ * pack (receipt.product.pack)
|
|
|
+ * platform (receipt.product.app.device)
|
|
|
+ * subscription\_status (kdan.pack\_subscriptions)
|
|
|
+ * A/B Testing
|
|
|
+ * Main version %, default 100%
|
|
|
+
|
|
|
+3. To prevent unsubscribed, bounced, complaint emails into the list
|
|
|
+ * Unsubscribe flag should be considered as global
|
|
|
+ * Cache unsubscribed, bounced, complaint emails as black list
|
|
|
+
|
|
|
+4. To delete list
|
|
|
+
|
|
|
+# Models
|
|
|
+## IAP Service
|
|
|
+### Kdan
|
|
|
+```
|
|
|
+has_many :pack_subscriptions, class: 'KdanPackSubscriptionStatus'
|
|
|
+```
|
|
|
+### Pack
|
|
|
+```
|
|
|
+has_many :products
|
|
|
+has_many :subscribed_kdans, class: 'KdanPackSubscriptionStatus'
|
|
|
+```
|
|
|
+
|
|
|
+```
|
|
|
+{
|
|
|
+ name:string,
|
|
|
+ code:string
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+```
|
|
|
+# C365
|
|
|
+Pack.create(name: 'Creativity 365', code: 'C365')
|
|
|
+Pack.create(name: 'Creativity 365 Teacher & Student Offer', code: 'C365TS')
|
|
|
+Pack.create(name: 'Creativity 365 Education', code: 'C365EDU')
|
|
|
+Pack.create(name: 'Creativity 365 Business', code: 'C365BUS')
|
|
|
+# D365
|
|
|
+Pack.create(name: 'Document 365', code: 'D365')
|
|
|
+Pack.create(name: 'Document 365 Volumen Licensing', code: 'D365VL')
|
|
|
+# Cloud
|
|
|
+Pack.create(name: 'Cloud Pack for Animation Desk', code: 'cloud_pack_ad')
|
|
|
+Pack.create(name: 'Cloud Pack for Noteledge', code: 'cloud_pack_nl')
|
|
|
+Pack.create(name: 'Cloud Pack for PDF', code: 'cloud_pack_pdf')
|
|
|
+Pack.create(name: 'Cloud Pack for Write-on', code: 'cloud_pack_wo')
|
|
|
+Pack.create(name: 'Cloud Pack for Pocket Scanner', code: 'cloud_pack_scan')
|
|
|
+# Deluxe
|
|
|
+Pack.create(name: 'Deluxe Pack for Animation Desk', code: 'deluxe_pack_Ad')
|
|
|
+Pack.create(name: 'Deluxe Pack for Noteledge', code: 'deluxe_pack_nl')
|
|
|
+Pack.create(name: 'Deluxe Pack for PDF', code: 'deluxe_pack_pdf')
|
|
|
+Pack.create(name: 'Deluxe Pack for Write-on', code: 'deluxe_pack_wo')
|
|
|
+Pack.create(name: 'Deluxe Pack for Pocket Scanner', code: 'deluxe_pack_scan')
|
|
|
+```
|
|
|
+### Product
|
|
|
+```
|
|
|
+belongs_to :pack
|
|
|
+```
|
|
|
+### KdanPackSubscriptionStatus
|
|
|
+```
|
|
|
+belongs_to :kdan
|
|
|
+belongs_to :pack
|
|
|
+```
|
|
|
+```
|
|
|
+{
|
|
|
+ kdan_id:integer,
|
|
|
+ pack_id:integer,
|
|
|
+ stauts:[free_trial, active, expired, refund, cancel]
|
|
|
+}
|
|
|
+```
|
|
|
+* free\_trial: this subscription is in its free trial period.
|
|
|
+* active: this subscription is active now.
|
|
|
+* expired: this subscription is expired now.
|
|
|
+* cancel: this subscription has been canceled on auto-renew.
|
|
|
+* refund: this subscription has been refund.
|
|
|
+* status priority: active \> free\_trial \> expired \> refund \> cancel
|
|
|
+
|
|
|
+### Schedule.rb
|
|
|
+* update KdanPackSubscriptionStatus every 15m
|
|
|
+* select updated receipts in 15min
|
|
|
+* select expired receipts in 15min
|
|
|
+
|
|
|
+## CR System
|
|
|
+### SendyMailList
|
|
|
+```
|
|
|
+{
|
|
|
+ description:string,
|
|
|
+ sendy_list_long_id:string,
|
|
|
+ sendy_list_short_id:integer,
|
|
|
+ select_criteria:json,
|
|
|
+ active_count:integer,
|
|
|
+ unsubscribed_count:integer,
|
|
|
+ bounced_count:integer,
|
|
|
+ bounced_soft_count:integer,
|
|
|
+ complaint_count:integer,
|
|
|
+ sendy_delete_at:datetime,
|
|
|
+}
|
|
|
+```
|
|
|
+### SendyBlackList
|
|
|
+```
|
|
|
+{
|
|
|
+ email:string,
|
|
|
+ reason: [unsubscribed, bounced, bounced_soft, complaint]
|
|
|
+}
|
|
|
+```
|
|
|
+### Schedule.rb
|
|
|
+* update SendyBlackList every 15m
|
|
|
+* select subscribers.timestamp > 15.minutes.ago
|
|
|
+
|
|
|
+# Views
|
|
|
+## CR System
|
|
|
+
|
|
|
+### Select Criteria
|
|
|
+* member\_center
|
|
|
+ * from\_application
|
|
|
+ * comfirmed
|
|
|
+ * location
|
|
|
+ * language
|
|
|
+* iap\_service
|
|
|
+ * app\_series
|
|
|
+ * pack
|
|
|
+ * platform
|
|
|
+ * subscription_status
|
|
|
+* A/B Testing
|
|
|
+ * Main version %, default 100%
|
|
|
+
|
|
|
+### Search Result
|
|
|
+
|
|
|
+Going to Build up Sendy list [Go]
|
|
|
+
|
|
|
+* List Name: [ZCR] my list
|
|
|
+* List Count: 100
|
|
|
+* List Content:
|
|
|
+ * kdan\_id, email, from\_application, comfirmed, location, language, app\_series, pack, platform
|
|
|
+
|
|
|
+----
|
|
|
+
|
|
|
+* List Name: [ZCR] my list ver. A
|
|
|
+* List Count: 100
|
|
|
+* List Content:
|
|
|
+ * kdan\_id, email, from\_application, comfirmed, location, language, app\_series, pack, platform
|
|
|
+
|
|
|
+* List Name: [ZCR] my list ver. B
|
|
|
+* List Count: 100
|
|
|
+* List Content:
|
|
|
+ * kdan\_id, email, from\_application, comfirmed, location, language, app\_series, pack, platform
|