@grapadigital/shared-schemas 1.0.191 → 1.0.193

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.
@@ -60,6 +60,24 @@ export declare const ResponsiblesSchema: MongooseSchema<Responsibles, import("mo
60
60
  }>;
61
61
  export declare const ACTION_BUSINESS_UNIT_VALUES: readonly ["service", "comercial", "squad_a", "squad_b"];
62
62
  export type ActionBusinessUnit = (typeof ACTION_BUSINESS_UNIT_VALUES)[number];
63
+ export declare class ActionPromptConfig {
64
+ context?: string;
65
+ targetPrompt?: string;
66
+ influencerPrompt?: string;
67
+ brandPrompt?: string;
68
+ contentPrompt?: string;
69
+ polarityPrompt?: string;
70
+ funnelPrompt?: string;
71
+ }
72
+ export declare const ActionPromptConfigSchema: MongooseSchema<ActionPromptConfig, import("mongoose").Model<ActionPromptConfig, any, any, any, import("mongoose").Document<unknown, any, ActionPromptConfig, any, {}> & ActionPromptConfig & {
73
+ _id: Types.ObjectId;
74
+ } & {
75
+ __v: number;
76
+ }, any>, {}, {}, {}, {}, import("mongoose").DefaultSchemaOptions, ActionPromptConfig, import("mongoose").Document<unknown, {}, import("mongoose").FlatRecord<ActionPromptConfig>, {}, import("mongoose").ResolveSchemaOptions<import("mongoose").DefaultSchemaOptions>> & import("mongoose").FlatRecord<ActionPromptConfig> & {
77
+ _id: Types.ObjectId;
78
+ } & {
79
+ __v: number;
80
+ }>;
63
81
  export declare const ACTION_STATUS_VALUES: readonly ["config", "inProgress", "finished", "archived", "cancelled"];
64
82
  export type ActionStatus = (typeof ACTION_STATUS_VALUES)[number];
65
83
  export declare class Action {
@@ -102,6 +120,7 @@ export declare class Action {
102
120
  tags?: Types.ObjectId[];
103
121
  businessUnit?: ActionBusinessUnit;
104
122
  campaign?: Types.ObjectId | Campaign;
123
+ promptConfig?: ActionPromptConfig | null;
105
124
  }
106
125
  export declare const ActionSchema: MongooseSchema<Action, import("mongoose").Model<Action, any, any, any, import("mongoose").Document<unknown, any, Action, any, {}> & Action & Required<{
107
126
  _id: Types.ObjectId;
@@ -9,7 +9,7 @@ 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.ActionModel = exports.ActionSchema = exports.Action = exports.ACTION_STATUS_VALUES = exports.ACTION_BUSINESS_UNIT_VALUES = exports.ResponsiblesSchema = exports.Responsibles = exports.ResponsibleSchema = exports.Responsible = void 0;
12
+ exports.ActionModel = exports.ActionSchema = exports.Action = exports.ACTION_STATUS_VALUES = exports.ActionPromptConfigSchema = exports.ActionPromptConfig = exports.ACTION_BUSINESS_UNIT_VALUES = exports.ResponsiblesSchema = exports.Responsibles = exports.ResponsibleSchema = exports.Responsible = 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");
@@ -64,6 +64,48 @@ exports.ACTION_BUSINESS_UNIT_VALUES = [
64
64
  'squad_a',
65
65
  'squad_b',
66
66
  ];
67
+ let ActionPromptConfig = class ActionPromptConfig {
68
+ };
69
+ __decorate([
70
+ (0, swagger_1.ApiProperty)({ required: false, description: 'Contexto da campanha (cliente, influencer, produto) para os prompts de classificação de comentário por IA' }),
71
+ (0, mongoose_1.Prop)({ type: String, required: false }),
72
+ __metadata("design:type", String)
73
+ ], ActionPromptConfig.prototype, "context", void 0);
74
+ __decorate([
75
+ (0, swagger_1.ApiProperty)({ required: false, description: 'Prompt customizado do estágio "alvo" (target)' }),
76
+ (0, mongoose_1.Prop)({ type: String, required: false }),
77
+ __metadata("design:type", String)
78
+ ], ActionPromptConfig.prototype, "targetPrompt", void 0);
79
+ __decorate([
80
+ (0, swagger_1.ApiProperty)({ required: false, description: 'Prompt customizado do estágio "assunto" (subject) para o grupo Influencer' }),
81
+ (0, mongoose_1.Prop)({ type: String, required: false }),
82
+ __metadata("design:type", String)
83
+ ], ActionPromptConfig.prototype, "influencerPrompt", void 0);
84
+ __decorate([
85
+ (0, swagger_1.ApiProperty)({ required: false, description: 'Prompt customizado do estágio "assunto" (subject) para o grupo Marca' }),
86
+ (0, mongoose_1.Prop)({ type: String, required: false }),
87
+ __metadata("design:type", String)
88
+ ], ActionPromptConfig.prototype, "brandPrompt", void 0);
89
+ __decorate([
90
+ (0, swagger_1.ApiProperty)({ required: false, description: 'Prompt customizado do estágio "assunto" (subject) para o grupo Conteúdo' }),
91
+ (0, mongoose_1.Prop)({ type: String, required: false }),
92
+ __metadata("design:type", String)
93
+ ], ActionPromptConfig.prototype, "contentPrompt", void 0);
94
+ __decorate([
95
+ (0, swagger_1.ApiProperty)({ required: false, description: 'Prompt customizado do estágio "polaridade" (polarity)' }),
96
+ (0, mongoose_1.Prop)({ type: String, required: false }),
97
+ __metadata("design:type", String)
98
+ ], ActionPromptConfig.prototype, "polarityPrompt", void 0);
99
+ __decorate([
100
+ (0, swagger_1.ApiProperty)({ required: false, description: 'Prompt customizado do estágio "funil" (funnel)' }),
101
+ (0, mongoose_1.Prop)({ type: String, required: false }),
102
+ __metadata("design:type", String)
103
+ ], ActionPromptConfig.prototype, "funnelPrompt", void 0);
104
+ ActionPromptConfig = __decorate([
105
+ (0, mongoose_1.Schema)({ _id: false })
106
+ ], ActionPromptConfig);
107
+ exports.ActionPromptConfig = ActionPromptConfig;
108
+ exports.ActionPromptConfigSchema = mongoose_1.SchemaFactory.createForClass(ActionPromptConfig);
67
109
  exports.ACTION_STATUS_VALUES = [
68
110
  'config',
69
111
  'inProgress',
@@ -283,6 +325,11 @@ __decorate([
283
325
  (0, mongoose_1.Prop)({ type: mongoose_2.Schema.Types.ObjectId, ref: 'Campaign', required: false }),
284
326
  __metadata("design:type", Object)
285
327
  ], Action.prototype, "campaign", void 0);
328
+ __decorate([
329
+ (0, swagger_1.ApiProperty)({ type: () => ActionPromptConfig, required: false, description: 'Customização de prompts de classificação de comentário por IA para esta action — campos ausentes caem no prompt genérico default' }),
330
+ (0, mongoose_1.Prop)({ type: exports.ActionPromptConfigSchema, required: false, default: null }),
331
+ __metadata("design:type", Object)
332
+ ], Action.prototype, "promptConfig", void 0);
286
333
  Action = __decorate([
287
334
  (0, mongoose_1.Schema)({ timestamps: true })
288
335
  ], Action);
@@ -27,6 +27,12 @@ import { HydratedDocument, Schema as MongooseSchema, Types } from 'mongoose';
27
27
  import { Content } from './content.schema';
28
28
  import { Action } from './action.schema';
29
29
  export type CommentDocument = HydratedDocument<Comment>;
30
+ export declare const COMMENT_TARGET_VALUES: readonly ["brand", "influencer", "content", "emoji", "spam"];
31
+ export type CommentTarget = (typeof COMMENT_TARGET_VALUES)[number];
32
+ export declare const COMMENT_SUBJECT_VALUES: readonly ["compliment_to_person", "criticism", "question", "brand_recognition", "influencer_response", "account", "reaction", "doubt", "about_story", "about_self", "competition", "customer_service", "tagged_someone", "other", "emoji_reaction"];
33
+ export type CommentSubject = (typeof COMMENT_SUBJECT_VALUES)[number];
34
+ export declare const COMMENT_CLASSIFICATION_STATUS_VALUES: readonly ["pending", "processing", "completed", "failed", "not_applicable"];
35
+ export type CommentClassificationStatus = (typeof COMMENT_CLASSIFICATION_STATUS_VALUES)[number];
30
36
  export declare class Comment {
31
37
  _id?: Types.ObjectId;
32
38
  content: Types.ObjectId | Content;
@@ -40,11 +46,16 @@ export declare class Comment {
40
46
  postedAt: Date;
41
47
  likeCount?: number;
42
48
  parent?: Types.ObjectId | Comment | null;
43
- target?: 'brand' | 'influencer' | 'content' | 'emoji' | 'spam' | null;
49
+ target?: CommentTarget | null;
50
+ subject?: CommentSubject | null;
44
51
  polarity?: 'positive' | 'negative' | 'neutral' | null;
45
- funnel?: 'awareness' | 'consideration' | 'conversion' | null;
52
+ funnel?: 'awareness' | 'consideration' | 'conversion' | 'none' | null;
46
53
  isEmojiOnly?: boolean;
47
54
  isSpam?: boolean;
55
+ classificationStatus?: CommentClassificationStatus;
56
+ classificationError?: string | null;
57
+ classificationProcessedAt?: Date | null;
58
+ sourceCommentId?: Types.ObjectId | Comment | null;
48
59
  createdAt?: Date;
49
60
  updatedAt?: Date;
50
61
  }
@@ -9,9 +9,34 @@ 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.CommentModel = exports.CommentSchema = exports.Comment = void 0;
12
+ exports.CommentModel = exports.CommentSchema = exports.Comment = exports.COMMENT_CLASSIFICATION_STATUS_VALUES = exports.COMMENT_SUBJECT_VALUES = exports.COMMENT_TARGET_VALUES = void 0;
13
13
  const mongoose_1 = require("@nestjs/mongoose");
14
14
  const mongoose_2 = require("mongoose");
15
+ exports.COMMENT_TARGET_VALUES = ['brand', 'influencer', 'content', 'emoji', 'spam'];
16
+ exports.COMMENT_SUBJECT_VALUES = [
17
+ 'compliment_to_person',
18
+ 'criticism',
19
+ 'question',
20
+ 'brand_recognition',
21
+ 'influencer_response',
22
+ 'account',
23
+ 'reaction',
24
+ 'doubt',
25
+ 'about_story',
26
+ 'about_self',
27
+ 'competition',
28
+ 'customer_service',
29
+ 'tagged_someone',
30
+ 'other',
31
+ 'emoji_reaction',
32
+ ];
33
+ exports.COMMENT_CLASSIFICATION_STATUS_VALUES = [
34
+ 'pending',
35
+ 'processing',
36
+ 'completed',
37
+ 'failed',
38
+ 'not_applicable',
39
+ ];
15
40
  let Comment = class Comment {
16
41
  };
17
42
  __decorate([
@@ -65,12 +90,21 @@ __decorate([
65
90
  __decorate([
66
91
  (0, mongoose_1.Prop)({
67
92
  type: String,
68
- enum: ['brand', 'influencer', 'content', 'emoji', 'spam'],
93
+ enum: exports.COMMENT_TARGET_VALUES,
69
94
  required: false,
70
95
  default: null,
71
96
  }),
72
97
  __metadata("design:type", Object)
73
98
  ], Comment.prototype, "target", void 0);
99
+ __decorate([
100
+ (0, mongoose_1.Prop)({
101
+ type: String,
102
+ enum: exports.COMMENT_SUBJECT_VALUES,
103
+ required: false,
104
+ default: null,
105
+ }),
106
+ __metadata("design:type", Object)
107
+ ], Comment.prototype, "subject", void 0);
74
108
  __decorate([
75
109
  (0, mongoose_1.Prop)({
76
110
  type: String,
@@ -83,7 +117,7 @@ __decorate([
83
117
  __decorate([
84
118
  (0, mongoose_1.Prop)({
85
119
  type: String,
86
- enum: ['awareness', 'consideration', 'conversion'],
120
+ enum: ['awareness', 'consideration', 'conversion', 'none'],
87
121
  required: false,
88
122
  default: null,
89
123
  }),
@@ -97,6 +131,27 @@ __decorate([
97
131
  (0, mongoose_1.Prop)({ type: Boolean, required: false, default: false }),
98
132
  __metadata("design:type", Boolean)
99
133
  ], Comment.prototype, "isSpam", void 0);
134
+ __decorate([
135
+ (0, mongoose_1.Prop)({
136
+ type: String,
137
+ enum: exports.COMMENT_CLASSIFICATION_STATUS_VALUES,
138
+ required: false,
139
+ default: 'pending',
140
+ }),
141
+ __metadata("design:type", String)
142
+ ], Comment.prototype, "classificationStatus", void 0);
143
+ __decorate([
144
+ (0, mongoose_1.Prop)({ type: String, required: false, default: null }),
145
+ __metadata("design:type", Object)
146
+ ], Comment.prototype, "classificationError", void 0);
147
+ __decorate([
148
+ (0, mongoose_1.Prop)({ type: Date, required: false, default: null }),
149
+ __metadata("design:type", Object)
150
+ ], Comment.prototype, "classificationProcessedAt", void 0);
151
+ __decorate([
152
+ (0, mongoose_1.Prop)({ type: mongoose_2.Schema.Types.ObjectId, ref: 'Comment', required: false, default: null }),
153
+ __metadata("design:type", Object)
154
+ ], Comment.prototype, "sourceCommentId", void 0);
100
155
  __decorate([
101
156
  (0, mongoose_1.Prop)({ default: Date.now, required: false }),
102
157
  __metadata("design:type", Date)
@@ -110,8 +165,13 @@ Comment = __decorate([
110
165
  ], Comment);
111
166
  exports.Comment = Comment;
112
167
  exports.CommentSchema = mongoose_1.SchemaFactory.createForClass(Comment);
113
- exports.CommentSchema.index({ content: 1, externalId: 1 }, { unique: true });
168
+ // partialFilterExpression não aceita $exists:false (só $exists:true) — usamos
169
+ // igualdade com null, que no Mongo casa tanto "campo ausente" quanto "campo
170
+ // null" (cobre o documento original, sem exigir que quem insere via
171
+ // bulkWrite raw declare sourceCommentId explicitamente).
172
+ exports.CommentSchema.index({ content: 1, externalId: 1 }, { unique: true, partialFilterExpression: { sourceCommentId: null } });
114
173
  exports.CommentSchema.index({ action: 1, funnel: 1 });
115
174
  exports.CommentSchema.index({ action: 1, target: 1 });
116
175
  exports.CommentSchema.index({ content: 1, parent: 1 });
176
+ exports.CommentSchema.index({ content: 1, classificationStatus: 1 });
117
177
  exports.CommentModel = (0, mongoose_2.model)('Comment', exports.CommentSchema);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grapadigital/shared-schemas",
3
- "version": "1.0.191",
3
+ "version": "1.0.193",
4
4
  "description": "Shared Mongoose Schemas",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -55,6 +55,39 @@ export const ACTION_BUSINESS_UNIT_VALUES = [
55
55
  ] as const;
56
56
  export type ActionBusinessUnit = (typeof ACTION_BUSINESS_UNIT_VALUES)[number];
57
57
 
58
+ @Schema({ _id: false })
59
+ export class ActionPromptConfig {
60
+ @ApiProperty({ required: false, description: 'Contexto da campanha (cliente, influencer, produto) para os prompts de classificação de comentário por IA' })
61
+ @Prop({ type: String, required: false })
62
+ context?: string;
63
+
64
+ @ApiProperty({ required: false, description: 'Prompt customizado do estágio "alvo" (target)' })
65
+ @Prop({ type: String, required: false })
66
+ targetPrompt?: string;
67
+
68
+ @ApiProperty({ required: false, description: 'Prompt customizado do estágio "assunto" (subject) para o grupo Influencer' })
69
+ @Prop({ type: String, required: false })
70
+ influencerPrompt?: string;
71
+
72
+ @ApiProperty({ required: false, description: 'Prompt customizado do estágio "assunto" (subject) para o grupo Marca' })
73
+ @Prop({ type: String, required: false })
74
+ brandPrompt?: string;
75
+
76
+ @ApiProperty({ required: false, description: 'Prompt customizado do estágio "assunto" (subject) para o grupo Conteúdo' })
77
+ @Prop({ type: String, required: false })
78
+ contentPrompt?: string;
79
+
80
+ @ApiProperty({ required: false, description: 'Prompt customizado do estágio "polaridade" (polarity)' })
81
+ @Prop({ type: String, required: false })
82
+ polarityPrompt?: string;
83
+
84
+ @ApiProperty({ required: false, description: 'Prompt customizado do estágio "funil" (funnel)' })
85
+ @Prop({ type: String, required: false })
86
+ funnelPrompt?: string;
87
+ }
88
+
89
+ export const ActionPromptConfigSchema = SchemaFactory.createForClass(ActionPromptConfig);
90
+
58
91
  export const ACTION_STATUS_VALUES = [
59
92
  'config',
60
93
  'inProgress',
@@ -236,6 +269,10 @@ export class Action {
236
269
  @ApiProperty({ type: () => Campaign, required: false })
237
270
  @Prop({ type: MongooseSchema.Types.ObjectId, ref: 'Campaign', required: false })
238
271
  campaign?: Types.ObjectId | Campaign;
272
+
273
+ @ApiProperty({ type: () => ActionPromptConfig, required: false, description: 'Customização de prompts de classificação de comentário por IA para esta action — campos ausentes caem no prompt genérico default' })
274
+ @Prop({ type: ActionPromptConfigSchema, required: false, default: null })
275
+ promptConfig?: ActionPromptConfig | null;
239
276
  }
240
277
 
241
278
  export const ActionSchema = SchemaFactory.createForClass(Action);
@@ -10,6 +10,37 @@ import { Action } from './action.schema';
10
10
 
11
11
  export type CommentDocument = HydratedDocument<Comment>;
12
12
 
13
+ export const COMMENT_TARGET_VALUES = ['brand', 'influencer', 'content', 'emoji', 'spam'] as const;
14
+ export type CommentTarget = (typeof COMMENT_TARGET_VALUES)[number];
15
+
16
+ export const COMMENT_SUBJECT_VALUES = [
17
+ 'compliment_to_person',
18
+ 'criticism',
19
+ 'question',
20
+ 'brand_recognition',
21
+ 'influencer_response',
22
+ 'account',
23
+ 'reaction',
24
+ 'doubt',
25
+ 'about_story',
26
+ 'about_self',
27
+ 'competition',
28
+ 'customer_service',
29
+ 'tagged_someone',
30
+ 'other',
31
+ 'emoji_reaction',
32
+ ] as const;
33
+ export type CommentSubject = (typeof COMMENT_SUBJECT_VALUES)[number];
34
+
35
+ export const COMMENT_CLASSIFICATION_STATUS_VALUES = [
36
+ 'pending',
37
+ 'processing',
38
+ 'completed',
39
+ 'failed',
40
+ 'not_applicable',
41
+ ] as const;
42
+ export type CommentClassificationStatus = (typeof COMMENT_CLASSIFICATION_STATUS_VALUES)[number];
43
+
13
44
  @Schema({ timestamps: true })
14
45
  export class Comment {
15
46
  @Prop({ type: MongooseSchema.Types.ObjectId, auto: true, required: false })
@@ -50,11 +81,19 @@ export class Comment {
50
81
 
51
82
  @Prop({
52
83
  type: String,
53
- enum: ['brand', 'influencer', 'content', 'emoji', 'spam'],
84
+ enum: COMMENT_TARGET_VALUES,
54
85
  required: false,
55
86
  default: null,
56
87
  })
57
- target?: 'brand' | 'influencer' | 'content' | 'emoji' | 'spam' | null;
88
+ target?: CommentTarget | null;
89
+
90
+ @Prop({
91
+ type: String,
92
+ enum: COMMENT_SUBJECT_VALUES,
93
+ required: false,
94
+ default: null,
95
+ })
96
+ subject?: CommentSubject | null;
58
97
 
59
98
  @Prop({
60
99
  type: String,
@@ -66,11 +105,11 @@ export class Comment {
66
105
 
67
106
  @Prop({
68
107
  type: String,
69
- enum: ['awareness', 'consideration', 'conversion'],
108
+ enum: ['awareness', 'consideration', 'conversion', 'none'],
70
109
  required: false,
71
110
  default: null,
72
111
  })
73
- funnel?: 'awareness' | 'consideration' | 'conversion' | null;
112
+ funnel?: 'awareness' | 'consideration' | 'conversion' | 'none' | null;
74
113
 
75
114
  @Prop({ type: Boolean, required: false, default: false })
76
115
  isEmojiOnly?: boolean;
@@ -78,6 +117,23 @@ export class Comment {
78
117
  @Prop({ type: Boolean, required: false, default: false })
79
118
  isSpam?: boolean;
80
119
 
120
+ @Prop({
121
+ type: String,
122
+ enum: COMMENT_CLASSIFICATION_STATUS_VALUES,
123
+ required: false,
124
+ default: 'pending',
125
+ })
126
+ classificationStatus?: CommentClassificationStatus;
127
+
128
+ @Prop({ type: String, required: false, default: null })
129
+ classificationError?: string | null;
130
+
131
+ @Prop({ type: Date, required: false, default: null })
132
+ classificationProcessedAt?: Date | null;
133
+
134
+ @Prop({ type: MongooseSchema.Types.ObjectId, ref: 'Comment', required: false, default: null })
135
+ sourceCommentId?: Types.ObjectId | Comment | null;
136
+
81
137
  @Prop({ default: Date.now, required: false })
82
138
  createdAt?: Date;
83
139
 
@@ -87,9 +143,17 @@ export class Comment {
87
143
 
88
144
  export const CommentSchema = SchemaFactory.createForClass(Comment);
89
145
 
90
- CommentSchema.index({ content: 1, externalId: 1 }, { unique: true });
146
+ // partialFilterExpression não aceita $exists:false (só $exists:true) — usamos
147
+ // igualdade com null, que no Mongo casa tanto "campo ausente" quanto "campo
148
+ // null" (cobre o documento original, sem exigir que quem insere via
149
+ // bulkWrite raw declare sourceCommentId explicitamente).
150
+ CommentSchema.index(
151
+ { content: 1, externalId: 1 },
152
+ { unique: true, partialFilterExpression: { sourceCommentId: null } },
153
+ );
91
154
  CommentSchema.index({ action: 1, funnel: 1 });
92
155
  CommentSchema.index({ action: 1, target: 1 });
93
156
  CommentSchema.index({ content: 1, parent: 1 });
157
+ CommentSchema.index({ content: 1, classificationStatus: 1 });
94
158
 
95
159
  export const CommentModel = MongooseModel('Comment', CommentSchema);