@proveanything/smartlinks 1.0.65 → 1.1.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/README.md CHANGED
@@ -128,6 +128,49 @@ const content = await ai.generateContent('collectionId', {
128
128
  console.log(content)
129
129
  ```
130
130
 
131
+ ### Analytics (Actions & Broadcasts)
132
+
133
+ Track user actions and broadcast deliveries per collection. These endpoints live under admin and require valid auth (API key or bearer token).
134
+
135
+ ```ts
136
+ import { actions, broadcasts } from '@proveanything/smartlinks'
137
+
138
+ // List action events for a user
139
+ const actionEvents = await actions.byUser('collectionId', {
140
+ userId: 'user_123',
141
+ from: '2025-01-01T00:00:00Z',
142
+ to: '2025-12-31T23:59:59Z',
143
+ limit: 100,
144
+ })
145
+
146
+ // Outcome counts, optionally deduping latest per actor
147
+ const counts = await actions.countsByOutcome('collectionId', {
148
+ actionId: 'click',
149
+ dedupeLatest: true,
150
+ idField: 'userId',
151
+ })
152
+
153
+ // Append a single action event
154
+ await actions.append('collectionId', {
155
+ userId: 'user_123',
156
+ actionId: 'click',
157
+ outcome: 'success',
158
+ })
159
+
160
+ // Broadcast recipients and filters
161
+ const recipients = await broadcasts.recipientIds('collectionId', {
162
+ broadcastId: 'br_456',
163
+ idField: 'contactId',
164
+ })
165
+
166
+ // Append broadcast recipients in bulk (preferred shape)
167
+ await broadcasts.appendBulk('collectionId', {
168
+ params: { broadcastId: 'br_456', channel: 'email' },
169
+ ids: ['contact_1','contact_2'],
170
+ idField: 'contactId',
171
+ })
172
+ ```
173
+
131
174
  ## Browser and React
132
175
 
133
176
  The SDK works in modern browsers. Initialize once and call public endpoints without an API key; authenticate to access protected/admin endpoints.
@@ -0,0 +1,32 @@
1
+ import type { ActionQueryByUser, ActionCountsQuery, ActorIdsByActionQuery, AppendActionBody, OutcomeCount, ActorId, ActorWithOutcome, ActionEventRow, AdminByUserRequest, AdminCountsByOutcomeRequest, AdminActorIdsByActionRequest, PublicCountsByOutcomeRequest, PublicByUserRequest, CreateActionBody, UpdateActionBody, ListActionsQuery, ActionRecord, ActionList } from "../types/actions";
2
+ export declare namespace actions {
3
+ /**
4
+ * POST /admin/collection/:collectionId/actions/by-user
5
+ * Returns BigQuery action rows, newest first.
6
+ */
7
+ function byUser(collectionId: string, query?: AdminByUserRequest | ActionQueryByUser): Promise<ActionEventRow[]>;
8
+ /**
9
+ * POST /admin/collection/:collectionId/actions/counts-by-outcome
10
+ * Returns array of { outcome, count }.
11
+ */
12
+ function countsByOutcome(collectionId: string, query?: AdminCountsByOutcomeRequest | ActionCountsQuery): Promise<OutcomeCount[]>;
13
+ /**
14
+ * POST /admin/collection/:collectionId/actions/actor-ids/by-action
15
+ * Returns list of IDs, optionally with outcome when includeOutcome=true.
16
+ */
17
+ function actorIdsByAction(collectionId: string, query: AdminActorIdsByActionRequest | ActorIdsByActionQuery): Promise<ActorId[] | ActorWithOutcome[]>;
18
+ /**
19
+ * POST /admin/collection/:collectionId/actions/append
20
+ * Appends one action event.
21
+ */
22
+ function append(collectionId: string, body: AppendActionBody): Promise<{
23
+ success: true;
24
+ }>;
25
+ function create(collectionId: string, body: CreateActionBody): Promise<ActionRecord>;
26
+ function list(collectionId: string, query?: ListActionsQuery): Promise<ActionList>;
27
+ function get(collectionId: string, id: string): Promise<ActionRecord>;
28
+ function update(collectionId: string, id: string, patchBody: UpdateActionBody): Promise<ActionRecord>;
29
+ function remove(collectionId: string, id: string): Promise<void>;
30
+ function publicCountsByOutcome(collectionId: string, body: PublicCountsByOutcomeRequest, authToken?: string): Promise<OutcomeCount[]>;
31
+ function publicMyActions(collectionId: string, body: PublicByUserRequest, authToken?: string): Promise<ActionEventRow[]>;
32
+ }
@@ -0,0 +1,99 @@
1
+ // src/api/actions.ts
2
+ import { request, post, patch, del } from "../http";
3
+ function encodeQuery(params) {
4
+ const search = new URLSearchParams();
5
+ for (const [key, value] of Object.entries(params)) {
6
+ if (value === undefined || value === null || value === "")
7
+ continue;
8
+ if (typeof value === "boolean") {
9
+ search.set(key, value ? "true" : "false");
10
+ }
11
+ else {
12
+ search.set(key, String(value));
13
+ }
14
+ }
15
+ const qs = search.toString();
16
+ return qs ? `?${qs}` : "";
17
+ }
18
+ export var actions;
19
+ (function (actions) {
20
+ /**
21
+ * POST /admin/collection/:collectionId/actions/by-user
22
+ * Returns BigQuery action rows, newest first.
23
+ */
24
+ async function byUser(collectionId, query = {}) {
25
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/actions/by-user`;
26
+ return post(path, query);
27
+ }
28
+ actions.byUser = byUser;
29
+ /**
30
+ * POST /admin/collection/:collectionId/actions/counts-by-outcome
31
+ * Returns array of { outcome, count }.
32
+ */
33
+ async function countsByOutcome(collectionId, query = {}) {
34
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/actions/counts-by-outcome`;
35
+ return post(path, query);
36
+ }
37
+ actions.countsByOutcome = countsByOutcome;
38
+ /**
39
+ * POST /admin/collection/:collectionId/actions/actor-ids/by-action
40
+ * Returns list of IDs, optionally with outcome when includeOutcome=true.
41
+ */
42
+ async function actorIdsByAction(collectionId, query) {
43
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/actions/actor-ids/by-action`;
44
+ return post(path, query);
45
+ }
46
+ actions.actorIdsByAction = actorIdsByAction;
47
+ /**
48
+ * POST /admin/collection/:collectionId/actions/append
49
+ * Appends one action event.
50
+ */
51
+ async function append(collectionId, body) {
52
+ if (!body.userId && !body.contactId) {
53
+ throw new Error("AppendActionBody must include one of userId or contactId");
54
+ }
55
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/actions/append`;
56
+ return post(path, body);
57
+ }
58
+ actions.append = append;
59
+ // CRUD: Actions (Postgres)
60
+ async function create(collectionId, body) {
61
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/actions/`;
62
+ return post(path, body);
63
+ }
64
+ actions.create = create;
65
+ async function list(collectionId, query = {}) {
66
+ const qs = encodeQuery(query);
67
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/actions/${qs}`;
68
+ return request(path);
69
+ }
70
+ actions.list = list;
71
+ async function get(collectionId, id) {
72
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/actions/${encodeURIComponent(id)}`;
73
+ return request(path);
74
+ }
75
+ actions.get = get;
76
+ async function update(collectionId, id, patchBody) {
77
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/actions/${encodeURIComponent(id)}`;
78
+ return patch(path, patchBody);
79
+ }
80
+ actions.update = update;
81
+ async function remove(collectionId, id) {
82
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/actions/${encodeURIComponent(id)}`;
83
+ return del(path);
84
+ }
85
+ actions.remove = remove;
86
+ // Public endpoints (permission-aware)
87
+ async function publicCountsByOutcome(collectionId, body, authToken) {
88
+ const path = `/public/collection/${encodeURIComponent(collectionId)}/actions/counts-by-outcome`;
89
+ const headers = authToken ? { AUTHORIZATION: `Bearer ${authToken}` } : undefined;
90
+ return post(path, body, headers);
91
+ }
92
+ actions.publicCountsByOutcome = publicCountsByOutcome;
93
+ async function publicMyActions(collectionId, body, authToken) {
94
+ const path = `/public/collection/${encodeURIComponent(collectionId)}/actions/by-user`;
95
+ const headers = authToken ? { AUTHORIZATION: `Bearer ${authToken}` } : undefined;
96
+ return post(path, body, headers);
97
+ }
98
+ actions.publicMyActions = publicMyActions;
99
+ })(actions || (actions = {}));
@@ -0,0 +1,44 @@
1
+ import type { BroadcastQueryByUser, RecipientIdsQuery, RecipientsWithoutActionQuery, RecipientsWithActionQuery, AppendBroadcastBody, AppendBroadcastBulkBody, BroadcastEvent, RecipientId, RecipientWithOutcome, AppendResult, AppendBulkResult, CreateBroadcastBody, UpdateBroadcastBody, ListBroadcastsQuery, BroadcastRecord, BroadcastList } from "../types/broadcasts";
2
+ export declare namespace broadcasts {
3
+ /**
4
+ * POST /admin/collection/:collectionId/broadcasts/by-user
5
+ * Returns broadcast events array, newest first.
6
+ */
7
+ function byUser(collectionId: string, query?: BroadcastQueryByUser): Promise<BroadcastEvent[]>;
8
+ /**
9
+ * POST /admin/collection/:collectionId/broadcasts/recipient-ids
10
+ * Returns recipient IDs for a broadcast.
11
+ */
12
+ function recipientIds(collectionId: string, query: RecipientIdsQuery): Promise<RecipientId[]>;
13
+ /**
14
+ * POST /admin/collection/:collectionId/broadcasts/recipients/without-action
15
+ * Returns IDs who received the broadcast but did not perform an action.
16
+ */
17
+ function recipientsWithoutAction(collectionId: string, query: RecipientsWithoutActionQuery): Promise<RecipientId[]>;
18
+ /**
19
+ * POST /admin/collection/:collectionId/broadcasts/recipients/with-action
20
+ * Returns IDs who received the broadcast and performed an action; optionally includes outcome.
21
+ */
22
+ function recipientsWithAction(collectionId: string, query: RecipientsWithActionQuery): Promise<RecipientId[] | RecipientWithOutcome[]>;
23
+ /**
24
+ * POST /admin/collection/:collectionId/broadcasts/append
25
+ * Appends one broadcast event.
26
+ */
27
+ function append(collectionId: string, body: AppendBroadcastBody): Promise<AppendResult>;
28
+ /**
29
+ * POST /admin/collection/:collectionId/broadcasts/append/bulk
30
+ * Appends many broadcast recipients.
31
+ * Accepts preferred body shape with params + ids, and legacy flat shape.
32
+ */
33
+ function appendBulk(collectionId: string, body: AppendBroadcastBulkBody | ({
34
+ broadcastId: string;
35
+ ids: string[];
36
+ idField?: 'userId' | 'contactId';
37
+ [k: string]: any;
38
+ })): Promise<AppendBulkResult>;
39
+ function create(collectionId: string, body: CreateBroadcastBody): Promise<BroadcastRecord>;
40
+ function list(collectionId: string, query?: ListBroadcastsQuery): Promise<BroadcastList>;
41
+ function get(collectionId: string, id: string): Promise<BroadcastRecord>;
42
+ function update(collectionId: string, id: string, body: UpdateBroadcastBody): Promise<BroadcastRecord>;
43
+ function remove(collectionId: string, id: string): Promise<void>;
44
+ }
@@ -0,0 +1,105 @@
1
+ // src/api/broadcasts.ts
2
+ import { request, post, patch, del } from "../http";
3
+ function encodeQuery(params) {
4
+ const search = new URLSearchParams();
5
+ for (const [key, value] of Object.entries(params)) {
6
+ if (value === undefined || value === null || value === "")
7
+ continue;
8
+ if (typeof value === "boolean") {
9
+ search.set(key, value ? "true" : "false");
10
+ }
11
+ else {
12
+ search.set(key, String(value));
13
+ }
14
+ }
15
+ const qs = search.toString();
16
+ return qs ? `?${qs}` : "";
17
+ }
18
+ export var broadcasts;
19
+ (function (broadcasts) {
20
+ /**
21
+ * POST /admin/collection/:collectionId/broadcasts/by-user
22
+ * Returns broadcast events array, newest first.
23
+ */
24
+ async function byUser(collectionId, query = {}) {
25
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/broadcasts/by-user`;
26
+ return post(path, query);
27
+ }
28
+ broadcasts.byUser = byUser;
29
+ /**
30
+ * POST /admin/collection/:collectionId/broadcasts/recipient-ids
31
+ * Returns recipient IDs for a broadcast.
32
+ */
33
+ async function recipientIds(collectionId, query) {
34
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/broadcasts/recipient-ids`;
35
+ return post(path, query);
36
+ }
37
+ broadcasts.recipientIds = recipientIds;
38
+ /**
39
+ * POST /admin/collection/:collectionId/broadcasts/recipients/without-action
40
+ * Returns IDs who received the broadcast but did not perform an action.
41
+ */
42
+ async function recipientsWithoutAction(collectionId, query) {
43
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/broadcasts/recipients/without-action`;
44
+ return post(path, query);
45
+ }
46
+ broadcasts.recipientsWithoutAction = recipientsWithoutAction;
47
+ /**
48
+ * POST /admin/collection/:collectionId/broadcasts/recipients/with-action
49
+ * Returns IDs who received the broadcast and performed an action; optionally includes outcome.
50
+ */
51
+ async function recipientsWithAction(collectionId, query) {
52
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/broadcasts/recipients/with-action`;
53
+ return post(path, query);
54
+ }
55
+ broadcasts.recipientsWithAction = recipientsWithAction;
56
+ /**
57
+ * POST /admin/collection/:collectionId/broadcasts/append
58
+ * Appends one broadcast event.
59
+ */
60
+ async function append(collectionId, body) {
61
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/broadcasts/append`;
62
+ return post(path, body);
63
+ }
64
+ broadcasts.append = append;
65
+ /**
66
+ * POST /admin/collection/:collectionId/broadcasts/append/bulk
67
+ * Appends many broadcast recipients.
68
+ * Accepts preferred body shape with params + ids, and legacy flat shape.
69
+ */
70
+ async function appendBulk(collectionId, body) {
71
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/broadcasts/append/bulk`;
72
+ return post(path, body);
73
+ }
74
+ broadcasts.appendBulk = appendBulk;
75
+ // CRUD: Create broadcast
76
+ async function create(collectionId, body) {
77
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/broadcasts/`;
78
+ return post(path, body);
79
+ }
80
+ broadcasts.create = create;
81
+ // CRUD: List broadcasts (GET with query)
82
+ async function list(collectionId, query = {}) {
83
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/broadcasts/${encodeQuery(query)}`;
84
+ return request(path);
85
+ }
86
+ broadcasts.list = list;
87
+ // CRUD: Get a single broadcast
88
+ async function get(collectionId, id) {
89
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/broadcasts/${encodeURIComponent(id)}`;
90
+ return request(path);
91
+ }
92
+ broadcasts.get = get;
93
+ // CRUD: Update a broadcast
94
+ async function update(collectionId, id, body) {
95
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/broadcasts/${encodeURIComponent(id)}`;
96
+ return patch(path, body);
97
+ }
98
+ broadcasts.update = update;
99
+ // CRUD: Delete a broadcast
100
+ async function remove(collectionId, id) {
101
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/broadcasts/${encodeURIComponent(id)}`;
102
+ return del(path);
103
+ }
104
+ broadcasts.remove = remove;
105
+ })(broadcasts || (broadcasts = {}));
@@ -16,4 +16,8 @@ export { ai } from "./ai";
16
16
  export { comms } from "./comms";
17
17
  export { nfc } from "./nfc";
18
18
  export { contact } from "./contact";
19
+ export { actions } from "./actions";
20
+ export { broadcasts } from "./broadcasts";
21
+ export { segments } from "./segments";
22
+ export { journeys } from "./journeys";
19
23
  export type { AIGenerateContentRequest, AIGenerateImageRequest, AISearchPhotosRequest, AISearchPhotosPhoto } from "./ai";
package/dist/api/index.js CHANGED
@@ -18,3 +18,7 @@ export { ai } from "./ai";
18
18
  export { comms } from "./comms";
19
19
  export { nfc } from "./nfc";
20
20
  export { contact } from "./contact";
21
+ export { actions } from "./actions";
22
+ export { broadcasts } from "./broadcasts";
23
+ export { segments } from "./segments";
24
+ export { journeys } from "./journeys";
@@ -0,0 +1,8 @@
1
+ import type { JourneyRecord, JourneyList, ListJourneysQuery, CreateJourneyBody, UpdateJourneyBody } from "../types/journeys";
2
+ export declare namespace journeys {
3
+ function create(collectionId: string, body: CreateJourneyBody): Promise<JourneyRecord>;
4
+ function list(collectionId: string, query?: ListJourneysQuery): Promise<JourneyList>;
5
+ function get(collectionId: string, id: string): Promise<JourneyRecord>;
6
+ function update(collectionId: string, id: string, body: UpdateJourneyBody): Promise<JourneyRecord>;
7
+ function remove(collectionId: string, id: string): Promise<void>;
8
+ }
@@ -0,0 +1,48 @@
1
+ // src/api/journeys.ts
2
+ import { request, post, patch, del } from "../http";
3
+ function encodeQuery(params) {
4
+ const search = new URLSearchParams();
5
+ for (const [key, value] of Object.entries(params)) {
6
+ if (value === undefined || value === null || value === "")
7
+ continue;
8
+ if (typeof value === "boolean")
9
+ search.set(key, value ? "true" : "false");
10
+ else
11
+ search.set(key, String(value));
12
+ }
13
+ const qs = search.toString();
14
+ return qs ? `?${qs}` : "";
15
+ }
16
+ export var journeys;
17
+ (function (journeys) {
18
+ // Create
19
+ async function create(collectionId, body) {
20
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/journeys/`;
21
+ return post(path, body);
22
+ }
23
+ journeys.create = create;
24
+ // List
25
+ async function list(collectionId, query = {}) {
26
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/journeys/${encodeQuery(query)}`;
27
+ return request(path);
28
+ }
29
+ journeys.list = list;
30
+ // Get
31
+ async function get(collectionId, id) {
32
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/journeys/${encodeURIComponent(id)}`;
33
+ return request(path);
34
+ }
35
+ journeys.get = get;
36
+ // Update
37
+ async function update(collectionId, id, body) {
38
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/journeys/${encodeURIComponent(id)}`;
39
+ return patch(path, body);
40
+ }
41
+ journeys.update = update;
42
+ // Delete
43
+ async function remove(collectionId, id) {
44
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/journeys/${encodeURIComponent(id)}`;
45
+ return del(path);
46
+ }
47
+ journeys.remove = remove;
48
+ })(journeys || (journeys = {}));
@@ -0,0 +1,13 @@
1
+ import type { SegmentRecord, ListSegmentsQuery, SegmentList, SegmentCalculateResult, SegmentRecipientsResponse } from "../types/segments";
2
+ export declare namespace segments {
3
+ function create(collectionId: string, body: Omit<SegmentRecord, 'id' | 'collectionId' | 'createdAt'>): Promise<SegmentRecord>;
4
+ function list(collectionId: string, query?: ListSegmentsQuery): Promise<SegmentList>;
5
+ function get(collectionId: string, id: string): Promise<SegmentRecord>;
6
+ function update(collectionId: string, id: string, body: Partial<Omit<SegmentRecord, 'id' | 'collectionId' | 'createdAt'>>): Promise<SegmentRecord>;
7
+ function remove(collectionId: string, id: string): Promise<void>;
8
+ function calculate(collectionId: string, id: string): Promise<SegmentCalculateResult>;
9
+ function recipients(collectionId: string, id: string, query?: {
10
+ limit?: number;
11
+ offset?: number;
12
+ }): Promise<SegmentRecipientsResponse>;
13
+ }
@@ -0,0 +1,60 @@
1
+ // src/api/segments.ts
2
+ import { request, post, patch, del } from "../http";
3
+ function encodeQuery(params) {
4
+ const search = new URLSearchParams();
5
+ for (const [key, value] of Object.entries(params)) {
6
+ if (value === undefined || value === null || value === "")
7
+ continue;
8
+ if (typeof value === "boolean")
9
+ search.set(key, value ? "true" : "false");
10
+ else
11
+ search.set(key, String(value));
12
+ }
13
+ const qs = search.toString();
14
+ return qs ? `?${qs}` : "";
15
+ }
16
+ export var segments;
17
+ (function (segments) {
18
+ // Create
19
+ async function create(collectionId, body) {
20
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/segments/`;
21
+ return post(path, body);
22
+ }
23
+ segments.create = create;
24
+ // List
25
+ async function list(collectionId, query = {}) {
26
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/segments/${encodeQuery(query)}`;
27
+ return request(path);
28
+ }
29
+ segments.list = list;
30
+ // Get
31
+ async function get(collectionId, id) {
32
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/segments/${encodeURIComponent(id)}`;
33
+ return request(path);
34
+ }
35
+ segments.get = get;
36
+ // Update
37
+ async function update(collectionId, id, body) {
38
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/segments/${encodeURIComponent(id)}`;
39
+ return patch(path, body);
40
+ }
41
+ segments.update = update;
42
+ // Delete
43
+ async function remove(collectionId, id) {
44
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/segments/${encodeURIComponent(id)}`;
45
+ return del(path);
46
+ }
47
+ segments.remove = remove;
48
+ // Stub: calculate
49
+ async function calculate(collectionId, id) {
50
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/segments/${encodeURIComponent(id)}/calculate`;
51
+ return post(path, {});
52
+ }
53
+ segments.calculate = calculate;
54
+ // Stub: recipients
55
+ async function recipients(collectionId, id, query = {}) {
56
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/segments/${encodeURIComponent(id)}/recipients${encodeQuery(query)}`;
57
+ return request(path);
58
+ }
59
+ segments.recipients = recipients;
60
+ })(segments || (segments = {}));
@@ -0,0 +1,120 @@
1
+ import type { IdField } from './common';
2
+ export interface AdminByUserRequest {
3
+ userId?: string;
4
+ contactId?: string;
5
+ appId?: string;
6
+ actionId?: string;
7
+ broadcastId?: string;
8
+ outcome?: string | null;
9
+ from?: string;
10
+ to?: string;
11
+ limit?: number;
12
+ }
13
+ export interface AdminCountsByOutcomeRequest {
14
+ appId?: string;
15
+ actionId?: string;
16
+ from?: string;
17
+ to?: string;
18
+ limit?: number;
19
+ dedupeLatest?: boolean;
20
+ idField?: IdField;
21
+ }
22
+ export interface AdminActorIdsByActionRequest {
23
+ actionId: string;
24
+ idField?: IdField;
25
+ outcome?: string | null;
26
+ includeOutcome?: boolean;
27
+ from?: string;
28
+ to?: string;
29
+ limit?: number;
30
+ }
31
+ export interface PublicCountsByOutcomeRequest {
32
+ appId: string;
33
+ actionId: string;
34
+ from?: string;
35
+ to?: string;
36
+ limit?: number;
37
+ }
38
+ export interface PublicByUserRequest {
39
+ appId: string;
40
+ actionId: string;
41
+ from?: string;
42
+ to?: string;
43
+ limit?: number;
44
+ }
45
+ export interface ActionEventRow {
46
+ orgId: string;
47
+ timestamp: string;
48
+ appId?: string;
49
+ actionId?: string;
50
+ broadcastId?: string;
51
+ userId?: string;
52
+ contactId?: string;
53
+ outcome?: string | null;
54
+ [k: string]: unknown;
55
+ }
56
+ export interface OutcomeCount {
57
+ outcome: string | null;
58
+ count: number;
59
+ }
60
+ export type ActorId = string;
61
+ export interface ActorWithOutcome {
62
+ id: string;
63
+ outcome: string | null;
64
+ }
65
+ export interface AppendActionBody {
66
+ userId?: string;
67
+ contactId?: string;
68
+ actionId: string;
69
+ appId?: string;
70
+ broadcastId?: string;
71
+ outcome?: string;
72
+ timestamp?: string;
73
+ [k: string]: any;
74
+ }
75
+ export interface ActionPermissions {
76
+ allowOwnRead?: boolean;
77
+ allowPublicSummary?: boolean;
78
+ allowAuthenticatedSummary?: boolean;
79
+ }
80
+ export interface ActionRecord {
81
+ id: string;
82
+ collectionId: string;
83
+ appId: string;
84
+ permissions?: ActionPermissions;
85
+ data?: {
86
+ display?: {
87
+ title?: string;
88
+ description?: string;
89
+ icon?: string;
90
+ color?: string;
91
+ };
92
+ actionType?: string;
93
+ [key: string]: unknown;
94
+ };
95
+ createdAt: string;
96
+ }
97
+ export interface ActionList {
98
+ items: ActionRecord[];
99
+ limit: number;
100
+ offset: number;
101
+ }
102
+ export interface CreateActionBody {
103
+ id: string;
104
+ appId: string;
105
+ permissions?: ActionPermissions;
106
+ data?: Record<string, unknown>;
107
+ }
108
+ export interface UpdateActionBody {
109
+ appId?: string;
110
+ permissions?: ActionPermissions;
111
+ data?: Record<string, unknown>;
112
+ }
113
+ export interface ListActionsQuery {
114
+ appId?: string;
115
+ limit?: number;
116
+ offset?: number;
117
+ }
118
+ export type ActionQueryByUser = AdminByUserRequest;
119
+ export type ActionCountsQuery = AdminCountsByOutcomeRequest;
120
+ export type ActorIdsByActionQuery = AdminActorIdsByActionRequest;
@@ -0,0 +1,2 @@
1
+ // src/types/actions.ts
2
+ export {};
File without changes
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ // Deprecated: types moved to ./actions.ts and ./broadcasts.ts
3
+ // This file is intentionally left empty to avoid duplicate exports.