@happyvertical/smrt-sales 0.55.7 → 0.55.9

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.
@@ -1,4 +1,4 @@
1
- import { SmrtCollection, SmrtObject, crossPackageRef, field, foreignKey, smrt } from "@happyvertical/smrt-core";
1
+ import { SmrtCollection, SmrtObject, SmrtRecipe, crossPackageRef, field, foreignKey, smrt } from "@happyvertical/smrt-core";
2
2
  import { TenantContextError, TenantScoped, getTenantId, requireTenantId, tenantId } from "@happyvertical/smrt-tenancy";
3
3
  import { createHash } from "node:crypto";
4
4
  //#region src/crm/models/Lead.ts
@@ -37,17 +37,12 @@ var loadedLeadStatus = /* @__PURE__ */ new WeakMap();
37
37
  var Lead = class extends SmrtObject {
38
38
  tenantId = null;
39
39
  name = "";
40
- /** Primary human contact name. */
41
40
  contactName = "";
42
- /** Primary contact email. */
43
41
  email = "";
44
- /** Primary contact phone. */
45
42
  phone = "";
46
- /** Prospect organization/company name. */
47
43
  organizationName = "";
48
44
  profileId = "";
49
45
  ownerRepId = "";
50
- /** Lifecycle status; transitions are save-guarded (see module map). */
51
46
  status = "new";
52
47
  /**
53
48
  * Generic acquisition-source kind (open string): `'campaign'`,
@@ -189,9 +184,17 @@ var Lead = class extends SmrtObject {
189
184
  };
190
185
  __publicField$6(Lead, "__smrtPackage__", "@happyvertical/smrt-sales");
191
186
  __decorateClass$6([tenantId({ nullable: true })], Lead.prototype, "tenantId", 2);
192
- __decorateClass$6([field({ required: true })], Lead.prototype, "name", 2);
187
+ __decorateClass$6([field({
188
+ required: true,
189
+ description: "What you call this lead."
190
+ })], Lead.prototype, "name", 2);
191
+ __decorateClass$6([field({ description: "The person to talk to." })], Lead.prototype, "contactName", 2);
192
+ __decorateClass$6([field({ description: "Their email address." })], Lead.prototype, "email", 2);
193
+ __decorateClass$6([field({ description: "Their phone number." })], Lead.prototype, "phone", 2);
194
+ __decorateClass$6([field({ description: "The company they are with." })], Lead.prototype, "organizationName", 2);
193
195
  __decorateClass$6([crossPackageRef("@happyvertical/smrt-profiles:Profile")], Lead.prototype, "profileId", 2);
194
- __decorateClass$6([foreignKey("SalesRepresentative")], Lead.prototype, "ownerRepId", 2);
196
+ __decorateClass$6([field({ description: "The sales representative who owns this lead." }), foreignKey("SalesRepresentative")], Lead.prototype, "ownerRepId", 2);
197
+ __decorateClass$6([field({ description: "Where the lead stands, for example new or qualified." })], Lead.prototype, "status", 2);
195
198
  __decorateClass$6([foreignKey("Lead")], Lead.prototype, "mergedIntoId", 2);
196
199
  Lead = __decorateClass$6([TenantScoped({ mode: "optional" }), smrt({
197
200
  api: { include: [
@@ -352,18 +355,10 @@ var Opportunity = class extends SmrtObject {
352
355
  ownerRepId = "";
353
356
  pipelineId = "";
354
357
  stageId = "";
355
- /** Expected deal value in integer cents (INTEGER column). */
356
358
  expectedValueCents = 0;
357
- /** ISO 4217 currency code for `expectedValueCents`. */
358
359
  currency = "USD";
359
- /**
360
- * Win probability (`0`–`1`, DECIMAL). Adopted from the current stage's
361
- * default on stage moves unless explicitly overridden.
362
- */
363
360
  probability = 0;
364
- /** Forecasted close date. */
365
361
  expectedCloseAt = null;
366
- /** Lifecycle status; `open → won|lost` is save-guarded, terminal after. */
367
362
  status = "open";
368
363
  /**
369
364
  * Human-readable outcome note — conventionally the loss reason
@@ -476,11 +471,19 @@ var Opportunity = class extends SmrtObject {
476
471
  };
477
472
  __publicField$5(Opportunity, "__smrtPackage__", "@happyvertical/smrt-sales");
478
473
  __decorateClass$5([tenantId({ nullable: true })], Opportunity.prototype, "tenantId", 2);
479
- __decorateClass$5([field({ required: true })], Opportunity.prototype, "name", 2);
480
- __decorateClass$5([foreignKey("Lead")], Opportunity.prototype, "leadId", 2);
481
- __decorateClass$5([foreignKey("SalesRepresentative")], Opportunity.prototype, "ownerRepId", 2);
482
- __decorateClass$5([foreignKey("PipelineDefinition")], Opportunity.prototype, "pipelineId", 2);
483
- __decorateClass$5([foreignKey("PipelineStage")], Opportunity.prototype, "stageId", 2);
474
+ __decorateClass$5([field({
475
+ required: true,
476
+ description: "What you call this deal."
477
+ })], Opportunity.prototype, "name", 2);
478
+ __decorateClass$5([field({ description: "The lead it came from." }), foreignKey("Lead")], Opportunity.prototype, "leadId", 2);
479
+ __decorateClass$5([field({ description: "The sales representative who owns this deal." }), foreignKey("SalesRepresentative")], Opportunity.prototype, "ownerRepId", 2);
480
+ __decorateClass$5([field({ description: "The pipeline it moves through." }), foreignKey("PipelineDefinition")], Opportunity.prototype, "pipelineId", 2);
481
+ __decorateClass$5([field({ description: "The stage it is at now." }), foreignKey("PipelineStage")], Opportunity.prototype, "stageId", 2);
482
+ __decorateClass$5([field({ description: "What you expect the deal to be worth, in cents." })], Opportunity.prototype, "expectedValueCents", 2);
483
+ __decorateClass$5([field({ description: "The currency of that value." })], Opportunity.prototype, "currency", 2);
484
+ __decorateClass$5([field({ description: "How likely it is to close, as a decimal (0.5 is 50%)." })], Opportunity.prototype, "probability", 2);
485
+ __decorateClass$5([field({ description: "When you expect it to close." })], Opportunity.prototype, "expectedCloseAt", 2);
486
+ __decorateClass$5([field({ description: "open, won or lost." })], Opportunity.prototype, "status", 2);
484
487
  Opportunity = __decorateClass$5([TenantScoped({ mode: "optional" }), smrt({
485
488
  api: { include: [
486
489
  "list",
@@ -512,18 +515,10 @@ var PipelineStage = class extends SmrtObject {
512
515
  tenantId = null;
513
516
  pipelineId = "";
514
517
  key = "";
515
- /** Human-readable stage name shown on board columns. */
516
518
  name = "";
517
- /** Ordering within the pipeline (ascending). Seeded in steps of 10. */
518
519
  sortOrder = 0;
519
- /**
520
- * Default win probability (`0`–`1`, DECIMAL) adopted by an opportunity
521
- * entering this stage unless the move overrides it.
522
- */
523
520
  probability = 0;
524
- /** Terminal flag: moving an opportunity here closes it as `won`. */
525
521
  isWon = false;
526
- /** Terminal flag: moving an opportunity here closes it as `lost`. */
527
522
  isLost = false;
528
523
  /**
529
524
  * Free-form JSON object stored as a string. Use
@@ -563,8 +558,16 @@ var PipelineStage = class extends SmrtObject {
563
558
  };
564
559
  __publicField$4(PipelineStage, "__smrtPackage__", "@happyvertical/smrt-sales");
565
560
  __decorateClass$4([tenantId({ nullable: true })], PipelineStage.prototype, "tenantId", 2);
566
- __decorateClass$4([foreignKey("PipelineDefinition", { required: true })], PipelineStage.prototype, "pipelineId", 2);
567
- __decorateClass$4([field({ required: true })], PipelineStage.prototype, "key", 2);
561
+ __decorateClass$4([field({ description: "The pipeline this stage belongs to." }), foreignKey("PipelineDefinition", { required: true })], PipelineStage.prototype, "pipelineId", 2);
562
+ __decorateClass$4([field({
563
+ required: true,
564
+ description: "A short code for the stage."
565
+ })], PipelineStage.prototype, "key", 2);
566
+ __decorateClass$4([field({ description: "What the stage is called." })], PipelineStage.prototype, "name", 2);
567
+ __decorateClass$4([field({ description: "Where it comes in the pipeline." })], PipelineStage.prototype, "sortOrder", 2);
568
+ __decorateClass$4([field({ description: "How likely a deal at this stage is to close, as a decimal." })], PipelineStage.prototype, "probability", 2);
569
+ __decorateClass$4([field({ description: "Whether reaching this stage closes the deal as won." })], PipelineStage.prototype, "isWon", 2);
570
+ __decorateClass$4([field({ description: "Whether reaching this stage closes the deal as lost." })], PipelineStage.prototype, "isLost", 2);
568
571
  PipelineStage = __decorateClass$4([TenantScoped({ mode: "optional" }), smrt({
569
572
  api: { include: [
570
573
  "list",
@@ -632,21 +635,11 @@ function permitSalesActivityWorkflowCompletion(activity) {
632
635
  }
633
636
  var SalesActivity = class extends SmrtObject {
634
637
  tenantId = null;
635
- /** Which model the activity attaches to: `'lead'` or `'opportunity'`. */
636
638
  subjectKind = "lead";
637
639
  subjectId = "";
638
- /**
639
- * Kind of activity — OPEN string so consumers can extend the vocabulary
640
- * without schema changes. See `SALES_ACTIVITY_KINDS` for the recommended
641
- * kinds (framework-written rows use `qualification`, `stage_change`,
642
- * `merge`).
643
- */
644
640
  activityKind = "note";
645
- /** One-line human-readable description. */
646
641
  summary = "";
647
- /** Next-action due date — set for `task`-like activities. */
648
642
  dueAt = null;
649
- /** When the next action was completed; `null` while open. */
650
643
  completedAt = null;
651
644
  actorProfileId = "";
652
645
  /**
@@ -722,7 +715,15 @@ var SalesActivity = class extends SmrtObject {
722
715
  };
723
716
  __publicField$3(SalesActivity, "__smrtPackage__", "@happyvertical/smrt-sales");
724
717
  __decorateClass$3([tenantId({ nullable: true })], SalesActivity.prototype, "tenantId", 2);
725
- __decorateClass$3([field({ required: true })], SalesActivity.prototype, "subjectId", 2);
718
+ __decorateClass$3([field({ description: "What the activity is about: a lead or an opportunity." })], SalesActivity.prototype, "subjectKind", 2);
719
+ __decorateClass$3([field({
720
+ required: true,
721
+ description: "The lead or opportunity it is about."
722
+ })], SalesActivity.prototype, "subjectId", 2);
723
+ __decorateClass$3([field({ description: "The kind of activity, for example call, note or email." })], SalesActivity.prototype, "activityKind", 2);
724
+ __decorateClass$3([field({ description: "What happened or what needs doing." })], SalesActivity.prototype, "summary", 2);
725
+ __decorateClass$3([field({ description: "When it is due." })], SalesActivity.prototype, "dueAt", 2);
726
+ __decorateClass$3([field({ description: "When it was done." })], SalesActivity.prototype, "completedAt", 2);
726
727
  __decorateClass$3([crossPackageRef("@happyvertical/smrt-profiles:Profile")], SalesActivity.prototype, "actorProfileId", 2);
727
728
  SalesActivity = __decorateClass$3([TenantScoped({ mode: "optional" }), smrt({
728
729
  api: { include: [
@@ -904,19 +905,9 @@ var __publicField$2 = (obj, key, value) => __defNormalProp$2(obj, typeof key !==
904
905
  var PipelineDefinition = class extends SmrtObject {
905
906
  tenantId = null;
906
907
  key = "";
907
- /** Human-readable pipeline name shown on CRM surfaces. */
908
908
  name = "";
909
- /**
910
- * Marks the tenant's default pipeline. Informational for pickers/UI; the
911
- * seeded default pipeline sets it `true`.
912
- */
913
909
  isDefault = false;
914
- /** `active` pipelines accept new opportunities; `archived` are read-only history. */
915
910
  status = "active";
916
- /**
917
- * Free-form JSON object stored as a string. Use
918
- * {@link getMetadata}/{@link setMetadata} instead of parsing manually.
919
- */
920
911
  metadata = "{}";
921
912
  constructor(options = {}) {
922
913
  super(options);
@@ -948,7 +939,14 @@ var PipelineDefinition = class extends SmrtObject {
948
939
  };
949
940
  __publicField$2(PipelineDefinition, "__smrtPackage__", "@happyvertical/smrt-sales");
950
941
  __decorateClass$2([tenantId({ nullable: true })], PipelineDefinition.prototype, "tenantId", 2);
951
- __decorateClass$2([field({ required: true })], PipelineDefinition.prototype, "key", 2);
942
+ __decorateClass$2([field({
943
+ required: true,
944
+ description: "A short code for the pipeline."
945
+ })], PipelineDefinition.prototype, "key", 2);
946
+ __decorateClass$2([field({ description: "What the pipeline is called." })], PipelineDefinition.prototype, "name", 2);
947
+ __decorateClass$2([field({ description: "Whether this is the default pipeline for new deals." })], PipelineDefinition.prototype, "isDefault", 2);
948
+ __decorateClass$2([field({ description: "Whether the pipeline is active (accepts new deals) or archived." })], PipelineDefinition.prototype, "status", 2);
949
+ __decorateClass$2([field({ description: "Extra details kept with the pipeline." })], PipelineDefinition.prototype, "metadata", 2);
952
950
  PipelineDefinition = __decorateClass$2([TenantScoped({ mode: "optional" }), smrt({
953
951
  api: { include: [
954
952
  "list",
@@ -1771,6 +1769,79 @@ var OpportunityConversionCollection = class extends SmrtCollection {
1771
1769
  }
1772
1770
  };
1773
1771
  //#endregion
1772
+ //#region src/crm/recipes.ts
1773
+ var SalesPipelineRecipe = class extends SmrtRecipe {
1774
+ static id = "sales.pipeline";
1775
+ static help = "./pipeline.recipe.md";
1776
+ static label = "Leads & pipeline";
1777
+ static summary = "Capture leads and move them through your sales stages.";
1778
+ static synonyms = [
1779
+ "crm",
1780
+ "prospects",
1781
+ "opportunities",
1782
+ "deals",
1783
+ "funnel"
1784
+ ];
1785
+ static section = {
1786
+ id: "sales",
1787
+ label: "Sales",
1788
+ icon: "shoppingBag",
1789
+ description: "Customers, orders and quotes: everything you sell."
1790
+ };
1791
+ static models = [
1792
+ Lead,
1793
+ Opportunity,
1794
+ PipelineDefinition,
1795
+ PipelineStage,
1796
+ SalesActivity
1797
+ ];
1798
+ static nav = [
1799
+ {
1800
+ label: "Leads",
1801
+ model: Lead,
1802
+ icon: "users",
1803
+ description: "People who might become customers, and where each one stands."
1804
+ },
1805
+ {
1806
+ label: "Opportunities",
1807
+ model: Opportunity,
1808
+ icon: "briefcase",
1809
+ description: "Deals in progress, with their value and next step."
1810
+ },
1811
+ {
1812
+ label: "Pipelines",
1813
+ model: PipelineDefinition,
1814
+ icon: "layers",
1815
+ description: "The stages a deal moves through on its way to a sale."
1816
+ }
1817
+ ];
1818
+ static options = {
1819
+ Lead: { fields: {
1820
+ profileId: { visibility: "hidden" },
1821
+ mergedIntoId: { visibility: "hidden" },
1822
+ sourceKind: { visibility: "hidden" },
1823
+ sourceId: { visibility: "hidden" },
1824
+ acquisitionContext: { visibility: "hidden" },
1825
+ intakeRef: { visibility: "hidden" },
1826
+ metadata: { visibility: "hidden" },
1827
+ qualifiedAt: { visibility: "hidden" }
1828
+ } },
1829
+ Opportunity: { fields: {
1830
+ sourceKind: { visibility: "hidden" },
1831
+ sourceId: { visibility: "hidden" },
1832
+ metadata: { visibility: "hidden" },
1833
+ outcomeReason: { visibility: "hidden" },
1834
+ wonAt: { visibility: "hidden" },
1835
+ lostAt: { visibility: "hidden" }
1836
+ } },
1837
+ PipelineStage: { fields: { metadata: { visibility: "hidden" } } },
1838
+ SalesActivity: { fields: {
1839
+ metadata: { visibility: "hidden" },
1840
+ actorProfileId: { visibility: "hidden" }
1841
+ } }
1842
+ };
1843
+ };
1844
+ //#endregion
1774
1845
  //#region src/crm/services/LeadWorkflowService.ts
1775
1846
  var LEAD_HUMAN_ACTIVITY_KINDS = [
1776
1847
  "note",
@@ -2607,6 +2678,6 @@ function uuidFromHash(hash) {
2607
2678
  return `${value.slice(0, 8)}-${value.slice(8, 12)}-${value.slice(12, 16)}-${value.slice(16, 20)}-${value.slice(20)}`;
2608
2679
  }
2609
2680
  //#endregion
2610
- export { PIPELINE_STATUSES as C, Lead as D, SALES_REPRESENTATIVE_STATUSES as E, OPPORTUNITY_STATUSES as S, SALES_ACTIVITY_SUBJECT_KINDS as T, PipelineStage as _, projectLeadWorkQueue as a, DEFAULT_PIPELINE_STAGES as b, LeadCollection as c, PipelineDefinitionCollection as d, PipelineDefinition as f, PipelineStageCollection as g, SalesActivity as h, MAX_LEAD_WORKFLOW_TEXT_LENGTH as i, SalesRepresentativeCollection as l, SalesActivityCollection as m, LeadWorkflowService as n, OpportunityConversionCollection as o, OpportunityCollection as p, LeadWorkflowValidationError as r, OpportunityConversion as s, LEAD_HUMAN_ACTIVITY_KINDS as t, SalesRepresentative as u, Opportunity as v, SALES_ACTIVITY_KINDS as w, LEAD_STATUSES as x, DEFAULT_PIPELINE_KEY as y };
2681
+ export { OPPORTUNITY_STATUSES as C, SALES_REPRESENTATIVE_STATUSES as D, SALES_ACTIVITY_SUBJECT_KINDS as E, Lead as O, LEAD_STATUSES as S, SALES_ACTIVITY_KINDS as T, PipelineStageCollection as _, projectLeadWorkQueue as a, DEFAULT_PIPELINE_KEY as b, OpportunityConversion as c, SalesRepresentative as d, PipelineDefinitionCollection as f, SalesActivity as g, SalesActivityCollection as h, MAX_LEAD_WORKFLOW_TEXT_LENGTH as i, LeadCollection as l, OpportunityCollection as m, LeadWorkflowService as n, SalesPipelineRecipe as o, PipelineDefinition as p, LeadWorkflowValidationError as r, OpportunityConversionCollection as s, LEAD_HUMAN_ACTIVITY_KINDS as t, SalesRepresentativeCollection as u, PipelineStage as v, PIPELINE_STATUSES as w, DEFAULT_PIPELINE_STAGES as x, Opportunity as y };
2611
2682
 
2612
- //# sourceMappingURL=crm-B-irXbbr.js.map
2683
+ //# sourceMappingURL=crm-DaUkdNoG.js.map