ad2app-lib 1.44.1 → 1.49.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 +44 -0
- package/dist/analytics/index.js +17 -0
- package/dist/types/I_AccessDenial.d.ts +19 -0
- package/dist/types/I_AccessDenial.js +19 -0
- package/dist/types/I_Offer.d.ts +3 -1
- package/dist/types/I_Offer.js +2 -0
- package/dist/types/agency-campaigns.d.ts +391 -0
- package/dist/types/agency-campaigns.js +426 -0
- package/dist/types/agency-threads.d.ts +87 -0
- package/dist/types/agency-threads.js +60 -0
- package/dist/types/agency.d.ts +250 -6
- package/dist/types/agency.js +54 -2
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.js +2 -0
- package/dist/types/scheduling/I_SchedulingProUpgrade.d.ts +10 -1
- package/dist/types/scheduling/I_SchedulingProUpgrade.js +4 -0
- package/package.json +2 -2
- package/src/analytics/index.test.ts +41 -1
- package/src/analytics/index.ts +39 -0
- package/src/types/I_AccessDenial.ts +19 -0
- package/src/types/I_Offer.ts +2 -0
- package/src/types/access-denial.test.ts +1 -1
- package/src/types/agency-billing.test.ts +83 -0
- package/src/types/agency-campaigns.test.ts +85 -0
- package/src/types/agency-campaigns.ts +663 -0
- package/src/types/agency-discover.test.ts +79 -0
- package/src/types/agency-threads.ts +103 -0
- package/src/types/agency.test.ts +21 -1
- package/src/types/agency.ts +261 -6
- package/src/types/index.ts +2 -0
- package/src/types/scheduling/I_SchedulingProUpgrade.ts +13 -0
|
@@ -106,6 +106,20 @@ export declare const EVENTS: {
|
|
|
106
106
|
readonly AGENCY_SPONSORSHIP_ENDED: "agency_sponsorship_ended";
|
|
107
107
|
readonly AGENCY_DISCOVER_SEARCHED: "agency_discover_searched";
|
|
108
108
|
readonly AGENCY_ACCESS_REQUESTED: "agency_access_requested";
|
|
109
|
+
readonly AGENCY_CAMPAIGN_CREATED: "agency_campaign_created";
|
|
110
|
+
readonly AGENCY_CAMPAIGN_CREATOR_INVITED: "agency_campaign_creator_invited";
|
|
111
|
+
readonly AGENCY_CAMPAIGN_JOINED: "agency_campaign_joined";
|
|
112
|
+
readonly AGENCY_CAMPAIGN_DECLINED: "agency_campaign_declined";
|
|
113
|
+
readonly AGENCY_CAMPAIGN_LEFT: "agency_campaign_left";
|
|
114
|
+
readonly AGENCY_CAMPAIGN_CREATOR_REMOVED: "agency_campaign_creator_removed";
|
|
115
|
+
readonly AGENCY_CAMPAIGN_OFFER_SENT: "agency_campaign_offer_sent";
|
|
116
|
+
readonly AGENCY_CAMPAIGN_OFFER_ACTED: "agency_campaign_offer_acted";
|
|
117
|
+
readonly AGENCY_CAMPAIGN_MATERIAL_UPLOADED: "agency_campaign_material_uploaded";
|
|
118
|
+
readonly AGENCY_CAMPAIGN_MATERIAL_REVIEWED: "agency_campaign_material_reviewed";
|
|
119
|
+
readonly AGENCY_CAMPAIGN_PUBLISHED: "agency_campaign_published";
|
|
120
|
+
readonly AGENCY_CAMPAIGN_MILESTONE_CONFIRMED: "agency_campaign_milestone_confirmed";
|
|
121
|
+
readonly AGENCY_THREAD_STARTED: "agency_thread_started";
|
|
122
|
+
readonly AGENCY_THREAD_MESSAGE_SENT: "agency_thread_message_sent";
|
|
109
123
|
};
|
|
110
124
|
export type EventName = (typeof EVENTS)[keyof typeof EVENTS];
|
|
111
125
|
/** Which email program a send belongs to (spec 120). Wire values — do not rename. */
|
|
@@ -253,6 +267,10 @@ export interface AgencyEventProperties {
|
|
|
253
267
|
*/
|
|
254
268
|
creator_user_id?: string;
|
|
255
269
|
}
|
|
270
|
+
/** A campaign-loop event: the agency event plus the campaign it concerns. */
|
|
271
|
+
export interface AgencyCampaignEventProperties extends AgencyEventProperties {
|
|
272
|
+
campaign_id: string;
|
|
273
|
+
}
|
|
256
274
|
export interface EventProperties {
|
|
257
275
|
[EVENTS.LANDING_CTA_CLICKED]: {
|
|
258
276
|
location: 'hero' | 'pricing' | 'final_cta' | 'nav' | 'ai_connector' | 'free_skills';
|
|
@@ -584,6 +602,32 @@ export interface EventProperties {
|
|
|
584
602
|
matched: boolean;
|
|
585
603
|
};
|
|
586
604
|
[EVENTS.AGENCY_ACCESS_REQUESTED]: AgencyEventProperties;
|
|
605
|
+
[EVENTS.AGENCY_CAMPAIGN_CREATED]: AgencyCampaignEventProperties;
|
|
606
|
+
[EVENTS.AGENCY_CAMPAIGN_CREATOR_INVITED]: AgencyCampaignEventProperties & {
|
|
607
|
+
with_access_request: boolean;
|
|
608
|
+
};
|
|
609
|
+
[EVENTS.AGENCY_CAMPAIGN_JOINED]: AgencyCampaignEventProperties;
|
|
610
|
+
[EVENTS.AGENCY_CAMPAIGN_DECLINED]: AgencyCampaignEventProperties;
|
|
611
|
+
[EVENTS.AGENCY_CAMPAIGN_LEFT]: AgencyCampaignEventProperties;
|
|
612
|
+
[EVENTS.AGENCY_CAMPAIGN_CREATOR_REMOVED]: AgencyCampaignEventProperties;
|
|
613
|
+
[EVENTS.AGENCY_CAMPAIGN_OFFER_SENT]: AgencyCampaignEventProperties;
|
|
614
|
+
[EVENTS.AGENCY_CAMPAIGN_OFFER_ACTED]: AgencyCampaignEventProperties & {
|
|
615
|
+
action: 'accept' | 'counter' | 'confirm' | 'reject';
|
|
616
|
+
};
|
|
617
|
+
[EVENTS.AGENCY_CAMPAIGN_MATERIAL_UPLOADED]: AgencyCampaignEventProperties & {
|
|
618
|
+
version: number;
|
|
619
|
+
};
|
|
620
|
+
[EVENTS.AGENCY_CAMPAIGN_MATERIAL_REVIEWED]: AgencyCampaignEventProperties & {
|
|
621
|
+
action: 'approve' | 'request_changes' | 'reject';
|
|
622
|
+
};
|
|
623
|
+
[EVENTS.AGENCY_CAMPAIGN_PUBLISHED]: AgencyCampaignEventProperties;
|
|
624
|
+
[EVENTS.AGENCY_CAMPAIGN_MILESTONE_CONFIRMED]: AgencyCampaignEventProperties;
|
|
625
|
+
[EVENTS.AGENCY_THREAD_STARTED]: AgencyEventProperties & {
|
|
626
|
+
thread_id: string;
|
|
627
|
+
};
|
|
628
|
+
[EVENTS.AGENCY_THREAD_MESSAGE_SENT]: AgencyEventProperties & {
|
|
629
|
+
thread_id: string;
|
|
630
|
+
};
|
|
587
631
|
}
|
|
588
632
|
/** Canonical person property keys (set via identify / $set). */
|
|
589
633
|
export declare const PERSON_PROPS: {
|
package/dist/analytics/index.js
CHANGED
|
@@ -177,6 +177,23 @@ exports.EVENTS = {
|
|
|
177
177
|
// creators an agency went looking for.
|
|
178
178
|
AGENCY_DISCOVER_SEARCHED: 'agency_discover_searched',
|
|
179
179
|
AGENCY_ACCESS_REQUESTED: 'agency_access_requested',
|
|
180
|
+
// The campaign loop (175 US7). Server-owned: each is captured in the act's
|
|
181
|
+
// own transaction path, under the ACTOR's distinct id.
|
|
182
|
+
AGENCY_CAMPAIGN_CREATED: 'agency_campaign_created',
|
|
183
|
+
AGENCY_CAMPAIGN_CREATOR_INVITED: 'agency_campaign_creator_invited',
|
|
184
|
+
AGENCY_CAMPAIGN_JOINED: 'agency_campaign_joined',
|
|
185
|
+
AGENCY_CAMPAIGN_DECLINED: 'agency_campaign_declined',
|
|
186
|
+
AGENCY_CAMPAIGN_LEFT: 'agency_campaign_left',
|
|
187
|
+
AGENCY_CAMPAIGN_CREATOR_REMOVED: 'agency_campaign_creator_removed',
|
|
188
|
+
AGENCY_CAMPAIGN_OFFER_SENT: 'agency_campaign_offer_sent',
|
|
189
|
+
AGENCY_CAMPAIGN_OFFER_ACTED: 'agency_campaign_offer_acted',
|
|
190
|
+
AGENCY_CAMPAIGN_MATERIAL_UPLOADED: 'agency_campaign_material_uploaded',
|
|
191
|
+
AGENCY_CAMPAIGN_MATERIAL_REVIEWED: 'agency_campaign_material_reviewed',
|
|
192
|
+
AGENCY_CAMPAIGN_PUBLISHED: 'agency_campaign_published',
|
|
193
|
+
AGENCY_CAMPAIGN_MILESTONE_CONFIRMED: 'agency_campaign_milestone_confirmed',
|
|
194
|
+
// Threads (175 US8). Never the message body: a conversation is not analytics.
|
|
195
|
+
AGENCY_THREAD_STARTED: 'agency_thread_started',
|
|
196
|
+
AGENCY_THREAD_MESSAGE_SENT: 'agency_thread_message_sent',
|
|
180
197
|
};
|
|
181
198
|
/**
|
|
182
199
|
* Canonical email event property KEYS (spec 120 T001). Emitters and tests
|
|
@@ -79,6 +79,25 @@ export declare const ACCESS_DENIAL_CODES: {
|
|
|
79
79
|
* per person, FR-004). Names the case and NOTHING else about that account.
|
|
80
80
|
*/
|
|
81
81
|
readonly AGENCY_ALREADY_IN_ORGANIZATION: "agency-already-in-organization";
|
|
82
|
+
/**
|
|
83
|
+
* The owner invited an address that is ALREADY on this organization's team,
|
|
84
|
+
* themselves included (T063). A different case from the one above: the owner
|
|
85
|
+
* is told this person is already in, not that they belong elsewhere.
|
|
86
|
+
*/
|
|
87
|
+
readonly AGENCY_ALREADY_MEMBER: "agency-already-member";
|
|
88
|
+
/**
|
|
89
|
+
* The owner tried to cover a creator who pays for their own plan. Covering
|
|
90
|
+
* is for a creator without a paid plan (US4 scenario 3); covering a payer
|
|
91
|
+
* would leave them paying for what the agency also pays for (T066).
|
|
92
|
+
*/
|
|
93
|
+
readonly AGENCY_CREATOR_PAYS_OWN_PLAN: "agency-creator-pays-own-plan";
|
|
94
|
+
/**
|
|
95
|
+
* A creator whose plan an agency covers asked for the billing portal, and
|
|
96
|
+
* has no Stripe customer of their own to open it for (FR-014). The body
|
|
97
|
+
* names the covering agency; the client hides the portal button instead of
|
|
98
|
+
* showing a Stripe error.
|
|
99
|
+
*/
|
|
100
|
+
readonly SPONSORED_NO_PORTAL: "sponsored-no-portal";
|
|
82
101
|
};
|
|
83
102
|
export type AccessDenialCode = (typeof ACCESS_DENIAL_CODES)[keyof typeof ACCESS_DENIAL_CODES];
|
|
84
103
|
/**
|
|
@@ -83,6 +83,25 @@ exports.ACCESS_DENIAL_CODES = {
|
|
|
83
83
|
* per person, FR-004). Names the case and NOTHING else about that account.
|
|
84
84
|
*/
|
|
85
85
|
AGENCY_ALREADY_IN_ORGANIZATION: "agency-already-in-organization",
|
|
86
|
+
/**
|
|
87
|
+
* The owner invited an address that is ALREADY on this organization's team,
|
|
88
|
+
* themselves included (T063). A different case from the one above: the owner
|
|
89
|
+
* is told this person is already in, not that they belong elsewhere.
|
|
90
|
+
*/
|
|
91
|
+
AGENCY_ALREADY_MEMBER: "agency-already-member",
|
|
92
|
+
/**
|
|
93
|
+
* The owner tried to cover a creator who pays for their own plan. Covering
|
|
94
|
+
* is for a creator without a paid plan (US4 scenario 3); covering a payer
|
|
95
|
+
* would leave them paying for what the agency also pays for (T066).
|
|
96
|
+
*/
|
|
97
|
+
AGENCY_CREATOR_PAYS_OWN_PLAN: "agency-creator-pays-own-plan",
|
|
98
|
+
/**
|
|
99
|
+
* A creator whose plan an agency covers asked for the billing portal, and
|
|
100
|
+
* has no Stripe customer of their own to open it for (FR-014). The body
|
|
101
|
+
* names the covering agency; the client hides the portal button instead of
|
|
102
|
+
* showing a Stripe error.
|
|
103
|
+
*/
|
|
104
|
+
SPONSORED_NO_PORTAL: "sponsored-no-portal",
|
|
86
105
|
};
|
|
87
106
|
/**
|
|
88
107
|
* WHICH precondition the entitlement wall refused on (backend#305, spec 170).
|
package/dist/types/I_Offer.d.ts
CHANGED
|
@@ -21,7 +21,9 @@ export declare enum I_OfferStatus {
|
|
|
21
21
|
INFLUENCER_NEGOTIATED = "influencerNegotiated",
|
|
22
22
|
AGENCY_NEGOTIATED = "agencyNegotiated",
|
|
23
23
|
CONFIRMED = "confirmed",
|
|
24
|
-
ALTERNATIVE_SUGGESTED = "alternativeSuggested"
|
|
24
|
+
ALTERNATIVE_SUGGESTED = "alternativeSuggested",
|
|
25
|
+
/** The creator left the campaign before the offer was confirmed (spec 175 US7). Added, never renamed: Postgres enums only grow. */
|
|
26
|
+
WITHDRAWN = "withdrawn"
|
|
25
27
|
}
|
|
26
28
|
export declare class I_OfferGetDTO {
|
|
27
29
|
campaignId: string;
|
package/dist/types/I_Offer.js
CHANGED
|
@@ -34,6 +34,8 @@ var I_OfferStatus;
|
|
|
34
34
|
I_OfferStatus["AGENCY_NEGOTIATED"] = "agencyNegotiated";
|
|
35
35
|
I_OfferStatus["CONFIRMED"] = "confirmed";
|
|
36
36
|
I_OfferStatus["ALTERNATIVE_SUGGESTED"] = "alternativeSuggested";
|
|
37
|
+
/** The creator left the campaign before the offer was confirmed (spec 175 US7). Added, never renamed: Postgres enums only grow. */
|
|
38
|
+
I_OfferStatus["WITHDRAWN"] = "withdrawn";
|
|
37
39
|
})(I_OfferStatus || (exports.I_OfferStatus = I_OfferStatus = {}));
|
|
38
40
|
class I_GetOffersDTO {
|
|
39
41
|
}
|
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
import { I_MediaStage } from './I_Media';
|
|
2
|
+
import { I_OfferStatus } from './I_Offer';
|
|
3
|
+
import { type I_AgencyGrantScope } from './agency';
|
|
4
|
+
/**
|
|
5
|
+
* The campaign loop (spec 175 US7) — an organization runs a campaign with the
|
|
6
|
+
* creators on its roster or in the directory.
|
|
7
|
+
*
|
|
8
|
+
* Two steps, never one (Jan, 2026-09-28):
|
|
9
|
+
*
|
|
10
|
+
* 1. MEMBERSHIP — the agency invites a creator; the creator joins or
|
|
11
|
+
* declines. Joining answers any access request folded into the
|
|
12
|
+
* invitation. No money is named here.
|
|
13
|
+
* 2. OFFER — once joined, the agency sends a rate. It is countered, accepted,
|
|
14
|
+
* confirmed or rejected; a creator who leaves withdraws it.
|
|
15
|
+
*
|
|
16
|
+
* The server owns every transition. Each view carries `availableActions`, and
|
|
17
|
+
* a screen renders exactly those acts — it never derives them from a status,
|
|
18
|
+
* so the two can never disagree.
|
|
19
|
+
*
|
|
20
|
+
* See specs/speckit/175-agency-roster/contracts/agency-api.md → US7.
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* What a deliverable may be, per platform. A named list in one place, so a
|
|
24
|
+
* "placement" can never be free text that drifts per campaign.
|
|
25
|
+
*/
|
|
26
|
+
export declare const CAMPAIGN_PLACEMENTS: {
|
|
27
|
+
readonly instagram: readonly ["reel", "post", "carousel", "stories", "collab_post"];
|
|
28
|
+
readonly tiktok: readonly ["video", "repost", "duet", "stories"];
|
|
29
|
+
readonly youtube: readonly ["video", "short", "integration", "community_post"];
|
|
30
|
+
readonly facebook: readonly ["post", "reel", "stories"];
|
|
31
|
+
readonly linkedin: readonly ["post", "article"];
|
|
32
|
+
};
|
|
33
|
+
export type CampaignPlatform = keyof typeof CAMPAIGN_PLACEMENTS;
|
|
34
|
+
export type CampaignPlacement = (typeof CAMPAIGN_PLACEMENTS)[CampaignPlatform][number];
|
|
35
|
+
export declare const CAMPAIGN_PLATFORMS: CampaignPlatform[];
|
|
36
|
+
export declare const isCampaignPlacement: (platform: string, placement: string) => boolean;
|
|
37
|
+
/** The creator's own setting. The agency reads it and can never set it. */
|
|
38
|
+
export declare const SETTLEMENT_FORMS: readonly ["invoice", "contract", "barter"];
|
|
39
|
+
export type SettlementForm = (typeof SETTLEMENT_FORMS)[number];
|
|
40
|
+
export declare const AGENCY_CAMPAIGN_MEMBER_STATES: readonly ["invited", "joined", "declined", "left", "removed"];
|
|
41
|
+
export type AgencyCampaignMemberState = (typeof AGENCY_CAMPAIGN_MEMBER_STATES)[number];
|
|
42
|
+
/** The offer statuses the agency loop writes. `draft`, `deleted` and `alternativeSuggested` are legacy-only. */
|
|
43
|
+
export declare const AGENCY_OFFER_STATUSES: readonly [I_OfferStatus.SENT, I_OfferStatus.INFLUENCER_NEGOTIATED, I_OfferStatus.AGENCY_NEGOTIATED, I_OfferStatus.ACCEPTED, I_OfferStatus.CONFIRMED, I_OfferStatus.REJECTED, I_OfferStatus.WITHDRAWN];
|
|
44
|
+
export type AgencyOfferStatus = (typeof AGENCY_OFFER_STATUSES)[number];
|
|
45
|
+
export type CampaignSide = 'agency' | 'creator';
|
|
46
|
+
/**
|
|
47
|
+
* Every act on an offer, by either side. Which of them a given caller may take
|
|
48
|
+
* right now is the server's `availableActions`, never a client guess.
|
|
49
|
+
*
|
|
50
|
+
* agency: counter · confirm · reject
|
|
51
|
+
* creator: accept · counter · reject
|
|
52
|
+
*/
|
|
53
|
+
export declare const AGENCY_OFFER_ACTIONS: readonly ["accept", "counter", "confirm", "reject"];
|
|
54
|
+
export type AgencyOfferAction = (typeof AGENCY_OFFER_ACTIONS)[number];
|
|
55
|
+
/** The agency's acts on the latest material; the creator's only act is to upload. */
|
|
56
|
+
export declare const AGENCY_MATERIAL_ACTIONS: readonly ["approve", "request_changes", "reject"];
|
|
57
|
+
export type AgencyMaterialAction = (typeof AGENCY_MATERIAL_ACTIONS)[number];
|
|
58
|
+
/**
|
|
59
|
+
* The board's columns, in order (FR-024). A creator stands in exactly one.
|
|
60
|
+
* `declined`, `left`, `removed` and `rejected` are OFF the board: those rows
|
|
61
|
+
* stay in the list with their date (US7 scenario 9), never in a column.
|
|
62
|
+
*/
|
|
63
|
+
export declare const AGENCY_CAMPAIGN_STEPS: readonly ["invited", "joined", "offer_sent", "negotiating", "confirmed", "material_in", "approved", "published"];
|
|
64
|
+
export type AgencyCampaignStep = (typeof AGENCY_CAMPAIGN_STEPS)[number];
|
|
65
|
+
export type AgencyCampaignOffBoard = 'declined' | 'left' | 'removed' | 'rejected';
|
|
66
|
+
export declare const AGENCY_MILESTONE_KINDS: readonly ["draft_due", "live_by", "custom"];
|
|
67
|
+
export type AgencyMilestoneKind = (typeof AGENCY_MILESTONE_KINDS)[number];
|
|
68
|
+
/** A milestone may wait on one rule: every ACTIVE offer at a status, or every active creator's latest material at a stage. */
|
|
69
|
+
export declare const AGENCY_MILESTONE_OFFER_RULES: readonly [I_OfferStatus.CONFIRMED];
|
|
70
|
+
export declare const AGENCY_MILESTONE_MEDIA_RULES: readonly [I_MediaStage.UPLOADED, I_MediaStage.ACCEPTED];
|
|
71
|
+
export declare const AGENCY_CAMPAIGN_EVENT_KINDS: readonly ["invited", "joined", "declined", "left", "removed", "offer_sent", "offer_countered", "offer_accepted", "offer_confirmed", "offer_rejected", "offer_withdrawn", "material_uploaded", "material_approved", "material_changes_asked", "material_rejected", "published", "milestone_confirmed"];
|
|
72
|
+
export type AgencyCampaignEventKind = (typeof AGENCY_CAMPAIGN_EVENT_KINDS)[number];
|
|
73
|
+
/** Refusal codes the frontend owes its own copy for. */
|
|
74
|
+
export declare const AGENCY_CAMPAIGN_CODES: {
|
|
75
|
+
/** The transition is not open at this state, or not for this side. */
|
|
76
|
+
readonly TRANSITION_REFUSED: "agency-campaign-transition-refused";
|
|
77
|
+
/** A campaign sent to a creator must carry its brief text (FR-025). */
|
|
78
|
+
readonly BRIEF_REQUIRED: "agency-campaign-brief-required";
|
|
79
|
+
/** A deliverable on a platform the creator has not connected (FR-025). */
|
|
80
|
+
readonly PLATFORM_NOT_CONNECTED: "agency-campaign-platform-not-connected";
|
|
81
|
+
/** The creator is already on this campaign. */
|
|
82
|
+
readonly ALREADY_MEMBER: "agency-campaign-already-member";
|
|
83
|
+
/** The upload was confirmed but no stored file exists at its path (FR-029). */
|
|
84
|
+
readonly MATERIAL_NOT_STORED: "agency-campaign-material-not-stored";
|
|
85
|
+
/** A demo creator cannot be invited or mailed (spec 179). */
|
|
86
|
+
readonly DEMO_CREATOR: "agency-campaign-demo-creator";
|
|
87
|
+
};
|
|
88
|
+
export type AgencyCampaignCode = (typeof AGENCY_CAMPAIGN_CODES)[keyof typeof AGENCY_CAMPAIGN_CODES];
|
|
89
|
+
export interface I_CampaignDeliverable {
|
|
90
|
+
platform: CampaignPlatform;
|
|
91
|
+
placement: CampaignPlacement;
|
|
92
|
+
qty: number;
|
|
93
|
+
note?: string;
|
|
94
|
+
}
|
|
95
|
+
export interface I_AgencyCampaignBrief {
|
|
96
|
+
/** The concept, in prose. May be empty only while the campaign is a draft. */
|
|
97
|
+
text: string;
|
|
98
|
+
deliverables: I_CampaignDeliverable[];
|
|
99
|
+
/** ISO dates, or null when not set. */
|
|
100
|
+
draftDueAt: string | null;
|
|
101
|
+
liveByAt: string | null;
|
|
102
|
+
/** Usage rights on the brand's profiles, in months. */
|
|
103
|
+
licenceMonths: number | null;
|
|
104
|
+
/** Paid promotion (whitelisting), in months. */
|
|
105
|
+
paidPromoMonths: number | null;
|
|
106
|
+
revisionRounds: number | null;
|
|
107
|
+
}
|
|
108
|
+
/** Money is integer minor units plus an ISO-4217 code; the legacy float `price` is never written. */
|
|
109
|
+
export interface I_Money {
|
|
110
|
+
minor: number;
|
|
111
|
+
currency: string;
|
|
112
|
+
}
|
|
113
|
+
export interface I_AgencyOfferView {
|
|
114
|
+
id: string;
|
|
115
|
+
status: AgencyOfferStatus;
|
|
116
|
+
/** The price on the table now: the latest one either side named. */
|
|
117
|
+
price: I_Money;
|
|
118
|
+
/** Whose move it is; null once the offer is settled. */
|
|
119
|
+
turn: CampaignSide | null;
|
|
120
|
+
/** The acts open to the CALLER'S side, right now. */
|
|
121
|
+
availableActions: AgencyOfferAction[];
|
|
122
|
+
sentAt: string;
|
|
123
|
+
updatedAt: string;
|
|
124
|
+
}
|
|
125
|
+
export interface I_AgencyMaterial {
|
|
126
|
+
id: string;
|
|
127
|
+
fileName: string;
|
|
128
|
+
contentType: string;
|
|
129
|
+
sizeBytes: number | null;
|
|
130
|
+
stage: I_MediaStage;
|
|
131
|
+
uploadedAt: string;
|
|
132
|
+
/** The note sent with a change request or a rejection of THIS version. */
|
|
133
|
+
note: string | null;
|
|
134
|
+
}
|
|
135
|
+
export interface I_AgencyMilestone {
|
|
136
|
+
id: string;
|
|
137
|
+
kind: AgencyMilestoneKind;
|
|
138
|
+
/** Only for `custom`; the others are named by i18n from `kind`. */
|
|
139
|
+
label: string | null;
|
|
140
|
+
dueAt: string | null;
|
|
141
|
+
/** Null = campaign-wide. */
|
|
142
|
+
creatorUserId: string | null;
|
|
143
|
+
offerRule: (typeof AGENCY_MILESTONE_OFFER_RULES)[number] | null;
|
|
144
|
+
mediaRule: (typeof AGENCY_MILESTONE_MEDIA_RULES)[number] | null;
|
|
145
|
+
readyToConfirm: boolean;
|
|
146
|
+
confirmedAt: string | null;
|
|
147
|
+
}
|
|
148
|
+
export interface I_AgencyCampaignEvent {
|
|
149
|
+
kind: AgencyCampaignEventKind;
|
|
150
|
+
side: CampaignSide;
|
|
151
|
+
at: string;
|
|
152
|
+
price?: I_Money;
|
|
153
|
+
note?: string;
|
|
154
|
+
}
|
|
155
|
+
export interface I_CampaignCreatorIdentity {
|
|
156
|
+
userId: string | null;
|
|
157
|
+
handle: string;
|
|
158
|
+
displayName?: string;
|
|
159
|
+
avatarUrl?: string;
|
|
160
|
+
}
|
|
161
|
+
/** One creator's row on the campaign screen (the list twin of the board). */
|
|
162
|
+
export interface I_AgencyCampaignMemberRow {
|
|
163
|
+
memberId: string;
|
|
164
|
+
creator: I_CampaignCreatorIdentity;
|
|
165
|
+
state: AgencyCampaignMemberState;
|
|
166
|
+
/** The board column, or the reason the row is off the board. */
|
|
167
|
+
step: AgencyCampaignStep | AgencyCampaignOffBoard;
|
|
168
|
+
/** When the row reached its current step. */
|
|
169
|
+
stepAt: string;
|
|
170
|
+
offer: I_AgencyOfferView | null;
|
|
171
|
+
latestMaterial: I_AgencyMaterial | null;
|
|
172
|
+
/** The agency's acts on `latestMaterial`. */
|
|
173
|
+
materialActions: AgencyMaterialAction[];
|
|
174
|
+
/** Read from the creator's own setting (FR-027); null when they have not set it. */
|
|
175
|
+
settlementForm: SettlementForm | null;
|
|
176
|
+
nextDeadline: {
|
|
177
|
+
at: string;
|
|
178
|
+
kind: AgencyMilestoneKind;
|
|
179
|
+
label: string | null;
|
|
180
|
+
} | null;
|
|
181
|
+
/** True when the agency may still remove them (no confirmed offer). */
|
|
182
|
+
removable: boolean;
|
|
183
|
+
/** True when the agency may send an offer now (joined, none sent yet). */
|
|
184
|
+
canSendOffer: boolean;
|
|
185
|
+
canMarkPublished: boolean;
|
|
186
|
+
/** Scopes a folded access request asked for, while the invitation is open. */
|
|
187
|
+
requestedScopes: I_AgencyGrantScope[];
|
|
188
|
+
}
|
|
189
|
+
export interface I_AgencyCampaignPipeline {
|
|
190
|
+
/** Creators per board column; off-board rows are not counted. */
|
|
191
|
+
steps: Record<AgencyCampaignStep, number>;
|
|
192
|
+
total: number;
|
|
193
|
+
}
|
|
194
|
+
export interface I_AgencyCampaignCard {
|
|
195
|
+
id: string;
|
|
196
|
+
name: string;
|
|
197
|
+
isDraft: boolean;
|
|
198
|
+
liveByAt: string | null;
|
|
199
|
+
draftDueAt: string | null;
|
|
200
|
+
pipeline: I_AgencyCampaignPipeline;
|
|
201
|
+
/** How many things on this campaign wait on the agency (the rail's definition). */
|
|
202
|
+
attention: number;
|
|
203
|
+
createdAt: string;
|
|
204
|
+
}
|
|
205
|
+
export interface I_AgencyCampaign {
|
|
206
|
+
id: string;
|
|
207
|
+
name: string;
|
|
208
|
+
isDraft: boolean;
|
|
209
|
+
brief: I_AgencyCampaignBrief;
|
|
210
|
+
members: I_AgencyCampaignMemberRow[];
|
|
211
|
+
milestones: I_AgencyMilestone[];
|
|
212
|
+
pipeline: I_AgencyCampaignPipeline;
|
|
213
|
+
createdAt: string;
|
|
214
|
+
}
|
|
215
|
+
/** Opening one creator (FR-024): their course with dates, notes, files and milestones. */
|
|
216
|
+
export interface I_AgencyCampaignCreatorDetail {
|
|
217
|
+
row: I_AgencyCampaignMemberRow;
|
|
218
|
+
creatorBrief: string | null;
|
|
219
|
+
events: I_AgencyCampaignEvent[];
|
|
220
|
+
materials: I_AgencyMaterial[];
|
|
221
|
+
milestones: I_AgencyMilestone[];
|
|
222
|
+
}
|
|
223
|
+
/** `GET /agency/campaigns/attention` — what waits on the agency (FR-022, the rail). */
|
|
224
|
+
export interface I_AgencyCampaignAttention {
|
|
225
|
+
counterOffers: number;
|
|
226
|
+
materialsToReview: number;
|
|
227
|
+
milestonesReady: number;
|
|
228
|
+
total: number;
|
|
229
|
+
}
|
|
230
|
+
/** `GET /agency/panel` (FR-022). */
|
|
231
|
+
export interface I_AgencyPanel {
|
|
232
|
+
/** Open milestones of running (non-draft) campaigns due today. */
|
|
233
|
+
dueToday: number;
|
|
234
|
+
/** Open milestones of running (non-draft) campaigns past their date. */
|
|
235
|
+
overdue: number;
|
|
236
|
+
/** The roster's own "needs attention" count, or null when it could not be read: shown as a dash, never 0. */
|
|
237
|
+
needsAttention: number | null;
|
|
238
|
+
deadlines: Array<{
|
|
239
|
+
campaignId: string;
|
|
240
|
+
campaignName: string;
|
|
241
|
+
milestoneId: string;
|
|
242
|
+
kind: AgencyMilestoneKind;
|
|
243
|
+
label: string | null;
|
|
244
|
+
dueAt: string;
|
|
245
|
+
creatorHandle: string | null;
|
|
246
|
+
confirmed: boolean;
|
|
247
|
+
}>;
|
|
248
|
+
campaigns: Array<{
|
|
249
|
+
id: string;
|
|
250
|
+
name: string;
|
|
251
|
+
pipeline: I_AgencyCampaignPipeline;
|
|
252
|
+
liveByAt: string | null;
|
|
253
|
+
}>;
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* What a creator reads about ONE campaign they are on. Deliberately narrow
|
|
257
|
+
* (SC-014): their own membership, offer, brief, materials and deadlines — no
|
|
258
|
+
* other creator, no total, no average, no count of others.
|
|
259
|
+
*/
|
|
260
|
+
export interface I_CreatorCampaignView {
|
|
261
|
+
memberId: string;
|
|
262
|
+
state: AgencyCampaignMemberState;
|
|
263
|
+
organization: {
|
|
264
|
+
id: string;
|
|
265
|
+
name: string;
|
|
266
|
+
};
|
|
267
|
+
campaign: {
|
|
268
|
+
id: string;
|
|
269
|
+
name: string;
|
|
270
|
+
brief: I_AgencyCampaignBrief;
|
|
271
|
+
};
|
|
272
|
+
creatorBrief: string | null;
|
|
273
|
+
/** The access request folded into the invitation, while it is open. */
|
|
274
|
+
requestedScopes: I_AgencyGrantScope[];
|
|
275
|
+
offer: I_AgencyOfferView | null;
|
|
276
|
+
materials: I_AgencyMaterial[];
|
|
277
|
+
/** True when the creator may upload now (confirmed, and no version awaits review). */
|
|
278
|
+
canUpload: boolean;
|
|
279
|
+
/** True when the creator may leave (no confirmed offer). */
|
|
280
|
+
canLeave: boolean;
|
|
281
|
+
milestones: I_AgencyMilestone[];
|
|
282
|
+
invitedAt: string;
|
|
283
|
+
}
|
|
284
|
+
/** `GET /agency/campaign-invitations/mine` — pending invitations and live campaigns. */
|
|
285
|
+
export interface I_CreatorCampaigns {
|
|
286
|
+
items: I_CreatorCampaignView[];
|
|
287
|
+
/** The creator's turn, the creator's badge: invitations to answer, offers to answer, and materials to upload (a first version, or a new one after changes were asked or a version was rejected). */
|
|
288
|
+
waitingOnYou: number;
|
|
289
|
+
}
|
|
290
|
+
export interface I_MaterialUploadTicket {
|
|
291
|
+
/** Opaque; sent back on confirm. */
|
|
292
|
+
uploadId: string;
|
|
293
|
+
/** PUT the file's bytes here with `headers`. */
|
|
294
|
+
uploadUrl: string;
|
|
295
|
+
headers: Record<string, string>;
|
|
296
|
+
expiresAt: string;
|
|
297
|
+
}
|
|
298
|
+
export interface I_SignedRead {
|
|
299
|
+
url: string;
|
|
300
|
+
expiresAt: string;
|
|
301
|
+
}
|
|
302
|
+
/** The brief's fields, shared by create and update. All optional on the wire. */
|
|
303
|
+
declare class AgencyCampaignBriefFields {
|
|
304
|
+
text?: string;
|
|
305
|
+
deliverables?: I_CampaignDeliverable[];
|
|
306
|
+
draftDueAt?: string | null;
|
|
307
|
+
liveByAt?: string | null;
|
|
308
|
+
licenceMonths?: number | null;
|
|
309
|
+
paidPromoMonths?: number | null;
|
|
310
|
+
revisionRounds?: number | null;
|
|
311
|
+
protected assignBrief(data?: Partial<AgencyCampaignBriefFields>): void;
|
|
312
|
+
}
|
|
313
|
+
export declare class CreateAgencyCampaignDto extends AgencyCampaignBriefFields {
|
|
314
|
+
name: string;
|
|
315
|
+
constructor(data?: Partial<CreateAgencyCampaignDto>);
|
|
316
|
+
}
|
|
317
|
+
export declare class UpdateAgencyCampaignDto extends AgencyCampaignBriefFields {
|
|
318
|
+
name?: string;
|
|
319
|
+
/** Setting false publishes the draft; the brief text must then be present (FR-025). */
|
|
320
|
+
isDraft?: boolean;
|
|
321
|
+
constructor(data?: Partial<UpdateAgencyCampaignDto>);
|
|
322
|
+
}
|
|
323
|
+
export declare class InviteCampaignCreatorDto {
|
|
324
|
+
/** A user id: a UUID or a Firebase uid. */
|
|
325
|
+
creatorUserId: string;
|
|
326
|
+
creatorBrief?: string;
|
|
327
|
+
/** The access request folded into the invitation when no grant covers them (FR-026). */
|
|
328
|
+
scopes?: I_AgencyGrantScope[];
|
|
329
|
+
constructor(data?: Partial<InviteCampaignCreatorDto>);
|
|
330
|
+
}
|
|
331
|
+
export declare class SendCampaignOfferDto {
|
|
332
|
+
priceMinor: number;
|
|
333
|
+
currency: string;
|
|
334
|
+
constructor(data?: Partial<SendCampaignOfferDto>);
|
|
335
|
+
}
|
|
336
|
+
/** One act on an offer. `counter` needs `priceMinor`; any act may carry a note. */
|
|
337
|
+
export declare class CampaignOfferActDto {
|
|
338
|
+
action: AgencyOfferAction;
|
|
339
|
+
/** A counter keeps the offer's currency; only the amount moves. */
|
|
340
|
+
priceMinor?: number;
|
|
341
|
+
note?: string;
|
|
342
|
+
constructor(data?: Partial<CampaignOfferActDto>);
|
|
343
|
+
}
|
|
344
|
+
/** One agency act on a material. `request_changes` requires the note. */
|
|
345
|
+
export declare class CampaignMaterialActDto {
|
|
346
|
+
action: AgencyMaterialAction;
|
|
347
|
+
note?: string;
|
|
348
|
+
constructor(data?: Partial<CampaignMaterialActDto>);
|
|
349
|
+
}
|
|
350
|
+
export declare class JoinCampaignDto {
|
|
351
|
+
/** A subset of what was asked; absent = everything asked. */
|
|
352
|
+
scopes?: I_AgencyGrantScope[];
|
|
353
|
+
constructor(data?: Partial<JoinCampaignDto>);
|
|
354
|
+
}
|
|
355
|
+
/** Material files: images and video only, at most 2 GB. */
|
|
356
|
+
export declare const MATERIAL_MAX_BYTES: number;
|
|
357
|
+
/**
|
|
358
|
+
* The photo formats a material may be. Raster only: no SVG or HTML, because a
|
|
359
|
+
* material is opened in the browser. Shared so the upload picker, the
|
|
360
|
+
* creator's own check and the API refuse exactly the same files.
|
|
361
|
+
*/
|
|
362
|
+
export declare const MATERIAL_IMAGE_TYPES: readonly ["image/png", "image/jpeg", "image/gif", "image/webp", "image/heic", "image/heif", "image/avif"];
|
|
363
|
+
/** A material's content type: one of MATERIAL_IMAGE_TYPES, or any video. */
|
|
364
|
+
export declare const MATERIAL_CONTENT_TYPE: RegExp;
|
|
365
|
+
export declare class PrepareMaterialUploadDto {
|
|
366
|
+
fileName: string;
|
|
367
|
+
contentType: string;
|
|
368
|
+
sizeBytes: number;
|
|
369
|
+
constructor(data?: Partial<PrepareMaterialUploadDto>);
|
|
370
|
+
}
|
|
371
|
+
export declare class ConfirmMaterialUploadDto {
|
|
372
|
+
uploadId: string;
|
|
373
|
+
constructor(data?: Partial<ConfirmMaterialUploadDto>);
|
|
374
|
+
}
|
|
375
|
+
export declare class CreateAgencyMilestoneDto {
|
|
376
|
+
kind: AgencyMilestoneKind;
|
|
377
|
+
/** Required for `custom`, ignored otherwise. */
|
|
378
|
+
label?: string;
|
|
379
|
+
dueAt?: string | null;
|
|
380
|
+
/** Absent = campaign-wide. */
|
|
381
|
+
creatorUserId?: string | null;
|
|
382
|
+
offerRule?: (typeof AGENCY_MILESTONE_OFFER_RULES)[number] | null;
|
|
383
|
+
mediaRule?: (typeof AGENCY_MILESTONE_MEDIA_RULES)[number] | null;
|
|
384
|
+
constructor(data?: Partial<CreateAgencyMilestoneDto>);
|
|
385
|
+
}
|
|
386
|
+
/** `PATCH /users/me/settlement-form` — the creator's own setting (FR-027). */
|
|
387
|
+
export declare class UpdateSettlementFormDto {
|
|
388
|
+
settlementForm: SettlementForm | null;
|
|
389
|
+
constructor(data?: Partial<UpdateSettlementFormDto>);
|
|
390
|
+
}
|
|
391
|
+
export {};
|