ad2app-lib 1.49.0 → 1.50.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 +32 -0
- package/dist/analytics/index.js +12 -0
- package/dist/types/agency-campaigns.d.ts +39 -3
- package/dist/types/agency-campaigns.js +56 -3
- package/dist/types/agency-pots.d.ts +518 -0
- package/dist/types/agency-pots.js +393 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.js +1 -0
- package/package.json +1 -1
- package/src/analytics/index.test.ts +12 -1
- package/src/analytics/index.ts +23 -0
- package/src/types/agency-campaigns.ts +79 -3
- package/src/types/agency-pots.test.ts +255 -0
- package/src/types/agency-pots.ts +751 -0
- package/src/types/index.ts +1 -0
|
@@ -0,0 +1,518 @@
|
|
|
1
|
+
import { type I_AgencyGrantScope } from './agency';
|
|
2
|
+
import type { I_CampaignCreatorIdentity, SettlementForm } from './agency-campaigns';
|
|
3
|
+
/**
|
|
4
|
+
* Pot campaigns (spec 175 US9): the second way to pay creators on a campaign,
|
|
5
|
+
* beside the negotiated offer of US7.
|
|
6
|
+
*
|
|
7
|
+
* The agency funds ONE pot and sets a maximum per creator; each creator applies
|
|
8
|
+
* with their own guarantee and rate per 1,000 views; the agency accepts or
|
|
9
|
+
* declines, never counters (SC-018). Earnings are the guarantee plus the rate
|
|
10
|
+
* times the counted views, never above the maximum, and accrue only while the
|
|
11
|
+
* pot has unreserved money (FR-030, FR-032).
|
|
12
|
+
*
|
|
13
|
+
* Money is integer minor units plus an ISO-4217 code, everywhere. A creator
|
|
14
|
+
* never receives a pot-level figure: the only pot-level signal they get is the
|
|
15
|
+
* two-valued availability (SC-016), fenced by `creatorPotForbiddenKeys`.
|
|
16
|
+
*
|
|
17
|
+
* See specs/speckit/175-agency-roster/plan.md → US9 addendum.
|
|
18
|
+
*/
|
|
19
|
+
/** A caption shows this many characters before "more"; the disclosure must sit inside them. */
|
|
20
|
+
export declare const DISCLOSURE_VISIBLE_CHARS = 125;
|
|
21
|
+
export declare const DISCLOSURE_RESULTS: readonly ["pass", "weak", "missing"];
|
|
22
|
+
export type DisclosureResult = (typeof DISCLOSURE_RESULTS)[number];
|
|
23
|
+
export interface I_DisclosureCheck {
|
|
24
|
+
/**
|
|
25
|
+
* `pass`: a recommended wording within the first 125 characters.
|
|
26
|
+
* `weak`: only a bare tag, or a recommended wording placed past the fold.
|
|
27
|
+
* `missing`: nothing.
|
|
28
|
+
*/
|
|
29
|
+
result: DisclosureResult;
|
|
30
|
+
/** The text that was found, as written. */
|
|
31
|
+
found: string | null;
|
|
32
|
+
/** Its character index in the caption. */
|
|
33
|
+
at: number | null;
|
|
34
|
+
}
|
|
35
|
+
export declare const checkDisclosure: (raw: string) => I_DisclosureCheck;
|
|
36
|
+
/** The per-view part for `views`: rate × views / 1000, rounded DOWN to the minor unit. Exact for any size. */
|
|
37
|
+
export declare const potBonusMinor: (ratePer1000Minor: number, views: number) => number;
|
|
38
|
+
export interface I_PotEarningsInput {
|
|
39
|
+
guaranteeMinor: number;
|
|
40
|
+
ratePer1000Minor: number;
|
|
41
|
+
views: number;
|
|
42
|
+
maxMinor: number;
|
|
43
|
+
}
|
|
44
|
+
/** What a creator's terms earn at `views` with an unlimited pot: never above the maximum. */
|
|
45
|
+
export declare const potEarnings: ({ guaranteeMinor, ratePer1000Minor, views, maxMinor }: I_PotEarningsInput) => number;
|
|
46
|
+
/** The exact view count at which the terms reach the maximum (rounded up), or null when they never do. */
|
|
47
|
+
export declare const potViewsAtMax: ({ guaranteeMinor, ratePer1000Minor, maxMinor }: Omit<I_PotEarningsInput, "views">) => number | null;
|
|
48
|
+
/** Cost per 1,000 views in minor units, rounded half up; null without views. */
|
|
49
|
+
export declare const potCostPer1000Minor: (costMinor: number, views: number) => number | null;
|
|
50
|
+
/**
|
|
51
|
+
* The currencies a pot may be kept in: every amount is in minor units of two
|
|
52
|
+
* decimals (grosz, cents), so a zero- or three-decimal currency (JPY, KWD) is
|
|
53
|
+
* refused rather than shown a hundred times off (review 2026-10-06 L14).
|
|
54
|
+
*/
|
|
55
|
+
export declare const POT_CURRENCIES: readonly ["PLN", "EUR", "USD", "GBP", "CHF", "CZK", "SEK", "NOK", "DKK"];
|
|
56
|
+
export type PotCurrency = (typeof POT_CURRENCIES)[number];
|
|
57
|
+
/** Any key carrying a pot-level figure. A creator-facing response must have none, at any depth. */
|
|
58
|
+
export declare const CREATOR_POT_FORBIDDEN_KEY: RegExp;
|
|
59
|
+
/** The paths of every forbidden key in `value`; empty when the response is clean. */
|
|
60
|
+
export declare const creatorPotForbiddenKeys: (value: unknown, path?: string) => string[];
|
|
61
|
+
/**
|
|
62
|
+
* An entry is one creator's application on one pot.
|
|
63
|
+
* applied → accepted | declined | withdrawn; accepted → released (left or
|
|
64
|
+
* removed before publication).
|
|
65
|
+
*/
|
|
66
|
+
export declare const POT_ENTRY_STATES: readonly ["applied", "accepted", "declined", "withdrawn", "released"];
|
|
67
|
+
export type PotEntryState = (typeof POT_ENTRY_STATES)[number];
|
|
68
|
+
/**
|
|
69
|
+
* The pot board's columns, in order (design A2): invitation sent, application,
|
|
70
|
+
* in the campaign, material in, scheduled, bonus counting, bonus final, done
|
|
71
|
+
* (the keep-up period ended with the post still up).
|
|
72
|
+
*/
|
|
73
|
+
export declare const POT_STEPS: readonly ["invited", "applied", "accepted", "material_in", "scheduled", "counting", "final", "done"];
|
|
74
|
+
export type PotStep = (typeof POT_STEPS)[number];
|
|
75
|
+
/** Rows off the board, kept in the table with their date. */
|
|
76
|
+
export type PotOffBoard = 'declined' | 'withdrawn' | 'released' | 'left' | 'removed' | 'broken';
|
|
77
|
+
export declare const POT_AVAILABILITY: readonly ["full_max_available", "filling_up"];
|
|
78
|
+
export type PotAvailability = (typeof POT_AVAILABILITY)[number];
|
|
79
|
+
/** Why a bonus is held (FR-037): the jump against the creator's own history, or paid delivery ad2app did not start. */
|
|
80
|
+
export declare const POT_HOLD_REASONS: readonly ["jump", "paid_delivery"];
|
|
81
|
+
export type PotHoldReason = (typeof POT_HOLD_REASONS)[number];
|
|
82
|
+
/** The agency's three acts on a held bonus. `message` records the act; the thread opens on the client. */
|
|
83
|
+
export declare const POT_HOLD_ACTIONS: readonly ["approve", "cap", "message"];
|
|
84
|
+
export type PotHoldAction = (typeof POT_HOLD_ACTIONS)[number];
|
|
85
|
+
/** The keep-up check's outcome (FR-032): still up, or taken down before the end. */
|
|
86
|
+
export type PotKeepUpOutcome = 'kept' | 'broken';
|
|
87
|
+
/**
|
|
88
|
+
* A post taken down after the bonus window but before the keep-up end: the
|
|
89
|
+
* agency is informed and decides whether the guarantee stays earned (FR-032).
|
|
90
|
+
* Before the window ends the guarantee is not earned, with no decision.
|
|
91
|
+
*/
|
|
92
|
+
export declare const POT_REMOVAL_DECISIONS: readonly ["keep_base", "withhold_base"];
|
|
93
|
+
export type PotRemovalDecision = (typeof POT_REMOVAL_DECISIONS)[number];
|
|
94
|
+
/** Refusal codes the frontend owes its own copy for. */
|
|
95
|
+
export declare const AGENCY_POT_CODES: {
|
|
96
|
+
/** Accepting would reserve more than the pot has unreserved. */
|
|
97
|
+
readonly POT_CANNOT_COVER: "agency-pot-cannot-cover";
|
|
98
|
+
/** The guarantee must be below the maximum per creator. */
|
|
99
|
+
readonly GUARANTEE_TOO_HIGH: "agency-pot-guarantee-too-high";
|
|
100
|
+
/** Applications closed at the application deadline, or the pot was moved. */
|
|
101
|
+
readonly APPLICATIONS_CLOSED: "agency-pot-applications-closed";
|
|
102
|
+
/** The kind is fixed once a creator is invited; the terms once an entry is accepted. */
|
|
103
|
+
readonly POT_LOCKED: "agency-pot-locked";
|
|
104
|
+
/** A refill above the maximum budget. */
|
|
105
|
+
readonly ABOVE_MAX_BUDGET: "agency-pot-above-max-budget";
|
|
106
|
+
/** The caption fails the disclosure check (FR-040). */
|
|
107
|
+
readonly DISCLOSURE_REQUIRED: "agency-pot-disclosure-required";
|
|
108
|
+
/** The creator has not connected the platform the post goes to. */
|
|
109
|
+
readonly NO_ACCOUNT: "agency-pot-no-account";
|
|
110
|
+
/** The confirmed time is not the one on the row now (the agency moved it meanwhile). */
|
|
111
|
+
readonly PUBLISH_TIME_CHANGED: "agency-pot-publish-time-changed";
|
|
112
|
+
};
|
|
113
|
+
export type AgencyPotCode = (typeof AGENCY_POT_CODES)[keyof typeof AGENCY_POT_CODES];
|
|
114
|
+
export interface I_PotTerms {
|
|
115
|
+
guaranteeMinor: number;
|
|
116
|
+
ratePer1000Minor: number;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Set once by the agency, pre-filled for the creator (FR-040). A field the
|
|
120
|
+
* platform does not support is dropped at publish (research/us9/publishing-fields.md).
|
|
121
|
+
*/
|
|
122
|
+
export interface I_PotPublishingSettings {
|
|
123
|
+
/** Instagram "Paid partnership", TikTok "Branded content", X "Paid partnership". */
|
|
124
|
+
paidPartnershipLabel: boolean;
|
|
125
|
+
/** The brand tagged as sponsor on Instagram. */
|
|
126
|
+
sponsorHandle: string | null;
|
|
127
|
+
/** A Collab invite to the brand's Instagram account. */
|
|
128
|
+
collabHandle: string | null;
|
|
129
|
+
/** A link or a discount code, posted as the first comment. */
|
|
130
|
+
firstComment: string | null;
|
|
131
|
+
commentsEnabled: boolean;
|
|
132
|
+
}
|
|
133
|
+
/** The dates on the timeline (FR-036). Bonus and keep-up ends derive from publication due; never set by hand. */
|
|
134
|
+
export interface I_PotSchedule {
|
|
135
|
+
materialsDueAt: string | null;
|
|
136
|
+
publicationDueAt: string | null;
|
|
137
|
+
bonusEndsAt: string | null;
|
|
138
|
+
keepUpEndsAt: string | null;
|
|
139
|
+
}
|
|
140
|
+
/** The pot's parts. approvedBonus + heldBonus + reservedGuarantees + unreserved = funded, always. */
|
|
141
|
+
export interface I_AgencyPotParts {
|
|
142
|
+
fundedMinor: number;
|
|
143
|
+
/** Accepted creators' guarantees, published or not. */
|
|
144
|
+
reservedGuaranteesMinor: number;
|
|
145
|
+
/** Per-view bonus accrued and payable. */
|
|
146
|
+
approvedBonusMinor: number;
|
|
147
|
+
/** Per-view bonus accrued and held under FR-037: committed, not payable, out of the cost figures. */
|
|
148
|
+
heldBonusMinor: number;
|
|
149
|
+
unreservedMinor: number;
|
|
150
|
+
}
|
|
151
|
+
export interface I_AgencyPotView {
|
|
152
|
+
currency: string;
|
|
153
|
+
maxBudgetMinor: number;
|
|
154
|
+
maxPerCreatorMinor: number;
|
|
155
|
+
bonusWindowDays: number;
|
|
156
|
+
keepUpMonths: number;
|
|
157
|
+
goalViews: number | null;
|
|
158
|
+
coverUrl: string | null;
|
|
159
|
+
applicationDeadlineAt: string | null;
|
|
160
|
+
/** Set when the remainder was moved into another campaign: closed to new applications. */
|
|
161
|
+
movedTo: {
|
|
162
|
+
campaignId: string;
|
|
163
|
+
name: string;
|
|
164
|
+
} | null;
|
|
165
|
+
publishing: I_PotPublishingSettings;
|
|
166
|
+
schedule: I_PotSchedule;
|
|
167
|
+
parts: I_AgencyPotParts;
|
|
168
|
+
/** floor(funded / max per creator). */
|
|
169
|
+
creatorsCoveredAtFullMax: number;
|
|
170
|
+
/** Accepted creators × the maximum: what the pot could owe if every one reached it. */
|
|
171
|
+
maxCommitmentMinor: number;
|
|
172
|
+
/** Published creators' guarantees plus approved bonus. */
|
|
173
|
+
earnedMinor: number;
|
|
174
|
+
/** Raw readings summed over every row: the totals row. */
|
|
175
|
+
views: number;
|
|
176
|
+
/** The goal's progress: raw readings of posts whose bonus is not under review, as the client report counts them (FR-037). */
|
|
177
|
+
resultViews: number;
|
|
178
|
+
/** Raw readings of posts whose bonus is under review, named beside the goal and left out of it. */
|
|
179
|
+
heldViews: number;
|
|
180
|
+
/** Views the bonus counts toward (capped under FR-037): the cost basis. */
|
|
181
|
+
countedViews: number;
|
|
182
|
+
/** Blended cost per 1,000 views over published, unheld rows; null with no views. */
|
|
183
|
+
blendedCostPer1000Minor: number | null;
|
|
184
|
+
/** The latest count across the pot; every export is stamped with it. */
|
|
185
|
+
lastCountAt: string | null;
|
|
186
|
+
}
|
|
187
|
+
/** The FR-037 evidence, in numbers. */
|
|
188
|
+
export interface I_PotHoldEvidence {
|
|
189
|
+
reason: PotHoldReason;
|
|
190
|
+
medianViews: number | null;
|
|
191
|
+
/** views / median, two decimals. */
|
|
192
|
+
viewsVsMedian: number | null;
|
|
193
|
+
/** Engagement per view now and usually, as fractions. */
|
|
194
|
+
engagementNow: number | null;
|
|
195
|
+
engagementUsual: number | null;
|
|
196
|
+
jumpViews: number | null;
|
|
197
|
+
jumpDays: number | null;
|
|
198
|
+
}
|
|
199
|
+
export interface I_PotHold {
|
|
200
|
+
heldAt: string;
|
|
201
|
+
evidence: I_PotHoldEvidence;
|
|
202
|
+
/** null while it waits on the agency. */
|
|
203
|
+
decision: 'approved' | 'capped' | null;
|
|
204
|
+
decidedAt: string | null;
|
|
205
|
+
/** With `capped`: the views the bonus counts to (2 × median). */
|
|
206
|
+
capViews: number | null;
|
|
207
|
+
/** What `cap` would leave as bonus, for the button. */
|
|
208
|
+
cappedBonusMinor: number | null;
|
|
209
|
+
}
|
|
210
|
+
/** Zernio refused the post when ad2app scheduled it: the confirmation is cleared and the creator confirms again. */
|
|
211
|
+
export interface I_PotPublishRefusal {
|
|
212
|
+
at: string;
|
|
213
|
+
/** The provider's words, per platform (`tiktok: …; instagram: …`). */
|
|
214
|
+
reason: string;
|
|
215
|
+
}
|
|
216
|
+
/** One creator's row in the pot table (FR-035). Every total equals the sum of its rows. */
|
|
217
|
+
export interface I_AgencyPotRow {
|
|
218
|
+
memberId: string;
|
|
219
|
+
entryId: string | null;
|
|
220
|
+
creator: I_CampaignCreatorIdentity;
|
|
221
|
+
step: PotStep | PotOffBoard;
|
|
222
|
+
stepAt: string;
|
|
223
|
+
terms: I_PotTerms | null;
|
|
224
|
+
/** The latest reading; null before publication. */
|
|
225
|
+
views: number | null;
|
|
226
|
+
/** Views the bonus counts toward: `views`, stopped at the FR-037 cap when the agency set one. */
|
|
227
|
+
countedViews: number | null;
|
|
228
|
+
guaranteeReservedMinor: number;
|
|
229
|
+
/** Earned so far: the guarantee once published plus approved bonus. */
|
|
230
|
+
earnedMinor: number;
|
|
231
|
+
heldBonusMinor: number;
|
|
232
|
+
/** earned / max, as a fraction; null before publication. */
|
|
233
|
+
shareOfMax: number | null;
|
|
234
|
+
costPer1000Minor: number | null;
|
|
235
|
+
settlementForm: SettlementForm | null;
|
|
236
|
+
publishAt: string | null;
|
|
237
|
+
publishConfirmedAt: string | null;
|
|
238
|
+
publishedAt: string | null;
|
|
239
|
+
postUrl: string | null;
|
|
240
|
+
bonusEndsAt: string | null;
|
|
241
|
+
keepUpEndsAt: string | null;
|
|
242
|
+
frozen: boolean;
|
|
243
|
+
/** `needsDecision`: taken down after the bonus window, waiting on the agency's keep-or-withhold (FR-032). */
|
|
244
|
+
outcome: {
|
|
245
|
+
kind: PotKeepUpOutcome;
|
|
246
|
+
lastFoundAt: string | null;
|
|
247
|
+
decision: PotRemovalDecision | null;
|
|
248
|
+
needsDecision: boolean;
|
|
249
|
+
} | null;
|
|
250
|
+
hold: I_PotHold | null;
|
|
251
|
+
lastCountAt: string | null;
|
|
252
|
+
/** The provider refused the post at scheduling, since the time was last set or confirmed; null otherwise. */
|
|
253
|
+
publishRefusal?: I_PotPublishRefusal | null;
|
|
254
|
+
}
|
|
255
|
+
export interface I_AgencyPotTotals {
|
|
256
|
+
acceptedCreators: number;
|
|
257
|
+
reservedGuaranteesMinor: number;
|
|
258
|
+
views: number;
|
|
259
|
+
countedViews: number;
|
|
260
|
+
earnedMinor: number;
|
|
261
|
+
blendedCostPer1000Minor: number | null;
|
|
262
|
+
}
|
|
263
|
+
/** `GET /agency/campaigns/:id/pot/board` (FR-035). */
|
|
264
|
+
export interface I_AgencyPotBoard {
|
|
265
|
+
pot: I_AgencyPotView;
|
|
266
|
+
rows: I_AgencyPotRow[];
|
|
267
|
+
totals: I_AgencyPotTotals;
|
|
268
|
+
/** Creators per board column. */
|
|
269
|
+
steps: Record<PotStep, number>;
|
|
270
|
+
}
|
|
271
|
+
/** The creator's statistics an application shows, from what they shared (FR-035). */
|
|
272
|
+
export interface I_PotCreatorProfile {
|
|
273
|
+
platforms: Array<{
|
|
274
|
+
platform: string;
|
|
275
|
+
followers: number | null;
|
|
276
|
+
}>;
|
|
277
|
+
medianViews: number | null;
|
|
278
|
+
meanViews: number | null;
|
|
279
|
+
p25Views: number | null;
|
|
280
|
+
p75Views: number | null;
|
|
281
|
+
/** Interactions per view over 90 days, as a fraction. */
|
|
282
|
+
engagement: number | null;
|
|
283
|
+
posts90: number;
|
|
284
|
+
recent: Array<{
|
|
285
|
+
postedAt: string;
|
|
286
|
+
views: number | null;
|
|
287
|
+
url: string | null;
|
|
288
|
+
thumbnailUrl: string | null;
|
|
289
|
+
}>;
|
|
290
|
+
}
|
|
291
|
+
export type PotScenario = 'none' | 'p25' | 'median' | 'p75' | 'max';
|
|
292
|
+
/** `GET /agency/campaigns/:id/pot/entries/:entryId` while it is an application. */
|
|
293
|
+
export interface I_PotApplicationView {
|
|
294
|
+
entryId: string;
|
|
295
|
+
memberId: string;
|
|
296
|
+
creator: I_CampaignCreatorIdentity;
|
|
297
|
+
terms: I_PotTerms;
|
|
298
|
+
appliedAt: string;
|
|
299
|
+
/**
|
|
300
|
+
* `shared`: the profile is filled. `not_shared`: no active grant with the
|
|
301
|
+
* analytics scope, said in words. `unavailable`: the read failed just now;
|
|
302
|
+
* never shown as zeros.
|
|
303
|
+
*/
|
|
304
|
+
profileState: 'shared' | 'not_shared' | 'unavailable';
|
|
305
|
+
/** Set only when `profileState` is `shared`. */
|
|
306
|
+
profile: I_PotCreatorProfile | null;
|
|
307
|
+
viewsAtMax: number | null;
|
|
308
|
+
scenarios: Array<{
|
|
309
|
+
scenario: PotScenario;
|
|
310
|
+
views: number | null;
|
|
311
|
+
costMinor: number | null;
|
|
312
|
+
costPer1000Minor: number | null;
|
|
313
|
+
}>;
|
|
314
|
+
blendedCostPer1000Minor: number | null;
|
|
315
|
+
unreservedBeforeMinor: number;
|
|
316
|
+
unreservedAfterMinor: number;
|
|
317
|
+
/** False when the pot cannot cover the guarantee: accept is refused with POT_CANNOT_COVER. */
|
|
318
|
+
canAccept: boolean;
|
|
319
|
+
}
|
|
320
|
+
export interface I_CreatorPotEarnings {
|
|
321
|
+
guaranteeMinor: number;
|
|
322
|
+
/** Payable per-view bonus. */
|
|
323
|
+
bonusMinor: number;
|
|
324
|
+
/** Bonus under review (FR-037): shown with the amount, never as an accusation. */
|
|
325
|
+
heldBonusMinor: number;
|
|
326
|
+
totalMinor: number;
|
|
327
|
+
views: number;
|
|
328
|
+
lastCountAt: string | null;
|
|
329
|
+
frozen: boolean;
|
|
330
|
+
}
|
|
331
|
+
export interface I_CreatorPotEntry {
|
|
332
|
+
state: PotEntryState;
|
|
333
|
+
terms: I_PotTerms;
|
|
334
|
+
appliedAt: string;
|
|
335
|
+
decidedAt: string | null;
|
|
336
|
+
publishAt: string | null;
|
|
337
|
+
publishConfirmedAt: string | null;
|
|
338
|
+
publishedAt: string | null;
|
|
339
|
+
postUrl: string | null;
|
|
340
|
+
bonusEndsAt: string | null;
|
|
341
|
+
keepUpEndsAt: string | null;
|
|
342
|
+
outcome: PotKeepUpOutcome | null;
|
|
343
|
+
/** True once the keep-up period ended with the post still up. */
|
|
344
|
+
mayTakeDown: boolean;
|
|
345
|
+
/**
|
|
346
|
+
* A post taken down before the keep-up end (FR-032): inside the bonus window
|
|
347
|
+
* the guarantee is lost; after it the agency decides, then keeps or returns it.
|
|
348
|
+
*/
|
|
349
|
+
removal: 'guarantee_lost' | 'agency_deciding' | 'guarantee_kept' | 'guarantee_returned' | null;
|
|
350
|
+
/** null before publication. */
|
|
351
|
+
earnings: I_CreatorPotEarnings | null;
|
|
352
|
+
/** The provider refused the post at scheduling, since the time was last set or confirmed; null otherwise. */
|
|
353
|
+
publishRefusal?: I_PotPublishRefusal | null;
|
|
354
|
+
}
|
|
355
|
+
/** Attached to `I_CreatorCampaignView.pot` on a pot campaign. */
|
|
356
|
+
export interface I_CreatorPotView {
|
|
357
|
+
campaignId: string;
|
|
358
|
+
currency: string;
|
|
359
|
+
maxPerCreatorMinor: number;
|
|
360
|
+
bonusWindowDays: number;
|
|
361
|
+
keepUpMonths: number;
|
|
362
|
+
coverUrl: string | null;
|
|
363
|
+
applicationDeadlineAt: string | null;
|
|
364
|
+
availability: PotAvailability;
|
|
365
|
+
/** The maximum in the creator's preferred currency, approximate; null with no rate for the day. */
|
|
366
|
+
approx: {
|
|
367
|
+
currency: string;
|
|
368
|
+
maxPerCreatorMinor: number;
|
|
369
|
+
rateDate: string;
|
|
370
|
+
} | null;
|
|
371
|
+
schedule: I_PotSchedule;
|
|
372
|
+
publishing: I_PotPublishingSettings;
|
|
373
|
+
entry: I_CreatorPotEntry | null;
|
|
374
|
+
canApply: boolean;
|
|
375
|
+
canWithdraw: boolean;
|
|
376
|
+
canConfirmPublishAt: boolean;
|
|
377
|
+
/** The creator's own 90-day median views from their shared statistics, for the application estimate; null when unknown. */
|
|
378
|
+
medianViews: number | null;
|
|
379
|
+
}
|
|
380
|
+
/** One published post in the brand's report. Costs ride along; the page shows them only when the agency ticks them. */
|
|
381
|
+
export interface I_PotReportPost {
|
|
382
|
+
memberId: string;
|
|
383
|
+
creator: I_CampaignCreatorIdentity;
|
|
384
|
+
platform: string | null;
|
|
385
|
+
publishedAt: string;
|
|
386
|
+
postUrl: string | null;
|
|
387
|
+
thumbnailUrl: string | null;
|
|
388
|
+
caption: string | null;
|
|
389
|
+
disclosure: I_DisclosureCheck | null;
|
|
390
|
+
/** Whether the platform's paid-partnership label went out (null: not asked for). */
|
|
391
|
+
labelApplied: boolean | null;
|
|
392
|
+
/** A durable ad2app link that opens a fresh signed read of the approved material on every open; null when none. */
|
|
393
|
+
materialLink: string | null;
|
|
394
|
+
views: number;
|
|
395
|
+
likes: number | null;
|
|
396
|
+
comments: number | null;
|
|
397
|
+
shares: number | null;
|
|
398
|
+
saves: number | null;
|
|
399
|
+
followers: number | null;
|
|
400
|
+
/** The creator's own 90-day median, when known: each post is judged against its creator. */
|
|
401
|
+
medianViews: number | null;
|
|
402
|
+
/** Views by day since publication, as counted (the latest reading of each day). */
|
|
403
|
+
daily: Array<{
|
|
404
|
+
day: string;
|
|
405
|
+
views: number;
|
|
406
|
+
}>;
|
|
407
|
+
/** A bonus under review (FR-037): left out of the sums and named as such. */
|
|
408
|
+
held: boolean;
|
|
409
|
+
publishedOnTime: boolean | null;
|
|
410
|
+
keepUpEndsAt: string | null;
|
|
411
|
+
versions: number;
|
|
412
|
+
revisionRounds: number;
|
|
413
|
+
/** The most-liked comments, text and likes only; null when the creator does not share comments. */
|
|
414
|
+
topComments: Array<{
|
|
415
|
+
text: string;
|
|
416
|
+
likes: number;
|
|
417
|
+
}> | null;
|
|
418
|
+
earnedMinor: number;
|
|
419
|
+
}
|
|
420
|
+
/** `GET /agency/campaigns/:id/pot/report`. */
|
|
421
|
+
export interface I_PotClientReport {
|
|
422
|
+
campaign: {
|
|
423
|
+
id: string;
|
|
424
|
+
name: string;
|
|
425
|
+
organizationName: string;
|
|
426
|
+
brief: string;
|
|
427
|
+
};
|
|
428
|
+
currency: string;
|
|
429
|
+
goalViews: number | null;
|
|
430
|
+
publicationDueAt: string | null;
|
|
431
|
+
/** When the bonus window of the campaign closes (publication due + the window): the pacing projection runs to it. */
|
|
432
|
+
campaignEndsAt: string | null;
|
|
433
|
+
keepUpMonths: number;
|
|
434
|
+
generatedAt: string;
|
|
435
|
+
lastCountAt: string | null;
|
|
436
|
+
posts: I_PotReportPost[];
|
|
437
|
+
/** What the published, unheld posts cost: shown only when the agency includes costs. */
|
|
438
|
+
totalCostMinor: number;
|
|
439
|
+
}
|
|
440
|
+
export interface I_CampaignFile {
|
|
441
|
+
id: string;
|
|
442
|
+
fileName: string;
|
|
443
|
+
contentType: string;
|
|
444
|
+
sizeBytes: number;
|
|
445
|
+
uploadedAt: string;
|
|
446
|
+
uploadedBy: string;
|
|
447
|
+
}
|
|
448
|
+
/** PDF, images, video, office documents and archives; no HTML or SVG (opened in the browser). */
|
|
449
|
+
export declare const CAMPAIGN_FILE_CONTENT_TYPE: RegExp;
|
|
450
|
+
export declare const CAMPAIGN_FILE_MAX_BYTES: number;
|
|
451
|
+
/**
|
|
452
|
+
* `POST /agency/campaign-invitations/:memberId/application` — the creator's own
|
|
453
|
+
* terms. Applying from an invitation also joins the campaign, answering any
|
|
454
|
+
* access request folded into it with `scopes` (absent = everything asked).
|
|
455
|
+
*/
|
|
456
|
+
export declare class ApplyToPotDto {
|
|
457
|
+
guaranteeMinor: number;
|
|
458
|
+
ratePer1000Minor: number;
|
|
459
|
+
scopes?: I_AgencyGrantScope[];
|
|
460
|
+
constructor(data?: Partial<ApplyToPotDto>);
|
|
461
|
+
}
|
|
462
|
+
/** `POST /agency/campaigns/:id/pot/refill` — up to the maximum budget. */
|
|
463
|
+
export declare class RefillPotDto {
|
|
464
|
+
amountMinor: number;
|
|
465
|
+
constructor(data?: Partial<RefillPotDto>);
|
|
466
|
+
}
|
|
467
|
+
/** `PATCH /agency/campaigns/:id/pot/application-deadline`. */
|
|
468
|
+
export declare class MovePotDeadlineDto {
|
|
469
|
+
applicationDeadlineAt: string;
|
|
470
|
+
constructor(data?: Partial<MovePotDeadlineDto>);
|
|
471
|
+
}
|
|
472
|
+
/** The agency sets the time agreed with the brand; the creator confirms that same value. */
|
|
473
|
+
export declare class PotPublishAtDto {
|
|
474
|
+
publishAt: string;
|
|
475
|
+
constructor(data?: Partial<PotPublishAtDto>);
|
|
476
|
+
}
|
|
477
|
+
export declare class PotHoldActDto {
|
|
478
|
+
action: PotHoldAction;
|
|
479
|
+
constructor(data?: Partial<PotHoldActDto>);
|
|
480
|
+
}
|
|
481
|
+
/** `POST /agency/campaigns/:id/pot/entries/:entryId/removal` — the agency's decision on a late takedown (FR-032). */
|
|
482
|
+
export declare class PotRemovalDecisionDto {
|
|
483
|
+
decision: PotRemovalDecision;
|
|
484
|
+
constructor(data?: Partial<PotRemovalDecisionDto>);
|
|
485
|
+
}
|
|
486
|
+
/** The caption is the creator's until publication (FR-032). */
|
|
487
|
+
export declare class UpdateMaterialCaptionDto {
|
|
488
|
+
caption: string;
|
|
489
|
+
constructor(data?: Partial<UpdateMaterialCaptionDto>);
|
|
490
|
+
}
|
|
491
|
+
export declare class PrepareCampaignFileUploadDto {
|
|
492
|
+
fileName: string;
|
|
493
|
+
contentType: string;
|
|
494
|
+
sizeBytes: number;
|
|
495
|
+
constructor(data?: Partial<PrepareCampaignFileUploadDto>);
|
|
496
|
+
}
|
|
497
|
+
/** The pot's fields on campaign create (and on a move); flat for the reason given in agency-campaigns.ts. */
|
|
498
|
+
export declare class PotFields {
|
|
499
|
+
potBudgetMinor?: number;
|
|
500
|
+
potMaxBudgetMinor?: number;
|
|
501
|
+
/**
|
|
502
|
+
* The maximum one creator can earn, guarantee included. Named "cap" on the
|
|
503
|
+
* wire: a body field matching /creator|user/ reads as a person id to the
|
|
504
|
+
* agency boundary scan (backend agency-grant-never-opens-inbox.spec.ts).
|
|
505
|
+
*/
|
|
506
|
+
potCapMinor?: number;
|
|
507
|
+
potBonusWindowDays?: number;
|
|
508
|
+
potKeepUpMonths?: number;
|
|
509
|
+
potGoalViews?: number | null;
|
|
510
|
+
potCurrency?: string;
|
|
511
|
+
potApplicationDeadlineAt?: string | null;
|
|
512
|
+
potPaidPartnershipLabel?: boolean;
|
|
513
|
+
potSponsorHandle?: string | null;
|
|
514
|
+
potCollabHandle?: string | null;
|
|
515
|
+
potFirstComment?: string | null;
|
|
516
|
+
potCommentsEnabled?: boolean;
|
|
517
|
+
protected assignPot(data?: Partial<PotFields>): void;
|
|
518
|
+
}
|