@opencxh/domain 1.219.0 → 1.222.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/entities/activity/catalog.d.ts +17 -0
- package/dist/entities/activity/resolve.d.ts +2 -0
- package/dist/entities/activity/types.d.ts +17 -0
- package/dist/entities/reaction/index.d.ts +1 -0
- package/dist/entities/reaction/summarize.test.d.ts +1 -0
- package/dist/entities/reaction/types.d.ts +73 -0
- package/dist/entities/work/activity.d.ts +9 -0
- package/dist/entities/work/keys.d.ts +9 -0
- package/dist/index.cjs +14 -14
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1350 -935
- package/dist/platform/communication.d.ts +25 -0
- package/dist/platform/document-operations.d.ts +6 -0
- package/dist/platform/documents.d.ts +151 -0
- package/dist/platform/permission.d.ts +1 -1
- package/package.json +1 -1
|
@@ -99,6 +99,23 @@ export declare function channelKindOf(type: string): ActivityChannelKind | undef
|
|
|
99
99
|
export declare function isMessageShape(shape: ActivityShape | undefined): boolean;
|
|
100
100
|
/** See {@link isMessageShape}. For the built-in types. */
|
|
101
101
|
export declare function isMessageType(type: string): boolean;
|
|
102
|
+
/**
|
|
103
|
+
* Does an answer of this kind fold into the list under the message it answers, instead of
|
|
104
|
+
* taking its own place in the timeline?
|
|
105
|
+
*
|
|
106
|
+
* Only notes. A mail carrying a `parentId` is still a message that was really sent, at a real
|
|
107
|
+
* moment, and burying it under the thing it answered would take it out of the chronology the
|
|
108
|
+
* rest of the conversation is read in — and out of view entirely while the thread is folded.
|
|
109
|
+
* An internal note has no such life of its own: it exists *about* that message.
|
|
110
|
+
*
|
|
111
|
+
* Keyed on the shape, so the rule has exactly one definition and an app-declared note kind
|
|
112
|
+
* behaves the same — see {@link ActivityTypeRegistry.nestsUnderParent}. `parentId` itself stays
|
|
113
|
+
* set on every reply regardless: it is a true fact about the row, and mail threading, the
|
|
114
|
+
* provider `In-Reply-To` and the reply notification all read it.
|
|
115
|
+
*/
|
|
116
|
+
export declare function isNoteShape(shape: ActivityShape | undefined): boolean;
|
|
117
|
+
/** See {@link isNoteShape}. For the built-in types. */
|
|
118
|
+
export declare function nestsUnderParent(type: string): boolean;
|
|
102
119
|
/** Can a human reply to it? Not to notes — those go nowhere. */
|
|
103
120
|
export declare function isReplyableType(type: string): boolean;
|
|
104
121
|
/**
|
|
@@ -70,6 +70,8 @@ export declare class ActivityTypeRegistry {
|
|
|
70
70
|
* {@link ResolvedActivityType}.
|
|
71
71
|
*/
|
|
72
72
|
isMessage(type: string): boolean;
|
|
73
|
+
/** Folds into the list under the message it answers. See {@link isNoteShape}. */
|
|
74
|
+
nestsUnderParent(type: string): boolean;
|
|
73
75
|
/** Can a person reply to this? Notes cannot — those go nowhere. */
|
|
74
76
|
isReplyable(type: string): boolean;
|
|
75
77
|
/** Readable content for a model: messages, notes and transcripts. */
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ActingIdentity } from '../../platform/identity';
|
|
2
2
|
import { TranscriptSegment } from '../../platform/media';
|
|
3
3
|
import { AIMessageInput, AIMessageOutput } from '../ai-message/types';
|
|
4
|
+
import { ReactionSummary } from '../reaction/types';
|
|
4
5
|
export type CallStatus = "new" | "connecting" | "ringing" | "connected" | "held" | "ended" | "failed";
|
|
5
6
|
export type CallDirection = "inbound" | "outbound";
|
|
6
7
|
export type CallType = "audio" | "video" | "data" | "screen-share";
|
|
@@ -34,6 +35,14 @@ export interface BaseActivity {
|
|
|
34
35
|
contactId?: string;
|
|
35
36
|
};
|
|
36
37
|
direction: "inbound" | "outbound" | "internal" | "none";
|
|
38
|
+
/**
|
|
39
|
+
* The activity this one answers, if any — the in-app thread, one level deep.
|
|
40
|
+
*
|
|
41
|
+
* Not `EmailPayload.threadId`: that is the provider's own conversation id and groups a whole
|
|
42
|
+
* mail thread. This points at one activity, and an internal note can hang off a customer's
|
|
43
|
+
* mail with it. A reply to a reply stores the *top* parent, so the feed never nests twice.
|
|
44
|
+
*/
|
|
45
|
+
parentId?: string;
|
|
37
46
|
externalIds?: string[];
|
|
38
47
|
attachments?: Attachment[];
|
|
39
48
|
/**
|
|
@@ -42,6 +51,14 @@ export interface BaseActivity {
|
|
|
42
51
|
* indicator while true.
|
|
43
52
|
*/
|
|
44
53
|
pending?: boolean;
|
|
54
|
+
/**
|
|
55
|
+
* The emoji on this message, as the list and get routes project them.
|
|
56
|
+
*
|
|
57
|
+
* Read-only and **never stored on the activity row**: reactions are their own rows, keyed
|
|
58
|
+
* by (resource, actor, emoji), so two people reacting at once cannot race on one column.
|
|
59
|
+
* The server joins them on in one bulk query per page; a writer that sets this is ignored.
|
|
60
|
+
*/
|
|
61
|
+
reactions?: ReactionSummary[];
|
|
45
62
|
/** Epoch ms — matches the DB model and Interaction.createdAt. */
|
|
46
63
|
createdAt?: number;
|
|
47
64
|
updatedAt?: number;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './types';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Who reacted.
|
|
3
|
+
*
|
|
4
|
+
* Not a bare `userId`, and not `MutationAuthor`: a reaction can come from outside the
|
|
5
|
+
* organisation. A Teams chat is synced with the customer in it, and their 👍 has to land
|
|
6
|
+
* somewhere — as a `contact`, with the name the provider gave. Mirrors `BaseActivity.author`,
|
|
7
|
+
* which already carries that same four-way distinction.
|
|
8
|
+
*
|
|
9
|
+
* `id` is the user id, the app name, or the provider's id for a contact; absent for `system`.
|
|
10
|
+
*/
|
|
11
|
+
export interface ReactionActor {
|
|
12
|
+
type: "user" | "contact" | "app" | "system";
|
|
13
|
+
id?: string;
|
|
14
|
+
/** Shown on hover. Kept on the row because an external reactor has no record to look up. */
|
|
15
|
+
name?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* One emoji, put on one resource, by one actor.
|
|
19
|
+
*
|
|
20
|
+
* Addressed by (resourceType, resourceId) — the same `ResourceRef` shape read-state and the
|
|
21
|
+
* attribute store use — so an activity, a work comment, a file or a knowledge article all
|
|
22
|
+
* reuse this without the store learning what any of them are.
|
|
23
|
+
*
|
|
24
|
+
* A row per (resource, actor, emoji), never an array on the resource: two people reacting at
|
|
25
|
+
* the same moment would otherwise race on one column, and the unique index makes both the
|
|
26
|
+
* toggle and a re-sync from a provider idempotent.
|
|
27
|
+
*/
|
|
28
|
+
export interface Reaction {
|
|
29
|
+
id: string;
|
|
30
|
+
organizationId: string;
|
|
31
|
+
resourceType: string;
|
|
32
|
+
resourceId: string;
|
|
33
|
+
actor: ReactionActor;
|
|
34
|
+
/**
|
|
35
|
+
* The literal character, e.g. `"👍"` — never a shortcode and never a provider's name for it.
|
|
36
|
+
* One vocabulary means no mapping table in the core; the six legacy Teams names are
|
|
37
|
+
* translated at the edge, in the app that speaks to Graph.
|
|
38
|
+
*/
|
|
39
|
+
emoji: string;
|
|
40
|
+
createdAt?: number;
|
|
41
|
+
}
|
|
42
|
+
/** One chip: an emoji, how many put it there, and who — for the hover. */
|
|
43
|
+
export interface ReactionSummary {
|
|
44
|
+
emoji: string;
|
|
45
|
+
count: number;
|
|
46
|
+
actors: ReactionActor[];
|
|
47
|
+
}
|
|
48
|
+
/** `POST /reaction/:type/:id` body. `on` absent means "flip whatever it is now". */
|
|
49
|
+
export interface ToggleReactionRequest {
|
|
50
|
+
emoji: string;
|
|
51
|
+
on?: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Who to record it for, instead of the caller.
|
|
54
|
+
*
|
|
55
|
+
* **Honoured for an app-to-app caller only**, and ignored outright for a user — otherwise
|
|
56
|
+
* anyone could put an emoji on a message in a colleague's name. It exists for provider
|
|
57
|
+
* sync: a reaction pulled out of Teams belongs to the person who left it there, not to the
|
|
58
|
+
* app that carried it across.
|
|
59
|
+
*/
|
|
60
|
+
actor?: ReactionActor;
|
|
61
|
+
}
|
|
62
|
+
/** Reactions per resource id, as the list endpoints hand them to a feed. */
|
|
63
|
+
export type ReactionsByResource = Record<string, ReactionSummary[]>;
|
|
64
|
+
/**
|
|
65
|
+
* Rows to chips.
|
|
66
|
+
*
|
|
67
|
+
* Most-used first so the chip that carries the most agreement sits nearest the message, with
|
|
68
|
+
* ties broken by which emoji appeared first — a stable order, so a chip does not jump when
|
|
69
|
+
* someone else reacts. Pure: this is the one piece of the feature worth a test.
|
|
70
|
+
*/
|
|
71
|
+
export declare function summarizeReactions(rows: Reaction[]): ReactionSummary[];
|
|
72
|
+
/** Did this user put this emoji there? The chip's own state, asked without a second query. */
|
|
73
|
+
export declare function hasReacted(summary: ReactionSummary, userId: string | undefined): boolean;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ReactionSummary } from '../reaction/types';
|
|
1
2
|
import { WorkStatusCategory } from './types';
|
|
2
3
|
/**
|
|
3
4
|
* The activity feed under a work item.
|
|
@@ -36,6 +37,8 @@ export interface WorkActivity {
|
|
|
36
37
|
* "the customer answered" and would wake every waiting assignment on the item.
|
|
37
38
|
*/
|
|
38
39
|
direction: "internal";
|
|
40
|
+
/** The activity this one answers — same one-level thread as comms' `BaseActivity.parentId`. */
|
|
41
|
+
parentId?: string;
|
|
39
42
|
/** `html` is the composer's markup for a comment; `text` stays the plain reading of it. */
|
|
40
43
|
payload: {
|
|
41
44
|
text?: string;
|
|
@@ -46,6 +49,12 @@ export interface WorkActivity {
|
|
|
46
49
|
toStatus?: string;
|
|
47
50
|
toCategory?: WorkStatusCategory;
|
|
48
51
|
};
|
|
52
|
+
/**
|
|
53
|
+
* The emoji on this comment, as the list route projects them. Read-only and never stored
|
|
54
|
+
* on the row — see `BaseActivity.reactions`, which this mirrors, and the generic store in
|
|
55
|
+
* the communication app that both read from.
|
|
56
|
+
*/
|
|
57
|
+
reactions?: ReactionSummary[];
|
|
49
58
|
createdAt?: number;
|
|
50
59
|
updatedAt?: number;
|
|
51
60
|
}
|
|
@@ -10,8 +10,17 @@ import { WorkItem, WorkProject } from './types';
|
|
|
10
10
|
/** The scope kinds `apps/work` claims through `/provider/scope/describe`. */
|
|
11
11
|
export declare const WORK_ITEM_SCOPE_KIND = "work_item";
|
|
12
12
|
export declare const WORK_PROJECT_SCOPE_KIND = "work_project";
|
|
13
|
+
/**
|
|
14
|
+
* A row in an item's feed, addressable on its own.
|
|
15
|
+
*
|
|
16
|
+
* Claimed so the generic stores can hang something off a single comment — reactions today,
|
|
17
|
+
* whatever is resource-agnostic tomorrow. It inherits its item's access exactly the way
|
|
18
|
+
* comms' `activity:` inherits its conversation's: a comment is not a second boundary.
|
|
19
|
+
*/
|
|
20
|
+
export declare const WORK_ACTIVITY_SCOPE_KIND = "work_activity";
|
|
13
21
|
export declare function workItemScopeKey(itemId: string): string;
|
|
14
22
|
export declare function workProjectScopeKey(projectId: string): string;
|
|
23
|
+
export declare function workActivityScopeKey(activityId: string): string;
|
|
15
24
|
/**
|
|
16
25
|
* The human key: `SAL-142`, or `SAL-142-1` for a subitem.
|
|
17
26
|
*
|