ad2app-lib 1.50.0 → 1.59.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.
- package/dist/analytics/index.d.ts +53 -2
- package/dist/analytics/index.js +14 -0
- package/dist/types/I_AccessDenial.d.ts +7 -0
- package/dist/types/I_AccessDenial.js +7 -0
- package/dist/types/agency-campaigns.d.ts +70 -3
- package/dist/types/agency-campaigns.js +56 -3
- package/dist/types/agency-threads.d.ts +22 -1
- package/dist/types/agency.d.ts +93 -6
- package/dist/types/agency.js +70 -3
- package/dist/types/dealroom.d.ts +651 -0
- package/dist/types/dealroom.js +387 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.js +2 -0
- package/package.json +1 -1
- package/src/analytics/index.test.ts +11 -0
- package/src/analytics/index.ts +46 -2
- package/src/types/I_AccessDenial.ts +7 -0
- package/src/types/access-denial.test.ts +2 -1
- package/src/types/agency-campaigns.ts +108 -2
- package/src/types/agency-threads.ts +14 -3
- package/src/types/agency.ts +120 -7
- package/src/types/consumer-compat.test.ts +90 -0
- package/src/types/dealroom-audit1.test.ts +56 -0
- package/src/types/dealroom-wave2.test.ts +61 -0
- package/src/types/dealroom-wave3.test.ts +68 -0
- package/src/types/dealroom-wave4.test.ts +103 -0
- package/src/types/dealroom.test.ts +231 -0
- package/src/types/dealroom.ts +868 -0
- package/src/types/index.ts +3 -0
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Dealroom (spec 148): only what spec 175 has no concept of.
|
|
4
|
+
*
|
|
5
|
+
* The organization, membership, grant, campaign, offer loop, materials,
|
|
6
|
+
* threads and pots are 175's (`agency*.ts`); 148 adds unions there and keeps
|
|
7
|
+
* this file for the open listing, matching, the coarse creator row, its codes,
|
|
8
|
+
* the dormant money layer and the commission lane.
|
|
9
|
+
*
|
|
10
|
+
* The money types below are DORMANT: the backend refuses every money act with
|
|
11
|
+
* `dealroom-money-disabled` until the money release (FR-027). Their state
|
|
12
|
+
* lists mirror data-model.md's state machine exactly.
|
|
13
|
+
*
|
|
14
|
+
* See specs/148-dealroom/contracts/lib-types.md.
|
|
15
|
+
*/
|
|
16
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
17
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
18
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
19
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
20
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
21
|
+
};
|
|
22
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
23
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.DealroomCalendarQueryDto = exports.DEALROOM_CALENDAR_MAX_DAYS = exports.DEALROOM_CALENDAR_KINDS = exports.ReviewCommissionAdSpaceDto = exports.COMMISSION_AD_SPACE_DECISIONS = exports.COMMISSION_AD_SPACE_STATES = exports.COMMISSION_JOIN_STATES = exports.COMMISSION_MATERIAL_KINDS = exports.COMMISSION_LINK_MODES = exports.COMMISSION_LINK_STATES = exports.COMMISSION_OFFER_STATES = exports.COMMISSION_NETWORKS = exports.UpsertPayoutProfileDto = exports.PAYOUT_PROFILE_FIELDS = exports.DEAL_MONEY_ACTIONS = exports.StartDealPaymentDto = exports.DEAL_PAYMENT_METHODS = exports.CreateDealContractDto = exports.DEAL_SIGNATURE_LEVELS = exports.DEAL_CONTRACT_STATES = exports.DEAL_CONTRACT_SOURCES = exports.DEALROOM_MONEY_EVENT_KINDS = exports.PAYOUT_LEDGER_STATES = exports.PAYOUT_LEDGER_SOURCES = exports.PAYOUT_BILLING_VARIANTS = exports.DEAL_PAYOUT_STATES = exports.DEAL_MONEY_STATES = exports.DEALROOM_CODES = exports.ApplyToDealroomListingDto = exports.DEALROOM_LISTING_STATES = exports.DEALROOM_PROFILE_FIELDS = exports.isCampaignVisibility = exports.CAMPAIGN_VISIBILITIES = void 0;
|
|
27
|
+
const class_validator_1 = require("class-validator");
|
|
28
|
+
const agency_1 = require("./agency");
|
|
29
|
+
// ── Open listing ─────────────────────────────────────────────────────────────
|
|
30
|
+
/** `private` is every 175 campaign today (members only); `open` is listed in the feed to matching creators. */
|
|
31
|
+
exports.CAMPAIGN_VISIBILITIES = ['private', 'open'];
|
|
32
|
+
const isCampaignVisibility = (value) => exports.CAMPAIGN_VISIBILITIES.includes(value);
|
|
33
|
+
exports.isCampaignVisibility = isCampaignVisibility;
|
|
34
|
+
/** The profile fields whose absence makes the feed `profile_incomplete` (FR-026). */
|
|
35
|
+
exports.DEALROOM_PROFILE_FIELDS = ['country', 'niches'];
|
|
36
|
+
// ── The organization's side of a listing (US3) ──────────────────────────────
|
|
37
|
+
/**
|
|
38
|
+
* Derived, never stored: `draft` (175 isDraft) → `live` (open, not closed,
|
|
39
|
+
* before its deadline, a slot free) → `frozen` (live, and a creator has been
|
|
40
|
+
* invited or applied: only the deadline, the slots and closing may change) →
|
|
41
|
+
* `closed` (closed by the organization, past its deadline, or full).
|
|
42
|
+
*/
|
|
43
|
+
exports.DEALROOM_LISTING_STATES = ['draft', 'live', 'frozen', 'closed'];
|
|
44
|
+
// ── Applying (US4) ───────────────────────────────────────────────────────────
|
|
45
|
+
/**
|
|
46
|
+
* `POST /dealroom/listings/:campaignId/apply`. `scopes`: what the creator
|
|
47
|
+
* shares, a non-empty subset of the listing's `askedScopes`. An offer
|
|
48
|
+
* listing takes the opening price (`priceMinor` + `currency`); a pot listing
|
|
49
|
+
* takes the creator's own terms (`guaranteeMinor` + `ratePer1000Minor`).
|
|
50
|
+
*/
|
|
51
|
+
class ApplyToDealroomListingDto {
|
|
52
|
+
constructor(data) {
|
|
53
|
+
this.scopes = data?.scopes ?? [];
|
|
54
|
+
this.priceMinor = data?.priceMinor;
|
|
55
|
+
this.currency = data?.currency;
|
|
56
|
+
this.guaranteeMinor = data?.guaranteeMinor;
|
|
57
|
+
this.ratePer1000Minor = data?.ratePer1000Minor;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
exports.ApplyToDealroomListingDto = ApplyToDealroomListingDto;
|
|
61
|
+
__decorate([
|
|
62
|
+
(0, class_validator_1.IsArray)(),
|
|
63
|
+
(0, class_validator_1.ArrayNotEmpty)(),
|
|
64
|
+
(0, class_validator_1.IsIn)(agency_1.AGENCY_GRANT_SCOPES, { each: true }),
|
|
65
|
+
__metadata("design:type", Array)
|
|
66
|
+
], ApplyToDealroomListingDto.prototype, "scopes", void 0);
|
|
67
|
+
__decorate([
|
|
68
|
+
(0, class_validator_1.IsOptional)(),
|
|
69
|
+
(0, class_validator_1.IsInt)(),
|
|
70
|
+
(0, class_validator_1.Min)(0),
|
|
71
|
+
(0, class_validator_1.Max)(1000000000),
|
|
72
|
+
__metadata("design:type", Number)
|
|
73
|
+
], ApplyToDealroomListingDto.prototype, "priceMinor", void 0);
|
|
74
|
+
__decorate([
|
|
75
|
+
(0, class_validator_1.IsOptional)(),
|
|
76
|
+
(0, class_validator_1.IsString)(),
|
|
77
|
+
(0, class_validator_1.Matches)(/^[A-Z]{3}$/),
|
|
78
|
+
__metadata("design:type", String)
|
|
79
|
+
], ApplyToDealroomListingDto.prototype, "currency", void 0);
|
|
80
|
+
__decorate([
|
|
81
|
+
(0, class_validator_1.IsOptional)(),
|
|
82
|
+
(0, class_validator_1.IsInt)(),
|
|
83
|
+
(0, class_validator_1.Min)(0),
|
|
84
|
+
(0, class_validator_1.Max)(1000000000),
|
|
85
|
+
__metadata("design:type", Number)
|
|
86
|
+
], ApplyToDealroomListingDto.prototype, "guaranteeMinor", void 0);
|
|
87
|
+
__decorate([
|
|
88
|
+
(0, class_validator_1.IsOptional)(),
|
|
89
|
+
(0, class_validator_1.IsInt)(),
|
|
90
|
+
(0, class_validator_1.Min)(0),
|
|
91
|
+
(0, class_validator_1.Max)(1000000000),
|
|
92
|
+
__metadata("design:type", Number)
|
|
93
|
+
], ApplyToDealroomListingDto.prototype, "ratePer1000Minor", void 0);
|
|
94
|
+
// ── Codes ────────────────────────────────────────────────────────────────────
|
|
95
|
+
/** Refusal codes the frontend owes its own copy for (contracts/dealroom-api.md). */
|
|
96
|
+
exports.DEALROOM_CODES = {
|
|
97
|
+
OFFER_FILLED: 'dealroom-offer-filled',
|
|
98
|
+
LISTING_FROZEN: 'dealroom-listing-frozen',
|
|
99
|
+
NEAR_MATCH_NOT_APPLIABLE: 'dealroom-near-match-not-appliable',
|
|
100
|
+
PROFILE_INCOMPLETE: 'dealroom-profile-incomplete',
|
|
101
|
+
BRAND_DOOR_CLOSED: 'dealroom-brand-door-closed',
|
|
102
|
+
BRAND_NO_ROSTER: 'dealroom-brand-no-roster',
|
|
103
|
+
DELEGATE_FORBIDDEN: 'dealroom-delegate-forbidden',
|
|
104
|
+
DELEGATE_OWN_DEAL: 'dealroom-delegate-own-deal',
|
|
105
|
+
/** A delegate never writes the creator's grant consent: joining with an access request, or an apply that would create or widen the grant's reads. */
|
|
106
|
+
DELEGATE_CONSENT_FORBIDDEN: 'dealroom-delegate-consent-forbidden',
|
|
107
|
+
/** The money switch is off: every money route and act answers 404 with this code (FR-027). Means nothing else. */
|
|
108
|
+
MONEY_DISABLED: 'dealroom-money-disabled',
|
|
109
|
+
/** Money on, but a value the act needs is not configured yet (e.g. the deal's deposit %). 422. */
|
|
110
|
+
CONFIG_MISSING: 'dealroom-config-missing',
|
|
111
|
+
/** Money on, but the platform contract template is still waiting for counsel: upload your own. 422. */
|
|
112
|
+
TEMPLATE_PENDING: 'dealroom-template-pending',
|
|
113
|
+
/** An open listing needs the organization's logo first (US2). 400. */
|
|
114
|
+
LOGO_REQUIRED: 'dealroom-logo-required',
|
|
115
|
+
CONTRACT_UNSIGNED: 'dealroom-contract-unsigned',
|
|
116
|
+
DEPOSIT_REQUIRED: 'dealroom-deposit-required',
|
|
117
|
+
NOT_FUNDED: 'dealroom-not-funded',
|
|
118
|
+
/** Money release: the agreed amount is under the fee config's minimum deal. */
|
|
119
|
+
DEAL_BELOW_MINIMUM: 'dealroom-deal-below-minimum',
|
|
120
|
+
/** Money release: that money act is not open at the deal's current step. */
|
|
121
|
+
MONEY_WRONG_STEP: 'dealroom-money-wrong-step',
|
|
122
|
+
/** Money release: the deal already has a contract out for signature or signed. */
|
|
123
|
+
CONTRACT_EXISTS: 'dealroom-contract-exists',
|
|
124
|
+
/** Money release: no guarantee is configured, or the claim is not open yet. */
|
|
125
|
+
GUARANTEE_UNAVAILABLE: 'dealroom-guarantee-unavailable',
|
|
126
|
+
/** Commission lane (2026-10-07): the creator's Admitad Ad Space is still under admin review; no link yet. */
|
|
127
|
+
COMMISSION_AD_SPACE_PENDING: 'commission-ad-space-pending',
|
|
128
|
+
/** Commission lane (2026-10-07): the creator's Admitad Ad Space was rejected or suspended; no Admitad link. */
|
|
129
|
+
COMMISSION_AD_SPACE_UNAVAILABLE: 'commission-ad-space-unavailable',
|
|
130
|
+
/** Admin: that decision is not open from the Ad Space's state (a suspended or rejected Ad Space is never re-registered under a new id). */
|
|
131
|
+
COMMISSION_AD_SPACE_DECISION_CLOSED: 'commission-ad-space-decision-closed',
|
|
132
|
+
/** The network did not answer a join or a registration; nothing was written. */
|
|
133
|
+
COMMISSION_NETWORK_UNAVAILABLE: 'commission-network-unavailable',
|
|
134
|
+
};
|
|
135
|
+
// ── Money (DORMANT until the money release) ──────────────────────────────────
|
|
136
|
+
/**
|
|
137
|
+
* The deal's money state (FR-010), exactly data-model.md's machine:
|
|
138
|
+
*
|
|
139
|
+
* awaiting_material → material_submitted → deposit_paid → funded → approved → published
|
|
140
|
+
* deposit declined → closed_unviewed
|
|
141
|
+
* funded/approved, never published → refund_pending → refunded
|
|
142
|
+
* delivered, never funded → guarantee_claimed
|
|
143
|
+
*
|
|
144
|
+
* The payout after publication is its own column (DEAL_PAYOUT_STATES).
|
|
145
|
+
*/
|
|
146
|
+
exports.DEAL_MONEY_STATES = [
|
|
147
|
+
'awaiting_material',
|
|
148
|
+
'material_submitted',
|
|
149
|
+
'deposit_paid',
|
|
150
|
+
'funded',
|
|
151
|
+
'approved',
|
|
152
|
+
'published',
|
|
153
|
+
'closed_unviewed',
|
|
154
|
+
'refund_pending',
|
|
155
|
+
'refunded',
|
|
156
|
+
'guarantee_claimed',
|
|
157
|
+
];
|
|
158
|
+
exports.DEAL_PAYOUT_STATES = ['none', 'initiated', 'paid'];
|
|
159
|
+
/** Derived from 175's settlement form (`invoice` → faktura_vat, `contract` → umowa_o_dzielo); `international` is 148's. */
|
|
160
|
+
exports.PAYOUT_BILLING_VARIANTS = ['faktura_vat', 'umowa_o_dzielo', 'international'];
|
|
161
|
+
exports.PAYOUT_LEDGER_SOURCES = ['deal', 'pot', 'commission'];
|
|
162
|
+
/** Commission entries are `validated` only after the network pays us. */
|
|
163
|
+
exports.PAYOUT_LEDGER_STATES = ['earned', 'validated', 'paid'];
|
|
164
|
+
// ── Money release, wave 4 (DORMANT): contract step, deal money, payouts ──────
|
|
165
|
+
/** The contract, money and payout kinds this release writes into 175's event log (FR-008a). */
|
|
166
|
+
exports.DEALROOM_MONEY_EVENT_KINDS = [
|
|
167
|
+
'contract_sent',
|
|
168
|
+
'contract_signed',
|
|
169
|
+
'contract_declined',
|
|
170
|
+
'deposit_paid',
|
|
171
|
+
'deal_funded',
|
|
172
|
+
'deal_closed_unviewed',
|
|
173
|
+
'deal_refund_requested',
|
|
174
|
+
'deal_refunded',
|
|
175
|
+
'guarantee_claimed',
|
|
176
|
+
'payout_initiated',
|
|
177
|
+
'payout_paid',
|
|
178
|
+
];
|
|
179
|
+
exports.DEAL_CONTRACT_SOURCES = ['template', 'uploaded'];
|
|
180
|
+
/** `draft` again after a signer declines; `signed` once every party signed (the e-sign provider's word). */
|
|
181
|
+
exports.DEAL_CONTRACT_STATES = ['draft', 'sent', 'signed'];
|
|
182
|
+
/** SES by default, QES as an option (research R2; counsel point 3 may require QES for some documents). */
|
|
183
|
+
exports.DEAL_SIGNATURE_LEVELS = ['SES', 'QES'];
|
|
184
|
+
/**
|
|
185
|
+
* `POST /agency/campaigns/:id/members/:memberId/contract` (organization side).
|
|
186
|
+
* `template`: the form fields (deliverables default to the brief's, the rate is
|
|
187
|
+
* the agreed price). `uploaded`: the organization's own file, base64.
|
|
188
|
+
*/
|
|
189
|
+
class CreateDealContractDto {
|
|
190
|
+
constructor(data) {
|
|
191
|
+
this.source = data?.source ?? 'template';
|
|
192
|
+
this.signatureLevel = data?.signatureLevel;
|
|
193
|
+
this.deliverables = data?.deliverables;
|
|
194
|
+
this.draftDueAt = data?.draftDueAt;
|
|
195
|
+
this.liveByAt = data?.liveByAt;
|
|
196
|
+
this.licenceMonths = data?.licenceMonths;
|
|
197
|
+
this.paidPromoMonths = data?.paidPromoMonths;
|
|
198
|
+
this.fileName = data?.fileName;
|
|
199
|
+
this.fileBase64 = data?.fileBase64;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
exports.CreateDealContractDto = CreateDealContractDto;
|
|
203
|
+
__decorate([
|
|
204
|
+
(0, class_validator_1.IsIn)(exports.DEAL_CONTRACT_SOURCES),
|
|
205
|
+
__metadata("design:type", String)
|
|
206
|
+
], CreateDealContractDto.prototype, "source", void 0);
|
|
207
|
+
__decorate([
|
|
208
|
+
(0, class_validator_1.IsOptional)(),
|
|
209
|
+
(0, class_validator_1.IsIn)(exports.DEAL_SIGNATURE_LEVELS),
|
|
210
|
+
__metadata("design:type", String)
|
|
211
|
+
], CreateDealContractDto.prototype, "signatureLevel", void 0);
|
|
212
|
+
__decorate([
|
|
213
|
+
(0, class_validator_1.IsOptional)(),
|
|
214
|
+
(0, class_validator_1.IsArray)(),
|
|
215
|
+
(0, class_validator_1.ArrayMaxSize)(20),
|
|
216
|
+
(0, class_validator_1.IsString)({ each: true }),
|
|
217
|
+
(0, class_validator_1.MaxLength)(500, { each: true }),
|
|
218
|
+
__metadata("design:type", Array)
|
|
219
|
+
], CreateDealContractDto.prototype, "deliverables", void 0);
|
|
220
|
+
__decorate([
|
|
221
|
+
(0, class_validator_1.IsOptional)(),
|
|
222
|
+
(0, class_validator_1.IsDateString)(),
|
|
223
|
+
__metadata("design:type", String)
|
|
224
|
+
], CreateDealContractDto.prototype, "draftDueAt", void 0);
|
|
225
|
+
__decorate([
|
|
226
|
+
(0, class_validator_1.IsOptional)(),
|
|
227
|
+
(0, class_validator_1.IsDateString)(),
|
|
228
|
+
__metadata("design:type", String)
|
|
229
|
+
], CreateDealContractDto.prototype, "liveByAt", void 0);
|
|
230
|
+
__decorate([
|
|
231
|
+
(0, class_validator_1.IsOptional)(),
|
|
232
|
+
(0, class_validator_1.IsInt)(),
|
|
233
|
+
(0, class_validator_1.Min)(0),
|
|
234
|
+
(0, class_validator_1.Max)(120),
|
|
235
|
+
__metadata("design:type", Number)
|
|
236
|
+
], CreateDealContractDto.prototype, "licenceMonths", void 0);
|
|
237
|
+
__decorate([
|
|
238
|
+
(0, class_validator_1.IsOptional)(),
|
|
239
|
+
(0, class_validator_1.IsInt)(),
|
|
240
|
+
(0, class_validator_1.Min)(0),
|
|
241
|
+
(0, class_validator_1.Max)(120),
|
|
242
|
+
__metadata("design:type", Number)
|
|
243
|
+
], CreateDealContractDto.prototype, "paidPromoMonths", void 0);
|
|
244
|
+
__decorate([
|
|
245
|
+
(0, class_validator_1.IsOptional)(),
|
|
246
|
+
(0, class_validator_1.IsString)(),
|
|
247
|
+
(0, class_validator_1.MaxLength)(255),
|
|
248
|
+
__metadata("design:type", String)
|
|
249
|
+
], CreateDealContractDto.prototype, "fileName", void 0);
|
|
250
|
+
__decorate([
|
|
251
|
+
(0, class_validator_1.IsOptional)(),
|
|
252
|
+
(0, class_validator_1.IsString)(),
|
|
253
|
+
__metadata("design:type", String)
|
|
254
|
+
], CreateDealContractDto.prototype, "fileBase64", void 0);
|
|
255
|
+
/** Card (PaymentIntent, confirmed in the browser) or invoice (a Stripe invoice the organization pays by transfer). */
|
|
256
|
+
exports.DEAL_PAYMENT_METHODS = ['card', 'invoice'];
|
|
257
|
+
/** `POST /agency/campaigns/:id/members/:memberId/deal/deposit|fund`. Big sums go by invoice whatever is asked. */
|
|
258
|
+
class StartDealPaymentDto {
|
|
259
|
+
constructor(data) {
|
|
260
|
+
this.method = data?.method;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
exports.StartDealPaymentDto = StartDealPaymentDto;
|
|
264
|
+
__decorate([
|
|
265
|
+
(0, class_validator_1.IsOptional)(),
|
|
266
|
+
(0, class_validator_1.IsIn)(exports.DEAL_PAYMENT_METHODS),
|
|
267
|
+
__metadata("design:type", String)
|
|
268
|
+
], StartDealPaymentDto.prototype, "method", void 0);
|
|
269
|
+
/** The money acts a deal view may offer; the server decides which, per side and step. */
|
|
270
|
+
exports.DEAL_MONEY_ACTIONS = ['send_contract', 'pay_deposit', 'decline_deposit', 'fund', 'refund', 'claim_guarantee'];
|
|
271
|
+
/** What the first payout needs and is missing; the provider's KYC runs behind the form and is never a field. */
|
|
272
|
+
exports.PAYOUT_PROFILE_FIELDS = ['settlement_form', 'nip', 'tax_statement', 'intl_billing_data', 'iban', 'payout_currency'];
|
|
273
|
+
/**
|
|
274
|
+
* `PUT /dealroom/payouts/profile`. The track is NOT here: it is read from the
|
|
275
|
+
* 175 settlement form. `international` picks the international variant.
|
|
276
|
+
*/
|
|
277
|
+
class UpsertPayoutProfileDto {
|
|
278
|
+
constructor(data) {
|
|
279
|
+
this.international = data?.international;
|
|
280
|
+
this.nip = data?.nip;
|
|
281
|
+
this.taxStatement = data?.taxStatement;
|
|
282
|
+
this.intlBillingData = data?.intlBillingData;
|
|
283
|
+
this.iban = data?.iban ?? '';
|
|
284
|
+
this.payoutCurrency = data?.payoutCurrency ?? '';
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
exports.UpsertPayoutProfileDto = UpsertPayoutProfileDto;
|
|
288
|
+
__decorate([
|
|
289
|
+
(0, class_validator_1.IsOptional)(),
|
|
290
|
+
(0, class_validator_1.IsBoolean)(),
|
|
291
|
+
__metadata("design:type", Boolean)
|
|
292
|
+
], UpsertPayoutProfileDto.prototype, "international", void 0);
|
|
293
|
+
__decorate([
|
|
294
|
+
(0, class_validator_1.IsOptional)(),
|
|
295
|
+
(0, class_validator_1.IsString)(),
|
|
296
|
+
(0, class_validator_1.Matches)(/^[0-9]{10}$/),
|
|
297
|
+
__metadata("design:type", String)
|
|
298
|
+
], UpsertPayoutProfileDto.prototype, "nip", void 0);
|
|
299
|
+
__decorate([
|
|
300
|
+
(0, class_validator_1.IsOptional)(),
|
|
301
|
+
(0, class_validator_1.IsString)(),
|
|
302
|
+
(0, class_validator_1.MaxLength)(2000),
|
|
303
|
+
__metadata("design:type", String)
|
|
304
|
+
], UpsertPayoutProfileDto.prototype, "taxStatement", void 0);
|
|
305
|
+
__decorate([
|
|
306
|
+
(0, class_validator_1.IsOptional)(),
|
|
307
|
+
(0, class_validator_1.IsObject)(),
|
|
308
|
+
__metadata("design:type", Object)
|
|
309
|
+
], UpsertPayoutProfileDto.prototype, "intlBillingData", void 0);
|
|
310
|
+
__decorate([
|
|
311
|
+
(0, class_validator_1.IsString)(),
|
|
312
|
+
(0, class_validator_1.Matches)(/^[A-Z]{2}[0-9]{2}(?:\s?[A-Z0-9]){11,30}$/),
|
|
313
|
+
__metadata("design:type", String)
|
|
314
|
+
], UpsertPayoutProfileDto.prototype, "iban", void 0);
|
|
315
|
+
__decorate([
|
|
316
|
+
(0, class_validator_1.IsString)(),
|
|
317
|
+
(0, class_validator_1.Matches)(/^[A-Z]{3}$/),
|
|
318
|
+
__metadata("design:type", String)
|
|
319
|
+
], UpsertPayoutProfileDto.prototype, "payoutCurrency", void 0);
|
|
320
|
+
// ── Commission lane ──────────────────────────────────────────────────────────
|
|
321
|
+
exports.COMMISSION_NETWORKS = ['awin', 'admitad'];
|
|
322
|
+
exports.COMMISSION_OFFER_STATES = ['live', 'paused', 'gone'];
|
|
323
|
+
exports.COMMISSION_LINK_STATES = ['active', 'suspended'];
|
|
324
|
+
/**
|
|
325
|
+
* `subnetwork`: minted from OUR publisher account with the creator's own
|
|
326
|
+
* attribution (Awin `clickref` = creator id; Admitad = the creator's registered
|
|
327
|
+
* Ad Space). `deeplink`: the fallback while a network's subnetwork mode is off,
|
|
328
|
+
* a plain link to the programme on the network, carrying no attribution of ours.
|
|
329
|
+
*/
|
|
330
|
+
exports.COMMISSION_LINK_MODES = ['subnetwork', 'deeplink'];
|
|
331
|
+
/** An advertiser creative as the network feed carries it (2026-10-07). */
|
|
332
|
+
exports.COMMISSION_MATERIAL_KINDS = ['logo', 'banner', 'landing_preview', 'coupon'];
|
|
333
|
+
/** `POST /dealroom/commission/offers/:id/join`: what the join produced. */
|
|
334
|
+
exports.COMMISSION_JOIN_STATES = ['link', 'deeplink', 'ad_space_pending'];
|
|
335
|
+
// ── Commission lane: the Admitad Ad Space per creator (2026-10-07) ───────────
|
|
336
|
+
/**
|
|
337
|
+
* One static Ad Space per creator (Admitad Subnetwork Code of Conduct §3.1/§5):
|
|
338
|
+
* created `pending_review` on the first Admitad join, `registered` through the
|
|
339
|
+
* Partner networks API after an admin approves, or `rejected` / `suspended`.
|
|
340
|
+
* Its id is never rotated, deleted or reassigned.
|
|
341
|
+
*/
|
|
342
|
+
exports.COMMISSION_AD_SPACE_STATES = ['pending_review', 'registered', 'rejected', 'suspended'];
|
|
343
|
+
exports.COMMISSION_AD_SPACE_DECISIONS = ['approve', 'reject', 'suspend'];
|
|
344
|
+
/** `PATCH /admin/dealroom/commission/ad-spaces/:id`. */
|
|
345
|
+
class ReviewCommissionAdSpaceDto {
|
|
346
|
+
constructor(data) {
|
|
347
|
+
this.decision = data?.decision;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
exports.ReviewCommissionAdSpaceDto = ReviewCommissionAdSpaceDto;
|
|
351
|
+
__decorate([
|
|
352
|
+
(0, class_validator_1.IsIn)(exports.COMMISSION_AD_SPACE_DECISIONS),
|
|
353
|
+
__metadata("design:type", String)
|
|
354
|
+
], ReviewCommissionAdSpaceDto.prototype, "decision", void 0);
|
|
355
|
+
// ── The calendar (US9, T041) ─────────────────────────────────────────────────
|
|
356
|
+
/**
|
|
357
|
+
* What a deal date on the creator's calendar is. No second deadline store:
|
|
358
|
+
* `milestone` is a 175 milestone (`campaign-deadlines`, the creator's own or
|
|
359
|
+
* campaign-wide); the pot dates are the US9 schedule; `publish_at` is the
|
|
360
|
+
* agreed publication time (a pot entry's, or an offer deal's, T067).
|
|
361
|
+
*/
|
|
362
|
+
exports.DEALROOM_CALENDAR_KINDS = [
|
|
363
|
+
'milestone',
|
|
364
|
+
'application_deadline',
|
|
365
|
+
'materials_due',
|
|
366
|
+
'publication_due',
|
|
367
|
+
'publish_at',
|
|
368
|
+
'bonus_ends',
|
|
369
|
+
'keep_up_ends',
|
|
370
|
+
];
|
|
371
|
+
/** The calendar window: both ends required, at most DEALROOM_CALENDAR_MAX_DAYS apart. */
|
|
372
|
+
exports.DEALROOM_CALENDAR_MAX_DAYS = 400;
|
|
373
|
+
class DealroomCalendarQueryDto {
|
|
374
|
+
constructor(data) {
|
|
375
|
+
this.from = data?.from ?? '';
|
|
376
|
+
this.to = data?.to ?? '';
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
exports.DealroomCalendarQueryDto = DealroomCalendarQueryDto;
|
|
380
|
+
__decorate([
|
|
381
|
+
(0, class_validator_1.IsDateString)(),
|
|
382
|
+
__metadata("design:type", String)
|
|
383
|
+
], DealroomCalendarQueryDto.prototype, "from", void 0);
|
|
384
|
+
__decorate([
|
|
385
|
+
(0, class_validator_1.IsDateString)(),
|
|
386
|
+
__metadata("design:type", String)
|
|
387
|
+
], DealroomCalendarQueryDto.prototype, "to", void 0);
|
package/dist/types/index.d.ts
CHANGED
package/dist/types/index.js
CHANGED
|
@@ -60,5 +60,7 @@ __exportStar(require("./agency"), exports);
|
|
|
60
60
|
__exportStar(require("./agency-campaigns"), exports);
|
|
61
61
|
__exportStar(require("./agency-pots"), exports);
|
|
62
62
|
__exportStar(require("./agency-threads"), exports);
|
|
63
|
+
// ── Dealroom (spec 148): what 175 has no concept of ──────────────────────────
|
|
64
|
+
__exportStar(require("./dealroom"), exports);
|
|
63
65
|
// ── Access control ────────────────────────────────────────────────────────────
|
|
64
66
|
__exportStar(require("./I_AccessDenial"), exports);
|
package/package.json
CHANGED
|
@@ -247,6 +247,17 @@ const EVENT_PROPERTY_WITNESS: { [E in keyof EventProperties]: EventProperties[E]
|
|
|
247
247
|
[EVENTS.AGENCY_POT_REMOVAL_DECIDED]: { organization_id: "org-1", actor_role: "owner", campaign_id: "c-1", decision: "withhold_base" },
|
|
248
248
|
[EVENTS.AGENCY_POT_EXPORTED]: { organization_id: "org-1", actor_role: "member", campaign_id: "c-1", format: "xlsx" },
|
|
249
249
|
[EVENTS.AGENCY_POT_FILE_UPLOADED]: { organization_id: "org-1", actor_role: "member", campaign_id: "c-1" },
|
|
250
|
+
// Dealroom (148)
|
|
251
|
+
[EVENTS.DEALROOM_FEED_VIEWED]: { state: "ok", listing_count: 3, broadened: true, near_match_count: 1 },
|
|
252
|
+
[EVENTS.DEALROOM_LISTING_OPENED]: { campaign_id: "c-1", organization_id: "org-1", kind: "offer" },
|
|
253
|
+
[EVENTS.DEALROOM_APPLIED]: { campaign_id: "c-1", organization_id: "org-1", kind: "pot", acting_grant_id: "g-1" },
|
|
254
|
+
[EVENTS.DEALROOM_BROADEN_TOGGLED]: { broadened: false },
|
|
255
|
+
[EVENTS.DEALROOM_NEAR_MATCH_SHOWN]: { campaign_id: "c-1", organization_id: "org-1", kind: "offer", gap: "followers" },
|
|
256
|
+
[EVENTS.DEALROOM_NEAR_MATCH_PROMOTED]: { campaign_id: "c-1", organization_id: "org-1", kind: "offer" },
|
|
257
|
+
[EVENTS.DEALROOM_CONNECT_FROM_NEAR_MATCH_CLICKED]: { campaign_id: "c-1", organization_id: "org-1", kind: "offer", platform: "tiktok" },
|
|
258
|
+
[EVENTS.DEALROOM_DELEGATION_CHANGED]: { organization_id: "org-1", actor_role: "creator", grant_id: "g-1", action: "granted" },
|
|
259
|
+
[EVENTS.DEALROOM_DEAL_MONEY_STATE_CHANGED]: { campaign_id: "c-1", organization_id: "org-1", kind: "offer", money_state: "deposit_paid" },
|
|
260
|
+
[EVENTS.DEALROOM_DEAL_PAYOUT_STATE_CHANGED]: { campaign_id: "c-1", organization_id: "org-1", kind: "offer", payout_state: "initiated" },
|
|
250
261
|
};
|
|
251
262
|
|
|
252
263
|
test("no agency event may carry the discover query — only whether it matched (FR-015)", () => {
|
package/src/analytics/index.ts
CHANGED
|
@@ -10,7 +10,9 @@
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import type { AccessDenialCode } from "../types/I_AccessDenial";
|
|
13
|
-
import type { SponsoredTier } from "../types/agency";
|
|
13
|
+
import type { CreatorAccessGrantOrigin, SponsoredTier } from "../types/agency";
|
|
14
|
+
import type { AgencyCampaignKind, CampaignPlatform } from "../types/agency-campaigns";
|
|
15
|
+
import type { DealMoneyState, DealPayoutState } from "../types/dealroom";
|
|
14
16
|
|
|
15
17
|
/** Canonical PostHog event names. */
|
|
16
18
|
export const EVENTS = {
|
|
@@ -220,6 +222,20 @@ export const EVENTS = {
|
|
|
220
222
|
AGENCY_POT_REMOVAL_DECIDED: 'agency_pot_removal_decided',
|
|
221
223
|
AGENCY_POT_EXPORTED: 'agency_pot_exported',
|
|
222
224
|
AGENCY_POT_FILE_UPLOADED: 'agency_pot_file_uploaded',
|
|
225
|
+
// Dealroom (148): only what 175 has no event for. Offer, material and thread
|
|
226
|
+
// acts on a Dealroom deal reuse the AGENCY_CAMPAIGN_* / AGENCY_THREAD_* events.
|
|
227
|
+
DEALROOM_FEED_VIEWED: 'dealroom_feed_viewed',
|
|
228
|
+
DEALROOM_LISTING_OPENED: 'dealroom_listing_opened',
|
|
229
|
+
DEALROOM_APPLIED: 'dealroom_applied',
|
|
230
|
+
DEALROOM_BROADEN_TOGGLED: 'dealroom_broaden_toggled',
|
|
231
|
+
DEALROOM_NEAR_MATCH_SHOWN: 'dealroom_near_match_shown',
|
|
232
|
+
DEALROOM_NEAR_MATCH_PROMOTED: 'dealroom_near_match_promoted',
|
|
233
|
+
// The near-match's missing-platform nudge, clicked through to Connect (US11).
|
|
234
|
+
DEALROOM_CONNECT_FROM_NEAR_MATCH_CLICKED: 'dealroom_connect_from_near_match_clicked',
|
|
235
|
+
DEALROOM_DELEGATION_CHANGED: 'dealroom_delegation_changed',
|
|
236
|
+
// Money release (dormant until then): state moves, never an amount.
|
|
237
|
+
DEALROOM_DEAL_MONEY_STATE_CHANGED: 'dealroom_deal_money_state_changed',
|
|
238
|
+
DEALROOM_DEAL_PAYOUT_STATE_CHANGED: 'dealroom_deal_payout_state_changed',
|
|
223
239
|
} as const;
|
|
224
240
|
|
|
225
241
|
export type EventName = (typeof EVENTS)[keyof typeof EVENTS];
|
|
@@ -445,7 +461,7 @@ export interface AgencyEventProperties {
|
|
|
445
461
|
/** Present once a specific consent is the subject of the act. */
|
|
446
462
|
grant_id?: string;
|
|
447
463
|
actor_role: 'owner' | 'member' | 'creator' | 'admin' | 'system';
|
|
448
|
-
origin?:
|
|
464
|
+
origin?: CreatorAccessGrantOrigin;
|
|
449
465
|
terms_version?: string;
|
|
450
466
|
tier?: SponsoredTier;
|
|
451
467
|
/**
|
|
@@ -461,6 +477,17 @@ export interface AgencyCampaignEventProperties extends AgencyEventProperties {
|
|
|
461
477
|
campaign_id: string;
|
|
462
478
|
}
|
|
463
479
|
|
|
480
|
+
/**
|
|
481
|
+
* A Dealroom listing event (148): which listing, of which organization and
|
|
482
|
+
* kind. Never a price and never a follower count: what a creator saw and
|
|
483
|
+
* applied to, not what they earn.
|
|
484
|
+
*/
|
|
485
|
+
export interface DealroomListingEventProperties {
|
|
486
|
+
campaign_id: string;
|
|
487
|
+
organization_id: string;
|
|
488
|
+
kind: AgencyCampaignKind;
|
|
489
|
+
}
|
|
490
|
+
|
|
464
491
|
export interface EventProperties {
|
|
465
492
|
[EVENTS.LANDING_CTA_CLICKED]: {
|
|
466
493
|
location:
|
|
@@ -737,6 +764,23 @@ export interface EventProperties {
|
|
|
737
764
|
[EVENTS.AGENCY_POT_REMOVAL_DECIDED]: AgencyCampaignEventProperties & { decision: 'keep_base' | 'withhold_base' };
|
|
738
765
|
[EVENTS.AGENCY_POT_EXPORTED]: AgencyCampaignEventProperties & { format: 'csv' | 'xlsx' | 'report' };
|
|
739
766
|
[EVENTS.AGENCY_POT_FILE_UPLOADED]: AgencyCampaignEventProperties;
|
|
767
|
+
// Dealroom (148).
|
|
768
|
+
[EVENTS.DEALROOM_FEED_VIEWED]: {
|
|
769
|
+
state: 'ok' | 'profile_incomplete';
|
|
770
|
+
listing_count: number;
|
|
771
|
+
broadened: boolean;
|
|
772
|
+
near_match_count?: number;
|
|
773
|
+
};
|
|
774
|
+
[EVENTS.DEALROOM_LISTING_OPENED]: DealroomListingEventProperties;
|
|
775
|
+
// `acting_grant_id` when a delegate applied for the creator.
|
|
776
|
+
[EVENTS.DEALROOM_APPLIED]: DealroomListingEventProperties & { acting_grant_id?: string };
|
|
777
|
+
[EVENTS.DEALROOM_BROADEN_TOGGLED]: { broadened: boolean };
|
|
778
|
+
[EVENTS.DEALROOM_NEAR_MATCH_SHOWN]: DealroomListingEventProperties & { gap: 'followers' | 'missing_platform' };
|
|
779
|
+
[EVENTS.DEALROOM_NEAR_MATCH_PROMOTED]: DealroomListingEventProperties;
|
|
780
|
+
[EVENTS.DEALROOM_CONNECT_FROM_NEAR_MATCH_CLICKED]: DealroomListingEventProperties & { platform: CampaignPlatform };
|
|
781
|
+
[EVENTS.DEALROOM_DELEGATION_CHANGED]: AgencyEventProperties & { action: 'granted' | 'revoked' };
|
|
782
|
+
[EVENTS.DEALROOM_DEAL_MONEY_STATE_CHANGED]: DealroomListingEventProperties & { money_state: DealMoneyState };
|
|
783
|
+
[EVENTS.DEALROOM_DEAL_PAYOUT_STATE_CHANGED]: DealroomListingEventProperties & { payout_state: DealPayoutState };
|
|
740
784
|
}
|
|
741
785
|
|
|
742
786
|
/** Canonical person property keys (set via identify / $set). */
|
|
@@ -64,6 +64,13 @@ export const ACCESS_DENIAL_CODES = {
|
|
|
64
64
|
AGENCY_SCOPE_NOT_GRANTED: "agency-scope-not-granted",
|
|
65
65
|
/** The consent screen is off in this environment (FR-020, the legal gate). */
|
|
66
66
|
AGENCY_CONSENT_DISABLED: "agency-consent-disabled",
|
|
67
|
+
/**
|
|
68
|
+
* The consent screen is on but this environment names no terms version, so
|
|
69
|
+
* no grant can be minted (FR-020). A deployment fault, said as a refusal
|
|
70
|
+
* rather than a 500 (spec 148 audit #1); the env gate requires the version
|
|
71
|
+
* wherever consent is switched on.
|
|
72
|
+
*/
|
|
73
|
+
AGENCY_TERMS_VERSION_MISSING: "agency-terms-version-missing",
|
|
67
74
|
/** The roster invite link expired, was rotated, or its organization is not approved. */
|
|
68
75
|
AGENCY_LINK_INVALID: "agency-link-invalid",
|
|
69
76
|
/** An admin may not decide on an organization they belong to (FR-017). */
|
|
@@ -87,7 +87,8 @@ test('every AGENCY code is namespaced, so a new domain cannot shadow an old wall
|
|
|
87
87
|
key.startsWith('AGENCY_'),
|
|
88
88
|
);
|
|
89
89
|
|
|
90
|
-
|
|
90
|
+
// Spec 148 audit #1 added agency-terms-version-missing.
|
|
91
|
+
assert.equal(agencyCodes.length, 15);
|
|
91
92
|
for (const [, value] of agencyCodes) {
|
|
92
93
|
assert.match(value, /^agency-/, `un-namespaced agency code: ${value}`);
|
|
93
94
|
}
|