ad2app-lib 1.17.0 → 1.20.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.
@@ -27,12 +27,42 @@ export declare const EVENTS: {
27
27
  readonly COMPOSE_STARTED: "compose_started";
28
28
  readonly POST_SCHEDULED: "post_scheduled";
29
29
  readonly POST_PUBLISHED: "post_published";
30
+ readonly PUBLISH_FAILED: "publish_failed";
30
31
  readonly ANALYTICS_VIEWED: "analytics_viewed";
31
32
  readonly LIMIT_REACHED: "limit_reached";
32
33
  readonly UPGRADE_CLICKED: "upgrade_clicked";
33
34
  readonly CHECKOUT_STARTED: "checkout_started";
34
35
  readonly SUBSCRIPTION_STARTED: "subscription_started";
35
36
  readonly SUBSCRIPTION_CANCELED: "subscription_canceled";
37
+ readonly PAYWALL_SHOWN: "paywall_shown";
38
+ readonly PAYWALL_DISMISSED: "paywall_dismissed";
39
+ readonly ONBOARDING_STEP_COMPLETED: "onboarding_step_completed";
40
+ readonly EXIT_INTENT_SHOWN: "exit_intent_shown";
41
+ readonly EXIT_INTENT_DISMISSED: "exit_intent_dismissed";
42
+ readonly EXIT_INTENT_CAPTURED: "exit_intent_captured";
43
+ readonly BETA_SIGNUP_CONFIRMED: "beta_signup_confirmed";
44
+ readonly PAYMENT_FAILED: "payment_failed";
45
+ readonly DUNNING_RECOVERED: "dunning_recovered";
46
+ readonly REFUND_ISSUED: "refund_issued";
47
+ readonly DISPUTE_OPENED: "dispute_opened";
48
+ readonly CANCEL_INITIATED: "cancel_initiated";
49
+ readonly RETENTION_OFFER_SHOWN: "retention_offer_shown";
50
+ readonly CANCEL_COMPLETED: "cancel_completed";
51
+ readonly ONBOARDING_STARTED: "onboarding_started";
52
+ readonly ONBOARDING_COMPLETED: "onboarding_completed";
53
+ readonly ONBOARDING_SKIPPED: "onboarding_skipped";
54
+ readonly COMMENT_REPLIED: "comment_replied";
55
+ readonly COMMENT_LIKED: "comment_liked";
56
+ readonly COMMENT_HIDDEN: "comment_hidden";
57
+ readonly COMMENT_DELETED: "comment_deleted";
58
+ readonly COMMENT_PRIVATE_REPLIED: "comment_private_replied";
59
+ readonly DM_REPLIED: "dm_replied";
60
+ readonly INBOX_MARKED_READ: "inbox_marked_read";
61
+ readonly POST_EDITED: "post_edited";
62
+ readonly POST_DELETED: "post_deleted";
63
+ readonly POST_RESCHEDULED: "post_rescheduled";
64
+ readonly ACCOUNT_DISCONNECTED: "account_disconnected";
65
+ readonly NOTIFICATION_PREFERENCES_UPDATED: "notification_preferences_updated";
36
66
  };
37
67
  export type EventName = (typeof EVENTS)[keyof typeof EVENTS];
38
68
  /** Shared shape for the Resend email lifecycle events (AD2-894). */
@@ -41,6 +71,30 @@ export interface EmailEventProperties {
41
71
  subject?: string;
42
72
  link?: string;
43
73
  }
74
+ /**
75
+ * Where a paywall / upgrade / checkout moment was triggered from (080). A named,
76
+ * stable, closed set so the revenue funnel can attribute conversions to their
77
+ * origin surface. `checkout_abandon_email` is the recovery-email re-entry point
78
+ * (Superwall transaction-abandonment pattern). Wire values — do not rename.
79
+ */
80
+ export type TriggerSource = 'connect_wall' | 'limit_reached' | 'exit_intent' | 'pricing_page' | 'checkout_abandon_email' | 'other';
81
+ /**
82
+ * The USER-CHOSEN i18n locale (080) — NOT `$browser_language`. Localization is
83
+ * the top structural conversion lever in the corpus (Adapty), so every wall /
84
+ * paywall insight slices by it. Stamped on the surfaces the emitter controls.
85
+ */
86
+ export type AppLocale = 'en' | 'pl';
87
+ /**
88
+ * Coarse failure-reason buckets for the `publish_failed` event (AD2-999).
89
+ *
90
+ * Deliberately a small, stable, closed set: it lets publish outcomes be sliced
91
+ * per failure class in PostHog WITHOUT putting raw provider (Zernio/platform)
92
+ * error text — which can carry user content or PII — on the event. The emitter
93
+ * (backend) maps a raw provider error string to exactly one of these; an
94
+ * absent/unclassifiable error is `'unknown'`. Do NOT rename these values after
95
+ * they ship — they are wire values, historical data does not migrate.
96
+ */
97
+ export type PublishFailureReason = 'auth' | 'rate_limit' | 'media' | 'content' | 'network' | 'platform' | 'unknown';
44
98
  /** Property shape per event. Keeps emitters honest across repos. */
45
99
  export interface EventProperties {
46
100
  [EVENTS.LANDING_CTA_CLICKED]: {
@@ -76,6 +130,7 @@ export interface EventProperties {
76
130
  [EVENTS.SOCIAL_ACCOUNT_CONNECTED]: {
77
131
  platform: string;
78
132
  account_count?: number;
133
+ connection_ordinal?: number;
79
134
  };
80
135
  [EVENTS.COMPOSE_STARTED]: {
81
136
  source?: 'wizard' | 'quick';
@@ -84,11 +139,23 @@ export interface EventProperties {
84
139
  platforms: string[];
85
140
  platform_count: number;
86
141
  scheduled_for?: string;
142
+ post_ordinal?: number;
87
143
  };
88
144
  [EVENTS.POST_PUBLISHED]: {
89
145
  platforms: string[];
90
146
  platform_count: number;
91
147
  status: 'success' | 'partial' | 'failed';
148
+ post_ordinal?: number;
149
+ platform?: string;
150
+ source?: 'scheduled_reconcile';
151
+ outcome?: 'success' | 'failed' | 'unknown';
152
+ reason_class?: PublishFailureReason;
153
+ };
154
+ [EVENTS.PUBLISH_FAILED]: {
155
+ platform: string;
156
+ reason_class: PublishFailureReason;
157
+ post_id: string;
158
+ platform_count: number;
92
159
  };
93
160
  [EVENTS.ANALYTICS_VIEWED]: {
94
161
  scope?: 'overview' | 'account' | 'post';
@@ -102,19 +169,157 @@ export interface EventProperties {
102
169
  from_plan?: string;
103
170
  to_plan?: string;
104
171
  surface: string;
172
+ trigger_source?: TriggerSource;
105
173
  };
106
174
  [EVENTS.CHECKOUT_STARTED]: {
107
175
  plan: string;
176
+ trigger_source?: TriggerSource;
108
177
  };
109
178
  [EVENTS.SUBSCRIPTION_STARTED]: {
110
179
  plan: string;
111
180
  mrr?: number;
112
181
  accounts_included?: number;
182
+ trigger_source?: TriggerSource;
113
183
  };
114
184
  [EVENTS.SUBSCRIPTION_CANCELED]: {
115
185
  plan: string;
116
186
  reason?: string;
117
187
  };
188
+ [EVENTS.PAYWALL_SHOWN]: {
189
+ surface: 'upgrade_modal' | 'pricing_page';
190
+ trigger: 'user_click' | 'limit_reached' | 'connect_wall';
191
+ plan?: string;
192
+ hit_number: number;
193
+ dwell_ms?: number;
194
+ page_views?: number;
195
+ app_locale: AppLocale;
196
+ };
197
+ [EVENTS.PAYWALL_DISMISSED]: {
198
+ surface: 'upgrade_modal' | 'pricing_page';
199
+ trigger: 'user_click' | 'limit_reached' | 'connect_wall';
200
+ hit_number: number;
201
+ app_locale: AppLocale;
202
+ };
203
+ [EVENTS.ONBOARDING_STEP_COMPLETED]: {
204
+ flow: 'complete_profile';
205
+ step: string;
206
+ step_index: number;
207
+ app_locale: AppLocale;
208
+ };
209
+ [EVENTS.EXIT_INTENT_SHOWN]: {
210
+ surface: 'connect_wall';
211
+ dwell_ms?: number;
212
+ page_views?: number;
213
+ app_locale?: AppLocale;
214
+ };
215
+ [EVENTS.EXIT_INTENT_DISMISSED]: {
216
+ surface: 'connect_wall';
217
+ dwell_ms?: number;
218
+ page_views?: number;
219
+ app_locale?: AppLocale;
220
+ };
221
+ [EVENTS.EXIT_INTENT_CAPTURED]: {
222
+ surface: 'connect_wall';
223
+ dwell_ms?: number;
224
+ page_views?: number;
225
+ app_locale?: AppLocale;
226
+ };
227
+ [EVENTS.BETA_SIGNUP_CONFIRMED]: {
228
+ source: 'exit_intent' | 'free_skills';
229
+ };
230
+ [EVENTS.PAYMENT_FAILED]: {
231
+ plan: string;
232
+ attempt: number;
233
+ };
234
+ [EVENTS.DUNNING_RECOVERED]: {
235
+ plan: string;
236
+ attempts: number;
237
+ days_late: number;
238
+ };
239
+ [EVENTS.REFUND_ISSUED]: {
240
+ plan: string;
241
+ days_since_start: number;
242
+ };
243
+ [EVENTS.DISPUTE_OPENED]: {
244
+ plan: string;
245
+ days_since_start: number;
246
+ };
247
+ [EVENTS.CANCEL_INITIATED]: {
248
+ plan: string;
249
+ days_since_start: number;
250
+ };
251
+ [EVENTS.RETENTION_OFFER_SHOWN]: {
252
+ plan: string;
253
+ offer: string;
254
+ };
255
+ [EVENTS.CANCEL_COMPLETED]: {
256
+ plan: string;
257
+ days_since_start: number;
258
+ reason?: string;
259
+ };
260
+ [EVENTS.ONBOARDING_STARTED]: {
261
+ flow?: string;
262
+ };
263
+ [EVENTS.ONBOARDING_COMPLETED]: {
264
+ flow?: string;
265
+ steps_completed?: number;
266
+ };
267
+ [EVENTS.ONBOARDING_SKIPPED]: {
268
+ flow?: string;
269
+ step?: string;
270
+ };
271
+ [EVENTS.COMMENT_REPLIED]: {
272
+ platform?: string;
273
+ success: boolean;
274
+ };
275
+ [EVENTS.COMMENT_LIKED]: {
276
+ platform?: string;
277
+ liked: boolean;
278
+ success: boolean;
279
+ };
280
+ [EVENTS.COMMENT_HIDDEN]: {
281
+ platform?: string;
282
+ hidden: boolean;
283
+ success: boolean;
284
+ };
285
+ [EVENTS.COMMENT_DELETED]: {
286
+ platform?: string;
287
+ success: boolean;
288
+ };
289
+ [EVENTS.COMMENT_PRIVATE_REPLIED]: {
290
+ platform?: string;
291
+ success: boolean;
292
+ };
293
+ [EVENTS.DM_REPLIED]: {
294
+ platform?: string;
295
+ success: boolean;
296
+ };
297
+ [EVENTS.INBOX_MARKED_READ]: {
298
+ platform?: string;
299
+ success: boolean;
300
+ };
301
+ [EVENTS.POST_EDITED]: {
302
+ platforms?: string[];
303
+ platform_count?: number;
304
+ success: boolean;
305
+ };
306
+ [EVENTS.POST_DELETED]: {
307
+ platform_count?: number;
308
+ success: boolean;
309
+ };
310
+ [EVENTS.POST_RESCHEDULED]: {
311
+ platform_count?: number;
312
+ success: boolean;
313
+ };
314
+ [EVENTS.ACCOUNT_DISCONNECTED]: {
315
+ platform: string;
316
+ success: boolean;
317
+ };
318
+ [EVENTS.NOTIFICATION_PREFERENCES_UPDATED]: {
319
+ preference?: string;
320
+ enabled?: boolean;
321
+ success: boolean;
322
+ };
118
323
  }
119
324
  /** Canonical person property keys (set via identify / $set). */
120
325
  export declare const PERSON_PROPS: {
@@ -122,5 +327,6 @@ export declare const PERSON_PROPS: {
122
327
  readonly ROLE: "role";
123
328
  readonly PLAN: "plan";
124
329
  readonly ACCOUNT_COUNT: "account_count";
330
+ readonly PAYWALL_HITS: "paywall_hits";
125
331
  };
126
332
  export type PersonPropKey = (typeof PERSON_PROPS)[keyof typeof PERSON_PROPS];
@@ -34,6 +34,7 @@ exports.EVENTS = {
34
34
  COMPOSE_STARTED: 'compose_started',
35
35
  POST_SCHEDULED: 'post_scheduled',
36
36
  POST_PUBLISHED: 'post_published', // server-confirmed (backend)
37
+ PUBLISH_FAILED: 'publish_failed', // per-platform publish failure, server-owned (backend, AD2-999)
37
38
  ANALYTICS_VIEWED: 'analytics_viewed',
38
39
  // Revenue (backend = source of truth). Paid-only product: no trial.
39
40
  LIMIT_REACHED: 'limit_reached', // cap hit (e.g. X link-post cap) — the upsell trigger
@@ -41,6 +42,42 @@ exports.EVENTS = {
41
42
  CHECKOUT_STARTED: 'checkout_started',
42
43
  SUBSCRIPTION_STARTED: 'subscription_started',
43
44
  SUBSCRIPTION_CANCELED: 'subscription_canceled',
45
+ // Measurement baseline (080) — paywall / onboarding / exit-intent (frontend-owned)
46
+ PAYWALL_SHOWN: 'paywall_shown', // any monetization surface is shown (upgrade modal / pricing page)
47
+ PAYWALL_DISMISSED: 'paywall_dismissed', // closed without converting
48
+ ONBOARDING_STEP_COMPLETED: 'onboarding_step_completed', // one step of a multi-step flow (complete-profile)
49
+ EXIT_INTENT_SHOWN: 'exit_intent_shown', // exit-intent capture modal armed (065, verbatim wire values)
50
+ EXIT_INTENT_DISMISSED: 'exit_intent_dismissed',
51
+ EXIT_INTENT_CAPTURED: 'exit_intent_captured', // email captured into the beta list
52
+ // Measurement baseline (080) — subscription lifecycle (backend = source of truth)
53
+ BETA_SIGNUP_CONFIRMED: 'beta_signup_confirmed', // double-opt-in confirm click
54
+ PAYMENT_FAILED: 'payment_failed', // invoice.payment_failed (excl. unexecuted hard-decline retries)
55
+ DUNNING_RECOVERED: 'dunning_recovered', // open→paid after ≥1 failure on the same invoice
56
+ REFUND_ISSUED: 'refund_issued',
57
+ DISPUTE_OPENED: 'dispute_opened',
58
+ CANCEL_INITIATED: 'cancel_initiated', // start of the cancel funnel
59
+ RETENTION_OFFER_SHOWN: 'retention_offer_shown', // emitted ONLY when an offer is actually shown — no fabrication
60
+ CANCEL_COMPLETED: 'cancel_completed',
61
+ // Onboarding flow (promoted from the frontend-local onboardingEvents.ts into the
62
+ // governed taxonomy, 2026-07-19 — ONBOARDING_STEP_COMPLETED is defined above).
63
+ ONBOARDING_STARTED: 'onboarding_started',
64
+ ONBOARDING_COMPLETED: 'onboarding_completed',
65
+ ONBOARDING_SKIPPED: 'onboarding_skipped',
66
+ // Inbox engagement (tracking-coverage gap: the inbox surface had ZERO events).
67
+ COMMENT_REPLIED: 'comment_replied',
68
+ COMMENT_LIKED: 'comment_liked',
69
+ COMMENT_HIDDEN: 'comment_hidden',
70
+ COMMENT_DELETED: 'comment_deleted',
71
+ COMMENT_PRIVATE_REPLIED: 'comment_private_replied',
72
+ DM_REPLIED: 'dm_replied',
73
+ INBOX_MARKED_READ: 'inbox_marked_read', // sanctioned; wired when 082 mark-read lands
74
+ // Post lifecycle + account (tracking-coverage gap).
75
+ POST_EDITED: 'post_edited',
76
+ POST_DELETED: 'post_deleted',
77
+ POST_RESCHEDULED: 'post_rescheduled',
78
+ ACCOUNT_DISCONNECTED: 'account_disconnected',
79
+ // Settings.
80
+ NOTIFICATION_PREFERENCES_UPDATED: 'notification_preferences_updated',
44
81
  };
45
82
  /** Canonical person property keys (set via identify / $set). */
46
83
  exports.PERSON_PROPS = {
@@ -48,4 +85,8 @@ exports.PERSON_PROPS = {
48
85
  ROLE: 'role',
49
86
  PLAN: 'plan', // 'free' | 'starter' | 'pro' (SchedulingSubscriptionTier)
50
87
  ACCOUNT_COUNT: 'account_count',
88
+ // 080: convenience $set mirror of paywall exposure. The event-level `hit_number`
89
+ // is the analytical truth — person props are query-time-latest here, so a counter
90
+ // stored here would rewrite the value on every historical paywall_shown event.
91
+ PAYWALL_HITS: 'paywall_hits',
51
92
  };
@@ -53,6 +53,12 @@ export declare class SchedulingInboxCommentDTO {
53
53
  /** Parent comment id on nested replies (AD2-1088). Absent on top-level comments. */
54
54
  parentId?: string;
55
55
  replies?: SchedulingInboxCommentDTO[];
56
+ /**
57
+ * True when this comment can be moderated (approve/reject/hold) — YouTube only
58
+ * per Zernio (OpenAPI v1.0.4:22489, `platform` enum = [youtube]). Absent for
59
+ * every other platform; never fabricated to false-as-if-known (082 US7).
60
+ */
61
+ canModerate?: boolean;
56
62
  constructor(data: SchedulingInboxCommentDTO);
57
63
  }
58
64
  /** Input DTO for sending a DM reply. */
@@ -70,3 +76,162 @@ export declare class SchedulingReplyToCommentDTO {
70
76
  commentId?: string;
71
77
  constructor(data: SchedulingReplyToCommentDTO);
72
78
  }
79
+ /**
80
+ * One message inside a DM thread.
81
+ * Returned (paginated) by GET /social/inbox/messages/:id/thread — backed by
82
+ * Zernio GET /v1/inbox/conversations/{id}/messages (OpenAPI v1.0.4:20845).
83
+ */
84
+ export declare class SchedulingInboxMessageDTO {
85
+ id: string;
86
+ conversationId: string;
87
+ authorId: string;
88
+ authorName: string;
89
+ text: string;
90
+ createdAt: string;
91
+ /** True when OUR connected account authored this message. */
92
+ isOwn: boolean;
93
+ mediaUrl?: string;
94
+ constructor(data: SchedulingInboxMessageDTO);
95
+ }
96
+ /**
97
+ * A cursor page of thread messages — kills the prior 100-message truncation.
98
+ * `nextCursor` absent = last page.
99
+ */
100
+ export declare class SchedulingInboxMessagePageDTO {
101
+ items: SchedulingInboxMessageDTO[];
102
+ nextCursor?: string;
103
+ constructor(data: SchedulingInboxMessagePageDTO);
104
+ }
105
+ /**
106
+ * Mark-read acknowledgement — POST /social/inbox/messages/:id/read → Zernio
107
+ * POST /v1/inbox/conversations/{id}/read (OpenAPI v1.0.4:21692). `unreadCount`
108
+ * absent unless Zernio reports the post-read count.
109
+ */
110
+ export declare class SchedulingConversationReadDTO {
111
+ conversationId: string;
112
+ unreadCount?: number;
113
+ constructor(data: SchedulingConversationReadDTO);
114
+ }
115
+ /**
116
+ * An inbound mention.
117
+ * Returned by GET /social/inbox/mentions → Zernio GET /v1/inbox/mentions
118
+ * (OpenAPI v1.0.4:23108). Source post fields absent when the platform omits them.
119
+ */
120
+ export declare class SchedulingInboxMentionDTO {
121
+ id: string;
122
+ platform: string;
123
+ accountId: string;
124
+ authorName: string;
125
+ authorAvatarUrl?: string;
126
+ text: string;
127
+ createdAt: string;
128
+ sourcePostId?: string;
129
+ sourcePostUrl?: string;
130
+ constructor(data: SchedulingInboxMentionDTO);
131
+ }
132
+ /**
133
+ * Input for replying to a mention. Zernio requires [accountId, mediaId, message]
134
+ * (OpenAPI v1.0.4:23207) — `mediaId` (the mention's target media) is mandatory,
135
+ * unlike a DM reply.
136
+ */
137
+ export declare class SchedulingReplyToMentionDTO {
138
+ accountId: string;
139
+ mediaId: string;
140
+ message: string;
141
+ constructor(data: SchedulingReplyToMentionDTO);
142
+ }
143
+ /**
144
+ * A platform review (e.g. Google Business).
145
+ * Returned by GET /social/inbox/reviews → Zernio GET /v1/inbox/reviews
146
+ * (OpenAPI v1.0.4:23269). `replied` absent unless Zernio reports reply state.
147
+ */
148
+ export declare class SchedulingInboxReviewDTO {
149
+ id: string;
150
+ platform: string;
151
+ accountId: string;
152
+ authorName: string;
153
+ rating: number;
154
+ text: string;
155
+ createdAt: string;
156
+ replied?: boolean;
157
+ constructor(data: SchedulingInboxReviewDTO);
158
+ }
159
+ /**
160
+ * Input for replying to a review — POST /social/inbox/reviews/:reviewId/reply →
161
+ * Zernio POST /v1/inbox/reviews/{reviewId}/reply (OpenAPI v1.0.4:23377).
162
+ */
163
+ export declare class SchedulingReplyToReviewDTO {
164
+ reviewId: string;
165
+ accountId: string;
166
+ text: string;
167
+ constructor(data: SchedulingReplyToReviewDTO);
168
+ }
169
+ /**
170
+ * The moderation decision on a comment. Closed set per Zernio
171
+ * (OpenAPI v1.0.4:22489): `published` approves, `rejected` removes,
172
+ * `heldForReview` returns it to the queue. YouTube only. `banAuthor` is valid
173
+ * ONLY with `rejected` (any other pairing is a 400 — enforced server-side).
174
+ */
175
+ export type SchedulingCommentModerationStatus = 'published' | 'rejected' | 'heldForReview';
176
+ export declare class SchedulingCommentModerationDTO {
177
+ moderationStatus: SchedulingCommentModerationStatus;
178
+ banAuthor?: boolean;
179
+ constructor(data: SchedulingCommentModerationDTO);
180
+ }
181
+ /**
182
+ * Input for starting a new DM — POST /social/inbox/conversations → Zernio
183
+ * POST /v1/inbox/conversations (OpenAPI v1.0.4:20355). WhatsApp is excluded
184
+ * (it requires an approved template to open a thread; 082 non-goal).
185
+ */
186
+ export declare class SchedulingCreateConversationDTO {
187
+ accountId: string;
188
+ recipientId: string;
189
+ text: string;
190
+ constructor(data: SchedulingCreateConversationDTO);
191
+ }
192
+ /**
193
+ * Per-connected-account inbox capability truth — which surfaces a platform
194
+ * actually supports. Drives honest showing/hiding (082 FR-4): a false/absent
195
+ * surface is HIDDEN, never rendered as a fabricated empty. Reconciled from
196
+ * platform-capabilities + Zernio /accounts/health.
197
+ */
198
+ export declare class SchedulingInboxCapabilityDTO {
199
+ platform: string;
200
+ dm: boolean;
201
+ comments: boolean;
202
+ mentions: boolean;
203
+ reviews: boolean;
204
+ /** Can INITIATE a DM (not just reply). */
205
+ dmInit: boolean;
206
+ /** Comment moderation queue (YouTube). */
207
+ moderation: boolean;
208
+ constructor(data: SchedulingInboxCapabilityDTO);
209
+ }
210
+ /**
211
+ * A comment re-sourced from Zernio's cross-post inbox (GET /v1/inbox/comments),
212
+ * carrying its OWN post attribution so it surfaces even when the post is absent
213
+ * from our local SocialPostCache. The cache is enrichment ONLY (post snippet /
214
+ * thumbnail), never the source of truth (082 US3 / AD2-1110): a comment on an
215
+ * uncached post must still reach the moderator. Comment/engagement fields mirror
216
+ * SchedulingInboxCommentDTO; enrichment fields are honest-or-absent — filled from
217
+ * the cache when present, never zero/empty-backfilled.
218
+ */
219
+ export declare class SchedulingCrossPostCommentDTO {
220
+ id: string;
221
+ authorName: string;
222
+ authorAvatarUrl?: string;
223
+ text: string;
224
+ createdAt: string;
225
+ likeCount?: number;
226
+ replyCount?: number;
227
+ isOwner?: boolean;
228
+ parentId?: string;
229
+ canModerate?: boolean;
230
+ replies?: SchedulingCrossPostCommentDTO[];
231
+ postId: string;
232
+ platform: string;
233
+ accountId: string;
234
+ postContentSnippet?: string;
235
+ postThumbnailUrl?: string;
236
+ constructor(data: SchedulingCrossPostCommentDTO);
237
+ }