@wirecat/cli-core 0.587.0 → 0.588.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/CHANGELOG.md +22 -0
- package/dist/cli/messenger/store-maintenance-command.d.ts +1 -1
- package/dist/domain/deals.d.ts +8 -6
- package/dist/domain/deals.js +7 -8
- package/dist/domain/ref-summaries.js +2 -0
- package/dist/domain/references.d.ts +1 -1
- package/dist/domain/references.js +2 -0
- package/dist/errors/reasons.js +6 -6
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/services/proposals/registry.js +0 -2
- package/dist/store/index.d.ts +1 -1
- package/dist/store/sqlite/deals.d.ts +128 -29
- package/dist/store/sqlite/deals.js +270 -156
- package/dist/store/sqlite/entity-types.d.ts +3 -1
- package/dist/store/sqlite/entity-types.js +3 -1
- package/dist/store/sqlite/knowledge.js +3 -1
- package/dist/store/sqlite/migrations.generated.js +39 -11
- package/dist/store/sqlite/ref-summaries.js +11 -7
- package/dist/store/sqlite/schema.d.ts +600 -38
- package/dist/store/sqlite/schema.js +86 -14
- package/dist/store/sqlite/things.js +2 -0
- package/package.json +1 -1
- package/dist/services/proposals/kinds/deals.d.ts +0 -4
- package/dist/services/proposals/kinds/deals.js +0 -32
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,28 @@ Notable changes to `@wirecat/cli-core` (`@wirecat/cli-messaging` up to 0.261.0,
|
|
|
5
5
|
minor version may break callers, and says how under "Changed — may break callers". `pnpm docs:check` checks the
|
|
6
6
|
shape of this file.
|
|
7
7
|
|
|
8
|
+
## Unreleased
|
|
9
|
+
|
|
10
|
+
## 0.588.0 — 06.11.2026
|
|
11
|
+
|
|
12
|
+
### Changed — may break callers
|
|
13
|
+
|
|
14
|
+
- **Store version 52 is amended in place: deals and leads in their own tables, a stage history, and no review.**
|
|
15
|
+
0.585.0, 0.586.0 and 0.587.0 shipped an earlier shape of version 52, but no published CLI depends on them, so no real store
|
|
16
|
+
holds it; a store a test or a local build moved to 52 with them must be made again. Tables `deals` and `leads`
|
|
17
|
+
(refs `deal:<id>`, `lead:<id>`) replace `opportunities`; a lead may name the deal it became (`deal_id`). Pipelines
|
|
18
|
+
have a ref, `pipeline:<id>`, belong to the owner or to a CRM account (`account_id`, `external_id`, so two accounts
|
|
19
|
+
may each have "Sales"), and hold deals or leads (`kind`); stages have an `outcome` (`open`, `won`, `lost`) and an
|
|
20
|
+
`external_id`, and positions are not unique. Deals and leads keep the CRM's `account_id`, `external_id` and a board
|
|
21
|
+
`rank`. Triggers write every stage a deal or a lead enters to `pipeline_stage_changes`. The migration seeds one lead
|
|
22
|
+
pipeline, `Leads`, with the stages `new`, `contacted`, `qualified`, `won` and `lost`.
|
|
23
|
+
- **`store.deals` writes for the owner and his agents alike.** The `deal` proposal kind and the review columns are
|
|
24
|
+
gone; only the author is kept. `add`, `list` take `kind` (`deal` by default; a lead may leave out its stage when one
|
|
25
|
+
lead pipeline is stored). A pipeline is named by `pipeline:<id>` or by a name only one pipeline has; a shared name
|
|
26
|
+
is refused with the candidates (`pipeline.ambiguous`). Moving to a stage whose outcome is won or lost closes the row,
|
|
27
|
+
and `close` moves it to its pipeline's stage of that outcome when there is one. `store.deals.pipeline(ref)` reports
|
|
28
|
+
each stage's open rows, how many rows reached it and the conversion to the next stage, with won, lost and win rate.
|
|
29
|
+
|
|
8
30
|
## 0.587.0 — 06.11.2026
|
|
9
31
|
|
|
10
32
|
### Added
|
|
@@ -3,9 +3,9 @@ import type { CacheDatabase } from "../../store/driver.js";
|
|
|
3
3
|
import type { Messenger } from "./context.js";
|
|
4
4
|
/** `doctor`'s short summary of the store. Must answer for a broken file, so an error is a field. */
|
|
5
5
|
export declare const storeSummary: (env: NodeJS.ProcessEnv) => Promise<{
|
|
6
|
+
error?: undefined;
|
|
6
7
|
path: string;
|
|
7
8
|
exists: boolean;
|
|
8
|
-
error?: undefined;
|
|
9
9
|
} | {
|
|
10
10
|
path: string;
|
|
11
11
|
exists: boolean;
|
package/dist/domain/deals.d.ts
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/** A pipeline holds deals or leads, never both; a deal and a lead are rows of their own tables. */
|
|
2
|
+
export declare const DEAL_KINDS: readonly ["deal", "lead"];
|
|
3
|
+
/** Whether a deal or a lead ended, kept apart from the stage it stands in. */
|
|
3
4
|
export declare const DEAL_STATUSES: readonly ["open", "won", "lost"];
|
|
5
|
+
/** What reaching a stage means, as a CRM marks it: still open, or won or lost. */
|
|
6
|
+
export declare const STAGE_OUTCOMES: readonly ["open", "won", "lost"];
|
|
4
7
|
/** The part a person plays on a deal: the owner's side runs it, the client's side talks or decides. */
|
|
5
8
|
export declare const DEAL_ROLES: readonly ["owner", "contact", "decision-maker"];
|
|
9
|
+
export type DealKind = (typeof DEAL_KINDS)[number];
|
|
6
10
|
export type DealStatus = (typeof DEAL_STATUSES)[number];
|
|
11
|
+
export type StageOutcome = DealStatus;
|
|
7
12
|
export type DealRole = (typeof DEAL_ROLES)[number];
|
|
8
13
|
export interface DealTitleFields {
|
|
9
14
|
id: number;
|
|
@@ -12,9 +17,6 @@ export interface DealTitleFields {
|
|
|
12
17
|
amount: number | null;
|
|
13
18
|
currency: string | null;
|
|
14
19
|
status: DealStatus;
|
|
15
|
-
review: FinanceReview;
|
|
16
20
|
}
|
|
17
|
-
/** "Site redesign · Proposal, 500 000.00 RUB": a ref summary's title, which `refLabel` prefixes. */
|
|
21
|
+
/** "Site redesign · Proposal, 500 000.00 RUB (won)": a ref summary's title, which `refLabel` prefixes. */
|
|
18
22
|
export declare const dealLine: (deal: DealTitleFields) => string;
|
|
19
|
-
/** "Deal Site redesign · Proposal, 500 000.00 RUB (won)". */
|
|
20
|
-
export declare const dealTitle: (deal: DealTitleFields) => string;
|
package/dist/domain/deals.js
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import { moneyLabel } from "./money.js";
|
|
2
|
-
/**
|
|
2
|
+
/** A pipeline holds deals or leads, never both; a deal and a lead are rows of their own tables. */
|
|
3
|
+
export const DEAL_KINDS = ["deal", "lead"];
|
|
4
|
+
/** Whether a deal or a lead ended, kept apart from the stage it stands in. */
|
|
3
5
|
export const DEAL_STATUSES = ["open", "won", "lost"];
|
|
6
|
+
/** What reaching a stage means, as a CRM marks it: still open, or won or lost. */
|
|
7
|
+
export const STAGE_OUTCOMES = DEAL_STATUSES;
|
|
4
8
|
/** The part a person plays on a deal: the owner's side runs it, the client's side talks or decides. */
|
|
5
9
|
export const DEAL_ROLES = ["owner", "contact", "decision-maker"];
|
|
6
|
-
/** "Site redesign · Proposal, 500 000.00 RUB": a ref summary's title, which `refLabel` prefixes. */
|
|
10
|
+
/** "Site redesign · Proposal, 500 000.00 RUB (won)": a ref summary's title, which `refLabel` prefixes. */
|
|
7
11
|
export const dealLine = (deal) => {
|
|
8
12
|
const money = deal.amount === null || deal.currency === null ? "" : `, ${moneyLabel(deal.amount, deal.currency)}`;
|
|
9
|
-
|
|
10
|
-
.filter(Boolean)
|
|
11
|
-
.join(", ");
|
|
12
|
-
return `${deal.title} · ${deal.stage}${money}${notes ? ` (${notes})` : ""}`;
|
|
13
|
+
return `${deal.title} · ${deal.stage}${money}${deal.status === "open" ? "" : ` (${deal.status})`}`;
|
|
13
14
|
};
|
|
14
|
-
/** "Deal Site redesign · Proposal, 500 000.00 RUB (won)". */
|
|
15
|
-
export const dealTitle = (deal) => `Deal ${dealLine(deal)}`;
|
|
@@ -33,7 +33,7 @@ export type Reference = {
|
|
|
33
33
|
* Things named by their store id (a task also by its key or the task package's id). `entity` is the name
|
|
34
34
|
* before organizations and projects: it still parses, so an old file's reference resolves as not found.
|
|
35
35
|
*/
|
|
36
|
-
export declare const SIMPLE_REFERENCES: readonly ["note", "document", "person", "organization", "project", "task", "memory", "fact", "bot", "event", "invoice", "payment", "order", "deal", "entity"];
|
|
36
|
+
export declare const SIMPLE_REFERENCES: readonly ["note", "document", "person", "organization", "project", "task", "memory", "fact", "bot", "event", "invoice", "payment", "order", "deal", "lead", "pipeline", "entity"];
|
|
37
37
|
export type SimpleReference = (typeof SIMPLE_REFERENCES)[number];
|
|
38
38
|
export type RefKindName = Exclude<Reference["type"], "entity">;
|
|
39
39
|
export interface RefKindSpec<R extends Reference = Reference> {
|
package/dist/errors/reasons.js
CHANGED
|
@@ -203,14 +203,14 @@ const OTHERS = [
|
|
|
203
203
|
validation("money.amount", "the amount is not a decimal string in the currency's scale"),
|
|
204
204
|
validation("money.currency", "the currency is not one the store keeps money in"),
|
|
205
205
|
validation("money.quantity", "the quantity is not a decimal above 0"),
|
|
206
|
-
validation("deal.closed", "a
|
|
207
|
-
validation("deal.field", "a field of the deal is not valid"),
|
|
208
|
-
|
|
209
|
-
validation("deal.ref", "the reference names no deal"),
|
|
206
|
+
validation("deal.closed", "a deleted deal or lead does not move or close"),
|
|
207
|
+
validation("deal.field", "a field of the deal or lead is not valid"),
|
|
208
|
+
validation("deal.ref", "the reference names no deal or lead"),
|
|
210
209
|
validation("deal.stage", "no stage of that name, or a stage name more than one pipeline has"),
|
|
211
|
-
validation("pipeline.
|
|
210
|
+
validation("pipeline.ambiguous", "more than one pipeline has that name; name it by its pipeline: reference"),
|
|
211
|
+
validation("pipeline.duplicate", "a pipeline of that name and kind is already stored"),
|
|
212
212
|
validation("pipeline.field", "a pipeline needs a name and at least one stage, each named once"),
|
|
213
|
-
["pipeline.not-found", "not_found", "no stored pipeline has that name"],
|
|
213
|
+
["pipeline.not-found", "not_found", "no stored pipeline has that name or reference"],
|
|
214
214
|
validation("order.duplicate", "the shop's order with this number is already stored; change its status instead"),
|
|
215
215
|
validation("order.proposed", "the shop's order with this number already waits for the owner in a findings batch"),
|
|
216
216
|
validation("order.field", "a field of the order is not valid"),
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { bareCheck, type CheckWords, checkWords } from "./domain/checks.js";
|
|
2
2
|
export type { CounterField, CounterObservation, CounterObservations, CounterState } from "./domain/counters.js";
|
|
3
3
|
export { COUNTER_FIELDS, counterValue, observedCounters } from "./domain/counters.js";
|
|
4
|
-
export { DEAL_ROLES, DEAL_STATUSES, type DealRole, type DealStatus } from "./domain/deals.js";
|
|
4
|
+
export { DEAL_KINDS, DEAL_ROLES, DEAL_STATUSES, type DealKind, type DealRole, type DealStatus, STAGE_OUTCOMES, type StageOutcome, } from "./domain/deals.js";
|
|
5
5
|
export { FINANCE_REVIEWS, type FinanceReview, INVOICE_DIRECTIONS, INVOICE_STATUSES, type InvoiceDirection, type InvoiceStatus, MONEY_DIRECTIONS, type MoneyDirection, } from "./domain/finance.js";
|
|
6
6
|
export { type FormattedText, type HtmlFormatting, type MarkdownFormatting, type TextSpan, validateFormattedText, } from "./domain/formatting.js";
|
|
7
7
|
export { formatLocator, isLocator, type MessageLocator, parseLocator } from "./domain/locator.js";
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { bareCheck, checkWords } from "./domain/checks.js";
|
|
2
2
|
export { COUNTER_FIELDS, counterValue, observedCounters } from "./domain/counters.js";
|
|
3
|
-
export { DEAL_ROLES, DEAL_STATUSES } from "./domain/deals.js";
|
|
3
|
+
export { DEAL_KINDS, DEAL_ROLES, DEAL_STATUSES, STAGE_OUTCOMES, } from "./domain/deals.js";
|
|
4
4
|
export { FINANCE_REVIEWS, INVOICE_DIRECTIONS, INVOICE_STATUSES, MONEY_DIRECTIONS, } from "./domain/finance.js";
|
|
5
5
|
export { validateFormattedText, } from "./domain/formatting.js";
|
|
6
6
|
export { formatLocator, isLocator, parseLocator } from "./domain/locator.js";
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { CliError } from "@wirecat/cli-base";
|
|
2
2
|
import { mayDecide } from "../../store/decisions.js";
|
|
3
3
|
import { actionKind } from "./kinds/action.js";
|
|
4
|
-
import { dealKind } from "./kinds/deals.js";
|
|
5
4
|
import { factKind } from "./kinds/fact.js";
|
|
6
5
|
import { invoiceKind, paymentKind } from "./kinds/finance.js";
|
|
7
6
|
import { findingsKind } from "./kinds/findings.js";
|
|
@@ -136,7 +135,6 @@ export const proposalRegistry = (store) => {
|
|
|
136
135
|
invoiceKind(store),
|
|
137
136
|
paymentKind(store),
|
|
138
137
|
orderKind(store),
|
|
139
|
-
dealKind(store),
|
|
140
138
|
organizationKind(store),
|
|
141
139
|
memoryKind(store),
|
|
142
140
|
findingsKind(store),
|
package/dist/store/index.d.ts
CHANGED
|
@@ -34,7 +34,7 @@ export type { BotUpdate, BotUpdateStore } from "./sqlite/bot-updates.js";
|
|
|
34
34
|
export type { CatalogActor, CatalogEntry, CatalogInput, CatalogQuery, CatalogStore } from "./sqlite/catalog.js";
|
|
35
35
|
export { CATALOG_QUERY } from "./sqlite/catalog.js";
|
|
36
36
|
export type { ChatMetadata } from "./sqlite/chats.js";
|
|
37
|
-
export type { Deal, DealFilter, DealInput, DealPerson, DealsStore, Pipeline, PipelineStage, } from "./sqlite/deals.js";
|
|
37
|
+
export type { Deal, DealFilter, DealInput, DealPerson, DealsStore, FunnelStage, Pipeline, PipelineInput, PipelineReport, PipelineStage, } from "./sqlite/deals.js";
|
|
38
38
|
export type { Email, EmailAddress, EmailAttachment, EmailFacts, EmailFilter, EmailInput, EmailInThread, EmailLocationInput, EmailRecipient, EmailRef, EmailThread, EmailVectorHit, FolderEmail, Mailbox, MailboxInput, MailFilter, MailStore, PartialEmail, SenderScore, ThreadDetails, ThreadSave, } from "./sqlite/emails.js";
|
|
39
39
|
export { EVENT_FIELDS, type EventChunkToEmbed, type EventHit, type EventQuery, type EventSearch, type NearestEvent, } from "./sqlite/event-search.js";
|
|
40
40
|
export type { EvidenceSource } from "./sqlite/evidence-sources.js";
|
|
@@ -1,31 +1,61 @@
|
|
|
1
|
-
import { type DealRole, type DealStatus } from "../../domain/deals.js";
|
|
2
|
-
import { type FinanceReview } from "../../domain/finance.js";
|
|
3
|
-
import { type Decider } from "../decisions.js";
|
|
1
|
+
import { type DealKind, type DealRole, type DealStatus, type StageOutcome } from "../../domain/deals.js";
|
|
4
2
|
import { type ProposedByFilter } from "./actors.js";
|
|
5
|
-
import { type Party
|
|
3
|
+
import { type Party } from "./finance.js";
|
|
6
4
|
import { type Author } from "./memories.js";
|
|
7
5
|
import type { StoreContext } from "./open.js";
|
|
8
6
|
export interface PipelineStage {
|
|
9
7
|
name: string;
|
|
10
8
|
position: number;
|
|
11
|
-
|
|
9
|
+
outcome: StageOutcome;
|
|
10
|
+
externalId: string | null;
|
|
11
|
+
/** Open deals or leads standing in it now. */
|
|
12
12
|
open: number;
|
|
13
13
|
}
|
|
14
14
|
export interface Pipeline {
|
|
15
|
+
id: string;
|
|
16
|
+
ref: string;
|
|
15
17
|
name: string;
|
|
18
|
+
kind: DealKind;
|
|
19
|
+
/** The CRM account it was copied from; `null` for the owner's or an agent's own. */
|
|
20
|
+
account: {
|
|
21
|
+
provider: string;
|
|
22
|
+
account: string;
|
|
23
|
+
} | null;
|
|
24
|
+
externalId: string | null;
|
|
16
25
|
stages: PipelineStage[];
|
|
17
26
|
createdAt: string;
|
|
18
27
|
}
|
|
28
|
+
export interface FunnelStage extends PipelineStage {
|
|
29
|
+
/** Rows that got this far: entered this stage or a later one that is not lost, or were won. */
|
|
30
|
+
reached: number;
|
|
31
|
+
/** `reached` of the next stage that is not lost over this stage's, 0–1; `null` for the last or an empty one. */
|
|
32
|
+
conversion: number | null;
|
|
33
|
+
}
|
|
34
|
+
/** A pipeline with its funnel, counted from `pipeline_stage_changes`. */
|
|
35
|
+
export interface PipelineReport extends Omit<Pipeline, "stages"> {
|
|
36
|
+
stages: FunnelStage[];
|
|
37
|
+
totals: {
|
|
38
|
+
items: number;
|
|
39
|
+
open: number;
|
|
40
|
+
won: number;
|
|
41
|
+
lost: number;
|
|
42
|
+
winRate: number | null;
|
|
43
|
+
};
|
|
44
|
+
/** `YYYY-MM-DD`: only rows made since that day are counted; `null` for all. */
|
|
45
|
+
since: string | null;
|
|
46
|
+
}
|
|
19
47
|
export interface DealPerson extends Party {
|
|
20
48
|
role: DealRole;
|
|
21
49
|
}
|
|
22
|
-
export interface Deal
|
|
50
|
+
export interface Deal {
|
|
23
51
|
id: string;
|
|
24
52
|
ref: string;
|
|
53
|
+
kind: DealKind;
|
|
25
54
|
title: string;
|
|
26
|
-
/** One line with stage, amount and status, as a list
|
|
55
|
+
/** One line with stage, amount and status, as a list prints it. */
|
|
27
56
|
summary: string;
|
|
28
57
|
pipeline: string;
|
|
58
|
+
pipelineName: string;
|
|
29
59
|
stage: string;
|
|
30
60
|
status: DealStatus;
|
|
31
61
|
organization: Party | null;
|
|
@@ -36,14 +66,44 @@ export interface Deal extends Reviewed {
|
|
|
36
66
|
closeDate: string | null;
|
|
37
67
|
/** `YYYY-MM-DD`: the day it was won or lost. */
|
|
38
68
|
closedDate: string | null;
|
|
39
|
-
/** Why it was won or lost, as
|
|
69
|
+
/** Why it was won or lost, as given when closing it. */
|
|
40
70
|
closedReason: string | null;
|
|
71
|
+
rank: number | null;
|
|
72
|
+
/** A lead's deal, once it became one. */
|
|
73
|
+
deal: string | null;
|
|
74
|
+
account: {
|
|
75
|
+
provider: string;
|
|
76
|
+
account: string;
|
|
77
|
+
} | null;
|
|
78
|
+
externalId: string | null;
|
|
41
79
|
people: DealPerson[];
|
|
80
|
+
author: {
|
|
81
|
+
type: "person" | "bot";
|
|
82
|
+
id: string;
|
|
83
|
+
name: string | null;
|
|
84
|
+
kind: "agent" | "rule" | null;
|
|
85
|
+
};
|
|
86
|
+
model: string | null;
|
|
87
|
+
source: string;
|
|
88
|
+
reason: string | null;
|
|
89
|
+
evidence: string[];
|
|
90
|
+
project: string | null;
|
|
91
|
+
projectName: string | null;
|
|
92
|
+
createdAt: string;
|
|
93
|
+
updatedAt: string;
|
|
42
94
|
}
|
|
43
|
-
export interface DealInput
|
|
95
|
+
export interface DealInput {
|
|
96
|
+
/** Who writes it; the owner and an agent write alike, and only the author is kept. */
|
|
97
|
+
by: Author;
|
|
98
|
+
/** `deal` when left out. */
|
|
99
|
+
kind?: DealKind;
|
|
44
100
|
title: string;
|
|
45
|
-
/**
|
|
46
|
-
|
|
101
|
+
/**
|
|
102
|
+
* A stage's name, in `pipeline` when given, else in the only pipeline of the kind that has it. A lead may leave it
|
|
103
|
+
* out when there is one lead pipeline: it starts in that pipeline's first stage.
|
|
104
|
+
*/
|
|
105
|
+
stage?: string;
|
|
106
|
+
/** `pipeline:<id>`, or a name only one pipeline of the kind has. */
|
|
47
107
|
pipeline?: string;
|
|
48
108
|
organization?: string;
|
|
49
109
|
/** A decimal string in `currency`; give both or neither. */
|
|
@@ -54,51 +114,90 @@ export interface DealInput extends Written {
|
|
|
54
114
|
person: string;
|
|
55
115
|
role: DealRole;
|
|
56
116
|
}[];
|
|
117
|
+
project?: string;
|
|
118
|
+
/** Where an agent's row came from, such as `agent`; the owner's is always `owner`. */
|
|
119
|
+
source?: string;
|
|
120
|
+
reason?: string;
|
|
121
|
+
evidence?: string[];
|
|
57
122
|
}
|
|
58
123
|
export interface DealFilter {
|
|
124
|
+
/** `deal` when left out. */
|
|
125
|
+
kind?: DealKind;
|
|
59
126
|
status?: DealStatus;
|
|
60
|
-
/** A stage's
|
|
127
|
+
/** A stage's name, in any letter case. */
|
|
61
128
|
stage?: string;
|
|
129
|
+
/** `pipeline:<id>`, or a name only one pipeline of the kind has. */
|
|
62
130
|
pipeline?: string;
|
|
63
131
|
project?: string;
|
|
64
132
|
organization?: string;
|
|
65
|
-
review?: FinanceReview;
|
|
66
133
|
proposedBy?: ProposedByFilter;
|
|
67
134
|
/** 1–500, 100 by default; newest written first. */
|
|
68
135
|
limit?: number;
|
|
69
136
|
}
|
|
137
|
+
export interface PipelineInput {
|
|
138
|
+
name: string;
|
|
139
|
+
/** `deal` when left out. */
|
|
140
|
+
kind?: DealKind;
|
|
141
|
+
/** In order; a bare name is an open stage. */
|
|
142
|
+
stages: (string | {
|
|
143
|
+
name: string;
|
|
144
|
+
outcome?: StageOutcome;
|
|
145
|
+
})[];
|
|
146
|
+
by: Author;
|
|
147
|
+
}
|
|
70
148
|
/**
|
|
71
|
-
*
|
|
72
|
-
*
|
|
149
|
+
* Sales pipelines and the deals and leads in them. The owner and his agents write alike: nothing waits for review,
|
|
150
|
+
* and memo's permission settings are where writes are limited. Every stage a row enters is kept, by triggers, so a
|
|
151
|
+
* pipeline's report counts conversion between stages.
|
|
73
152
|
*/
|
|
74
153
|
export interface DealsStore {
|
|
75
|
-
addPipeline(input:
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
154
|
+
addPipeline(input: PipelineInput): Promise<Pipeline>;
|
|
155
|
+
pipelines(filter?: {
|
|
156
|
+
kind?: DealKind;
|
|
157
|
+
}): Promise<Pipeline[]>;
|
|
158
|
+
/** One pipeline by `pipeline:<id>` or a name only one pipeline has, with its funnel. */
|
|
159
|
+
pipeline(reference: string, options?: {
|
|
160
|
+
kind?: DealKind;
|
|
161
|
+
since?: string;
|
|
162
|
+
}): Promise<PipelineReport>;
|
|
81
163
|
add(input: DealInput): Promise<Deal>;
|
|
164
|
+
/** `deal:<id>` or `lead:<id>`; a bare id is a deal. */
|
|
82
165
|
get(reference: string): Promise<Deal>;
|
|
83
166
|
list(filter?: DealFilter): Promise<Deal[]>;
|
|
84
|
-
/** To another stage of
|
|
167
|
+
/** To another stage of its own pipeline; a stage whose outcome is won or lost closes it, an open one reopens it. */
|
|
85
168
|
move(reference: string, input: {
|
|
86
169
|
stage: string;
|
|
87
170
|
by: Author;
|
|
88
171
|
}): Promise<Deal>;
|
|
89
|
-
/** `date`
|
|
172
|
+
/** Won or lost, on `date` (today when left out); it moves to its pipeline's stage of that outcome when there is one. */
|
|
90
173
|
close(reference: string, input: {
|
|
91
174
|
status: Exclude<DealStatus, "open">;
|
|
92
175
|
date?: string;
|
|
93
176
|
reason?: string;
|
|
94
177
|
by: Author;
|
|
95
178
|
}): Promise<Deal>;
|
|
96
|
-
confirm(reference: string, by: Decider, reason?: string): Promise<Deal>;
|
|
97
|
-
reject(reference: string, by: Decider, reason?: string): Promise<Deal>;
|
|
98
179
|
}
|
|
99
|
-
|
|
100
|
-
|
|
180
|
+
export declare const dealOperationsOver: (context: StoreContext) => {
|
|
181
|
+
addPipeline: ({ name, kind, stages, by }: PipelineInput) => Pipeline;
|
|
182
|
+
pipelines: (filter?: {
|
|
183
|
+
kind?: DealKind;
|
|
184
|
+
}) => Pipeline[];
|
|
185
|
+
pipeline: (reference: string, options?: {
|
|
186
|
+
kind?: DealKind;
|
|
187
|
+
since?: string;
|
|
188
|
+
}) => PipelineReport;
|
|
189
|
+
add: (input: DealInput) => Deal;
|
|
190
|
+
get: (reference: string) => Deal;
|
|
191
|
+
list: (filter?: DealFilter) => Deal[];
|
|
192
|
+
move: (reference: string, { stage, by }: {
|
|
193
|
+
stage: string;
|
|
194
|
+
by: Author;
|
|
195
|
+
}) => Deal;
|
|
196
|
+
close: (reference: string, { status, date, reason, by }: {
|
|
197
|
+
status: Exclude<DealStatus, "open">;
|
|
198
|
+
date?: string;
|
|
199
|
+
reason?: string;
|
|
200
|
+
by: Author;
|
|
201
|
+
}) => Deal;
|
|
101
202
|
};
|
|
102
|
-
export declare const dealOperationsOver: (context: StoreContext) => DealOperations;
|
|
103
203
|
export declare const dealsStoreOver: (context: StoreContext) => DealsStore;
|
|
104
|
-
export {};
|