@glissandoo/lib 1.116.0 → 1.118.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 (58) hide show
  1. package/functions/event.d.ts +22 -0
  2. package/functions/eventPlayer.d.ts +2 -0
  3. package/functions/eventoPayout.d.ts +70 -0
  4. package/functions/eventoPayout.js +2 -0
  5. package/functions/groupModule.d.ts +13 -0
  6. package/functions/groupModule.js +2 -0
  7. package/functions/groupPayment.d.ts +62 -0
  8. package/functions/groupPayment.js +2 -0
  9. package/functions/groupPayoutRule.d.ts +18 -0
  10. package/functions/groupPayoutRule.js +2 -0
  11. package/functions/index.d.ts +12 -0
  12. package/functions/index.js +12 -0
  13. package/functions/regions.js +12 -0
  14. package/helpers/appScenes.d.ts +2 -0
  15. package/helpers/appScenes.js +2 -0
  16. package/helpers/currency.d.ts +4 -0
  17. package/helpers/currency.js +277 -0
  18. package/helpers/errors.d.ts +7 -1
  19. package/helpers/errors.js +6 -0
  20. package/helpers/paymentForecast.d.ts +37 -0
  21. package/helpers/paymentForecast.js +58 -0
  22. package/helpers/payoutRules.d.ts +45 -0
  23. package/helpers/payoutRules.js +166 -0
  24. package/lang/ca.json +6 -0
  25. package/lang/de.json +6 -0
  26. package/lang/en.json +6 -0
  27. package/lang/es.json +6 -0
  28. package/lang/eu.json +6 -0
  29. package/lang/fr.json +6 -0
  30. package/lang/gl.json +6 -0
  31. package/lang/it.json +6 -0
  32. package/lang/nl.json +6 -0
  33. package/lang/pt.json +6 -0
  34. package/models/Evento/Player/basic.d.ts +1 -0
  35. package/models/Evento/Player/basic.js +3 -0
  36. package/models/Evento/Player/index.d.ts +1 -0
  37. package/models/Evento/Player/index.js +3 -0
  38. package/models/Evento/Player/types.d.ts +1 -0
  39. package/models/Evento/index.d.ts +2 -0
  40. package/models/Evento/index.js +6 -0
  41. package/models/Evento/types.d.ts +14 -1
  42. package/models/Evento/types.js +3 -0
  43. package/models/Group/Payment/index.d.ts +45 -0
  44. package/models/Group/Payment/index.js +110 -0
  45. package/models/Group/Payment/supabase.d.ts +16 -0
  46. package/models/Group/Payment/supabase.js +46 -0
  47. package/models/Group/Payment/types.d.ts +96 -0
  48. package/models/Group/Payment/types.js +26 -0
  49. package/models/Group/index.d.ts +8 -1
  50. package/models/Group/index.js +19 -0
  51. package/models/Group/types.d.ts +30 -0
  52. package/models/Group/types.js +14 -1
  53. package/models/Notification/types.d.ts +4 -1
  54. package/models/Notification/types.js +3 -0
  55. package/package.json +1 -1
  56. package/types/payoutRule.d.ts +126 -0
  57. package/types/payoutRule.js +34 -0
  58. package/types/payoutRule.ts +132 -0
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const types_1 = require("./types");
4
+ /**
5
+ * Plain-object model for a `group_payment` row. Mirrors the previous
6
+ * Firestore-backed model API so dashboard components keep working with
7
+ * `payment.foo` getters. Build with `new GroupPayment(rowData)` where
8
+ * `rowData` is the deserialized DB record (or a snapshot built from a
9
+ * realtime callback).
10
+ *
11
+ * Timestamp getters return native `Date` objects so consumers can call
12
+ * `.getTime()` / format them with `date-fns`/`dayjs` directly.
13
+ */
14
+ class GroupPayment {
15
+ constructor(data) {
16
+ this.id = data.id;
17
+ this._data = data;
18
+ this.exists = true;
19
+ }
20
+ get data() {
21
+ return this._data;
22
+ }
23
+ get groupId() {
24
+ return this._data.groupId;
25
+ }
26
+ get type() {
27
+ return this._data.type;
28
+ }
29
+ get isIncome() {
30
+ return this.type === types_1.GroupPaymentType.Income;
31
+ }
32
+ get isExpense() {
33
+ return this.type === types_1.GroupPaymentType.Expense;
34
+ }
35
+ get eventId() {
36
+ return this._data.eventId || null;
37
+ }
38
+ get playerId() {
39
+ return this._data.playerId || null;
40
+ }
41
+ get concept() {
42
+ return this._data.concept || '';
43
+ }
44
+ get assignedTo() {
45
+ return this._data.assignedTo || '';
46
+ }
47
+ get totalAmount() {
48
+ return this._data.totalAmount;
49
+ }
50
+ get baseAmount() {
51
+ return this._data.baseAmount ?? this._data.totalAmount;
52
+ }
53
+ get appliedRules() {
54
+ return this._data.appliedRules || [];
55
+ }
56
+ get currency() {
57
+ return this._data.currency || 'EUR';
58
+ }
59
+ get displayTotal() {
60
+ if (this.totalAmount === null)
61
+ return '— €';
62
+ const sign = this.isExpense ? '-' : '';
63
+ return `${sign}${this.totalAmount} €`;
64
+ }
65
+ get status() {
66
+ return this._data.status;
67
+ }
68
+ get isPending() {
69
+ return this.status === types_1.GroupPaymentStatus.Pending;
70
+ }
71
+ get isPaid() {
72
+ return this.status === types_1.GroupPaymentStatus.Paid;
73
+ }
74
+ get isCancelled() {
75
+ return this.status === types_1.GroupPaymentStatus.Cancelled;
76
+ }
77
+ get paymentMethod() {
78
+ return this._data.paymentMethod || null;
79
+ }
80
+ get history() {
81
+ return this._data.history || [];
82
+ }
83
+ get historyOrdered() {
84
+ return this.history
85
+ .slice()
86
+ .sort((a, b) => new Date(a.changedAt).getTime() < new Date(b.changedAt).getTime() ? 1 : -1);
87
+ }
88
+ get paidAt() {
89
+ return this._data.paidAt ? new Date(this._data.paidAt) : null;
90
+ }
91
+ get paidBy() {
92
+ return this._data.paidBy || null;
93
+ }
94
+ get note() {
95
+ return this._data.note || null;
96
+ }
97
+ get createdAt() {
98
+ return new Date(this._data.createdAt);
99
+ }
100
+ get createdBy() {
101
+ return this._data.createdBy;
102
+ }
103
+ get editedAt() {
104
+ return this._data.editedAt ? new Date(this._data.editedAt) : null;
105
+ }
106
+ get editedBy() {
107
+ return this._data.editedBy || null;
108
+ }
109
+ }
110
+ exports.default = GroupPayment;
@@ -0,0 +1,16 @@
1
+ import { Database } from '../../../types/supabase';
2
+ import { GroupPaymentData, GroupPaymentHistoryItem } from './types';
3
+ export type GroupPaymentRow = Database['public']['Tables']['group_payment']['Row'];
4
+ export type GroupPaymentInsert = Database['public']['Tables']['group_payment']['Insert'];
5
+ export type GroupPaymentUpdate = Database['public']['Tables']['group_payment']['Update'];
6
+ export type GroupPaymentHistoryRow = Database['public']['Tables']['group_payment_history']['Row'];
7
+ export type GroupPaymentHistoryInsert = Database['public']['Tables']['group_payment_history']['Insert'];
8
+ export declare const GROUP_PAYMENT_TABLE: "group_payment";
9
+ export declare const GROUP_PAYMENT_HISTORY_TABLE: "group_payment_history";
10
+ /**
11
+ * Convert a raw `group_payment` DB row into the canonical `GroupPaymentData`
12
+ * shape consumed by the `GroupPayment` model. `history` defaults to an empty
13
+ * array; hydrate it from the history table when needed.
14
+ */
15
+ export declare function rowToGroupPaymentData(row: GroupPaymentRow, history?: GroupPaymentHistoryItem[]): GroupPaymentData;
16
+ export declare function historyRowToItem(row: GroupPaymentHistoryRow): GroupPaymentHistoryItem;
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.historyRowToItem = exports.rowToGroupPaymentData = exports.GROUP_PAYMENT_HISTORY_TABLE = exports.GROUP_PAYMENT_TABLE = void 0;
4
+ exports.GROUP_PAYMENT_TABLE = 'group_payment';
5
+ exports.GROUP_PAYMENT_HISTORY_TABLE = 'group_payment_history';
6
+ /**
7
+ * Convert a raw `group_payment` DB row into the canonical `GroupPaymentData`
8
+ * shape consumed by the `GroupPayment` model. `history` defaults to an empty
9
+ * array; hydrate it from the history table when needed.
10
+ */
11
+ function rowToGroupPaymentData(row, history = []) {
12
+ return {
13
+ id: row.id,
14
+ groupId: row.groupId,
15
+ type: row.type,
16
+ eventId: row.eventId,
17
+ playerId: row.playerId,
18
+ concept: row.concept,
19
+ assignedTo: row.assignedTo,
20
+ totalAmount: row.totalAmount === null ? null : Number(row.totalAmount),
21
+ baseAmount: row.baseAmount === null ? null : Number(row.baseAmount),
22
+ appliedRules: row.appliedRules ?? [],
23
+ currency: row.currency,
24
+ status: row.status,
25
+ history,
26
+ paymentMethod: row.paymentMethod ?? null,
27
+ paidAt: row.paidAt,
28
+ paidBy: row.paidBy,
29
+ note: row.note,
30
+ createdAt: row.createdAt,
31
+ createdBy: row.createdBy,
32
+ editedAt: row.updatedAt,
33
+ editedBy: row.editedBy,
34
+ };
35
+ }
36
+ exports.rowToGroupPaymentData = rowToGroupPaymentData;
37
+ function historyRowToItem(row) {
38
+ return {
39
+ action: row.action,
40
+ oldValue: row.old_value,
41
+ newValue: row.new_value,
42
+ changedAt: row.changed_at,
43
+ changedBy: row.changed_by,
44
+ };
45
+ }
46
+ exports.historyRowToItem = historyRowToItem;
@@ -0,0 +1,96 @@
1
+ import { AppliedRuleEntry } from '../../../helpers/payoutRules';
2
+ export declare enum GroupPaymentType {
3
+ Income = "income",
4
+ Expense = "expense"
5
+ }
6
+ export declare enum GroupPaymentStatus {
7
+ Pending = "pending",
8
+ Paid = "paid",
9
+ Cancelled = "cancelled"
10
+ }
11
+ export declare enum GroupPaymentMethod {
12
+ Cash = "cash",
13
+ Transfer = "transfer"
14
+ }
15
+ export declare enum GroupPaymentHistoryAction {
16
+ Status = "status",
17
+ Amount = "amount",
18
+ Concept = "concept",
19
+ Method = "method"
20
+ }
21
+ /**
22
+ * Unified audit entry for a payment. Each entry records one change to a
23
+ * single field (status, amount, concept or method) with the previous and
24
+ * new values, who performed it and when.
25
+ *
26
+ * For the very first entry (creation), `oldValue` is `null` and `newValue`
27
+ * holds the initial status.
28
+ *
29
+ * Timestamps are ISO 8601 strings (Postgres `timestamptz` representation).
30
+ */
31
+ export interface GroupPaymentHistoryItem {
32
+ action: GroupPaymentHistoryAction;
33
+ oldValue: string | number | null;
34
+ newValue: string | number | null;
35
+ changedAt: string;
36
+ changedBy: string;
37
+ }
38
+ /**
39
+ * Flat payment record at the group level — represents both incomes
40
+ * (e.g. event payout owed to a musician) and expenses (e.g. fuel reimbursement,
41
+ * supplier invoice). Persisted in Postgres (`public.group_payment`).
42
+ *
43
+ * `totalAmount` is always positive; the sign is encoded by `type`.
44
+ *
45
+ * `assignedTo` is a free-form string: it may be a userId (a player), a groupId
46
+ * (the band itself), or any free string (external supplier name).
47
+ *
48
+ * `playerId` is only set when the payment originates from rollcall — it links
49
+ * the payment back to the attendee via `eventPlayer.paymentId`.
50
+ *
51
+ * Timestamps are ISO 8601 strings.
52
+ */
53
+ export interface GroupPaymentData {
54
+ id: string;
55
+ groupId: string;
56
+ type: GroupPaymentType;
57
+ eventId: string | null;
58
+ playerId: string | null;
59
+ concept: string;
60
+ assignedTo: string;
61
+ /**
62
+ * Positive amount. `null` only while the payment is Pending (e.g. payouts
63
+ * waiting for the admin to fix a per-member share). Transitioning to Paid
64
+ * requires a concrete number.
65
+ */
66
+ totalAmount: number | null;
67
+ /**
68
+ * `importByMember` at the moment the payment was created/recomputed.
69
+ * Equals `totalAmount` when no rules apply. `null` mirrors `totalAmount`
70
+ * when the per-member share is "to be determined".
71
+ */
72
+ baseAmount: number | null;
73
+ /**
74
+ * Snapshot of the event payout rules that affected this player, ordered
75
+ * by `order`. Empty array when no rules matched. Used for traceability
76
+ * and to drive the breakdown tooltip in the UI.
77
+ */
78
+ appliedRules: AppliedRuleEntry[];
79
+ currency: string;
80
+ status: GroupPaymentStatus;
81
+ /**
82
+ * In-memory audit trail loaded from `group_payment_history`. Empty `[]`
83
+ * when not hydrated. Use the model's `historyOrdered` getter for a desc
84
+ * view.
85
+ */
86
+ history: GroupPaymentHistoryItem[];
87
+ paymentMethod: GroupPaymentMethod | null;
88
+ paidAt: string | null;
89
+ paidBy: string | null;
90
+ note: string | null;
91
+ createdAt: string;
92
+ createdBy: string;
93
+ editedAt: string | null;
94
+ editedBy: string | null;
95
+ }
96
+ export type AGroupPaymentData = GroupPaymentData;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GroupPaymentHistoryAction = exports.GroupPaymentMethod = exports.GroupPaymentStatus = exports.GroupPaymentType = void 0;
4
+ var GroupPaymentType;
5
+ (function (GroupPaymentType) {
6
+ GroupPaymentType["Income"] = "income";
7
+ GroupPaymentType["Expense"] = "expense";
8
+ })(GroupPaymentType = exports.GroupPaymentType || (exports.GroupPaymentType = {}));
9
+ var GroupPaymentStatus;
10
+ (function (GroupPaymentStatus) {
11
+ GroupPaymentStatus["Pending"] = "pending";
12
+ GroupPaymentStatus["Paid"] = "paid";
13
+ GroupPaymentStatus["Cancelled"] = "cancelled";
14
+ })(GroupPaymentStatus = exports.GroupPaymentStatus || (exports.GroupPaymentStatus = {}));
15
+ var GroupPaymentMethod;
16
+ (function (GroupPaymentMethod) {
17
+ GroupPaymentMethod["Cash"] = "cash";
18
+ GroupPaymentMethod["Transfer"] = "transfer";
19
+ })(GroupPaymentMethod = exports.GroupPaymentMethod || (exports.GroupPaymentMethod = {}));
20
+ var GroupPaymentHistoryAction;
21
+ (function (GroupPaymentHistoryAction) {
22
+ GroupPaymentHistoryAction["Status"] = "status";
23
+ GroupPaymentHistoryAction["Amount"] = "amount";
24
+ GroupPaymentHistoryAction["Concept"] = "concept";
25
+ GroupPaymentHistoryAction["Method"] = "method";
26
+ })(GroupPaymentHistoryAction = exports.GroupPaymentHistoryAction || (exports.GroupPaymentHistoryAction = {}));
@@ -1,10 +1,11 @@
1
1
  import { DocumentReference } from '@google-cloud/firestore';
2
2
  import { PlansGroup } from '../../helpers/plans';
3
3
  import { LanguagesTypes } from '../../lang';
4
+ import { GroupPayoutRuleEntry } from '../../types/payoutRule';
4
5
  import { EventPlayerStatus } from '../Evento/Player/types';
5
6
  import { DocumentModel } from '../Model';
6
7
  import GroupBasic from './basic';
7
- import { AGroupCustomField, AGroupInstrument, AdminPermissions, CustomGroupInstrument, GroupConfigShowAttendanceToMembers, GroupData, GroupStatus, SocialNetwork } from './types';
8
+ import { AGroupCustomField, AGroupInstrument, AdminPermissions, CustomGroupInstrument, GroupConfigShowAttendanceToMembers, GroupData, GroupModuleData, GroupModuleId, GroupModules, GroupStatus, SocialNetwork } from './types';
8
9
  export default class Group extends GroupBasic<GroupData> {
9
10
  constructor(doc: DocumentModel, lang?: LanguagesTypes);
10
11
  get owner(): DocumentReference;
@@ -32,6 +33,8 @@ export default class Group extends GroupBasic<GroupData> {
32
33
  get eventTotalCount(): number;
33
34
  get communicationCount(): number;
34
35
  get country(): string;
36
+ get currency(): string;
37
+ get currencySymbol(): string;
35
38
  get activePlayers(): string[];
36
39
  get playersList(): {
37
40
  id: string;
@@ -130,4 +133,8 @@ export default class Group extends GroupBasic<GroupData> {
130
133
  get customFieldsList(): AGroupCustomField[];
131
134
  get inventoryId(): string;
132
135
  get coverURL(): string | null;
136
+ get modules(): GroupModules;
137
+ getModule(id: GroupModuleId): GroupModuleData | null;
138
+ isModuleEnabled(id: GroupModuleId): boolean;
139
+ get payoutRules(): GroupPayoutRuleEntry[];
133
140
  }
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const date_fns_1 = require("date-fns");
7
7
  const lodash_1 = require("lodash");
8
8
  const collections_1 = require("../../helpers/collections");
9
+ const currency_1 = require("../../helpers/currency");
9
10
  const glissandooAdmin_1 = require("../../helpers/glissandooAdmin");
10
11
  const orders_1 = require("../../helpers/instruments/orders");
11
12
  const objects_1 = require("../../helpers/objects");
@@ -108,6 +109,12 @@ class Group extends basic_1.default {
108
109
  get country() {
109
110
  return this.data.country || 'ES';
110
111
  }
112
+ get currency() {
113
+ return this.data.currency || currency_1.DEFAULT_CURRENCY;
114
+ }
115
+ get currencySymbol() {
116
+ return (0, currency_1.getCurrencySymbol)(this.currency, this.lang);
117
+ }
111
118
  get activePlayers() {
112
119
  return Object.keys(this.players);
113
120
  }
@@ -301,5 +308,17 @@ class Group extends basic_1.default {
301
308
  get coverURL() {
302
309
  return this.data.coverURL || null;
303
310
  }
311
+ get modules() {
312
+ return this.data.modules || {};
313
+ }
314
+ getModule(id) {
315
+ return this.modules[id] || null;
316
+ }
317
+ isModuleEnabled(id) {
318
+ return !!this.getModule(id)?.enabled;
319
+ }
320
+ get payoutRules() {
321
+ return this.data.payoutRules || [];
322
+ }
304
323
  }
305
324
  exports.default = Group;
@@ -3,6 +3,7 @@ import { CustomInstrumentId, DefaultInstrumentId } from '../../helpers/instrumen
3
3
  import { MusicStyleType } from '../../helpers/musicStyles';
4
4
  import { PlansGroup } from '../../helpers/plans';
5
5
  import { CreatedOn } from '../../helpers/types';
6
+ import { GroupPayoutRuleEntry } from '../../types/payoutRule';
6
7
  import { EventPlayerStatus } from '../Evento/Player/types';
7
8
  import { EventType } from '../Evento/types';
8
9
  import { PlayerBasicData } from '../Player/types';
@@ -97,6 +98,32 @@ export declare enum GroupStatus {
97
98
  Inactive = "inactive",
98
99
  Deleted = "deleted"
99
100
  }
101
+ export declare enum GroupModuleId {
102
+ Payout = "payout",
103
+ Inventory = "inventory",
104
+ Vacancies = "vacancies",
105
+ Partnership = "partnership",
106
+ MusicSchool = "musicSchool"
107
+ }
108
+ export declare enum GroupModulePlan {
109
+ Free = "free",
110
+ Paid = "paid"
111
+ }
112
+ export interface GroupModuleData {
113
+ enabled: boolean;
114
+ activatedAt: Timestamp | null;
115
+ activatedBy: string | null;
116
+ disabledAt: Timestamp | null;
117
+ disabledBy: string | null;
118
+ plan: GroupModulePlan;
119
+ /**
120
+ * Reserved for future Stripe integration. Not used yet.
121
+ */
122
+ subscriptionId: string | null;
123
+ stripeCustomerId: string | null;
124
+ stripeSubscriptionId: string | null;
125
+ }
126
+ export type GroupModules = Partial<Record<GroupModuleId, GroupModuleData>>;
100
127
  export declare enum SocialNetwork {
101
128
  Facebook = "facebook",
102
129
  Twitter = "twitter",
@@ -242,6 +269,7 @@ export interface GroupData extends GroupBasicData {
242
269
  eventCount: Record<EventType, number>;
243
270
  communicationCount: number;
244
271
  country: string;
272
+ currency: string;
245
273
  instruments: GroupInstruments;
246
274
  metadata: Record<string, string>;
247
275
  firstAnswerAt: Timestamp | null;
@@ -254,6 +282,8 @@ export interface GroupData extends GroupBasicData {
254
282
  customFields: Record<string, GroupCustomField>;
255
283
  inventoryId: string;
256
284
  coverURL: string | null;
285
+ modules: GroupModules;
286
+ payoutRules: GroupPayoutRuleEntry[];
257
287
  readonly createdOn: CreatedOn;
258
288
  readonly owner: DocumentReference;
259
289
  readonly createdAt: Timestamp;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.GroupRepertoireTagDefault = exports.GroupRepertoireTagReserved = exports.SocialNetwork = exports.GroupStatus = exports.GroupConfigShowAttendanceToMembers = exports.GroupConfigSitesKey = exports.GroupConfigKey = exports.AdminPermissions = exports.GroupCustomFieldType = exports.GroupHistoryAction = void 0;
3
+ exports.GroupRepertoireTagDefault = exports.GroupRepertoireTagReserved = exports.SocialNetwork = exports.GroupModulePlan = exports.GroupModuleId = exports.GroupStatus = exports.GroupConfigShowAttendanceToMembers = exports.GroupConfigSitesKey = exports.GroupConfigKey = exports.AdminPermissions = exports.GroupCustomFieldType = exports.GroupHistoryAction = void 0;
4
4
  var GroupHistoryAction;
5
5
  (function (GroupHistoryAction) {
6
6
  GroupHistoryAction["Created"] = "created";
@@ -74,6 +74,19 @@ var GroupStatus;
74
74
  GroupStatus["Inactive"] = "inactive";
75
75
  GroupStatus["Deleted"] = "deleted";
76
76
  })(GroupStatus = exports.GroupStatus || (exports.GroupStatus = {}));
77
+ var GroupModuleId;
78
+ (function (GroupModuleId) {
79
+ GroupModuleId["Payout"] = "payout";
80
+ GroupModuleId["Inventory"] = "inventory";
81
+ GroupModuleId["Vacancies"] = "vacancies";
82
+ GroupModuleId["Partnership"] = "partnership";
83
+ GroupModuleId["MusicSchool"] = "musicSchool";
84
+ })(GroupModuleId = exports.GroupModuleId || (exports.GroupModuleId = {}));
85
+ var GroupModulePlan;
86
+ (function (GroupModulePlan) {
87
+ GroupModulePlan["Free"] = "free";
88
+ GroupModulePlan["Paid"] = "paid";
89
+ })(GroupModulePlan = exports.GroupModulePlan || (exports.GroupModulePlan = {}));
77
90
  var SocialNetwork;
78
91
  (function (SocialNetwork) {
79
92
  SocialNetwork["Facebook"] = "facebook";
@@ -148,7 +148,10 @@ export declare enum NotificationActions {
148
148
  GroupOnboardingEvent = "group.onboarding.event",
149
149
  OfferApplicantAdd = "offer.applicant.add",
150
150
  OfferSelectApplicant = "offer.select.applicant",
151
- OfferAlarm = "offer.alarm"
151
+ OfferAlarm = "offer.alarm",
152
+ GroupPaymentPaid = "groupPayment.paid",
153
+ GroupPaymentCancelled = "groupPayment.cancelled",
154
+ GroupPaymentAmountChanged = "groupPayment.amountChanged"
152
155
  }
153
156
  export declare enum NotificationActionsFilter {
154
157
  EventCreated = "eventCreated",
@@ -146,6 +146,9 @@ var NotificationActions;
146
146
  NotificationActions["OfferApplicantAdd"] = "offer.applicant.add";
147
147
  NotificationActions["OfferSelectApplicant"] = "offer.select.applicant";
148
148
  NotificationActions["OfferAlarm"] = "offer.alarm";
149
+ NotificationActions["GroupPaymentPaid"] = "groupPayment.paid";
150
+ NotificationActions["GroupPaymentCancelled"] = "groupPayment.cancelled";
151
+ NotificationActions["GroupPaymentAmountChanged"] = "groupPayment.amountChanged";
149
152
  })(NotificationActions = exports.NotificationActions || (exports.NotificationActions = {}));
150
153
  var NotificationActionsFilter;
151
154
  (function (NotificationActionsFilter) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@glissandoo/lib",
3
- "version": "1.116.0",
3
+ "version": "1.118.0",
4
4
  "description": "Glissandoo library js",
5
5
  "main": "./index.js",
6
6
  "types": "./index.d.ts",
@@ -0,0 +1,126 @@
1
+ import { Timestamp } from '@google-cloud/firestore';
2
+ /**
3
+ * Shared types for the payout rules engine.
4
+ * Rules live at two levels:
5
+ * - Group level (templates, can be `pinned` to auto-apply to new events)
6
+ * - Event level (snapshot copied from the group when payout is initialized)
7
+ */
8
+ export declare enum PayoutRuleType {
9
+ EntityShare = "entityShare",
10
+ DefaultExpense = "defaultExpense",
11
+ PlayerMultiplier = "playerMultiplier",
12
+ PlayerBonus = "playerBonus",
13
+ PlayerFixed = "playerFixed",
14
+ PlayerExclude = "playerExclude"
15
+ }
16
+ export declare enum PayoutRuleConditionOperator {
17
+ Eq = "eq",
18
+ Neq = "neq",
19
+ Gt = "gt",
20
+ Gte = "gte",
21
+ Lt = "lt",
22
+ Lte = "lte",
23
+ In = "in",
24
+ Nin = "nin"
25
+ }
26
+ export type PayoutRuleConditionFieldKind = 'mainInstrument' | 'isGuest' | `custom.${string}`;
27
+ export type PayoutRuleConditionValue = string | number | boolean | string[] | number[] | null;
28
+ export interface PayoutRuleCondition {
29
+ field: PayoutRuleConditionFieldKind;
30
+ operator: PayoutRuleConditionOperator;
31
+ value: PayoutRuleConditionValue;
32
+ }
33
+ export declare enum PayoutRuleEntityShareMode {
34
+ Fixed = "fixed",
35
+ Percentage = "percentage"
36
+ }
37
+ export interface PayoutRuleEntityShareEffect {
38
+ mode: PayoutRuleEntityShareMode;
39
+ value: number;
40
+ }
41
+ export interface PayoutRuleDefaultExpenseEffect {
42
+ concept: string;
43
+ amount: number;
44
+ /**
45
+ * `null` = expense remains general (reduces the shared pot).
46
+ * Future: could materialize per-attendee expenses.
47
+ */
48
+ assignTo: null;
49
+ }
50
+ export interface PayoutRulePlayerMultiplierEffect {
51
+ multiplier: number;
52
+ }
53
+ export interface PayoutRulePlayerBonusEffect {
54
+ amount: number;
55
+ }
56
+ export interface PayoutRulePlayerFixedEffect {
57
+ amount: number;
58
+ }
59
+ export type PayoutRulePlayerExcludeEffect = Record<string, never>;
60
+ export type PayoutRuleEffect = {
61
+ type: PayoutRuleType.EntityShare;
62
+ data: PayoutRuleEntityShareEffect;
63
+ } | {
64
+ type: PayoutRuleType.DefaultExpense;
65
+ data: PayoutRuleDefaultExpenseEffect;
66
+ } | {
67
+ type: PayoutRuleType.PlayerMultiplier;
68
+ data: PayoutRulePlayerMultiplierEffect;
69
+ } | {
70
+ type: PayoutRuleType.PlayerBonus;
71
+ data: PayoutRulePlayerBonusEffect;
72
+ } | {
73
+ type: PayoutRuleType.PlayerFixed;
74
+ data: PayoutRulePlayerFixedEffect;
75
+ } | {
76
+ type: PayoutRuleType.PlayerExclude;
77
+ data: PayoutRulePlayerExcludeEffect;
78
+ };
79
+ /**
80
+ * Common shape stored in both group templates and event snapshots.
81
+ */
82
+ export interface PayoutRuleBaseData {
83
+ name: string;
84
+ description: string | null;
85
+ order: number;
86
+ conditions: PayoutRuleCondition[];
87
+ effect: PayoutRuleEffect;
88
+ createdAt: Timestamp;
89
+ createdBy: string;
90
+ editedAt: Timestamp | null;
91
+ editedBy: string | null;
92
+ }
93
+ /**
94
+ * Helper used by the pure rules engine. Holds the minimal data
95
+ * required to evaluate conditions against a player.
96
+ */
97
+ export interface PayoutRulePlayerInput {
98
+ id: string;
99
+ mainInstrument: string;
100
+ isGuest: boolean;
101
+ customFields: Record<string, string | number | boolean | null>;
102
+ }
103
+ export interface GroupPayoutRuleEntry {
104
+ id: string;
105
+ name: string;
106
+ order: number;
107
+ pinned: boolean;
108
+ conditions: PayoutRuleCondition[];
109
+ effect: PayoutRuleEffect;
110
+ createdAt: Timestamp;
111
+ createdBy: string;
112
+ editedAt: Timestamp | null;
113
+ editedBy: string | null;
114
+ }
115
+ export interface EventoPayoutRuleEntry {
116
+ id: string;
117
+ name: string;
118
+ order: number;
119
+ sourceGroupRuleId: string | null;
120
+ conditions: PayoutRuleCondition[];
121
+ effect: PayoutRuleEffect;
122
+ createdAt: Timestamp;
123
+ createdBy: string;
124
+ editedAt: Timestamp | null;
125
+ editedBy: string | null;
126
+ }
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PayoutRuleEntityShareMode = exports.PayoutRuleConditionOperator = exports.PayoutRuleType = void 0;
4
+ /**
5
+ * Shared types for the payout rules engine.
6
+ * Rules live at two levels:
7
+ * - Group level (templates, can be `pinned` to auto-apply to new events)
8
+ * - Event level (snapshot copied from the group when payout is initialized)
9
+ */
10
+ var PayoutRuleType;
11
+ (function (PayoutRuleType) {
12
+ PayoutRuleType["EntityShare"] = "entityShare";
13
+ PayoutRuleType["DefaultExpense"] = "defaultExpense";
14
+ PayoutRuleType["PlayerMultiplier"] = "playerMultiplier";
15
+ PayoutRuleType["PlayerBonus"] = "playerBonus";
16
+ PayoutRuleType["PlayerFixed"] = "playerFixed";
17
+ PayoutRuleType["PlayerExclude"] = "playerExclude";
18
+ })(PayoutRuleType = exports.PayoutRuleType || (exports.PayoutRuleType = {}));
19
+ var PayoutRuleConditionOperator;
20
+ (function (PayoutRuleConditionOperator) {
21
+ PayoutRuleConditionOperator["Eq"] = "eq";
22
+ PayoutRuleConditionOperator["Neq"] = "neq";
23
+ PayoutRuleConditionOperator["Gt"] = "gt";
24
+ PayoutRuleConditionOperator["Gte"] = "gte";
25
+ PayoutRuleConditionOperator["Lt"] = "lt";
26
+ PayoutRuleConditionOperator["Lte"] = "lte";
27
+ PayoutRuleConditionOperator["In"] = "in";
28
+ PayoutRuleConditionOperator["Nin"] = "nin";
29
+ })(PayoutRuleConditionOperator = exports.PayoutRuleConditionOperator || (exports.PayoutRuleConditionOperator = {}));
30
+ var PayoutRuleEntityShareMode;
31
+ (function (PayoutRuleEntityShareMode) {
32
+ PayoutRuleEntityShareMode["Fixed"] = "fixed";
33
+ PayoutRuleEntityShareMode["Percentage"] = "percentage";
34
+ })(PayoutRuleEntityShareMode = exports.PayoutRuleEntityShareMode || (exports.PayoutRuleEntityShareMode = {}));