founder-schema 0.11.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/README.md +85 -0
  2. package/dist/access/access.d.ts +10 -6
  3. package/dist/access/access.d.ts.map +1 -1
  4. package/dist/access/access.js +8 -1
  5. package/dist/access/access.js.map +1 -1
  6. package/dist/access/permissions.d.ts +60 -3
  7. package/dist/access/permissions.d.ts.map +1 -1
  8. package/dist/access/permissions.js +24 -0
  9. package/dist/access/permissions.js.map +1 -1
  10. package/dist/access/roles.d.ts +3 -3
  11. package/dist/access/standing.d.ts +59 -0
  12. package/dist/access/standing.d.ts.map +1 -0
  13. package/dist/access/standing.js +52 -0
  14. package/dist/access/standing.js.map +1 -0
  15. package/dist/core/errors.d.ts +51 -1
  16. package/dist/core/errors.d.ts.map +1 -1
  17. package/dist/core/errors.js +89 -1
  18. package/dist/core/errors.js.map +1 -1
  19. package/dist/core/limits.d.ts +29 -3
  20. package/dist/core/limits.d.ts.map +1 -1
  21. package/dist/core/limits.js +30 -3
  22. package/dist/core/limits.js.map +1 -1
  23. package/dist/core/responses.d.ts +59 -0
  24. package/dist/core/responses.d.ts.map +1 -1
  25. package/dist/core/responses.js +6 -0
  26. package/dist/core/responses.js.map +1 -1
  27. package/dist/core/validation.d.ts +14 -0
  28. package/dist/core/validation.d.ts.map +1 -1
  29. package/dist/core/validation.js +14 -0
  30. package/dist/core/validation.js.map +1 -1
  31. package/dist/domains/audit/audit.d.ts +28 -7
  32. package/dist/domains/audit/audit.d.ts.map +1 -1
  33. package/dist/domains/audit/audit.js +17 -0
  34. package/dist/domains/audit/audit.js.map +1 -1
  35. package/dist/domains/billing/billing.d.ts +1180 -0
  36. package/dist/domains/billing/billing.d.ts.map +1 -0
  37. package/dist/domains/billing/billing.js +403 -0
  38. package/dist/domains/billing/billing.js.map +1 -0
  39. package/dist/domains/billing/gst.d.ts +229 -0
  40. package/dist/domains/billing/gst.d.ts.map +1 -0
  41. package/dist/domains/billing/gst.js +117 -0
  42. package/dist/domains/billing/gst.js.map +1 -0
  43. package/dist/domains/chat/chat.d.ts +85 -0
  44. package/dist/domains/chat/chat.d.ts.map +1 -1
  45. package/dist/domains/chat/chat.js +62 -0
  46. package/dist/domains/chat/chat.js.map +1 -1
  47. package/dist/domains/communities/communities.d.ts +13 -11
  48. package/dist/domains/communities/communities.d.ts.map +1 -1
  49. package/dist/domains/communities/communities.js +7 -0
  50. package/dist/domains/communities/communities.js.map +1 -1
  51. package/dist/domains/contributions/contributions.d.ts +2 -2
  52. package/dist/domains/contributions/contributions.d.ts.map +1 -1
  53. package/dist/domains/contributions/contributions.js +3 -2
  54. package/dist/domains/contributions/contributions.js.map +1 -1
  55. package/dist/domains/dashboard/dashboard.d.ts +9 -1
  56. package/dist/domains/dashboard/dashboard.d.ts.map +1 -1
  57. package/dist/domains/dashboard/dashboard.js +15 -0
  58. package/dist/domains/dashboard/dashboard.js.map +1 -1
  59. package/dist/domains/feed/feed.d.ts.map +1 -1
  60. package/dist/domains/feed/feed.js +7 -1
  61. package/dist/domains/feed/feed.js.map +1 -1
  62. package/dist/domains/members/members.d.ts +30 -5
  63. package/dist/domains/members/members.d.ts.map +1 -1
  64. package/dist/domains/members/members.js +23 -0
  65. package/dist/domains/members/members.js.map +1 -1
  66. package/dist/domains/membership/membership.d.ts +240 -0
  67. package/dist/domains/membership/membership.d.ts.map +1 -0
  68. package/dist/domains/membership/membership.js +159 -0
  69. package/dist/domains/membership/membership.js.map +1 -0
  70. package/dist/domains/notifications/notifications.d.ts +43 -1
  71. package/dist/domains/notifications/notifications.d.ts.map +1 -1
  72. package/dist/domains/notifications/notifications.js +19 -0
  73. package/dist/domains/notifications/notifications.js.map +1 -1
  74. package/dist/domains/onboarding/onboarding.d.ts +0 -10
  75. package/dist/domains/onboarding/onboarding.d.ts.map +1 -1
  76. package/dist/domains/onboarding/onboarding.js +9 -3
  77. package/dist/domains/onboarding/onboarding.js.map +1 -1
  78. package/dist/domains/products/products.d.ts +44 -12
  79. package/dist/domains/products/products.d.ts.map +1 -1
  80. package/dist/domains/products/products.js +33 -3
  81. package/dist/domains/products/products.js.map +1 -1
  82. package/dist/domains/profile/founder-profile.d.ts +10 -4
  83. package/dist/domains/profile/founder-profile.d.ts.map +1 -1
  84. package/dist/domains/profile/founder-profile.js +6 -3
  85. package/dist/domains/profile/founder-profile.js.map +1 -1
  86. package/dist/domains/reviews/reviews.d.ts +3 -0
  87. package/dist/domains/reviews/reviews.d.ts.map +1 -1
  88. package/dist/domains/reviews/reviews.js +6 -1
  89. package/dist/domains/reviews/reviews.js.map +1 -1
  90. package/dist/domains/support/support.d.ts +16 -1
  91. package/dist/domains/support/support.d.ts.map +1 -1
  92. package/dist/domains/support/support.js +5 -0
  93. package/dist/domains/support/support.js.map +1 -1
  94. package/dist/domains/team/team.d.ts +4 -4
  95. package/dist/index.d.ts +7 -4
  96. package/dist/index.d.ts.map +1 -1
  97. package/dist/index.js +9 -4
  98. package/dist/index.js.map +1 -1
  99. package/package.json +1 -1
@@ -0,0 +1,240 @@
1
+ /**
2
+ * founder-schema: membership and plans, as a member holds them (0.12.0)
3
+ *
4
+ * GET /api/v1/plans planCatalogSchema (anyone: prices and what each includes)
5
+ * GET /api/v1/me/membership meMembershipSchema (signed in: what I hold, what I have used)
6
+ *
7
+ * THE USER'S RULING (2026-10-11): looking is free; taking part needs a
8
+ * MEMBERSHIP, Rs 99 once, for life (the first 100 free with a coupon). On top,
9
+ * two PLANS: Premium (5 live products, 15 new people a month to message) and
10
+ * Business (unlimited products, 50 new people). Prices and plan contents come
11
+ * from the server, so a change needs no client release.
12
+ *
13
+ * A PLAN IS TIME, PREPAID, IN TWO BLOCKS: Business time first, then Premium
14
+ * time. Buying more APPENDS; buying Premium while on Business waits its turn;
15
+ * buying Business while on Premium is an upgrade that turns the Premium time
16
+ * left into Business for the difference (`domains/billing`). `blocks` says it
17
+ * as it stands, from now on.
18
+ *
19
+ * Money is integer PAISE everywhere in this package: never a float of rupees.
20
+ *
21
+ * @module founder-schema/domains/membership
22
+ */
23
+ import { z } from 'zod';
24
+ /**
25
+ * How someone came to hold a membership. ⚠ Stored: append only.
26
+ *
27
+ * founding the founding coupon (`FIRST100`): free for life, numbered
28
+ * coupon another free-membership coupon
29
+ * paid Rs 99, captured
30
+ * granted staff gave it (a partner, a press account), with a reason on record
31
+ */
32
+ export declare const MEMBERSHIP_KIND_VALUES: readonly ["founding", "coupon", "paid", "granted"];
33
+ export declare const membershipKindSchema: z.ZodEnum<{
34
+ founding: "founding";
35
+ coupon: "coupon";
36
+ paid: "paid";
37
+ granted: "granted";
38
+ }>;
39
+ export type MembershipKind = z.infer<typeof membershipKindSchema>;
40
+ /** ⚠ Stored: append only. Highest last is NOT implied: compare with `PLAN_TIER_RANK`. */
41
+ export declare const PLAN_TIER_VALUES: readonly ["premium", "business"];
42
+ export declare const planTierSchema: z.ZodEnum<{
43
+ premium: "premium";
44
+ business: "business";
45
+ }>;
46
+ export type PlanTier = z.infer<typeof planTierSchema>;
47
+ /** Which tier outranks which: Business above Premium. */
48
+ export declare const PLAN_TIER_RANK: Readonly<Record<PlanTier, number>>;
49
+ /** One payment buys a calendar month or a calendar year. ⚠ Stored: append only. */
50
+ export declare const PLAN_PERIOD_VALUES: readonly ["month", "year"];
51
+ export declare const planPeriodSchema: z.ZodEnum<{
52
+ month: "month";
53
+ year: "year";
54
+ }>;
55
+ export type PlanPeriod = z.infer<typeof planPeriodSchema>;
56
+ /** Integer paise, never negative. Rs 399 is 39900. */
57
+ export declare const paiseSchema: z.ZodNumber;
58
+ export type Paise = z.infer<typeof paiseSchema>;
59
+ /**
60
+ * What a standing or a plan allows that is COUNTED (the ability says whether;
61
+ * these say how many).
62
+ *
63
+ * productsLive products live at once; null is unlimited (the server
64
+ * still holds a safety ceiling, `PRODUCTS_LIVE_SAFETY_MAX`)
65
+ * newPeoplePerMonth conversations a month with people you do not know
66
+ */
67
+ export declare const planLimitsSchema: z.ZodObject<{
68
+ productsLive: z.ZodNullable<z.ZodNumber>;
69
+ newPeoplePerMonth: z.ZodNumber;
70
+ }, z.core.$strip>;
71
+ export type PlanLimits = z.infer<typeof planLimitsSchema>;
72
+ /** The membership: once, for life. */
73
+ export declare const MEMBERSHIP_PRICE_PAISE = 9900;
74
+ /** What a member with no plan may: 1 live product, no conversations with people they do not know. */
75
+ export declare const MEMBER_LIMIT_VALUES: PlanLimits;
76
+ /** Each plan's name, prices and limits. Exhaustive by type. */
77
+ export declare const PLAN_SPECS: Readonly<Record<PlanTier, {
78
+ name: string;
79
+ prices: Readonly<Record<PlanPeriod, number>>;
80
+ limits: PlanLimits;
81
+ }>>;
82
+ /** Free founding memberships on the seeded `FIRST100` code. */
83
+ export declare const FOUNDING_PLACES = 100;
84
+ export declare const planOfferSchema: z.ZodObject<{
85
+ tier: z.ZodEnum<{
86
+ premium: "premium";
87
+ business: "business";
88
+ }>;
89
+ name: z.ZodString;
90
+ prices: z.ZodObject<{
91
+ month: z.ZodNumber;
92
+ year: z.ZodNumber;
93
+ }, z.core.$strip>;
94
+ limits: z.ZodObject<{
95
+ productsLive: z.ZodNullable<z.ZodNumber>;
96
+ newPeoplePerMonth: z.ZodNumber;
97
+ }, z.core.$strip>;
98
+ }, z.core.$strip>;
99
+ export type PlanOffer = z.infer<typeof planOfferSchema>;
100
+ export declare const planCatalogSchema: z.ZodObject<{
101
+ currency: z.ZodLiteral<"INR">;
102
+ membership: z.ZodObject<{
103
+ price: z.ZodNumber;
104
+ limits: z.ZodObject<{
105
+ productsLive: z.ZodNullable<z.ZodNumber>;
106
+ newPeoplePerMonth: z.ZodNumber;
107
+ }, z.core.$strip>;
108
+ }, z.core.$strip>;
109
+ plans: z.ZodArray<z.ZodObject<{
110
+ tier: z.ZodEnum<{
111
+ premium: "premium";
112
+ business: "business";
113
+ }>;
114
+ name: z.ZodString;
115
+ prices: z.ZodObject<{
116
+ month: z.ZodNumber;
117
+ year: z.ZodNumber;
118
+ }, z.core.$strip>;
119
+ limits: z.ZodObject<{
120
+ productsLive: z.ZodNullable<z.ZodNumber>;
121
+ newPeoplePerMonth: z.ZodNumber;
122
+ }, z.core.$strip>;
123
+ }, z.core.$strip>>;
124
+ refundWindowDays: z.ZodNumber;
125
+ paymentsEnabled: z.ZodBoolean;
126
+ }, z.core.$strip>;
127
+ export type PlanCatalog = z.infer<typeof planCatalogSchema>;
128
+ export declare const membershipSchema: z.ZodObject<{
129
+ kind: z.ZodEnum<{
130
+ founding: "founding";
131
+ coupon: "coupon";
132
+ paid: "paid";
133
+ granted: "granted";
134
+ }>;
135
+ since: z.ZodISODateTime;
136
+ foundingNumber: z.ZodNullable<z.ZodNumber>;
137
+ }, z.core.$strip>;
138
+ export type Membership = z.infer<typeof membershipSchema>;
139
+ /** A stretch of one tier. Blocks never overlap and follow each other with no gap. */
140
+ export declare const planBlockSchema: z.ZodObject<{
141
+ tier: z.ZodEnum<{
142
+ premium: "premium";
143
+ business: "business";
144
+ }>;
145
+ startsAt: z.ZodISODateTime;
146
+ endsAt: z.ZodISODateTime;
147
+ }, z.core.$strip>;
148
+ export type PlanBlock = z.infer<typeof planBlockSchema>;
149
+ export declare const meMembershipSchema: z.ZodObject<{
150
+ standing: z.ZodEnum<{
151
+ viewer: "viewer";
152
+ member: "member";
153
+ }>;
154
+ membership: z.ZodNullable<z.ZodObject<{
155
+ kind: z.ZodEnum<{
156
+ founding: "founding";
157
+ coupon: "coupon";
158
+ paid: "paid";
159
+ granted: "granted";
160
+ }>;
161
+ since: z.ZodISODateTime;
162
+ foundingNumber: z.ZodNullable<z.ZodNumber>;
163
+ }, z.core.$strip>>;
164
+ through: z.ZodNullable<z.ZodEnum<{
165
+ staff: "staff";
166
+ membership: "membership";
167
+ }>>;
168
+ plan: z.ZodObject<{
169
+ tier: z.ZodNullable<z.ZodEnum<{
170
+ premium: "premium";
171
+ business: "business";
172
+ }>>;
173
+ blocks: z.ZodArray<z.ZodObject<{
174
+ tier: z.ZodEnum<{
175
+ premium: "premium";
176
+ business: "business";
177
+ }>;
178
+ startsAt: z.ZodISODateTime;
179
+ endsAt: z.ZodISODateTime;
180
+ }, z.core.$strip>>;
181
+ }, z.core.$strip>;
182
+ limits: z.ZodObject<{
183
+ productsLive: z.ZodNullable<z.ZodNumber>;
184
+ newPeoplePerMonth: z.ZodNumber;
185
+ }, z.core.$strip>;
186
+ products: z.ZodObject<{
187
+ live: z.ZodNumber;
188
+ owned: z.ZodNumber;
189
+ counted: z.ZodNumber;
190
+ }, z.core.$strip>;
191
+ messages: z.ZodObject<{
192
+ used: z.ZodNumber;
193
+ resetsAt: z.ZodISODateTime;
194
+ }, z.core.$strip>;
195
+ billing: z.ZodNullable<z.ZodObject<{
196
+ stateCode: z.ZodEnum<{
197
+ "01": "01";
198
+ "02": "02";
199
+ "03": "03";
200
+ "04": "04";
201
+ "05": "05";
202
+ "06": "06";
203
+ "07": "07";
204
+ "08": "08";
205
+ "09": "09";
206
+ 10: "10";
207
+ 11: "11";
208
+ 12: "12";
209
+ 13: "13";
210
+ 14: "14";
211
+ 15: "15";
212
+ 16: "16";
213
+ 17: "17";
214
+ 18: "18";
215
+ 19: "19";
216
+ 20: "20";
217
+ 21: "21";
218
+ 22: "22";
219
+ 23: "23";
220
+ 24: "24";
221
+ 26: "26";
222
+ 27: "27";
223
+ 29: "29";
224
+ 30: "30";
225
+ 31: "31";
226
+ 32: "32";
227
+ 33: "33";
228
+ 34: "34";
229
+ 35: "35";
230
+ 36: "36";
231
+ 37: "37";
232
+ 38: "38";
233
+ }>;
234
+ gstin: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>>;
235
+ legalName: z.ZodOptional<z.ZodString>;
236
+ address: z.ZodOptional<z.ZodString>;
237
+ }, z.core.$strip>>;
238
+ }, z.core.$strip>;
239
+ export type MeMembership = z.infer<typeof meMembershipSchema>;
240
+ //# sourceMappingURL=membership.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"membership.d.ts","sourceRoot":"","sources":["../../../src/domains/membership/membership.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,oDAAqD,CAAC;AACzF,eAAO,MAAM,oBAAoB;;;;;EAAiC,CAAC;AACnE,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,yFAAyF;AACzF,eAAO,MAAM,gBAAgB,kCAAmC,CAAC;AACjE,eAAO,MAAM,cAAc;;;EAA2B,CAAC;AACvD,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAEtD,yDAAyD;AACzD,eAAO,MAAM,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAA+B,CAAC;AAE9F,mFAAmF;AACnF,eAAO,MAAM,kBAAkB,4BAA6B,CAAC;AAC7D,eAAO,MAAM,gBAAgB;;;EAA6B,CAAC;AAC3D,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,sDAAsD;AACtD,eAAO,MAAM,WAAW,aAAiC,CAAC;AAC1D,MAAM,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAEhD;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB;;;iBAG3B,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAW1D,sCAAsC;AACtC,eAAO,MAAM,sBAAsB,OAAQ,CAAC;AAE5C,qGAAqG;AACrG,eAAO,MAAM,mBAAmB,EAAE,UAAsD,CAAC;AAEzF,+DAA+D;AAC/D,eAAO,MAAM,UAAU,EAAE,QAAQ,CAC/B,MAAM,CACJ,QAAQ,EACR;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;IAAC,MAAM,EAAE,UAAU,CAAA;CAAE,CACnF,CAYF,CAAC;AAEF,+DAA+D;AAC/D,eAAO,MAAM,eAAe,MAAM,CAAC;AAInC,eAAO,MAAM,eAAe;;;;;;;;;;;;;;iBAO1B,CAAC;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAExD,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;iBAiB5B,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAI5D,eAAO,MAAM,gBAAgB;;;;;;;;;iBAK3B,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,qFAAqF;AACrF,eAAO,MAAM,eAAe;;;;;;;iBAI1B,CAAC;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAExD,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAiC7B,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC"}
@@ -0,0 +1,159 @@
1
+ /**
2
+ * founder-schema: membership and plans, as a member holds them (0.12.0)
3
+ *
4
+ * GET /api/v1/plans planCatalogSchema (anyone: prices and what each includes)
5
+ * GET /api/v1/me/membership meMembershipSchema (signed in: what I hold, what I have used)
6
+ *
7
+ * THE USER'S RULING (2026-10-11): looking is free; taking part needs a
8
+ * MEMBERSHIP, Rs 99 once, for life (the first 100 free with a coupon). On top,
9
+ * two PLANS: Premium (5 live products, 15 new people a month to message) and
10
+ * Business (unlimited products, 50 new people). Prices and plan contents come
11
+ * from the server, so a change needs no client release.
12
+ *
13
+ * A PLAN IS TIME, PREPAID, IN TWO BLOCKS: Business time first, then Premium
14
+ * time. Buying more APPENDS; buying Premium while on Business waits its turn;
15
+ * buying Business while on Premium is an upgrade that turns the Premium time
16
+ * left into Business for the difference (`domains/billing`). `blocks` says it
17
+ * as it stands, from now on.
18
+ *
19
+ * Money is integer PAISE everywhere in this package: never a float of rupees.
20
+ *
21
+ * @module founder-schema/domains/membership
22
+ */
23
+ import { z } from 'zod';
24
+ import { standingSchema } from '../../access/standing.js';
25
+ import { billingDetailsSchema } from '../billing/gst.js';
26
+ /**
27
+ * How someone came to hold a membership. ⚠ Stored: append only.
28
+ *
29
+ * founding the founding coupon (`FIRST100`): free for life, numbered
30
+ * coupon another free-membership coupon
31
+ * paid Rs 99, captured
32
+ * granted staff gave it (a partner, a press account), with a reason on record
33
+ */
34
+ export const MEMBERSHIP_KIND_VALUES = ['founding', 'coupon', 'paid', 'granted'];
35
+ export const membershipKindSchema = z.enum(MEMBERSHIP_KIND_VALUES);
36
+ /** ⚠ Stored: append only. Highest last is NOT implied: compare with `PLAN_TIER_RANK`. */
37
+ export const PLAN_TIER_VALUES = ['premium', 'business'];
38
+ export const planTierSchema = z.enum(PLAN_TIER_VALUES);
39
+ /** Which tier outranks which: Business above Premium. */
40
+ export const PLAN_TIER_RANK = { premium: 1, business: 2 };
41
+ /** One payment buys a calendar month or a calendar year. ⚠ Stored: append only. */
42
+ export const PLAN_PERIOD_VALUES = ['month', 'year'];
43
+ export const planPeriodSchema = z.enum(PLAN_PERIOD_VALUES);
44
+ /** Integer paise, never negative. Rs 399 is 39900. */
45
+ export const paiseSchema = z.number().int().nonnegative();
46
+ /**
47
+ * What a standing or a plan allows that is COUNTED (the ability says whether;
48
+ * these say how many).
49
+ *
50
+ * productsLive products live at once; null is unlimited (the server
51
+ * still holds a safety ceiling, `PRODUCTS_LIVE_SAFETY_MAX`)
52
+ * newPeoplePerMonth conversations a month with people you do not know
53
+ */
54
+ export const planLimitsSchema = z.object({
55
+ productsLive: z.number().int().nonnegative().nullable(),
56
+ newPeoplePerMonth: z.number().int().nonnegative(),
57
+ });
58
+ // ─── The price list ──────────────────────────────────────────────────────────
59
+ //
60
+ // THE ONE PLACE a price or a plan's limit is written (0.12.0). The backend
61
+ // prices and counts from these (`modules/plans/catalog.ts`), `GET /plans`
62
+ // serves them, and the web's Terms of Service are written FROM them, so the
63
+ // Terms can never state a price the server does not charge. A change here is
64
+ // a schema release, then the backend, then the web. Integer PAISE, GST
65
+ // included. hary's India-first prices (the user: "you decide, India first").
66
+ /** The membership: once, for life. */
67
+ export const MEMBERSHIP_PRICE_PAISE = 9_900;
68
+ /** What a member with no plan may: 1 live product, no conversations with people they do not know. */
69
+ export const MEMBER_LIMIT_VALUES = { productsLive: 1, newPeoplePerMonth: 0 };
70
+ /** Each plan's name, prices and limits. Exhaustive by type. */
71
+ export const PLAN_SPECS = {
72
+ premium: {
73
+ name: 'Premium',
74
+ prices: { month: 39_900, year: 399_900 },
75
+ limits: { productsLive: 5, newPeoplePerMonth: 15 },
76
+ },
77
+ business: {
78
+ name: 'Business',
79
+ prices: { month: 99_900, year: 999_900 },
80
+ limits: { productsLive: null, newPeoplePerMonth: 50 },
81
+ },
82
+ };
83
+ /** Free founding memberships on the seeded `FIRST100` code. */
84
+ export const FOUNDING_PLACES = 100;
85
+ // ─── GET /plans ──────────────────────────────────────────────────────────────
86
+ export const planOfferSchema = z.object({
87
+ tier: planTierSchema,
88
+ /** "Premium", "Business": the server's word, so a rename needs no client release. */
89
+ name: z.string(),
90
+ /** GST included. */
91
+ prices: z.object({ month: paiseSchema, year: paiseSchema }),
92
+ limits: planLimitsSchema,
93
+ });
94
+ export const planCatalogSchema = z.object({
95
+ currency: z.literal('INR'),
96
+ membership: z.object({
97
+ /** Once, for life, GST included. */
98
+ price: paiseSchema,
99
+ limits: planLimitsSchema,
100
+ }),
101
+ /** Lowest first. */
102
+ plans: z.array(planOfferSchema),
103
+ /** Every purchase is refunded in full within this many days of paying. */
104
+ refundWindowDays: z.number().int().positive(),
105
+ /**
106
+ * Whether a payment can be taken here now. False when the gateway is not
107
+ * configured: a free coupon still works, a paid purchase answers
108
+ * `PAYMENTS_UNAVAILABLE`.
109
+ */
110
+ paymentsEnabled: z.boolean(),
111
+ });
112
+ // ─── GET /me/membership ──────────────────────────────────────────────────────
113
+ export const membershipSchema = z.object({
114
+ kind: membershipKindSchema,
115
+ since: z.iso.datetime(),
116
+ /** "Founding member #N": set only for `founding`. */
117
+ foundingNumber: z.number().int().positive().nullable(),
118
+ });
119
+ /** A stretch of one tier. Blocks never overlap and follow each other with no gap. */
120
+ export const planBlockSchema = z.object({
121
+ tier: planTierSchema,
122
+ startsAt: z.iso.datetime(),
123
+ endsAt: z.iso.datetime(),
124
+ });
125
+ export const meMembershipSchema = z.object({
126
+ standing: standingSchema,
127
+ /** Null for a viewer, and for staff who hold none (they take part through their role). */
128
+ membership: membershipSchema.nullable(),
129
+ /** Why they take part: their membership, or a staff role (staff are members). Null for a viewer. */
130
+ through: z.enum(['membership', 'staff']).nullable(),
131
+ plan: z.object({
132
+ /** The tier in force now; null with no plan. */
133
+ tier: planTierSchema.nullable(),
134
+ /** From now on, Business first, then Premium. Empty with no plan. */
135
+ blocks: z.array(planBlockSchema),
136
+ }),
137
+ limits: planLimitsSchema,
138
+ products: z.object({
139
+ /** Products they own that are live now. */
140
+ live: z.number().int().nonnegative(),
141
+ /** Products they own, paused ones included. */
142
+ owned: z.number().int().nonnegative(),
143
+ /**
144
+ * What adding another counts against (0.13.0): live ones and the ones
145
+ * they paused themselves, not those a plan's end paused. "Add a product"
146
+ * stops when this reaches `limits.productsLive`: pausing never makes room.
147
+ */
148
+ counted: z.number().int().nonnegative(),
149
+ }),
150
+ messages: z.object({
151
+ /** New people they started a conversation with this month (India time). */
152
+ used: z.number().int().nonnegative(),
153
+ /** When this month's count starts again. */
154
+ resetsAt: z.iso.datetime(),
155
+ }),
156
+ /** The billing details they last used, to prefill the next checkout; null before the first. */
157
+ billing: billingDetailsSchema.nullable(),
158
+ });
159
+ //# sourceMappingURL=membership.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"membership.js","sourceRoot":"","sources":["../../../src/domains/membership/membership.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * founder-schema: membership and plans, as a member holds them (0.12.0)\n *\n * GET /api/v1/plans planCatalogSchema (anyone: prices and what each includes)\n * GET /api/v1/me/membership meMembershipSchema (signed in: what I hold, what I have used)\n *\n * THE USER'S RULING (2026-10-11): looking is free; taking part needs a\n * MEMBERSHIP, Rs 99 once, for life (the first 100 free with a coupon). On top,\n * two PLANS: Premium (5 live products, 15 new people a month to message) and\n * Business (unlimited products, 50 new people). Prices and plan contents come\n * from the server, so a change needs no client release.\n *\n * A PLAN IS TIME, PREPAID, IN TWO BLOCKS: Business time first, then Premium\n * time. Buying more APPENDS; buying Premium while on Business waits its turn;\n * buying Business while on Premium is an upgrade that turns the Premium time\n * left into Business for the difference (`domains/billing`). `blocks` says it\n * as it stands, from now on.\n *\n * Money is integer PAISE everywhere in this package: never a float of rupees.\n *\n * @module founder-schema/domains/membership\n */\n\nimport { z } from 'zod';\nimport { standingSchema } from '../../access/standing.js';\nimport { billingDetailsSchema } from '../billing/gst.js';\n\n/**\n * How someone came to hold a membership. ⚠ Stored: append only.\n *\n * founding the founding coupon (`FIRST100`): free for life, numbered\n * coupon another free-membership coupon\n * paid Rs 99, captured\n * granted staff gave it (a partner, a press account), with a reason on record\n */\nexport const MEMBERSHIP_KIND_VALUES = ['founding', 'coupon', 'paid', 'granted'] as const;\nexport const membershipKindSchema = z.enum(MEMBERSHIP_KIND_VALUES);\nexport type MembershipKind = z.infer<typeof membershipKindSchema>;\n\n/** ⚠ Stored: append only. Highest last is NOT implied: compare with `PLAN_TIER_RANK`. */\nexport const PLAN_TIER_VALUES = ['premium', 'business'] as const;\nexport const planTierSchema = z.enum(PLAN_TIER_VALUES);\nexport type PlanTier = z.infer<typeof planTierSchema>;\n\n/** Which tier outranks which: Business above Premium. */\nexport const PLAN_TIER_RANK: Readonly<Record<PlanTier, number>> = { premium: 1, business: 2 };\n\n/** One payment buys a calendar month or a calendar year. ⚠ Stored: append only. */\nexport const PLAN_PERIOD_VALUES = ['month', 'year'] as const;\nexport const planPeriodSchema = z.enum(PLAN_PERIOD_VALUES);\nexport type PlanPeriod = z.infer<typeof planPeriodSchema>;\n\n/** Integer paise, never negative. Rs 399 is 39900. */\nexport const paiseSchema = z.number().int().nonnegative();\nexport type Paise = z.infer<typeof paiseSchema>;\n\n/**\n * What a standing or a plan allows that is COUNTED (the ability says whether;\n * these say how many).\n *\n * productsLive products live at once; null is unlimited (the server\n * still holds a safety ceiling, `PRODUCTS_LIVE_SAFETY_MAX`)\n * newPeoplePerMonth conversations a month with people you do not know\n */\nexport const planLimitsSchema = z.object({\n productsLive: z.number().int().nonnegative().nullable(),\n newPeoplePerMonth: z.number().int().nonnegative(),\n});\nexport type PlanLimits = z.infer<typeof planLimitsSchema>;\n\n// ─── The price list ──────────────────────────────────────────────────────────\n//\n// THE ONE PLACE a price or a plan's limit is written (0.12.0). The backend\n// prices and counts from these (`modules/plans/catalog.ts`), `GET /plans`\n// serves them, and the web's Terms of Service are written FROM them, so the\n// Terms can never state a price the server does not charge. A change here is\n// a schema release, then the backend, then the web. Integer PAISE, GST\n// included. hary's India-first prices (the user: \"you decide, India first\").\n\n/** The membership: once, for life. */\nexport const MEMBERSHIP_PRICE_PAISE = 9_900;\n\n/** What a member with no plan may: 1 live product, no conversations with people they do not know. */\nexport const MEMBER_LIMIT_VALUES: PlanLimits = { productsLive: 1, newPeoplePerMonth: 0 };\n\n/** Each plan's name, prices and limits. Exhaustive by type. */\nexport const PLAN_SPECS: Readonly<\n Record<\n PlanTier,\n { name: string; prices: Readonly<Record<PlanPeriod, number>>; limits: PlanLimits }\n >\n> = {\n premium: {\n name: 'Premium',\n prices: { month: 39_900, year: 399_900 },\n limits: { productsLive: 5, newPeoplePerMonth: 15 },\n },\n business: {\n name: 'Business',\n prices: { month: 99_900, year: 999_900 },\n limits: { productsLive: null, newPeoplePerMonth: 50 },\n },\n};\n\n/** Free founding memberships on the seeded `FIRST100` code. */\nexport const FOUNDING_PLACES = 100;\n\n// ─── GET /plans ──────────────────────────────────────────────────────────────\n\nexport const planOfferSchema = z.object({\n tier: planTierSchema,\n /** \"Premium\", \"Business\": the server's word, so a rename needs no client release. */\n name: z.string(),\n /** GST included. */\n prices: z.object({ month: paiseSchema, year: paiseSchema }),\n limits: planLimitsSchema,\n});\nexport type PlanOffer = z.infer<typeof planOfferSchema>;\n\nexport const planCatalogSchema = z.object({\n currency: z.literal('INR'),\n membership: z.object({\n /** Once, for life, GST included. */\n price: paiseSchema,\n limits: planLimitsSchema,\n }),\n /** Lowest first. */\n plans: z.array(planOfferSchema),\n /** Every purchase is refunded in full within this many days of paying. */\n refundWindowDays: z.number().int().positive(),\n /**\n * Whether a payment can be taken here now. False when the gateway is not\n * configured: a free coupon still works, a paid purchase answers\n * `PAYMENTS_UNAVAILABLE`.\n */\n paymentsEnabled: z.boolean(),\n});\nexport type PlanCatalog = z.infer<typeof planCatalogSchema>;\n\n// ─── GET /me/membership ──────────────────────────────────────────────────────\n\nexport const membershipSchema = z.object({\n kind: membershipKindSchema,\n since: z.iso.datetime(),\n /** \"Founding member #N\": set only for `founding`. */\n foundingNumber: z.number().int().positive().nullable(),\n});\nexport type Membership = z.infer<typeof membershipSchema>;\n\n/** A stretch of one tier. Blocks never overlap and follow each other with no gap. */\nexport const planBlockSchema = z.object({\n tier: planTierSchema,\n startsAt: z.iso.datetime(),\n endsAt: z.iso.datetime(),\n});\nexport type PlanBlock = z.infer<typeof planBlockSchema>;\n\nexport const meMembershipSchema = z.object({\n standing: standingSchema,\n /** Null for a viewer, and for staff who hold none (they take part through their role). */\n membership: membershipSchema.nullable(),\n /** Why they take part: their membership, or a staff role (staff are members). Null for a viewer. */\n through: z.enum(['membership', 'staff']).nullable(),\n plan: z.object({\n /** The tier in force now; null with no plan. */\n tier: planTierSchema.nullable(),\n /** From now on, Business first, then Premium. Empty with no plan. */\n blocks: z.array(planBlockSchema),\n }),\n limits: planLimitsSchema,\n products: z.object({\n /** Products they own that are live now. */\n live: z.number().int().nonnegative(),\n /** Products they own, paused ones included. */\n owned: z.number().int().nonnegative(),\n /**\n * What adding another counts against (0.13.0): live ones and the ones\n * they paused themselves, not those a plan's end paused. \"Add a product\"\n * stops when this reaches `limits.productsLive`: pausing never makes room.\n */\n counted: z.number().int().nonnegative(),\n }),\n messages: z.object({\n /** New people they started a conversation with this month (India time). */\n used: z.number().int().nonnegative(),\n /** When this month's count starts again. */\n resetsAt: z.iso.datetime(),\n }),\n /** The billing details they last used, to prefill the next checkout; null before the first. */\n billing: billingDetailsSchema.nullable(),\n});\nexport type MeMembership = z.infer<typeof meMembershipSchema>;\n"]}
@@ -48,12 +48,15 @@ import { z } from 'zod';
48
48
  * community_invite a community invited you (always delivered)
49
49
  * community_announcement a community you are in pinned an announcement for everyone
50
50
  * community_suggestion_decided your community suggestion was approved or declined (always delivered)
51
+ * plan_ending your plan ends in 7 days, then in 1 day (0.12.0, always delivered)
52
+ * plan_ended your plan ended; `paused` products were paused (0.12.0, always delivered)
53
+ * payment_refunded staff refunded one of your payments (0.12.0, always delivered)
51
54
  *
52
55
  * The three 0.8.0 kinds merge per target like the others. A reaction counts
53
56
  * once: changing it to another type is not a new event, and taking it back
54
57
  * does not take the event back.
55
58
  */
56
- export declare const NOTIFICATION_KIND_VALUES: readonly ["comment_on_post", "reply_to_comment", "product_invite", "product_invite_accepted", "product_review", "review_reply", "feedback_helpful", "tester_confirmed", "post_reaction", "comment_reaction", "repost", "community_join_request", "community_request_approved", "community_invite", "community_announcement", "community_suggestion_decided"];
59
+ export declare const NOTIFICATION_KIND_VALUES: readonly ["comment_on_post", "reply_to_comment", "product_invite", "product_invite_accepted", "product_review", "review_reply", "feedback_helpful", "tester_confirmed", "post_reaction", "comment_reaction", "repost", "community_join_request", "community_request_approved", "community_invite", "community_announcement", "community_suggestion_decided", "plan_ending", "plan_ended", "payment_refunded"];
57
60
  export declare const notificationKindSchema: z.ZodEnum<{
58
61
  feedback_helpful: "feedback_helpful";
59
62
  tester_confirmed: "tester_confirmed";
@@ -71,6 +74,9 @@ export declare const notificationKindSchema: z.ZodEnum<{
71
74
  community_invite: "community_invite";
72
75
  community_announcement: "community_announcement";
73
76
  community_suggestion_decided: "community_suggestion_decided";
77
+ plan_ending: "plan_ending";
78
+ plan_ended: "plan_ended";
79
+ payment_refunded: "payment_refunded";
74
80
  }>;
75
81
  export type NotificationKind = z.infer<typeof notificationKindSchema>;
76
82
  /** The switches a member has, each covering one or more kinds. */
@@ -106,6 +112,9 @@ export declare const NOTIFICATION_PREFERENCE_OF: {
106
112
  readonly community_invite: null;
107
113
  readonly community_announcement: "communities";
108
114
  readonly community_suggestion_decided: null;
115
+ readonly plan_ending: null;
116
+ readonly plan_ended: null;
117
+ readonly payment_refunded: null;
109
118
  };
110
119
  /**
111
120
  * One row of the bell. Which of the optional targets are present depends on
@@ -127,6 +136,9 @@ export declare const NOTIFICATION_PREFERENCE_OF: {
127
136
  * community_invite community
128
137
  * community_announcement community, content (the pinned post or poll)
129
138
  * community_suggestion_decided suggestion, community (once approved)
139
+ * plan_ending plan (the tier, and when it ends)
140
+ * plan_ended plan (the tier that ended), paused (how many products)
141
+ * payment_refunded payment
130
142
  *
131
143
  * Any row about something inside a community also carries `community`
132
144
  * (0.9.0), whatever its kind. When the recipient leaves the community, is
@@ -155,6 +167,9 @@ export declare const notificationSchema: z.ZodObject<{
155
167
  community_invite: "community_invite";
156
168
  community_announcement: "community_announcement";
157
169
  community_suggestion_decided: "community_suggestion_decided";
170
+ plan_ending: "plan_ending";
171
+ plan_ended: "plan_ended";
172
+ payment_refunded: "payment_refunded";
158
173
  }>;
159
174
  actor: z.ZodNullable<z.ZodObject<{
160
175
  userId: z.ZodString;
@@ -201,6 +216,18 @@ export declare const notificationSchema: z.ZodObject<{
201
216
  }>;
202
217
  reason: z.ZodOptional<z.ZodString>;
203
218
  }, z.core.$strip>>;
219
+ plan: z.ZodOptional<z.ZodObject<{
220
+ tier: z.ZodEnum<{
221
+ premium: "premium";
222
+ business: "business";
223
+ }>;
224
+ endsAt: z.ZodISODateTime;
225
+ }, z.core.$strip>>;
226
+ paused: z.ZodOptional<z.ZodNumber>;
227
+ payment: z.ZodOptional<z.ZodObject<{
228
+ id: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
229
+ title: z.ZodString;
230
+ }, z.core.$strip>>;
204
231
  role: z.ZodOptional<z.ZodEnum<{
205
232
  team: "team";
206
233
  cofounder: "cofounder";
@@ -240,6 +267,9 @@ export declare const notificationPageSchema: z.ZodObject<{
240
267
  community_invite: "community_invite";
241
268
  community_announcement: "community_announcement";
242
269
  community_suggestion_decided: "community_suggestion_decided";
270
+ plan_ending: "plan_ending";
271
+ plan_ended: "plan_ended";
272
+ payment_refunded: "payment_refunded";
243
273
  }>;
244
274
  actor: z.ZodNullable<z.ZodObject<{
245
275
  userId: z.ZodString;
@@ -286,6 +316,18 @@ export declare const notificationPageSchema: z.ZodObject<{
286
316
  }>;
287
317
  reason: z.ZodOptional<z.ZodString>;
288
318
  }, z.core.$strip>>;
319
+ plan: z.ZodOptional<z.ZodObject<{
320
+ tier: z.ZodEnum<{
321
+ premium: "premium";
322
+ business: "business";
323
+ }>;
324
+ endsAt: z.ZodISODateTime;
325
+ }, z.core.$strip>>;
326
+ paused: z.ZodOptional<z.ZodNumber>;
327
+ payment: z.ZodOptional<z.ZodObject<{
328
+ id: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
329
+ title: z.ZodString;
330
+ }, z.core.$strip>>;
289
331
  role: z.ZodOptional<z.ZodEnum<{
290
332
  team: "team";
291
333
  cofounder: "cofounder";
@@ -1 +1 @@
1
- {"version":3,"file":"notifications.d.ts","sourceRoot":"","sources":["../../../src/domains/notifications/notifications.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AASxB;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,wBAAwB,8VAiB3B,CAAC;AACX,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;EAAmC,CAAC;AACvE,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,kEAAkE;AAClE,eAAO,MAAM,8BAA8B,2GAQjC,CAAC;AACX,eAAO,MAAM,4BAA4B;;;;;;;;EAAyC,CAAC;AACnF,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAElF;;;GAGG;AACH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;CAiBqC,CAAC;AAE7E;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAmD7B,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAsC,CAAC;AAC1E,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,iBAAiB;AACjB,eAAO,MAAM,6BAA6B;;iBAExC,CAAC;AACH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAEpF,eAAO,MAAM,wBAAwB;;iBAA+C,CAAC;AACrF,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E,+CAA+C;AAC/C,eAAO,MAAM,6BAA6B;;;;;;;;iBAWxC,CAAC;AACH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAEpF,kFAAkF;AAClF,eAAO,MAAM,uCAAuC;;;;;;;;iBAQlD,CAAC;AACH,MAAM,MAAM,iCAAiC,GAAG,CAAC,CAAC,KAAK,CACrD,OAAO,uCAAuC,CAC/C,CAAC"}
1
+ {"version":3,"file":"notifications.d.ts","sourceRoot":"","sources":["../../../src/domains/notifications/notifications.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAUxB;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,eAAO,MAAM,wBAAwB,+YAoB3B,CAAC;AACX,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;EAAmC,CAAC;AACvE,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,kEAAkE;AAClE,eAAO,MAAM,8BAA8B,2GAQjC,CAAC;AACX,eAAO,MAAM,4BAA4B;;;;;;;;EAAyC,CAAC;AACnF,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAElF;;;GAGG;AACH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;CAoBqC,CAAC;AAE7E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAyD7B,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAsC,CAAC;AAC1E,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,iBAAiB;AACjB,eAAO,MAAM,6BAA6B;;iBAExC,CAAC;AACH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAEpF,eAAO,MAAM,wBAAwB;;iBAA+C,CAAC;AACrF,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E,+CAA+C;AAC/C,eAAO,MAAM,6BAA6B;;;;;;;;iBAWxC,CAAC;AACH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAEpF,kFAAkF;AAClF,eAAO,MAAM,uCAAuC;;;;;;;;iBAQlD,CAAC;AACH,MAAM,MAAM,iCAAiC,GAAG,CAAC,CAAC,KAAK,CACrD,OAAO,uCAAuC,CAC/C,CAAC"}
@@ -34,6 +34,7 @@ import { NOTIFICATION_EXCERPT_MAX } from '../../core/limits.js';
34
34
  import { paginatedSchema } from '../../core/responses.js';
35
35
  import { communityChipSchema } from '../communities/communities.js';
36
36
  import { contentKindSchema, reactionTypeSchema } from '../feed/feed.js';
37
+ import { planTierSchema } from '../membership/membership.js';
37
38
  import { productChipSchema, productInvitableRoleSchema } from '../products/products.js';
38
39
  import { memberBylineSchema } from '../profile/founder-profile.js';
39
40
  /**
@@ -55,6 +56,9 @@ import { memberBylineSchema } from '../profile/founder-profile.js';
55
56
  * community_invite a community invited you (always delivered)
56
57
  * community_announcement a community you are in pinned an announcement for everyone
57
58
  * community_suggestion_decided your community suggestion was approved or declined (always delivered)
59
+ * plan_ending your plan ends in 7 days, then in 1 day (0.12.0, always delivered)
60
+ * plan_ended your plan ended; `paused` products were paused (0.12.0, always delivered)
61
+ * payment_refunded staff refunded one of your payments (0.12.0, always delivered)
58
62
  *
59
63
  * The three 0.8.0 kinds merge per target like the others. A reaction counts
60
64
  * once: changing it to another type is not a new event, and taking it back
@@ -77,6 +81,9 @@ export const NOTIFICATION_KIND_VALUES = [
77
81
  'community_invite',
78
82
  'community_announcement',
79
83
  'community_suggestion_decided',
84
+ 'plan_ending',
85
+ 'plan_ended',
86
+ 'payment_refunded',
80
87
  ];
81
88
  export const notificationKindSchema = z.enum(NOTIFICATION_KIND_VALUES);
82
89
  /** The switches a member has, each covering one or more kinds. */
@@ -111,6 +118,9 @@ export const NOTIFICATION_PREFERENCE_OF = {
111
118
  community_invite: null,
112
119
  community_announcement: 'communities',
113
120
  community_suggestion_decided: null,
121
+ plan_ending: null,
122
+ plan_ended: null,
123
+ payment_refunded: null,
114
124
  };
115
125
  /**
116
126
  * One row of the bell. Which of the optional targets are present depends on
@@ -132,6 +142,9 @@ export const NOTIFICATION_PREFERENCE_OF = {
132
142
  * community_invite community
133
143
  * community_announcement community, content (the pinned post or poll)
134
144
  * community_suggestion_decided suggestion, community (once approved)
145
+ * plan_ending plan (the tier, and when it ends)
146
+ * plan_ended plan (the tier that ended), paused (how many products)
147
+ * payment_refunded payment
135
148
  *
136
149
  * Any row about something inside a community also carries `community`
137
150
  * (0.9.0), whatever its kind. When the recipient leaves the community, is
@@ -176,6 +189,12 @@ export const notificationSchema = z.object({
176
189
  reason: z.string().optional(),
177
190
  })
178
191
  .optional(),
192
+ /** For `plan_ending` and `plan_ended` (0.12.0): which tier, and when it ends or ended. */
193
+ plan: z.object({ tier: planTierSchema, endsAt: z.iso.datetime() }).optional(),
194
+ /** For `plan_ended` (0.12.0): products paused because the plan's live places went. */
195
+ paused: z.number().int().nonnegative().optional(),
196
+ /** For `payment_refunded` (0.12.0): which purchase, by its title. */
197
+ payment: z.object({ id: objectIdSchema, title: z.string() }).optional(),
179
198
  /** For `product_invite`: the role offered. */
180
199
  role: productInvitableRoleSchema.optional(),
181
200
  /** For the reaction kinds: the latest reaction, as it is now (0.8.0). */