@grapadigital/shared-schemas 1.0.183 → 1.0.185

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.
@@ -0,0 +1,274 @@
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.ScriptModel = exports.ScriptSchema = exports.Script = exports.ScriptVersionSchema = exports.ScriptVersion = exports.ScriptStaffReplySchema = exports.ScriptStaffReply = exports.ScriptDecisionSchema = exports.ScriptDecision = exports.SCRIPT_DECISION_VALUES = exports.SCRIPT_STATUS_VALUES = void 0;
13
+ const mongoose_1 = require("@nestjs/mongoose");
14
+ const swagger_1 = require("@nestjs/swagger");
15
+ const mongoose_2 = require("mongoose");
16
+ const action_schema_1 = require("./action.schema");
17
+ const client_schema_1 = require("./client.schema");
18
+ const profile_schema_1 = require("./profile.schema");
19
+ const task_schema_1 = require("./task.schema");
20
+ exports.SCRIPT_STATUS_VALUES = [
21
+ 'draft',
22
+ 'pending',
23
+ 'approved',
24
+ 'reproved',
25
+ ];
26
+ exports.SCRIPT_DECISION_VALUES = [
27
+ 'approved',
28
+ 'reproved',
29
+ 'questioned',
30
+ ];
31
+ let ScriptDecision = class ScriptDecision {
32
+ };
33
+ __decorate([
34
+ (0, swagger_1.ApiProperty)({ enum: exports.SCRIPT_DECISION_VALUES }),
35
+ (0, mongoose_1.Prop)({ type: String, enum: exports.SCRIPT_DECISION_VALUES, required: true }),
36
+ __metadata("design:type", String)
37
+ ], ScriptDecision.prototype, "decision", void 0);
38
+ __decorate([
39
+ (0, swagger_1.ApiProperty)({ required: false }),
40
+ (0, mongoose_1.Prop)({ type: String, required: false }),
41
+ __metadata("design:type", String)
42
+ ], ScriptDecision.prototype, "comment", void 0);
43
+ __decorate([
44
+ (0, swagger_1.ApiProperty)({ description: 'Time do cliente que respondeu, lido do JWT' }),
45
+ (0, mongoose_1.Prop)({ type: String, required: true }),
46
+ __metadata("design:type", String)
47
+ ], ScriptDecision.prototype, "team", void 0);
48
+ __decorate([
49
+ (0, swagger_1.ApiProperty)(),
50
+ (0, mongoose_1.Prop)({ type: String, required: true }),
51
+ __metadata("design:type", String)
52
+ ], ScriptDecision.prototype, "respondedBy", void 0);
53
+ __decorate([
54
+ (0, swagger_1.ApiProperty)(),
55
+ (0, mongoose_1.Prop)({ type: Date, required: true }),
56
+ __metadata("design:type", Date)
57
+ ], ScriptDecision.prototype, "respondedAt", void 0);
58
+ ScriptDecision = __decorate([
59
+ (0, mongoose_1.Schema)({ _id: false })
60
+ ], ScriptDecision);
61
+ exports.ScriptDecision = ScriptDecision;
62
+ exports.ScriptDecisionSchema = mongoose_1.SchemaFactory.createForClass(ScriptDecision);
63
+ let ScriptStaffReply = class ScriptStaffReply {
64
+ };
65
+ __decorate([
66
+ (0, swagger_1.ApiProperty)(),
67
+ (0, mongoose_1.Prop)({ type: String, required: true }),
68
+ __metadata("design:type", String)
69
+ ], ScriptStaffReply.prototype, "message", void 0);
70
+ __decorate([
71
+ (0, swagger_1.ApiProperty)(),
72
+ (0, mongoose_1.Prop)({ type: String, required: true }),
73
+ __metadata("design:type", String)
74
+ ], ScriptStaffReply.prototype, "repliedBy", void 0);
75
+ __decorate([
76
+ (0, swagger_1.ApiProperty)(),
77
+ (0, mongoose_1.Prop)({ type: Date, required: true }),
78
+ __metadata("design:type", Date)
79
+ ], ScriptStaffReply.prototype, "repliedAt", void 0);
80
+ ScriptStaffReply = __decorate([
81
+ (0, mongoose_1.Schema)({ _id: false })
82
+ ], ScriptStaffReply);
83
+ exports.ScriptStaffReply = ScriptStaffReply;
84
+ exports.ScriptStaffReplySchema = mongoose_1.SchemaFactory.createForClass(ScriptStaffReply);
85
+ let ScriptVersion = class ScriptVersion {
86
+ };
87
+ __decorate([
88
+ (0, swagger_1.ApiProperty)(),
89
+ (0, mongoose_1.Prop)({ type: Number, required: true }),
90
+ __metadata("design:type", Number)
91
+ ], ScriptVersion.prototype, "version", void 0);
92
+ __decorate([
93
+ (0, swagger_1.ApiProperty)({ required: false }),
94
+ (0, mongoose_1.Prop)({ type: String, required: false, default: null }),
95
+ __metadata("design:type", Object)
96
+ ], ScriptVersion.prototype, "fileUrl", void 0);
97
+ __decorate([
98
+ (0, swagger_1.ApiProperty)({ required: false }),
99
+ (0, mongoose_1.Prop)({ type: String, required: false, default: null }),
100
+ __metadata("design:type", Object)
101
+ ], ScriptVersion.prototype, "fileName", void 0);
102
+ __decorate([
103
+ (0, swagger_1.ApiProperty)({ required: false }),
104
+ (0, mongoose_1.Prop)({ type: String, required: false, default: null }),
105
+ __metadata("design:type", Object)
106
+ ], ScriptVersion.prototype, "link", void 0);
107
+ __decorate([
108
+ (0, swagger_1.ApiProperty)({ enum: ['approved', 'reproved'] }),
109
+ (0, mongoose_1.Prop)({ type: String, enum: ['approved', 'reproved'], required: true }),
110
+ __metadata("design:type", String)
111
+ ], ScriptVersion.prototype, "status", void 0);
112
+ __decorate([
113
+ (0, swagger_1.ApiProperty)({ required: false }),
114
+ (0, mongoose_1.Prop)({ type: String, required: false }),
115
+ __metadata("design:type", String)
116
+ ], ScriptVersion.prototype, "submittedBy", void 0);
117
+ __decorate([
118
+ (0, swagger_1.ApiProperty)({ required: false }),
119
+ (0, mongoose_1.Prop)({ type: Date, required: false }),
120
+ __metadata("design:type", Date)
121
+ ], ScriptVersion.prototype, "submittedAt", void 0);
122
+ __decorate([
123
+ (0, swagger_1.ApiProperty)({ type: () => [ScriptDecision] }),
124
+ (0, mongoose_1.Prop)({ type: [exports.ScriptDecisionSchema], default: [] }),
125
+ __metadata("design:type", Array)
126
+ ], ScriptVersion.prototype, "decisions", void 0);
127
+ __decorate([
128
+ (0, swagger_1.ApiProperty)({ type: () => [ScriptStaffReply] }),
129
+ (0, mongoose_1.Prop)({ type: [exports.ScriptStaffReplySchema], default: [] }),
130
+ __metadata("design:type", Array)
131
+ ], ScriptVersion.prototype, "staffReplies", void 0);
132
+ __decorate([
133
+ (0, swagger_1.ApiProperty)(),
134
+ (0, mongoose_1.Prop)({ type: Date, required: true }),
135
+ __metadata("design:type", Date)
136
+ ], ScriptVersion.prototype, "archivedAt", void 0);
137
+ ScriptVersion = __decorate([
138
+ (0, mongoose_1.Schema)({ _id: false })
139
+ ], ScriptVersion);
140
+ exports.ScriptVersion = ScriptVersion;
141
+ exports.ScriptVersionSchema = mongoose_1.SchemaFactory.createForClass(ScriptVersion);
142
+ /**
143
+ * Aprovação de roteiro: um documento por (action, profile, deliverableType,
144
+ * deliverableIndex) — não um doc único por Ação. A versão mora no mesmo doc;
145
+ * ao reprovar, o estado atual é arquivado em `versions[]` e o doc volta a
146
+ * `draft` para uma nova tentativa (ver GD-532).
147
+ */
148
+ let Script = class Script {
149
+ };
150
+ __decorate([
151
+ (0, swagger_1.ApiProperty)(),
152
+ (0, mongoose_1.Prop)({ type: mongoose_2.Schema.Types.ObjectId, auto: true, required: false }),
153
+ __metadata("design:type", mongoose_2.Types.ObjectId)
154
+ ], Script.prototype, "_id", void 0);
155
+ __decorate([
156
+ (0, swagger_1.ApiProperty)({ type: () => action_schema_1.Action }),
157
+ (0, mongoose_1.Prop)({ type: mongoose_2.Schema.Types.ObjectId, ref: 'Action', required: true }),
158
+ __metadata("design:type", Object)
159
+ ], Script.prototype, "action", void 0);
160
+ __decorate([
161
+ (0, swagger_1.ApiProperty)({ type: () => client_schema_1.Client }),
162
+ (0, mongoose_1.Prop)({ type: mongoose_2.Schema.Types.ObjectId, ref: 'Client', required: false }),
163
+ __metadata("design:type", Object)
164
+ ], Script.prototype, "client", void 0);
165
+ __decorate([
166
+ (0, swagger_1.ApiProperty)({ type: () => profile_schema_1.Profile }),
167
+ (0, mongoose_1.Prop)({ type: mongoose_2.Schema.Types.ObjectId, ref: 'Profile', required: true }),
168
+ __metadata("design:type", Object)
169
+ ], Script.prototype, "profile", void 0);
170
+ __decorate([
171
+ (0, swagger_1.ApiProperty)({
172
+ enum: task_schema_1.TASK_FORMAT_VALUES,
173
+ description: 'Unidade de entrega do escopo (mesmos valores de recruitment.scope.delivery)',
174
+ }),
175
+ (0, mongoose_1.Prop)({ type: String, enum: task_schema_1.TASK_FORMAT_VALUES, required: true }),
176
+ __metadata("design:type", String)
177
+ ], Script.prototype, "deliverableType", void 0);
178
+ __decorate([
179
+ (0, swagger_1.ApiProperty)({
180
+ description: 'Ex.: 1 de 2 quando o escopo pede mais de uma unidade do mesmo tipo; sempre 1 para "story"',
181
+ }),
182
+ (0, mongoose_1.Prop)({ type: Number, required: true, default: 1 }),
183
+ __metadata("design:type", Number)
184
+ ], Script.prototype, "deliverableIndex", void 0);
185
+ __decorate([
186
+ (0, swagger_1.ApiProperty)(),
187
+ (0, mongoose_1.Prop)({ type: Number, required: true, default: 1 }),
188
+ __metadata("design:type", Number)
189
+ ], Script.prototype, "version", void 0);
190
+ __decorate([
191
+ (0, swagger_1.ApiProperty)({ required: false }),
192
+ (0, mongoose_1.Prop)({ type: String, required: false, default: null }),
193
+ __metadata("design:type", Object)
194
+ ], Script.prototype, "fileUrl", void 0);
195
+ __decorate([
196
+ (0, swagger_1.ApiProperty)({ required: false }),
197
+ (0, mongoose_1.Prop)({ type: String, required: false, default: null }),
198
+ __metadata("design:type", Object)
199
+ ], Script.prototype, "fileName", void 0);
200
+ __decorate([
201
+ (0, swagger_1.ApiProperty)({
202
+ required: false,
203
+ description: 'Alternativa ao arquivo — staff usa arquivo OU link',
204
+ }),
205
+ (0, mongoose_1.Prop)({ type: String, required: false, default: null }),
206
+ __metadata("design:type", Object)
207
+ ], Script.prototype, "link", void 0);
208
+ __decorate([
209
+ (0, swagger_1.ApiProperty)({ enum: exports.SCRIPT_STATUS_VALUES }),
210
+ (0, mongoose_1.Prop)({
211
+ type: String,
212
+ enum: exports.SCRIPT_STATUS_VALUES,
213
+ required: true,
214
+ default: 'draft',
215
+ }),
216
+ __metadata("design:type", String)
217
+ ], Script.prototype, "status", void 0);
218
+ __decorate([
219
+ (0, swagger_1.ApiProperty)({
220
+ type: [String],
221
+ description: 'Snapshot de Client.requiredTeams no momento da criação — vazio = 1 aprovação resolve; com times = todos precisam aprovar',
222
+ }),
223
+ (0, mongoose_1.Prop)({ type: [String], required: false, default: [] }),
224
+ __metadata("design:type", Array)
225
+ ], Script.prototype, "requiredTeams", void 0);
226
+ __decorate([
227
+ (0, swagger_1.ApiProperty)({ required: false }),
228
+ (0, mongoose_1.Prop)({ type: String, required: false }),
229
+ __metadata("design:type", String)
230
+ ], Script.prototype, "submittedBy", void 0);
231
+ __decorate([
232
+ (0, swagger_1.ApiProperty)({ required: false }),
233
+ (0, mongoose_1.Prop)({ type: Date, required: false }),
234
+ __metadata("design:type", Date)
235
+ ], Script.prototype, "submittedAt", void 0);
236
+ __decorate([
237
+ (0, swagger_1.ApiProperty)({ type: () => [ScriptDecision] }),
238
+ (0, mongoose_1.Prop)({ type: [exports.ScriptDecisionSchema], default: [] }),
239
+ __metadata("design:type", Array)
240
+ ], Script.prototype, "decisions", void 0);
241
+ __decorate([
242
+ (0, swagger_1.ApiProperty)({ type: () => [ScriptStaffReply] }),
243
+ (0, mongoose_1.Prop)({ type: [exports.ScriptStaffReplySchema], default: [] }),
244
+ __metadata("design:type", Array)
245
+ ], Script.prototype, "staffReplies", void 0);
246
+ __decorate([
247
+ (0, swagger_1.ApiProperty)({ type: () => [ScriptVersion] }),
248
+ (0, mongoose_1.Prop)({ type: [exports.ScriptVersionSchema], default: [] }),
249
+ __metadata("design:type", Array)
250
+ ], Script.prototype, "versions", void 0);
251
+ __decorate([
252
+ (0, mongoose_1.Prop)({ type: mongoose_2.Schema.Types.ObjectId, required: false }),
253
+ __metadata("design:type", mongoose_2.Types.ObjectId)
254
+ ], Script.prototype, "organization", void 0);
255
+ __decorate([
256
+ (0, swagger_1.ApiProperty)(),
257
+ (0, mongoose_1.Prop)({ default: Date.now, required: false }),
258
+ __metadata("design:type", Date)
259
+ ], Script.prototype, "createdAt", void 0);
260
+ __decorate([
261
+ (0, swagger_1.ApiProperty)(),
262
+ (0, mongoose_1.Prop)({ default: Date.now, required: false }),
263
+ __metadata("design:type", Date)
264
+ ], Script.prototype, "updatedAt", void 0);
265
+ Script = __decorate([
266
+ (0, mongoose_1.Schema)({ timestamps: true })
267
+ ], Script);
268
+ exports.Script = Script;
269
+ exports.ScriptSchema = mongoose_1.SchemaFactory.createForClass(Script);
270
+ exports.ScriptSchema.index({ action: 1, profile: 1, deliverableType: 1, deliverableIndex: 1 }, { unique: true });
271
+ exports.ScriptSchema.index({ action: 1, status: 1 });
272
+ exports.ScriptSchema.index({ client: 1, status: 1 });
273
+ exports.ScriptSchema.index({ organization: 1, status: 1 });
274
+ exports.ScriptModel = (0, mongoose_2.model)('Script', exports.ScriptSchema);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grapadigital/shared-schemas",
3
- "version": "1.0.183",
3
+ "version": "1.0.185",
4
4
  "description": "Shared Mongoose Schemas",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/index.ts CHANGED
@@ -8,6 +8,8 @@ export * from './schemas/payment.schema';
8
8
  export * from './schemas/profile.schema';
9
9
  export * from './schemas/recruitment.schema';
10
10
  export * from './schemas/task.schema';
11
+ export * from './schemas/script.schema';
12
+ export * from './schemas/creative.schema';
11
13
  export * from './schemas/assignment.schema';
12
14
  export * from './schemas/token.schema';
13
15
  export * from './schemas/webhook.schema';
@@ -94,6 +94,14 @@ export class Client extends Party {
94
94
 
95
95
  @Prop({ type: [AgencyCommissionPeriodSchema], default: [] })
96
96
  agencyCommission: AgencyCommissionPeriod[];
97
+
98
+ /**
99
+ * Times obrigatórios pra aprovação de Roteiro/Conteúdo (ex.: Samsung
100
+ * exige Influência+Marcom+Produto). Vazio = 1 aprovação de qualquer
101
+ * time já resolve (padrão da maioria dos clientes). Ver GD-532/GD-535.
102
+ */
103
+ @Prop({ type: [String], default: [] })
104
+ requiredTeams: string[];
97
105
  }
98
106
 
99
107
  export const ClientSchema = SchemaFactory.createForClass(Client);
@@ -0,0 +1,256 @@
1
+ import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
2
+ import { ApiProperty } from '@nestjs/swagger';
3
+ import {
4
+ HydratedDocument,
5
+ Schema as MongooseSchema,
6
+ Types,
7
+ model as MongooseModel,
8
+ } from 'mongoose';
9
+
10
+ import { Action } from './action.schema';
11
+ import { Client } from './client.schema';
12
+ import { Profile } from './profile.schema';
13
+ import { TASK_FORMAT_VALUES, TaskFormat } from './task.schema';
14
+
15
+ export type CreativeDocument = HydratedDocument<Creative>;
16
+
17
+ export const CREATIVE_STATUS_VALUES = [
18
+ 'draft',
19
+ 'pending',
20
+ 'approved',
21
+ 'reproved',
22
+ ] as const;
23
+ export type CreativeStatus = (typeof CREATIVE_STATUS_VALUES)[number];
24
+
25
+ export const CREATIVE_DECISION_VALUES = [
26
+ 'approved',
27
+ 'reproved',
28
+ 'questioned',
29
+ ] as const;
30
+ export type CreativeDecisionValue = (typeof CREATIVE_DECISION_VALUES)[number];
31
+
32
+ export const CREATIVE_MEDIA_TYPE_VALUES = ['image', 'video'] as const;
33
+ export type CreativeMediaType = (typeof CREATIVE_MEDIA_TYPE_VALUES)[number];
34
+
35
+ @Schema({ _id: false })
36
+ export class CreativeDecision {
37
+ @ApiProperty({ enum: CREATIVE_DECISION_VALUES })
38
+ @Prop({ type: String, enum: CREATIVE_DECISION_VALUES, required: true })
39
+ decision: CreativeDecisionValue;
40
+
41
+ @ApiProperty({ required: false })
42
+ @Prop({ type: String, required: false })
43
+ comment?: string;
44
+
45
+ @ApiProperty({ description: 'Time do cliente que respondeu, lido do JWT' })
46
+ @Prop({ type: String, required: true })
47
+ team: string;
48
+
49
+ @ApiProperty()
50
+ @Prop({ type: String, required: true })
51
+ respondedBy: string;
52
+
53
+ @ApiProperty()
54
+ @Prop({ type: Date, required: true })
55
+ respondedAt: Date;
56
+ }
57
+
58
+ export const CreativeDecisionSchema =
59
+ SchemaFactory.createForClass(CreativeDecision);
60
+
61
+ @Schema({ _id: false })
62
+ export class CreativeStaffReply {
63
+ @ApiProperty()
64
+ @Prop({ type: String, required: true })
65
+ message: string;
66
+
67
+ @ApiProperty()
68
+ @Prop({ type: String, required: true })
69
+ repliedBy: string;
70
+
71
+ @ApiProperty()
72
+ @Prop({ type: Date, required: true })
73
+ repliedAt: Date;
74
+ }
75
+
76
+ export const CreativeStaffReplySchema =
77
+ SchemaFactory.createForClass(CreativeStaffReply);
78
+
79
+ @Schema({ _id: false })
80
+ export class CreativeVersion {
81
+ @ApiProperty()
82
+ @Prop({ type: Number, required: true })
83
+ version: number;
84
+
85
+ @ApiProperty({ required: false })
86
+ @Prop({ type: String, required: false, default: null })
87
+ fileUrl?: string | null;
88
+
89
+ @ApiProperty({ required: false })
90
+ @Prop({ type: String, required: false, default: null })
91
+ fileName?: string | null;
92
+
93
+ @ApiProperty({ enum: CREATIVE_MEDIA_TYPE_VALUES, required: false })
94
+ @Prop({
95
+ type: String,
96
+ enum: CREATIVE_MEDIA_TYPE_VALUES,
97
+ required: false,
98
+ default: null,
99
+ })
100
+ mediaType?: CreativeMediaType | null;
101
+
102
+ @ApiProperty({ required: false })
103
+ @Prop({ type: String, required: false, default: null })
104
+ caption?: string | null;
105
+
106
+ @ApiProperty({ enum: ['approved', 'reproved'] })
107
+ @Prop({ type: String, enum: ['approved', 'reproved'], required: true })
108
+ status: 'approved' | 'reproved';
109
+
110
+ @ApiProperty({ required: false })
111
+ @Prop({ type: String, required: false })
112
+ submittedBy?: string;
113
+
114
+ @ApiProperty({ required: false })
115
+ @Prop({ type: Date, required: false })
116
+ submittedAt?: Date;
117
+
118
+ @ApiProperty({ type: () => [CreativeDecision] })
119
+ @Prop({ type: [CreativeDecisionSchema], default: [] })
120
+ decisions: CreativeDecision[];
121
+
122
+ @ApiProperty({ type: () => [CreativeStaffReply] })
123
+ @Prop({ type: [CreativeStaffReplySchema], default: [] })
124
+ staffReplies: CreativeStaffReply[];
125
+
126
+ @ApiProperty()
127
+ @Prop({ type: Date, required: true })
128
+ archivedAt: Date;
129
+ }
130
+
131
+ export const CreativeVersionSchema =
132
+ SchemaFactory.createForClass(CreativeVersion);
133
+
134
+ /**
135
+ * Aprovação de conteúdo (prévia final): um documento por (action, profile,
136
+ * deliverableType, deliverableIndex) — não um doc único por Ação. Mesmo
137
+ * padrão de `Script` (ver GD-532); ao reprovar, o estado atual é arquivado em
138
+ * `versions[]` e o doc fica em `reproved` até o staff editar e reenviar
139
+ * (ver GD-537).
140
+ */
141
+ @Schema({ timestamps: true })
142
+ export class Creative {
143
+ @ApiProperty()
144
+ @Prop({ type: MongooseSchema.Types.ObjectId, auto: true, required: false })
145
+ _id?: Types.ObjectId;
146
+
147
+ @ApiProperty({ type: () => Action })
148
+ @Prop({ type: MongooseSchema.Types.ObjectId, ref: 'Action', required: true })
149
+ action: Types.ObjectId | Action;
150
+
151
+ @ApiProperty({ type: () => Client })
152
+ @Prop({ type: MongooseSchema.Types.ObjectId, ref: 'Client', required: false })
153
+ client?: Types.ObjectId | Client;
154
+
155
+ @ApiProperty({ type: () => Profile })
156
+ @Prop({ type: MongooseSchema.Types.ObjectId, ref: 'Profile', required: true })
157
+ profile: Types.ObjectId | Profile;
158
+
159
+ @ApiProperty({
160
+ enum: TASK_FORMAT_VALUES,
161
+ description: 'Unidade de entrega do escopo (mesmos valores de recruitment.scope.delivery)',
162
+ })
163
+ @Prop({ type: String, enum: TASK_FORMAT_VALUES, required: true })
164
+ deliverableType: TaskFormat;
165
+
166
+ @ApiProperty({
167
+ description: 'Ex.: 1 de 2 quando o escopo pede mais de uma unidade do mesmo tipo; sempre 1 para "story"',
168
+ })
169
+ @Prop({ type: Number, required: true, default: 1 })
170
+ deliverableIndex: number;
171
+
172
+ @ApiProperty()
173
+ @Prop({ type: Number, required: true, default: 1 })
174
+ version: number;
175
+
176
+ @ApiProperty({ required: false })
177
+ @Prop({ type: String, required: false, default: null })
178
+ fileUrl?: string | null;
179
+
180
+ @ApiProperty({ required: false })
181
+ @Prop({ type: String, required: false, default: null })
182
+ fileName?: string | null;
183
+
184
+ @ApiProperty({ enum: CREATIVE_MEDIA_TYPE_VALUES, required: false })
185
+ @Prop({
186
+ type: String,
187
+ enum: CREATIVE_MEDIA_TYPE_VALUES,
188
+ required: false,
189
+ default: null,
190
+ })
191
+ mediaType?: CreativeMediaType | null;
192
+
193
+ @ApiProperty({ required: false, description: 'Legenda, campo separado do arquivo' })
194
+ @Prop({ type: String, required: false, default: null })
195
+ caption?: string | null;
196
+
197
+ @ApiProperty({ enum: CREATIVE_STATUS_VALUES })
198
+ @Prop({
199
+ type: String,
200
+ enum: CREATIVE_STATUS_VALUES,
201
+ required: true,
202
+ default: 'draft',
203
+ })
204
+ status: CreativeStatus;
205
+
206
+ @ApiProperty({
207
+ type: [String],
208
+ description:
209
+ 'Snapshot de Client.requiredTeams no momento da criação — vazio = 1 aprovação resolve; com times = todos precisam aprovar',
210
+ })
211
+ @Prop({ type: [String], required: false, default: [] })
212
+ requiredTeams: string[];
213
+
214
+ @ApiProperty({ required: false })
215
+ @Prop({ type: String, required: false })
216
+ submittedBy?: string;
217
+
218
+ @ApiProperty({ required: false })
219
+ @Prop({ type: Date, required: false })
220
+ submittedAt?: Date;
221
+
222
+ @ApiProperty({ type: () => [CreativeDecision] })
223
+ @Prop({ type: [CreativeDecisionSchema], default: [] })
224
+ decisions: CreativeDecision[];
225
+
226
+ @ApiProperty({ type: () => [CreativeStaffReply] })
227
+ @Prop({ type: [CreativeStaffReplySchema], default: [] })
228
+ staffReplies: CreativeStaffReply[];
229
+
230
+ @ApiProperty({ type: () => [CreativeVersion] })
231
+ @Prop({ type: [CreativeVersionSchema], default: [] })
232
+ versions: CreativeVersion[];
233
+
234
+ @Prop({ type: MongooseSchema.Types.ObjectId, required: false })
235
+ organization?: Types.ObjectId;
236
+
237
+ @ApiProperty()
238
+ @Prop({ default: Date.now, required: false })
239
+ createdAt?: Date;
240
+
241
+ @ApiProperty()
242
+ @Prop({ default: Date.now, required: false })
243
+ updatedAt?: Date;
244
+ }
245
+
246
+ export const CreativeSchema = SchemaFactory.createForClass(Creative);
247
+
248
+ CreativeSchema.index(
249
+ { action: 1, profile: 1, deliverableType: 1, deliverableIndex: 1 },
250
+ { unique: true },
251
+ );
252
+ CreativeSchema.index({ action: 1, status: 1 });
253
+ CreativeSchema.index({ client: 1, status: 1 });
254
+ CreativeSchema.index({ organization: 1, status: 1 });
255
+
256
+ export const CreativeModel = MongooseModel('Creative', CreativeSchema);
@@ -28,9 +28,10 @@ export class Log {
28
28
  'sale',
29
29
  'invoice',
30
30
  'payment',
31
+ 'assignment',
31
32
  ],
32
33
  })
33
- reference: 'action' | 'recruitment' | 'content' | 'contract' | 'sale' | 'invoice' | 'payment';
34
+ reference: 'action' | 'recruitment' | 'content' | 'contract' | 'sale' | 'invoice' | 'payment' | 'assignment';
34
35
 
35
36
  @Prop({
36
37
  required: true,