@odla-ai/chapter 0.15.1 → 0.16.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.
@@ -233,9 +233,47 @@ interface ChapterConfig {
233
233
  * (owner-editable at runtime); this is the trigger, which is a build-time
234
234
  * decision. See {@link ChapterSends}. */
235
235
  sends?: ChapterSends;
236
+ /** Site policy for admin operations (approve side effects, refund rules).
237
+ * See {@link ChapterOperations}. */
238
+ operations?: ChapterOperations;
236
239
  }
237
240
  /** Apply-time Clerk account provisioning model. */
238
241
  type AccountModel = "invite" | "create" | "none";
242
+ /** Site policy for admin OPERATIONS: the DECISIONS, where the mechanics stay
243
+ * package-owned. Same model as {@link ChapterSends} — a site declares the rule,
244
+ * chapter enforces it. Distinct from {@link ChapterPolicy}, which is member-facing
245
+ * copy. (The privilege-escalation rules are NOT here: they are package-enforced
246
+ * in `canChangeRole`, gated on `auth.superAdmins`, so a site cannot weaken them.) */
247
+ interface ChapterOperations {
248
+ /** What approving an application does. */
249
+ onApprove?: {
250
+ /** Role to promote the applicant to in Clerk. Defaults to the ladder rung
251
+ * directly below admin (e.g. `"member"`); `false` promotes nobody. */
252
+ promoteTo?: string | false;
253
+ /** Group email template to send on approve. Default `"onboardingInvite"`;
254
+ * `false` sends nothing. */
255
+ send?: string | false;
256
+ };
257
+ /** Refund rules. */
258
+ refund?: {
259
+ /** Application statuses a refund may be issued from. Default: any status. */
260
+ allowedFrom?: readonly string[];
261
+ /** Also cancel the Stripe subscription. Default `true`. */
262
+ cancelSubscription?: boolean;
263
+ };
264
+ }
265
+ /** The fully-resolved {@link ChapterOperations} carried on the {@link Chapter}. */
266
+ interface ResolvedOperations {
267
+ onApprove: {
268
+ promoteTo: string | false;
269
+ send: string | false;
270
+ };
271
+ /** `allowedFrom: null` means "any status". */
272
+ refund: {
273
+ allowedFrom: readonly string[] | null;
274
+ cancelSubscription: boolean;
275
+ };
276
+ }
239
277
  /** When the admin notification fires: on application `submit` (default), on the
240
278
  * first successful `payment`, or `never` (the site drives it itself). */
241
279
  type AdminNotificationTrigger = "submit" | "payment" | "never";
@@ -270,6 +308,8 @@ interface Chapter {
270
308
  account: AccountModel;
271
309
  /** Resolved send policy — when each lifecycle email fires. */
272
310
  sends: ResolvedSends;
311
+ /** Resolved admin-operation policy (approve side effects, refund rules). */
312
+ operations: ResolvedOperations;
273
313
  /** The seed `groups` row derived from config (chapter mode), else `null`. */
274
314
  groupSeed(): Record<string, unknown> | null;
275
315
  }
@@ -233,9 +233,47 @@ interface ChapterConfig {
233
233
  * (owner-editable at runtime); this is the trigger, which is a build-time
234
234
  * decision. See {@link ChapterSends}. */
235
235
  sends?: ChapterSends;
236
+ /** Site policy for admin operations (approve side effects, refund rules).
237
+ * See {@link ChapterOperations}. */
238
+ operations?: ChapterOperations;
236
239
  }
237
240
  /** Apply-time Clerk account provisioning model. */
238
241
  type AccountModel = "invite" | "create" | "none";
242
+ /** Site policy for admin OPERATIONS: the DECISIONS, where the mechanics stay
243
+ * package-owned. Same model as {@link ChapterSends} — a site declares the rule,
244
+ * chapter enforces it. Distinct from {@link ChapterPolicy}, which is member-facing
245
+ * copy. (The privilege-escalation rules are NOT here: they are package-enforced
246
+ * in `canChangeRole`, gated on `auth.superAdmins`, so a site cannot weaken them.) */
247
+ interface ChapterOperations {
248
+ /** What approving an application does. */
249
+ onApprove?: {
250
+ /** Role to promote the applicant to in Clerk. Defaults to the ladder rung
251
+ * directly below admin (e.g. `"member"`); `false` promotes nobody. */
252
+ promoteTo?: string | false;
253
+ /** Group email template to send on approve. Default `"onboardingInvite"`;
254
+ * `false` sends nothing. */
255
+ send?: string | false;
256
+ };
257
+ /** Refund rules. */
258
+ refund?: {
259
+ /** Application statuses a refund may be issued from. Default: any status. */
260
+ allowedFrom?: readonly string[];
261
+ /** Also cancel the Stripe subscription. Default `true`. */
262
+ cancelSubscription?: boolean;
263
+ };
264
+ }
265
+ /** The fully-resolved {@link ChapterOperations} carried on the {@link Chapter}. */
266
+ interface ResolvedOperations {
267
+ onApprove: {
268
+ promoteTo: string | false;
269
+ send: string | false;
270
+ };
271
+ /** `allowedFrom: null` means "any status". */
272
+ refund: {
273
+ allowedFrom: readonly string[] | null;
274
+ cancelSubscription: boolean;
275
+ };
276
+ }
239
277
  /** When the admin notification fires: on application `submit` (default), on the
240
278
  * first successful `payment`, or `never` (the site drives it itself). */
241
279
  type AdminNotificationTrigger = "submit" | "payment" | "never";
@@ -270,6 +308,8 @@ interface Chapter {
270
308
  account: AccountModel;
271
309
  /** Resolved send policy — when each lifecycle email fires. */
272
310
  sends: ResolvedSends;
311
+ /** Resolved admin-operation policy (approve side effects, refund rules). */
312
+ operations: ResolvedOperations;
273
313
  /** The seed `groups` row derived from config (chapter mode), else `null`. */
274
314
  groupSeed(): Record<string, unknown> | null;
275
315
  }