@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,235 @@
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 ScriptDocument = HydratedDocument<Script>;
16
+
17
+ export const SCRIPT_STATUS_VALUES = [
18
+ 'draft',
19
+ 'pending',
20
+ 'approved',
21
+ 'reproved',
22
+ ] as const;
23
+ export type ScriptStatus = (typeof SCRIPT_STATUS_VALUES)[number];
24
+
25
+ export const SCRIPT_DECISION_VALUES = [
26
+ 'approved',
27
+ 'reproved',
28
+ 'questioned',
29
+ ] as const;
30
+ export type ScriptDecisionValue = (typeof SCRIPT_DECISION_VALUES)[number];
31
+
32
+ @Schema({ _id: false })
33
+ export class ScriptDecision {
34
+ @ApiProperty({ enum: SCRIPT_DECISION_VALUES })
35
+ @Prop({ type: String, enum: SCRIPT_DECISION_VALUES, required: true })
36
+ decision: ScriptDecisionValue;
37
+
38
+ @ApiProperty({ required: false })
39
+ @Prop({ type: String, required: false })
40
+ comment?: string;
41
+
42
+ @ApiProperty({ description: 'Time do cliente que respondeu, lido do JWT' })
43
+ @Prop({ type: String, required: true })
44
+ team: string;
45
+
46
+ @ApiProperty()
47
+ @Prop({ type: String, required: true })
48
+ respondedBy: string;
49
+
50
+ @ApiProperty()
51
+ @Prop({ type: Date, required: true })
52
+ respondedAt: Date;
53
+ }
54
+
55
+ export const ScriptDecisionSchema = SchemaFactory.createForClass(ScriptDecision);
56
+
57
+ @Schema({ _id: false })
58
+ export class ScriptStaffReply {
59
+ @ApiProperty()
60
+ @Prop({ type: String, required: true })
61
+ message: string;
62
+
63
+ @ApiProperty()
64
+ @Prop({ type: String, required: true })
65
+ repliedBy: string;
66
+
67
+ @ApiProperty()
68
+ @Prop({ type: Date, required: true })
69
+ repliedAt: Date;
70
+ }
71
+
72
+ export const ScriptStaffReplySchema =
73
+ SchemaFactory.createForClass(ScriptStaffReply);
74
+
75
+ @Schema({ _id: false })
76
+ export class ScriptVersion {
77
+ @ApiProperty()
78
+ @Prop({ type: Number, required: true })
79
+ version: number;
80
+
81
+ @ApiProperty({ required: false })
82
+ @Prop({ type: String, required: false, default: null })
83
+ fileUrl?: string | null;
84
+
85
+ @ApiProperty({ required: false })
86
+ @Prop({ type: String, required: false, default: null })
87
+ fileName?: string | null;
88
+
89
+ @ApiProperty({ required: false })
90
+ @Prop({ type: String, required: false, default: null })
91
+ link?: string | null;
92
+
93
+ @ApiProperty({ enum: ['approved', 'reproved'] })
94
+ @Prop({ type: String, enum: ['approved', 'reproved'], required: true })
95
+ status: 'approved' | 'reproved';
96
+
97
+ @ApiProperty({ required: false })
98
+ @Prop({ type: String, required: false })
99
+ submittedBy?: string;
100
+
101
+ @ApiProperty({ required: false })
102
+ @Prop({ type: Date, required: false })
103
+ submittedAt?: Date;
104
+
105
+ @ApiProperty({ type: () => [ScriptDecision] })
106
+ @Prop({ type: [ScriptDecisionSchema], default: [] })
107
+ decisions: ScriptDecision[];
108
+
109
+ @ApiProperty({ type: () => [ScriptStaffReply] })
110
+ @Prop({ type: [ScriptStaffReplySchema], default: [] })
111
+ staffReplies: ScriptStaffReply[];
112
+
113
+ @ApiProperty()
114
+ @Prop({ type: Date, required: true })
115
+ archivedAt: Date;
116
+ }
117
+
118
+ export const ScriptVersionSchema = SchemaFactory.createForClass(ScriptVersion);
119
+
120
+ /**
121
+ * Aprovação de roteiro: um documento por (action, profile, deliverableType,
122
+ * deliverableIndex) — não um doc único por Ação. A versão mora no mesmo doc;
123
+ * ao reprovar, o estado atual é arquivado em `versions[]` e o doc volta a
124
+ * `draft` para uma nova tentativa (ver GD-532).
125
+ */
126
+ @Schema({ timestamps: true })
127
+ export class Script {
128
+ @ApiProperty()
129
+ @Prop({ type: MongooseSchema.Types.ObjectId, auto: true, required: false })
130
+ _id?: Types.ObjectId;
131
+
132
+ @ApiProperty({ type: () => Action })
133
+ @Prop({ type: MongooseSchema.Types.ObjectId, ref: 'Action', required: true })
134
+ action: Types.ObjectId | Action;
135
+
136
+ @ApiProperty({ type: () => Client })
137
+ @Prop({ type: MongooseSchema.Types.ObjectId, ref: 'Client', required: false })
138
+ client?: Types.ObjectId | Client;
139
+
140
+ @ApiProperty({ type: () => Profile })
141
+ @Prop({ type: MongooseSchema.Types.ObjectId, ref: 'Profile', required: true })
142
+ profile: Types.ObjectId | Profile;
143
+
144
+ @ApiProperty({
145
+ enum: TASK_FORMAT_VALUES,
146
+ description: 'Unidade de entrega do escopo (mesmos valores de recruitment.scope.delivery)',
147
+ })
148
+ @Prop({ type: String, enum: TASK_FORMAT_VALUES, required: true })
149
+ deliverableType: TaskFormat;
150
+
151
+ @ApiProperty({
152
+ description: 'Ex.: 1 de 2 quando o escopo pede mais de uma unidade do mesmo tipo; sempre 1 para "story"',
153
+ })
154
+ @Prop({ type: Number, required: true, default: 1 })
155
+ deliverableIndex: number;
156
+
157
+ @ApiProperty()
158
+ @Prop({ type: Number, required: true, default: 1 })
159
+ version: number;
160
+
161
+ @ApiProperty({ required: false })
162
+ @Prop({ type: String, required: false, default: null })
163
+ fileUrl?: string | null;
164
+
165
+ @ApiProperty({ required: false })
166
+ @Prop({ type: String, required: false, default: null })
167
+ fileName?: string | null;
168
+
169
+ @ApiProperty({
170
+ required: false,
171
+ description: 'Alternativa ao arquivo — staff usa arquivo OU link',
172
+ })
173
+ @Prop({ type: String, required: false, default: null })
174
+ link?: string | null;
175
+
176
+ @ApiProperty({ enum: SCRIPT_STATUS_VALUES })
177
+ @Prop({
178
+ type: String,
179
+ enum: SCRIPT_STATUS_VALUES,
180
+ required: true,
181
+ default: 'draft',
182
+ })
183
+ status: ScriptStatus;
184
+
185
+ @ApiProperty({
186
+ type: [String],
187
+ description:
188
+ 'Snapshot de Client.requiredTeams no momento da criação — vazio = 1 aprovação resolve; com times = todos precisam aprovar',
189
+ })
190
+ @Prop({ type: [String], required: false, default: [] })
191
+ requiredTeams: string[];
192
+
193
+ @ApiProperty({ required: false })
194
+ @Prop({ type: String, required: false })
195
+ submittedBy?: string;
196
+
197
+ @ApiProperty({ required: false })
198
+ @Prop({ type: Date, required: false })
199
+ submittedAt?: Date;
200
+
201
+ @ApiProperty({ type: () => [ScriptDecision] })
202
+ @Prop({ type: [ScriptDecisionSchema], default: [] })
203
+ decisions: ScriptDecision[];
204
+
205
+ @ApiProperty({ type: () => [ScriptStaffReply] })
206
+ @Prop({ type: [ScriptStaffReplySchema], default: [] })
207
+ staffReplies: ScriptStaffReply[];
208
+
209
+ @ApiProperty({ type: () => [ScriptVersion] })
210
+ @Prop({ type: [ScriptVersionSchema], default: [] })
211
+ versions: ScriptVersion[];
212
+
213
+ @Prop({ type: MongooseSchema.Types.ObjectId, required: false })
214
+ organization?: Types.ObjectId;
215
+
216
+ @ApiProperty()
217
+ @Prop({ default: Date.now, required: false })
218
+ createdAt?: Date;
219
+
220
+ @ApiProperty()
221
+ @Prop({ default: Date.now, required: false })
222
+ updatedAt?: Date;
223
+ }
224
+
225
+ export const ScriptSchema = SchemaFactory.createForClass(Script);
226
+
227
+ ScriptSchema.index(
228
+ { action: 1, profile: 1, deliverableType: 1, deliverableIndex: 1 },
229
+ { unique: true },
230
+ );
231
+ ScriptSchema.index({ action: 1, status: 1 });
232
+ ScriptSchema.index({ client: 1, status: 1 });
233
+ ScriptSchema.index({ organization: 1, status: 1 });
234
+
235
+ export const ScriptModel = MongooseModel('Script', ScriptSchema);