@cofondateurauchomage/libs 1.1.152 → 1.1.155

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/build/api.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { IBlogHtmlArticle, IContact, INewsletter, IProject, IProspect, IReactionStatus, IUser, TPlan, TPlanOption, TVisibility } from "./db.model";
2
- export type CloudFunctionNames = "createProject" | "updateProject" | "deleteProject" | "createUser" | "updateUser" | "deleteUser" | "updateVisibility" | "addStripeId" | "updatePlan" | "updateMetaStripe" | "addStatsAssociation" | "updateNewsletter" | "createProspect" | "getProspect" | "updateProspect" | "createReaction" | "deleteReaction" | "createBlogHtmlArticle";
2
+ export type CloudFunctionNames = "createProject" | "updateProject" | "deleteProject" | "createUser" | "updateUser" | "deleteUser" | "updateVisibility" | "addStripeId" | "updatePlan" | "updateMetaStripe" | "addStatsAssociation" | "updateNewsletter" | "createProspect" | "getProspect" | "updateProspect" | "createReaction" | "deleteReaction" | "createBlogHtmlArticle" | "syncCrmProfiles";
3
3
  export type RouteNames = "checkout_session" | "delete_customer" | "portal_session" | "webhook";
4
4
  export type BodyForO<O extends CloudFunctionNames | RouteNames> = {
5
5
  createProject: Omit<IProject, "id" | "plan" | "visibility" | "clicks" | "creationDate" | "lastConnection" | "stripeId" | "referrer" | "postedOnLinkedInAt"> & IContact & {
@@ -53,6 +53,8 @@ export type BodyForO<O extends CloudFunctionNames | RouteNames> = {
53
53
  createBlogHtmlArticle: Omit<IBlogHtmlArticle, "date"> & {
54
54
  apiSecretKey: string;
55
55
  };
56
+ /** Admin-only: rebuild all `crm_profiles` from source collections. */
57
+ syncCrmProfiles: Record<string, never>;
56
58
  checkout_session: {
57
59
  customer: {
58
60
  email: string;
@@ -100,6 +102,13 @@ export type ResponseForO<O extends CloudFunctionNames | RouteNames> = {
100
102
  createReaction: WriteResult;
101
103
  deleteReaction: WriteResult;
102
104
  createBlogHtmlArticle: WriteResult;
105
+ syncCrmProfiles: {
106
+ users: number;
107
+ projects: number;
108
+ prospects: number;
109
+ synced: number;
110
+ failed: number;
111
+ };
103
112
  checkout_session: {
104
113
  sessionId: string;
105
114
  };
@@ -233,6 +233,7 @@ const schemasForAllRoutes = {
233
233
  content: zod_1.z.string(),
234
234
  toc: zod_1.z.string().optional(),
235
235
  }),
236
+ syncCrmProfiles: zod_1.z.object({}),
236
237
  checkout_session: zod_1.z.object({
237
238
  customer: zod_1.z.object({
238
239
  email: zod_1.z.string(),
@@ -112,7 +112,8 @@ export type TCrmPipelineBucket = "lead" | "inscrit" | "pro" | "ancien_pro";
112
112
  interface ICrmProfileBase {
113
113
  pipelineBucket: TCrmPipelineBucket;
114
114
  searchText: string;
115
- lastTeamCallAt?: number;
115
+ /** 0 if not called */
116
+ lastTeamCallAt: number;
116
117
  foundPartner?: boolean;
117
118
  }
118
119
  export interface ICrmProfileProspect extends ICrmProfileBase {
@@ -0,0 +1,14 @@
1
+ import type { ICrmProfile, ICrmProfileProject, ICrmProfileUser, IStripeMeta, TCrmPlanFilter, TPlan } from "../db.model";
2
+ type PlanPick = {
3
+ plan: TPlan;
4
+ complimentaryProGrantedAt?: number;
5
+ complimentaryProRevokedAt?: number;
6
+ };
7
+ /**
8
+ * Maps profile + Stripe mirror to a CRM pipeline plan filter bucket.
9
+ * Mirrors front-v2 `resolveCrmPlanBadgeModel` (free / paid Pro / complimentary Pro).
10
+ */
11
+ export declare function resolveCrmPlanFilterForUserOrProject(profile: PlanPick, stripe: Partial<IStripeMeta> | undefined): TCrmPlanFilter;
12
+ export declare function resolveCrmPlanFilterFromUserOrProjectDoc(doc: ICrmProfileUser | ICrmProfileProject): TCrmPlanFilter;
13
+ export declare function resolveCrmPlanFilter(profile: ICrmProfile): TCrmPlanFilter;
14
+ export {};
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveCrmPlanFilterForUserOrProject = resolveCrmPlanFilterForUserOrProject;
4
+ exports.resolveCrmPlanFilterFromUserOrProjectDoc = resolveCrmPlanFilterFromUserOrProjectDoc;
5
+ exports.resolveCrmPlanFilter = resolveCrmPlanFilter;
6
+ const PRO_PLANS = new Set(["pro", "premium"]);
7
+ function derivePaymentBadge(profile) {
8
+ const now = Date.now();
9
+ const periodEnd = profile.stripeCurrentPeriodEnd;
10
+ const payingPeriod = (profile.plan === "pro" || profile.plan === "premium") &&
11
+ periodEnd != null &&
12
+ periodEnd > now &&
13
+ profile.stripeLastPaymentAt != null;
14
+ if (payingPeriod) {
15
+ return "payant";
16
+ }
17
+ if (profile.stripeFirstPaidAt != null) {
18
+ return "ancien_payant";
19
+ }
20
+ return null;
21
+ }
22
+ function stripeBillingFields(profile, stripe) {
23
+ return {
24
+ plan: profile.plan,
25
+ stripeFirstPaidAt: stripe?.stripeFirstPaidAt,
26
+ stripeLastPaymentAt: stripe?.stripeLastPaymentAt,
27
+ stripeCurrentPeriodEnd: stripe?.stripeCurrentPeriodEnd,
28
+ stripeSubscriptionEndedAt: stripe?.stripeSubscriptionEndedAt,
29
+ };
30
+ }
31
+ /**
32
+ * Maps profile + Stripe mirror to a CRM pipeline plan filter bucket.
33
+ * Mirrors front-v2 `resolveCrmPlanBadgeModel` (free / paid Pro / complimentary Pro).
34
+ */
35
+ function resolveCrmPlanFilterForUserOrProject(profile, stripe) {
36
+ const stripeMeta = stripe ?? {};
37
+ const billing = stripeBillingFields(profile, stripeMeta);
38
+ const payBadge = derivePaymentBadge(billing);
39
+ const compAt = profile.complimentaryProGrantedAt;
40
+ const compRevoked = profile.complimentaryProRevokedAt != null && profile.complimentaryProRevokedAt > 0;
41
+ const plan = profile.plan;
42
+ if (PRO_PLANS.has(plan)) {
43
+ if (payBadge === "payant") {
44
+ return "pro";
45
+ }
46
+ if (compAt != null && compAt > 0 && !compRevoked) {
47
+ return "pro_offert";
48
+ }
49
+ return "pro";
50
+ }
51
+ if (compRevoked) {
52
+ return "free";
53
+ }
54
+ const endedAt = stripeMeta.stripeSubscriptionEndedAt != null && stripeMeta.stripeSubscriptionEndedAt > 0
55
+ ? stripeMeta.stripeSubscriptionEndedAt
56
+ : undefined;
57
+ if (payBadge === "ancien_payant" || stripeMeta.stripeFirstPaidAt != null || endedAt != null) {
58
+ return "free";
59
+ }
60
+ return "free";
61
+ }
62
+ function resolveCrmPlanFilterFromUserOrProjectDoc(doc) {
63
+ return resolveCrmPlanFilterForUserOrProject({
64
+ plan: doc.profile.plan,
65
+ complimentaryProGrantedAt: doc.complimentaryProGrantedAt,
66
+ complimentaryProRevokedAt: doc.complimentaryProRevokedAt,
67
+ }, doc.stripeMeta);
68
+ }
69
+ function resolveCrmPlanFilter(profile) {
70
+ if (profile.type === "prospect") {
71
+ return "free";
72
+ }
73
+ return resolveCrmPlanFilterFromUserOrProjectDoc(profile);
74
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cofondateurauchomage/libs",
3
- "version": "1.1.152",
3
+ "version": "1.1.155",
4
4
  "description": "",
5
5
  "main": "build/index",
6
6
  "scripts": {