@grapadigital/shared-schemas 1.0.217 → 1.0.219

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.
@@ -9,27 +9,11 @@ var __metadata = (this && this.__metadata) || function (k, v) {
9
9
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.ProspectModel = exports.ProspectSchema = exports.Prospect = exports.ProspectNoteSchema = exports.ProspectNote = exports.ProspectResponsibleSchema = exports.ProspectResponsible = void 0;
12
+ exports.ProspectModel = exports.ProspectSchema = exports.Prospect = exports.ProspectNoteSchema = exports.ProspectNote = void 0;
13
13
  const mongoose_1 = require("@nestjs/mongoose");
14
14
  const swagger_1 = require("@nestjs/swagger");
15
15
  const mongoose_2 = require("mongoose");
16
- let ProspectResponsible = class ProspectResponsible {
17
- };
18
- __decorate([
19
- (0, swagger_1.ApiProperty)({ example: 'João' }),
20
- (0, mongoose_1.Prop)({ required: true }),
21
- __metadata("design:type", String)
22
- ], ProspectResponsible.prototype, "name", void 0);
23
- __decorate([
24
- (0, swagger_1.ApiProperty)({ example: 'joao@empresa.com' }),
25
- (0, mongoose_1.Prop)({ required: true }),
26
- __metadata("design:type", String)
27
- ], ProspectResponsible.prototype, "email", void 0);
28
- ProspectResponsible = __decorate([
29
- (0, mongoose_1.Schema)({ _id: false })
30
- ], ProspectResponsible);
31
- exports.ProspectResponsible = ProspectResponsible;
32
- exports.ProspectResponsibleSchema = mongoose_1.SchemaFactory.createForClass(ProspectResponsible);
16
+ const responsible_schema_1 = require("./responsible.schema");
33
17
  let ProspectNote = class ProspectNote {
34
18
  };
35
19
  __decorate([
@@ -77,8 +61,9 @@ __decorate([
77
61
  __metadata("design:type", Boolean)
78
62
  ], Prospect.prototype, "hot", void 0);
79
63
  __decorate([
80
- (0, mongoose_1.Prop)({ type: exports.ProspectResponsibleSchema, required: true }),
81
- __metadata("design:type", ProspectResponsible)
64
+ (0, swagger_1.ApiProperty)({ type: () => [responsible_schema_1.Responsible] }),
65
+ (0, mongoose_1.Prop)({ type: [responsible_schema_1.ResponsibleSchema], required: true }),
66
+ __metadata("design:type", Array)
82
67
  ], Prospect.prototype, "responsible", void 0);
83
68
  __decorate([
84
69
  (0, mongoose_1.Prop)({ required: true }),
@@ -98,4 +83,5 @@ Prospect = __decorate([
98
83
  exports.Prospect = Prospect;
99
84
  exports.ProspectSchema = mongoose_1.SchemaFactory.createForClass(Prospect);
100
85
  exports.ProspectSchema.index({ organization: 1, status: 1, lastContactAt: 1 });
86
+ exports.ProspectSchema.index({ 'responsible.email': 1 });
101
87
  exports.ProspectModel = (0, mongoose_2.model)('Prospect', exports.ProspectSchema);
@@ -0,0 +1,45 @@
1
+ /// <reference types="mongoose/types/aggregate" />
2
+ /// <reference types="mongoose/types/callback" />
3
+ /// <reference types="mongoose/types/collection" />
4
+ /// <reference types="mongoose/types/connection" />
5
+ /// <reference types="mongoose/types/cursor" />
6
+ /// <reference types="mongoose/types/document" />
7
+ /// <reference types="mongoose/types/error" />
8
+ /// <reference types="mongoose/types/expressions" />
9
+ /// <reference types="mongoose/types/helpers" />
10
+ /// <reference types="mongoose/types/middlewares" />
11
+ /// <reference types="mongoose/types/indexes" />
12
+ /// <reference types="mongoose/types/models" />
13
+ /// <reference types="mongoose/types/mongooseoptions" />
14
+ /// <reference types="mongoose/types/pipelinestage" />
15
+ /// <reference types="mongoose/types/populate" />
16
+ /// <reference types="mongoose/types/query" />
17
+ /// <reference types="mongoose/types/schemaoptions" />
18
+ /// <reference types="mongoose/types/session" />
19
+ /// <reference types="mongoose/types/types" />
20
+ /// <reference types="mongoose/types/utility" />
21
+ /// <reference types="mongoose/types/validation" />
22
+ /// <reference types="mongoose/types/virtuals" />
23
+ /// <reference types="mongoose" />
24
+ /// <reference types="mongoose/types/schematypes" />
25
+ /// <reference types="mongoose/types/inferschematype" />
26
+ /// <reference types="mongoose/types/inferrawdoctype" />
27
+ /**
28
+ * Formato único de responsável em todas as entidades (`responsible`).
29
+ * `username` vem de `User.username` (api-admin).
30
+ */
31
+ export declare class Responsible {
32
+ name: string;
33
+ email: string;
34
+ username: string;
35
+ team?: string;
36
+ }
37
+ export declare const ResponsibleSchema: import("mongoose").Schema<Responsible, import("mongoose").Model<Responsible, any, any, any, import("mongoose").Document<unknown, any, Responsible, any, {}> & Responsible & {
38
+ _id: import("mongoose").Types.ObjectId;
39
+ } & {
40
+ __v: number;
41
+ }, any>, {}, {}, {}, {}, import("mongoose").DefaultSchemaOptions, Responsible, import("mongoose").Document<unknown, {}, import("mongoose").FlatRecord<Responsible>, {}, import("mongoose").ResolveSchemaOptions<import("mongoose").DefaultSchemaOptions>> & import("mongoose").FlatRecord<Responsible> & {
42
+ _id: import("mongoose").Types.ObjectId;
43
+ } & {
44
+ __v: number;
45
+ }>;
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.ResponsibleSchema = exports.Responsible = void 0;
13
+ const mongoose_1 = require("@nestjs/mongoose");
14
+ const swagger_1 = require("@nestjs/swagger");
15
+ /**
16
+ * Formato único de responsável em todas as entidades (`responsible`).
17
+ * `username` vem de `User.username` (api-admin).
18
+ */
19
+ let Responsible = class Responsible {
20
+ };
21
+ __decorate([
22
+ (0, swagger_1.ApiProperty)({ example: 'Maria Oliveira' }),
23
+ (0, mongoose_1.Prop)({ type: String, required: true }),
24
+ __metadata("design:type", String)
25
+ ], Responsible.prototype, "name", void 0);
26
+ __decorate([
27
+ (0, swagger_1.ApiProperty)({ example: 'maria@empresa.com' }),
28
+ (0, mongoose_1.Prop)({ type: String, required: true }),
29
+ __metadata("design:type", String)
30
+ ], Responsible.prototype, "email", void 0);
31
+ __decorate([
32
+ (0, swagger_1.ApiProperty)({ example: 'maria.oliveira' }),
33
+ (0, mongoose_1.Prop)({ type: String, required: true }),
34
+ __metadata("design:type", String)
35
+ ], Responsible.prototype, "username", void 0);
36
+ __decorate([
37
+ (0, swagger_1.ApiProperty)({ example: 'service', required: false }),
38
+ (0, mongoose_1.Prop)({ type: String, required: false }),
39
+ __metadata("design:type", String)
40
+ ], Responsible.prototype, "team", void 0);
41
+ Responsible = __decorate([
42
+ (0, mongoose_1.Schema)({ _id: false })
43
+ ], Responsible);
44
+ exports.Responsible = Responsible;
45
+ exports.ResponsibleSchema = mongoose_1.SchemaFactory.createForClass(Responsible);
@@ -28,6 +28,7 @@ import { Profile } from './profile.schema';
28
28
  import { Client } from './client.schema';
29
29
  import { Influencer } from './influencer.schema';
30
30
  import { Note } from './note.schema';
31
+ import { Responsible } from './responsible.schema';
31
32
  export type SaleDocument = HydratedDocument<Sale>;
32
33
  export declare class Proposal {
33
34
  businessUnit: 'service' | 'comercial';
@@ -36,11 +37,6 @@ export declare class Proposal {
36
37
  origin: 'inbound' | 'outbound';
37
38
  profile?: Types.ObjectId | Profile;
38
39
  influencer?: Types.ObjectId | Influencer;
39
- responsible: {
40
- team: string;
41
- name: string;
42
- email: string;
43
- }[];
44
40
  }
45
41
  export declare class Negotiation {
46
42
  calculatorType: 'withPreDefinedBudget' | 'withoutPreDefinedBudget' | 'byCommission' | 'bourbon';
@@ -117,18 +113,23 @@ export declare class Inbox {
117
113
  bodyHtml?: string;
118
114
  receivedAt: Date;
119
115
  }
116
+ /**
117
+ * Responsáveis da venda por papel: comercial (proposta), curadoria e planejamento.
118
+ */
120
119
  export declare class SaleResponsible {
121
- curation?: {
122
- team: string;
123
- name: string;
124
- email: string;
125
- }[];
126
- planning?: {
127
- team: string;
128
- name: string;
129
- email: string;
130
- }[];
120
+ proposal?: Responsible[];
121
+ curation?: Responsible[];
122
+ planning?: Responsible[];
131
123
  }
124
+ export declare const SaleResponsibleSchema: MongooseSchema<SaleResponsible, import("mongoose").Model<SaleResponsible, any, any, any, import("mongoose").Document<unknown, any, SaleResponsible, any, {}> & SaleResponsible & {
125
+ _id: Types.ObjectId;
126
+ } & {
127
+ __v: number;
128
+ }, any>, {}, {}, {}, {}, import("mongoose").DefaultSchemaOptions, SaleResponsible, import("mongoose").Document<unknown, {}, import("mongoose").FlatRecord<SaleResponsible>, {}, import("mongoose").ResolveSchemaOptions<import("mongoose").DefaultSchemaOptions>> & import("mongoose").FlatRecord<SaleResponsible> & {
129
+ _id: Types.ObjectId;
130
+ } & {
131
+ __v: number;
132
+ }>;
132
133
  export declare class SaleLinks {
133
134
  contract?: string;
134
135
  clientSheet?: string;
@@ -9,10 +9,11 @@ var __metadata = (this && this.__metadata) || function (k, v) {
9
9
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.SaleModel = exports.SaleSchema = exports.Sale = exports.SaleLinks = exports.SaleResponsible = exports.Inbox = exports.CommissionInfo = exports.CommissionParticipant = exports.TimelineEntry = exports.Activity = exports.Lost = exports.Formalization = exports.Negotiation = exports.Proposal = void 0;
12
+ exports.SaleModel = exports.SaleSchema = exports.Sale = exports.SaleLinks = exports.SaleResponsibleSchema = exports.SaleResponsible = exports.Inbox = exports.CommissionInfo = exports.CommissionParticipant = exports.TimelineEntry = exports.Activity = exports.Lost = exports.Formalization = exports.Negotiation = exports.Proposal = void 0;
13
13
  const mongoose_1 = require("@nestjs/mongoose");
14
14
  const mongoose_2 = require("mongoose");
15
15
  const note_schema_1 = require("./note.schema");
16
+ const responsible_schema_1 = require("./responsible.schema");
16
17
  let Proposal = class Proposal {
17
18
  };
18
19
  __decorate([
@@ -51,18 +52,6 @@ __decorate([
51
52
  }),
52
53
  __metadata("design:type", Object)
53
54
  ], Proposal.prototype, "influencer", void 0);
54
- __decorate([
55
- (0, mongoose_1.Prop)({
56
- _id: false,
57
- required: true,
58
- type: [{
59
- team: String,
60
- name: String,
61
- email: String,
62
- }],
63
- }),
64
- __metadata("design:type", Array)
65
- ], Proposal.prototype, "responsible", void 0);
66
55
  Proposal = __decorate([
67
56
  (0, mongoose_1.Schema)({ _id: false })
68
57
  ], Proposal);
@@ -351,36 +340,28 @@ Inbox = __decorate([
351
340
  (0, mongoose_1.Schema)({ _id: false })
352
341
  ], Inbox);
353
342
  exports.Inbox = Inbox;
343
+ /**
344
+ * Responsáveis da venda por papel: comercial (proposta), curadoria e planejamento.
345
+ */
354
346
  let SaleResponsible = class SaleResponsible {
355
347
  };
356
348
  __decorate([
357
- (0, mongoose_1.Prop)({
358
- _id: false,
359
- required: false,
360
- type: [{
361
- team: String,
362
- name: String,
363
- email: String,
364
- }],
365
- }),
349
+ (0, mongoose_1.Prop)({ type: [responsible_schema_1.ResponsibleSchema], required: false, default: [] }),
350
+ __metadata("design:type", Array)
351
+ ], SaleResponsible.prototype, "proposal", void 0);
352
+ __decorate([
353
+ (0, mongoose_1.Prop)({ type: [responsible_schema_1.ResponsibleSchema], required: false, default: [] }),
366
354
  __metadata("design:type", Array)
367
355
  ], SaleResponsible.prototype, "curation", void 0);
368
356
  __decorate([
369
- (0, mongoose_1.Prop)({
370
- _id: false,
371
- required: false,
372
- type: [{
373
- team: String,
374
- name: String,
375
- email: String,
376
- }],
377
- }),
357
+ (0, mongoose_1.Prop)({ type: [responsible_schema_1.ResponsibleSchema], required: false, default: [] }),
378
358
  __metadata("design:type", Array)
379
359
  ], SaleResponsible.prototype, "planning", void 0);
380
360
  SaleResponsible = __decorate([
381
361
  (0, mongoose_1.Schema)({ _id: false })
382
362
  ], SaleResponsible);
383
363
  exports.SaleResponsible = SaleResponsible;
364
+ exports.SaleResponsibleSchema = mongoose_1.SchemaFactory.createForClass(SaleResponsible);
384
365
  let SaleLinks = class SaleLinks {
385
366
  };
386
367
  __decorate([
@@ -510,7 +491,7 @@ __decorate([
510
491
  __metadata("design:type", String)
511
492
  ], Sale.prototype, "omieId", void 0);
512
493
  __decorate([
513
- (0, mongoose_1.Prop)({ type: SaleResponsible, required: false }),
494
+ (0, mongoose_1.Prop)({ type: exports.SaleResponsibleSchema, required: false }),
514
495
  __metadata("design:type", SaleResponsible)
515
496
  ], Sale.prototype, "responsible", void 0);
516
497
  __decorate([
@@ -528,6 +509,6 @@ exports.SaleSchema.index({ organization: 1, 'formalization.brand': 1 });
528
509
  exports.SaleSchema.index({ organization: 1, 'formalization.agency': 1 });
529
510
  exports.SaleSchema.index({ organization: 1, closedAt: 1, phase: 1 });
530
511
  exports.SaleSchema.index({ 'proposal.influencer': 1 });
531
- exports.SaleSchema.index({ 'proposal.responsible.email': 1 });
512
+ exports.SaleSchema.index({ 'responsible.proposal.email': 1 });
532
513
  exports.SaleSchema.index({ tags: 1 });
533
514
  exports.SaleModel = (0, mongoose_2.model)('Sale', exports.SaleSchema);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grapadigital/shared-schemas",
3
- "version": "1.0.217",
3
+ "version": "1.0.219",
4
4
  "description": "Shared Mongoose Schemas",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/index.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export * from './schemas/responsible.schema';
1
2
  export * from './schemas/action.schema';
2
3
  export * from './schemas/prospect.schema';
3
4
  export * from './schemas/client.schema';
@@ -14,34 +14,10 @@ import { Client } from './client.schema';
14
14
  import { Sale } from './sale.schema';
15
15
  import { Campaign } from './campaign.schema';
16
16
  import { Note, NoteSchema } from './note.schema';
17
+ import { Responsible, ResponsibleSchema } from './responsible.schema';
17
18
 
18
19
  export type ActionDocument = HydratedDocument<Action>;
19
20
 
20
- @Schema({ _id: false })
21
- export class Responsible {
22
- @ApiProperty({ example: 'Maria Oliveira' })
23
- @Prop()
24
- name: string;
25
-
26
- @ApiProperty({ example: 'Comercial' })
27
- @Prop()
28
- team: string;
29
-
30
- @ApiProperty({ example: 'maria@empresa.com' })
31
- @Prop()
32
- email: string;
33
- }
34
-
35
- export const ResponsibleSchema = SchemaFactory.createForClass(Responsible);
36
-
37
- /**
38
- * @deprecated Use `Responsible` or `Responsible[]` on Action.responsible
39
- */
40
- export class ActionResponsible extends Responsible {}
41
- export const ActionResponsibleSchema = SchemaFactory.createForClass(ActionResponsible);
42
-
43
- export { ActionResponsible as Responsibles, ActionResponsibleSchema as ResponsiblesSchema };
44
-
45
21
  export const ACTION_BUSINESS_UNIT_VALUES = [
46
22
  'service',
47
23
  'comercial',
@@ -9,6 +9,7 @@ import {
9
9
  } from 'mongoose';
10
10
 
11
11
  import { Action } from './action.schema';
12
+ import { Responsible, ResponsibleSchema } from './responsible.schema';
12
13
 
13
14
  export type AssignmentDocument = HydratedDocument<Assignment>;
14
15
 
@@ -100,9 +101,9 @@ export class Assignment {
100
101
  @Prop({ type: String, required: true })
101
102
  title: string;
102
103
 
103
- @ApiProperty({ example: '64bfc3a78d3f1e2a1234567a', required: false })
104
- @Prop({ type: MongooseSchema.Types.ObjectId, required: false })
105
- responsible?: Types.ObjectId;
104
+ @ApiProperty({ type: () => [Responsible], required: false })
105
+ @Prop({ type: [ResponsibleSchema], required: false, default: [] })
106
+ responsible?: Responsible[];
106
107
 
107
108
  @ApiProperty({ example: '2026-08-25T00:00:00.000Z', required: false })
108
109
  @Prop({ type: Date, required: false, default: null })
@@ -148,6 +149,6 @@ AssignmentSchema.index({ action: 1 });
148
149
  AssignmentSchema.index({ organization: 1, status: 1 });
149
150
  AssignmentSchema.index({ organization: 1, dueDate: 1 });
150
151
  AssignmentSchema.index({ seriesId: 1 });
151
- AssignmentSchema.index({ responsible: 1, dueDate: 1 });
152
+ AssignmentSchema.index({ 'responsible.email': 1, dueDate: 1 });
152
153
 
153
154
  export const AssignmentModel = MongooseModel('Assignment', AssignmentSchema);
@@ -8,6 +8,7 @@ import {
8
8
  } from 'mongoose';
9
9
  import { Party } from './party.schema';
10
10
  import { Profile } from './profile.schema';
11
+ import { Responsible, ResponsibleSchema } from './responsible.schema';
11
12
 
12
13
  export type ClientDocument = HydratedDocument<Client>;
13
14
 
@@ -18,6 +19,50 @@ export type ClientDocument = HydratedDocument<Client>;
18
19
  export const CLIENT_CUSTOMIZATION_VALUES = ['samsung'] as const;
19
20
  export type ClientCustomization = (typeof CLIENT_CUSTOMIZATION_VALUES)[number];
20
21
 
22
+ /**
23
+ * Catálogo de métricas que podem virar meta no Tier ou na Meta anual do
24
+ * cliente. Quem cadastra escolhe a métrica e o valor; nada fica fixo.
25
+ * `viralReachEngagementRate` é o limite de viral e só vale no Tier.
26
+ * Ver GD-687.
27
+ */
28
+ export const CLIENT_GOAL_METRIC_VALUES = [
29
+ 'potentialReach',
30
+ 'reachCount',
31
+ 'impressionCount',
32
+ 'engagementCount',
33
+ 'engagementRate',
34
+ 'reachEngagementRate',
35
+ 'qualifiedEngagementRate',
36
+ 'effectiveReach',
37
+ 'emv',
38
+ 'score',
39
+ 'cpmi',
40
+ 'cpi',
41
+ 'cpe',
42
+ 'viralReachEngagementRate',
43
+ ] as const;
44
+ export type ClientGoalMetric = (typeof CLIENT_GOAL_METRIC_VALUES)[number];
45
+
46
+ export type ClientGoalMetricUnit = 'count' | 'rate' | 'currency';
47
+
48
+ /** Unidade de cada métrica. `rate` é guardado como fração (0,10 = 10%). */
49
+ export const CLIENT_GOAL_METRIC_UNITS: Record<ClientGoalMetric, ClientGoalMetricUnit> = {
50
+ potentialReach: 'count',
51
+ reachCount: 'count',
52
+ impressionCount: 'count',
53
+ engagementCount: 'count',
54
+ engagementRate: 'rate',
55
+ reachEngagementRate: 'rate',
56
+ qualifiedEngagementRate: 'rate',
57
+ effectiveReach: 'count',
58
+ emv: 'currency',
59
+ score: 'count',
60
+ cpmi: 'currency',
61
+ cpi: 'currency',
62
+ cpe: 'currency',
63
+ viralReachEngagementRate: 'rate',
64
+ };
65
+
21
66
  @Schema({ _id: false })
22
67
  export class Cluster {
23
68
  @Prop({ required: true })
@@ -54,6 +99,54 @@ export class CommissionRange {
54
99
 
55
100
  export const CommissionRangeSchema = SchemaFactory.createForClass(CommissionRange);
56
101
 
102
+ @Schema({ _id: false })
103
+ export class ClientMetricGoal {
104
+ @Prop({ type: String, enum: CLIENT_GOAL_METRIC_VALUES, required: true })
105
+ metric: ClientGoalMetric;
106
+
107
+ /** Na unidade da métrica (`CLIENT_GOAL_METRIC_UNITS`); `rate` em fração. */
108
+ @Prop({ type: Number, required: true })
109
+ value: number;
110
+ }
111
+
112
+ export const ClientMetricGoalSchema = SchemaFactory.createForClass(ClientMetricGoal);
113
+
114
+ /**
115
+ * Faixa de seguidores do cliente com as metas dela (ex.: Micro, Macro, Hero,
116
+ * Icon da Samsung). O Tier é do cliente, não do Influenciador: para mudar a
117
+ * meta, edita o Tier. Faixas inclusivas nas duas pontas, contínuas e sem
118
+ * sobreposição (validado na api-entities). Ver GD-687.
119
+ */
120
+ @Schema({ _id: false })
121
+ export class ClientTier {
122
+ @Prop({ type: String, required: true })
123
+ name: string;
124
+
125
+ @Prop({ type: Number, required: true })
126
+ minFollowers: number;
127
+
128
+ /** `null` = sem teto (só o último Tier). */
129
+ @Prop({ type: Number, required: false, default: null })
130
+ maxFollowers?: number | null;
131
+
132
+ @Prop({ type: [ClientMetricGoalSchema], default: [] })
133
+ goals: ClientMetricGoal[];
134
+ }
135
+
136
+ export const ClientTierSchema = SchemaFactory.createForClass(ClientTier);
137
+
138
+ /** Metas do cliente num ano (alimentam os cards do gen_ia). Ver GD-687. */
139
+ @Schema({ _id: false })
140
+ export class ClientAnnualGoal {
141
+ @Prop({ type: Number, required: true })
142
+ year: number;
143
+
144
+ @Prop({ type: [ClientMetricGoalSchema], default: [] })
145
+ goals: ClientMetricGoal[];
146
+ }
147
+
148
+ export const ClientAnnualGoalSchema = SchemaFactory.createForClass(ClientAnnualGoal);
149
+
57
150
  @Schema({ _id: false })
58
151
  export class AgencyCommissionPeriod {
59
152
  @Prop({ type: [CommissionRangeSchema], required: true, default: [] })
@@ -82,19 +175,19 @@ export class NicheItem {
82
175
 
83
176
  export const NicheItemSchema = SchemaFactory.createForClass(NicheItem);
84
177
 
178
+ /**
179
+ * Responsáveis do cliente: `report` são usuários da plataforma que cuidam dos
180
+ * relatórios; `brand` é o contato do lado da marca (texto livre, não é usuário).
181
+ */
85
182
  @Schema({ _id: false })
86
183
  export class ClientResponsible {
87
- @ApiProperty({ example: 'Maria Oliveira' })
88
- @Prop()
89
- name: string;
184
+ @ApiProperty({ type: () => [Responsible], required: false })
185
+ @Prop({ type: [ResponsibleSchema], required: false, default: [] })
186
+ report?: Responsible[];
90
187
 
91
- @ApiProperty({ example: 'Comercial' })
92
- @Prop()
93
- team: string;
94
-
95
- @ApiProperty({ example: 'maria@empresa.com' })
96
- @Prop()
97
- email: string;
188
+ @ApiProperty({ example: 'Maite', required: false })
189
+ @Prop({ type: String, required: false })
190
+ brand?: string;
98
191
  }
99
192
 
100
193
  export const ClientResponsibleSchema = SchemaFactory.createForClass(ClientResponsible);
@@ -156,6 +249,14 @@ export class Client extends Party {
156
249
  @Prop({ type: String, enum: CLIENT_CUSTOMIZATION_VALUES, required: false, default: null })
157
250
  customization?: ClientCustomization | null;
158
251
 
252
+ /** Tiers do cliente (só com Personalização Samsung por enquanto). Ver GD-687. */
253
+ @Prop({ type: [ClientTierSchema], default: [] })
254
+ tiers: ClientTier[];
255
+
256
+ /** Metas anuais do cliente (só com Personalização Samsung por enquanto). Ver GD-687. */
257
+ @Prop({ type: [ClientAnnualGoalSchema], default: [] })
258
+ annualGoals: ClientAnnualGoal[];
259
+
159
260
  /**
160
261
  * Client de organização (ex.: "Oma Creators"): representa a organização
161
262
  * inteira, não uma marca. No hub, mostra todas as actions dessa organização
@@ -167,10 +268,7 @@ export class Client extends Party {
167
268
  organization?: Types.ObjectId;
168
269
 
169
270
  @Prop({ type: ClientResponsibleSchema, required: false })
170
- reportResponsible?: ClientResponsible;
171
-
172
- @Prop({ type: String, required: false })
173
- brandResponsible?: string;
271
+ responsible?: ClientResponsible;
174
272
 
175
273
  // Perfis da marca nas redes sociais (mesmo vínculo de Influencer.profiles).
176
274
  // Usado pelo comment-capture-worker pra reconhecer comentário da própria marca.
@@ -6,6 +6,7 @@ import {
6
6
  model as MongooseModel,
7
7
  } from 'mongoose';
8
8
  import { Action } from './action.schema';
9
+ import { Responsible, ResponsibleSchema } from './responsible.schema';
9
10
 
10
11
  export type ContentCaptureProcessDocument = HydratedDocument<ContentCaptureProcess>;
11
12
 
@@ -112,37 +113,6 @@ export class ContentCaptureProcessItem {
112
113
  export const ContentCaptureProcessItemSchema =
113
114
  SchemaFactory.createForClass(ContentCaptureProcessItem);
114
115
 
115
- @Schema({ _id: false })
116
- export class ContentCaptureProcessResponsibleContact {
117
- @Prop({ type: String, required: false })
118
- name?: string;
119
-
120
- @Prop({ type: String, required: false })
121
- team?: string;
122
-
123
- @Prop({ type: String, required: false })
124
- email?: string;
125
- }
126
-
127
- export const ContentCaptureProcessResponsibleContactSchema = SchemaFactory.createForClass(
128
- ContentCaptureProcessResponsibleContact,
129
- );
130
-
131
- @Schema({ _id: false })
132
- export class ContentCaptureProcessResponsible {
133
- @Prop({ type: [ContentCaptureProcessResponsibleContactSchema], required: false })
134
- service?: ContentCaptureProcessResponsibleContact[];
135
- }
136
-
137
- export const ContentCaptureProcessResponsibleSchema = SchemaFactory.createForClass(
138
- ContentCaptureProcessResponsible,
139
- );
140
-
141
- export {
142
- ContentCaptureProcessResponsible as ContentCaptureProcessResponsibles,
143
- ContentCaptureProcessResponsibleSchema as ContentCaptureProcessResponsiblesSchema,
144
- };
145
-
146
116
  @Schema({ collection: 'content-capture-processes', timestamps: true })
147
117
  export class ContentCaptureProcess {
148
118
  @Prop({ type: MongooseSchema.Types.ObjectId, auto: true, required: false })
@@ -160,8 +130,8 @@ export class ContentCaptureProcess {
160
130
  @Prop({ type: String, required: false })
161
131
  primetagId?: string;
162
132
 
163
- @Prop({ type: ContentCaptureProcessResponsibleSchema, required: false })
164
- responsible?: ContentCaptureProcessResponsible;
133
+ @Prop({ type: [ResponsibleSchema], required: false, default: [] })
134
+ responsible?: Responsible[];
165
135
 
166
136
  @Prop({
167
137
  type: String,
@@ -1,22 +1,10 @@
1
1
  import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
2
2
  import { ApiProperty } from '@nestjs/swagger';
3
3
  import { HydratedDocument, Schema as MongooseSchema, Types, model as MongooseModel } from 'mongoose';
4
+ import { Responsible, ResponsibleSchema } from './responsible.schema';
4
5
 
5
6
  export type ProspectDocument = HydratedDocument<Prospect>;
6
7
 
7
- @Schema({ _id: false })
8
- export class ProspectResponsible {
9
- @ApiProperty({ example: 'João' })
10
- @Prop({ required: true })
11
- name: string;
12
-
13
- @ApiProperty({ example: 'joao@empresa.com' })
14
- @Prop({ required: true })
15
- email: string;
16
- }
17
-
18
- export const ProspectResponsibleSchema = SchemaFactory.createForClass(ProspectResponsible);
19
-
20
8
  @Schema({ _id: false })
21
9
  export class ProspectNote {
22
10
  @Prop({ required: true })
@@ -52,8 +40,9 @@ export class Prospect {
52
40
  @Prop({ required: true, default: false })
53
41
  hot: boolean;
54
42
 
55
- @Prop({ type: ProspectResponsibleSchema, required: true })
56
- responsible: ProspectResponsible;
43
+ @ApiProperty({ type: () => [Responsible] })
44
+ @Prop({ type: [ResponsibleSchema], required: true })
45
+ responsible: Responsible[];
57
46
 
58
47
  @Prop({ required: true })
59
48
  lastContactAt: Date;
@@ -68,5 +57,6 @@ export class Prospect {
68
57
  export const ProspectSchema = SchemaFactory.createForClass(Prospect);
69
58
 
70
59
  ProspectSchema.index({ organization: 1, status: 1, lastContactAt: 1 });
60
+ ProspectSchema.index({ 'responsible.email': 1 });
71
61
 
72
62
  export const ProspectModel = MongooseModel('Prospect', ProspectSchema);
@@ -0,0 +1,27 @@
1
+ import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
2
+ import { ApiProperty } from '@nestjs/swagger';
3
+
4
+ /**
5
+ * Formato único de responsável em todas as entidades (`responsible`).
6
+ * `username` vem de `User.username` (api-admin).
7
+ */
8
+ @Schema({ _id: false })
9
+ export class Responsible {
10
+ @ApiProperty({ example: 'Maria Oliveira' })
11
+ @Prop({ type: String, required: true })
12
+ name: string;
13
+
14
+ @ApiProperty({ example: 'maria@empresa.com' })
15
+ @Prop({ type: String, required: true })
16
+ email: string;
17
+
18
+ @ApiProperty({ example: 'maria.oliveira' })
19
+ @Prop({ type: String, required: true })
20
+ username: string;
21
+
22
+ @ApiProperty({ example: 'service', required: false })
23
+ @Prop({ type: String, required: false })
24
+ team?: string;
25
+ }
26
+
27
+ export const ResponsibleSchema = SchemaFactory.createForClass(Responsible);