@grapadigital/shared-schemas 1.0.203 → 1.0.206
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/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/schemas/action.schema.d.ts +5 -0
- package/dist/schemas/action.schema.js +5 -0
- package/dist/schemas/client.schema.d.ts +8 -0
- package/dist/schemas/client.schema.js +5 -0
- package/dist/schemas/job.schema.d.ts +84 -0
- package/dist/schemas/job.schema.js +113 -0
- package/package.json +1 -1
- package/src/index.ts +1 -0
- package/src/schemas/action.schema.ts +8 -0
- package/src/schemas/client.schema.ts +11 -0
- package/src/schemas/job.schema.ts +101 -0
package/dist/index.d.ts
CHANGED
|
@@ -31,5 +31,6 @@ export { Note, NoteSchema, NoteMention, NoteMentionSchema } from './schemas/note
|
|
|
31
31
|
export * from './schemas/content-capture-process.schema';
|
|
32
32
|
export * from './schemas/content-draft.schema';
|
|
33
33
|
export * from './schemas/export-comments-job.schema';
|
|
34
|
+
export * from './schemas/job.schema';
|
|
34
35
|
export * from './schemas/profile-followers-snapshot.schema';
|
|
35
36
|
export * from './schemas/lead.schema';
|
package/dist/index.js
CHANGED
|
@@ -52,5 +52,6 @@ Object.defineProperty(exports, "NoteMentionSchema", { enumerable: true, get: fun
|
|
|
52
52
|
__exportStar(require("./schemas/content-capture-process.schema"), exports);
|
|
53
53
|
__exportStar(require("./schemas/content-draft.schema"), exports);
|
|
54
54
|
__exportStar(require("./schemas/export-comments-job.schema"), exports);
|
|
55
|
+
__exportStar(require("./schemas/job.schema"), exports);
|
|
55
56
|
__exportStar(require("./schemas/profile-followers-snapshot.schema"), exports);
|
|
56
57
|
__exportStar(require("./schemas/lead.schema"), exports);
|
|
@@ -111,6 +111,11 @@ export declare class Action {
|
|
|
111
111
|
updatedAt?: Date;
|
|
112
112
|
notes?: Note[];
|
|
113
113
|
primetagId?: string;
|
|
114
|
+
/**
|
|
115
|
+
* Liga a análise GenIA (comentários + classificação por IA) só pra esta
|
|
116
|
+
* action, mesmo que o client dela não tenha `Client.hasGenIAAnalysis`.
|
|
117
|
+
*/
|
|
118
|
+
hasGenIAAnalysis?: boolean;
|
|
114
119
|
hashtags?: string[];
|
|
115
120
|
instagramMentions?: string[];
|
|
116
121
|
tiktokMentions?: string[];
|
|
@@ -281,6 +281,11 @@ __decorate([
|
|
|
281
281
|
(0, mongoose_1.Prop)({ type: String, required: false }),
|
|
282
282
|
__metadata("design:type", String)
|
|
283
283
|
], Action.prototype, "primetagId", void 0);
|
|
284
|
+
__decorate([
|
|
285
|
+
(0, swagger_1.ApiProperty)({ example: false, required: false }),
|
|
286
|
+
(0, mongoose_1.Prop)({ type: Boolean, required: false }),
|
|
287
|
+
__metadata("design:type", Boolean)
|
|
288
|
+
], Action.prototype, "hasGenIAAnalysis", void 0);
|
|
284
289
|
__decorate([
|
|
285
290
|
(0, swagger_1.ApiProperty)({ example: ['#trending', '#viral'], required: false }),
|
|
286
291
|
(0, mongoose_1.Prop)({ type: [String], required: false }),
|
|
@@ -131,6 +131,14 @@ export declare class Client extends Party {
|
|
|
131
131
|
* (Antigo `hasReport`.)
|
|
132
132
|
*/
|
|
133
133
|
hasGenIAAnalysis: boolean;
|
|
134
|
+
/**
|
|
135
|
+
* Client de organização (ex.: "Oma Creators"): representa a organização
|
|
136
|
+
* inteira, não uma marca. No hub, mostra todas as actions dessa organização
|
|
137
|
+
* independentemente do client (marca) de cada action. Não liga a análise
|
|
138
|
+
* GenIA das actions — isso é `Client.hasGenIAAnalysis` do client da action
|
|
139
|
+
* ou `Action.hasGenIAAnalysis`.
|
|
140
|
+
*/
|
|
141
|
+
organization?: Types.ObjectId;
|
|
134
142
|
reportResponsable?: Responsable;
|
|
135
143
|
brandResponsable?: string;
|
|
136
144
|
profiles?: Types.ObjectId[] | Profile[];
|
|
@@ -165,6 +165,10 @@ __decorate([
|
|
|
165
165
|
(0, mongoose_1.Prop)({ type: Boolean, default: false }),
|
|
166
166
|
__metadata("design:type", Boolean)
|
|
167
167
|
], Client.prototype, "hasGenIAAnalysis", void 0);
|
|
168
|
+
__decorate([
|
|
169
|
+
(0, mongoose_1.Prop)({ type: mongoose_2.Schema.Types.ObjectId, ref: 'Organization', required: false }),
|
|
170
|
+
__metadata("design:type", mongoose_2.Types.ObjectId)
|
|
171
|
+
], Client.prototype, "organization", void 0);
|
|
168
172
|
__decorate([
|
|
169
173
|
(0, mongoose_1.Prop)({ type: exports.ResponsableSchema, required: false }),
|
|
170
174
|
__metadata("design:type", Responsable)
|
|
@@ -188,4 +192,5 @@ exports.ClientSchema.index({ name: 1 });
|
|
|
188
192
|
exports.ClientSchema.index({ 'company.legalName': 1 });
|
|
189
193
|
exports.ClientSchema.index({ 'company.document': 1 });
|
|
190
194
|
exports.ClientSchema.index({ createdAt: -1 });
|
|
195
|
+
exports.ClientSchema.index({ organization: 1 }, { sparse: true });
|
|
191
196
|
exports.ClientModel = (0, mongoose_2.model)('Client', exports.ClientSchema);
|
|
@@ -0,0 +1,84 @@
|
|
|
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/types/schematypes" />
|
|
24
|
+
/// <reference types="mongoose/types/inferschematype" />
|
|
25
|
+
/// <reference types="mongoose/types/inferrawdoctype" />
|
|
26
|
+
import { HydratedDocument, Schema as MongooseSchema, Types } from 'mongoose';
|
|
27
|
+
import { Action } from './action.schema';
|
|
28
|
+
export type JobDocument = HydratedDocument<Job>;
|
|
29
|
+
export declare const JOB_ORIGINS: readonly ["trigger", "approval", "reclassify"];
|
|
30
|
+
export type JobOrigin = (typeof JOB_ORIGINS)[number];
|
|
31
|
+
export declare const JOB_WORKERS: readonly ["content-capture-trigger", "content-capture", "comment-capture", "content-classification", "metrics-generator", "profile-sync"];
|
|
32
|
+
export type JobWorker = (typeof JOB_WORKERS)[number];
|
|
33
|
+
export declare const JOB_STATUSES: readonly ["done", "skipped", "error"];
|
|
34
|
+
export type JobStatus = (typeof JOB_STATUSES)[number];
|
|
35
|
+
/**
|
|
36
|
+
* Trilha única do pipeline de captura: cada worker grava uma linha por
|
|
37
|
+
* unidade de trabalho (action ou content), e todas as linhas da mesma rodada
|
|
38
|
+
* compartilham o `runId` gerado pelo content-capture-trigger. `requestId`
|
|
39
|
+
* separa cada disparo dentro de um `runId` — na captura é igual ao `runId`;
|
|
40
|
+
* na aprovação/reclassificação a api-campaigns gera um por clique. `input` é
|
|
41
|
+
* o payload recebido, `response` o que veio de fora (Primetag, exportcomments,
|
|
42
|
+
* OpenAI) e `result` o que o worker decidiu ou gravou.
|
|
43
|
+
*/
|
|
44
|
+
export declare class Job {
|
|
45
|
+
_id?: Types.ObjectId;
|
|
46
|
+
runId: string;
|
|
47
|
+
requestId: string;
|
|
48
|
+
origin: JobOrigin;
|
|
49
|
+
worker: JobWorker;
|
|
50
|
+
actionId: Types.ObjectId | Action;
|
|
51
|
+
contentId?: Types.ObjectId;
|
|
52
|
+
primetagId?: string;
|
|
53
|
+
status: JobStatus;
|
|
54
|
+
input?: unknown;
|
|
55
|
+
response?: unknown;
|
|
56
|
+
result?: unknown;
|
|
57
|
+
error?: string;
|
|
58
|
+
startedAt: Date;
|
|
59
|
+
finishedAt?: Date;
|
|
60
|
+
createdAt?: Date;
|
|
61
|
+
updatedAt?: Date;
|
|
62
|
+
}
|
|
63
|
+
export declare const JobSchema: MongooseSchema<Job, import("mongoose").Model<Job, any, any, any, import("mongoose").Document<unknown, any, Job, any, {}> & Job & Required<{
|
|
64
|
+
_id: Types.ObjectId;
|
|
65
|
+
}> & {
|
|
66
|
+
__v: number;
|
|
67
|
+
}, any>, {}, {}, {}, {}, import("mongoose").DefaultSchemaOptions, Job, import("mongoose").Document<unknown, {}, import("mongoose").FlatRecord<Job>, {}, import("mongoose").ResolveSchemaOptions<import("mongoose").DefaultSchemaOptions>> & import("mongoose").FlatRecord<Job> & Required<{
|
|
68
|
+
_id: Types.ObjectId;
|
|
69
|
+
}> & {
|
|
70
|
+
__v: number;
|
|
71
|
+
}>;
|
|
72
|
+
export declare const JobModel: import("mongoose").Model<Job, {}, {}, {}, import("mongoose").Document<unknown, {}, Job, {}, import("mongoose").DefaultSchemaOptions> & Job & Required<{
|
|
73
|
+
_id: Types.ObjectId;
|
|
74
|
+
}> & {
|
|
75
|
+
__v: number;
|
|
76
|
+
}, MongooseSchema<Job, import("mongoose").Model<Job, any, any, any, import("mongoose").Document<unknown, any, Job, any, {}> & Job & Required<{
|
|
77
|
+
_id: Types.ObjectId;
|
|
78
|
+
}> & {
|
|
79
|
+
__v: number;
|
|
80
|
+
}, any>, {}, {}, {}, {}, import("mongoose").DefaultSchemaOptions, Job, import("mongoose").Document<unknown, {}, import("mongoose").FlatRecord<Job>, {}, import("mongoose").ResolveSchemaOptions<import("mongoose").DefaultSchemaOptions>> & import("mongoose").FlatRecord<Job> & Required<{
|
|
81
|
+
_id: Types.ObjectId;
|
|
82
|
+
}> & {
|
|
83
|
+
__v: number;
|
|
84
|
+
}>>;
|
|
@@ -0,0 +1,113 @@
|
|
|
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.JobModel = exports.JobSchema = exports.Job = exports.JOB_STATUSES = exports.JOB_WORKERS = exports.JOB_ORIGINS = void 0;
|
|
13
|
+
const mongoose_1 = require("@nestjs/mongoose");
|
|
14
|
+
const mongoose_2 = require("mongoose");
|
|
15
|
+
exports.JOB_ORIGINS = ['trigger', 'approval', 'reclassify'];
|
|
16
|
+
exports.JOB_WORKERS = [
|
|
17
|
+
'content-capture-trigger',
|
|
18
|
+
'content-capture',
|
|
19
|
+
'comment-capture',
|
|
20
|
+
'content-classification',
|
|
21
|
+
'metrics-generator',
|
|
22
|
+
'profile-sync',
|
|
23
|
+
];
|
|
24
|
+
exports.JOB_STATUSES = ['done', 'skipped', 'error'];
|
|
25
|
+
/**
|
|
26
|
+
* Trilha única do pipeline de captura: cada worker grava uma linha por
|
|
27
|
+
* unidade de trabalho (action ou content), e todas as linhas da mesma rodada
|
|
28
|
+
* compartilham o `runId` gerado pelo content-capture-trigger. `requestId`
|
|
29
|
+
* separa cada disparo dentro de um `runId` — na captura é igual ao `runId`;
|
|
30
|
+
* na aprovação/reclassificação a api-campaigns gera um por clique. `input` é
|
|
31
|
+
* o payload recebido, `response` o que veio de fora (Primetag, exportcomments,
|
|
32
|
+
* OpenAI) e `result` o que o worker decidiu ou gravou.
|
|
33
|
+
*/
|
|
34
|
+
let Job = class Job {
|
|
35
|
+
};
|
|
36
|
+
__decorate([
|
|
37
|
+
(0, mongoose_1.Prop)({ type: mongoose_2.Schema.Types.ObjectId, auto: true, required: false }),
|
|
38
|
+
__metadata("design:type", mongoose_2.Types.ObjectId)
|
|
39
|
+
], Job.prototype, "_id", void 0);
|
|
40
|
+
__decorate([
|
|
41
|
+
(0, mongoose_1.Prop)({ type: String, required: true }),
|
|
42
|
+
__metadata("design:type", String)
|
|
43
|
+
], Job.prototype, "runId", void 0);
|
|
44
|
+
__decorate([
|
|
45
|
+
(0, mongoose_1.Prop)({ type: String, required: true }),
|
|
46
|
+
__metadata("design:type", String)
|
|
47
|
+
], Job.prototype, "requestId", void 0);
|
|
48
|
+
__decorate([
|
|
49
|
+
(0, mongoose_1.Prop)({ type: String, enum: exports.JOB_ORIGINS, required: true }),
|
|
50
|
+
__metadata("design:type", String)
|
|
51
|
+
], Job.prototype, "origin", void 0);
|
|
52
|
+
__decorate([
|
|
53
|
+
(0, mongoose_1.Prop)({ type: String, enum: exports.JOB_WORKERS, required: true }),
|
|
54
|
+
__metadata("design:type", String)
|
|
55
|
+
], Job.prototype, "worker", void 0);
|
|
56
|
+
__decorate([
|
|
57
|
+
(0, mongoose_1.Prop)({ type: mongoose_2.Schema.Types.ObjectId, ref: 'Action', required: true }),
|
|
58
|
+
__metadata("design:type", Object)
|
|
59
|
+
], Job.prototype, "actionId", void 0);
|
|
60
|
+
__decorate([
|
|
61
|
+
(0, mongoose_1.Prop)({ type: mongoose_2.Schema.Types.ObjectId, required: false }),
|
|
62
|
+
__metadata("design:type", mongoose_2.Types.ObjectId)
|
|
63
|
+
], Job.prototype, "contentId", void 0);
|
|
64
|
+
__decorate([
|
|
65
|
+
(0, mongoose_1.Prop)({ type: String, required: false }),
|
|
66
|
+
__metadata("design:type", String)
|
|
67
|
+
], Job.prototype, "primetagId", void 0);
|
|
68
|
+
__decorate([
|
|
69
|
+
(0, mongoose_1.Prop)({ type: String, enum: exports.JOB_STATUSES, required: true }),
|
|
70
|
+
__metadata("design:type", String)
|
|
71
|
+
], Job.prototype, "status", void 0);
|
|
72
|
+
__decorate([
|
|
73
|
+
(0, mongoose_1.Prop)({ type: mongoose_2.Schema.Types.Mixed, required: false }),
|
|
74
|
+
__metadata("design:type", Object)
|
|
75
|
+
], Job.prototype, "input", void 0);
|
|
76
|
+
__decorate([
|
|
77
|
+
(0, mongoose_1.Prop)({ type: mongoose_2.Schema.Types.Mixed, required: false }),
|
|
78
|
+
__metadata("design:type", Object)
|
|
79
|
+
], Job.prototype, "response", void 0);
|
|
80
|
+
__decorate([
|
|
81
|
+
(0, mongoose_1.Prop)({ type: mongoose_2.Schema.Types.Mixed, required: false }),
|
|
82
|
+
__metadata("design:type", Object)
|
|
83
|
+
], Job.prototype, "result", void 0);
|
|
84
|
+
__decorate([
|
|
85
|
+
(0, mongoose_1.Prop)({ type: String, required: false }),
|
|
86
|
+
__metadata("design:type", String)
|
|
87
|
+
], Job.prototype, "error", void 0);
|
|
88
|
+
__decorate([
|
|
89
|
+
(0, mongoose_1.Prop)({ type: Date, required: true, default: Date.now }),
|
|
90
|
+
__metadata("design:type", Date)
|
|
91
|
+
], Job.prototype, "startedAt", void 0);
|
|
92
|
+
__decorate([
|
|
93
|
+
(0, mongoose_1.Prop)({ type: Date, required: false }),
|
|
94
|
+
__metadata("design:type", Date)
|
|
95
|
+
], Job.prototype, "finishedAt", void 0);
|
|
96
|
+
__decorate([
|
|
97
|
+
(0, mongoose_1.Prop)({ default: Date.now, required: false }),
|
|
98
|
+
__metadata("design:type", Date)
|
|
99
|
+
], Job.prototype, "createdAt", void 0);
|
|
100
|
+
__decorate([
|
|
101
|
+
(0, mongoose_1.Prop)({ default: Date.now, required: false }),
|
|
102
|
+
__metadata("design:type", Date)
|
|
103
|
+
], Job.prototype, "updatedAt", void 0);
|
|
104
|
+
Job = __decorate([
|
|
105
|
+
(0, mongoose_1.Schema)({ collection: 'jobs', timestamps: true })
|
|
106
|
+
], Job);
|
|
107
|
+
exports.Job = Job;
|
|
108
|
+
exports.JobSchema = mongoose_1.SchemaFactory.createForClass(Job);
|
|
109
|
+
// Reentrega da mesma mensagem atualiza a mesma linha.
|
|
110
|
+
exports.JobSchema.index({ runId: 1, requestId: 1, worker: 1, contentId: 1, primetagId: 1 }, { unique: true });
|
|
111
|
+
// Trava do trigger: última rodada de uma action.
|
|
112
|
+
exports.JobSchema.index({ actionId: 1, worker: 1, origin: 1, startedAt: -1 });
|
|
113
|
+
exports.JobModel = (0, mongoose_2.model)('Job', exports.JobSchema);
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -31,5 +31,6 @@ export { Note, NoteSchema, NoteMention, NoteMentionSchema } from './schemas/note
|
|
|
31
31
|
export * from './schemas/content-capture-process.schema';
|
|
32
32
|
export * from './schemas/content-draft.schema';
|
|
33
33
|
export * from './schemas/export-comments-job.schema';
|
|
34
|
+
export * from './schemas/job.schema';
|
|
34
35
|
export * from './schemas/profile-followers-snapshot.schema';
|
|
35
36
|
export * from './schemas/lead.schema';
|
|
@@ -235,6 +235,14 @@ export class Action {
|
|
|
235
235
|
@Prop({ type: String, required: false })
|
|
236
236
|
primetagId?: string;
|
|
237
237
|
|
|
238
|
+
/**
|
|
239
|
+
* Liga a análise GenIA (comentários + classificação por IA) só pra esta
|
|
240
|
+
* action, mesmo que o client dela não tenha `Client.hasGenIAAnalysis`.
|
|
241
|
+
*/
|
|
242
|
+
@ApiProperty({ example: false, required: false })
|
|
243
|
+
@Prop({ type: Boolean, required: false })
|
|
244
|
+
hasGenIAAnalysis?: boolean;
|
|
245
|
+
|
|
238
246
|
@ApiProperty({ example: ['#trending', '#viral'], required: false })
|
|
239
247
|
@Prop({ type: [String], required: false })
|
|
240
248
|
hashtags?: string[];
|
|
@@ -137,6 +137,16 @@ export class Client extends Party {
|
|
|
137
137
|
@Prop({ type: Boolean, default: false })
|
|
138
138
|
hasGenIAAnalysis: boolean;
|
|
139
139
|
|
|
140
|
+
/**
|
|
141
|
+
* Client de organização (ex.: "Oma Creators"): representa a organização
|
|
142
|
+
* inteira, não uma marca. No hub, mostra todas as actions dessa organização
|
|
143
|
+
* independentemente do client (marca) de cada action. Não liga a análise
|
|
144
|
+
* GenIA das actions — isso é `Client.hasGenIAAnalysis` do client da action
|
|
145
|
+
* ou `Action.hasGenIAAnalysis`.
|
|
146
|
+
*/
|
|
147
|
+
@Prop({ type: MongooseSchema.Types.ObjectId, ref: 'Organization', required: false })
|
|
148
|
+
organization?: Types.ObjectId;
|
|
149
|
+
|
|
140
150
|
@Prop({ type: ResponsableSchema, required: false })
|
|
141
151
|
reportResponsable?: Responsable;
|
|
142
152
|
|
|
@@ -157,5 +167,6 @@ ClientSchema.index({ name: 1 });
|
|
|
157
167
|
ClientSchema.index({ 'company.legalName': 1 });
|
|
158
168
|
ClientSchema.index({ 'company.document': 1 });
|
|
159
169
|
ClientSchema.index({ createdAt: -1 });
|
|
170
|
+
ClientSchema.index({ organization: 1 }, { sparse: true });
|
|
160
171
|
|
|
161
172
|
export const ClientModel = MongooseModel('Client', ClientSchema);
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
|
|
2
|
+
import {
|
|
3
|
+
HydratedDocument,
|
|
4
|
+
Schema as MongooseSchema,
|
|
5
|
+
Types,
|
|
6
|
+
model as MongooseModel,
|
|
7
|
+
} from 'mongoose';
|
|
8
|
+
import { Action } from './action.schema';
|
|
9
|
+
|
|
10
|
+
export type JobDocument = HydratedDocument<Job>;
|
|
11
|
+
|
|
12
|
+
export const JOB_ORIGINS = ['trigger', 'approval', 'reclassify'] as const;
|
|
13
|
+
export type JobOrigin = (typeof JOB_ORIGINS)[number];
|
|
14
|
+
|
|
15
|
+
export const JOB_WORKERS = [
|
|
16
|
+
'content-capture-trigger',
|
|
17
|
+
'content-capture',
|
|
18
|
+
'comment-capture',
|
|
19
|
+
'content-classification',
|
|
20
|
+
'metrics-generator',
|
|
21
|
+
'profile-sync',
|
|
22
|
+
] as const;
|
|
23
|
+
export type JobWorker = (typeof JOB_WORKERS)[number];
|
|
24
|
+
|
|
25
|
+
export const JOB_STATUSES = ['done', 'skipped', 'error'] as const;
|
|
26
|
+
export type JobStatus = (typeof JOB_STATUSES)[number];
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Trilha única do pipeline de captura: cada worker grava uma linha por
|
|
30
|
+
* unidade de trabalho (action ou content), e todas as linhas da mesma rodada
|
|
31
|
+
* compartilham o `runId` gerado pelo content-capture-trigger. `requestId`
|
|
32
|
+
* separa cada disparo dentro de um `runId` — na captura é igual ao `runId`;
|
|
33
|
+
* na aprovação/reclassificação a api-campaigns gera um por clique. `input` é
|
|
34
|
+
* o payload recebido, `response` o que veio de fora (Primetag, exportcomments,
|
|
35
|
+
* OpenAI) e `result` o que o worker decidiu ou gravou.
|
|
36
|
+
*/
|
|
37
|
+
@Schema({ collection: 'jobs', timestamps: true })
|
|
38
|
+
export class Job {
|
|
39
|
+
@Prop({ type: MongooseSchema.Types.ObjectId, auto: true, required: false })
|
|
40
|
+
_id?: Types.ObjectId;
|
|
41
|
+
|
|
42
|
+
@Prop({ type: String, required: true })
|
|
43
|
+
runId: string;
|
|
44
|
+
|
|
45
|
+
@Prop({ type: String, required: true })
|
|
46
|
+
requestId: string;
|
|
47
|
+
|
|
48
|
+
@Prop({ type: String, enum: JOB_ORIGINS, required: true })
|
|
49
|
+
origin: JobOrigin;
|
|
50
|
+
|
|
51
|
+
@Prop({ type: String, enum: JOB_WORKERS, required: true })
|
|
52
|
+
worker: JobWorker;
|
|
53
|
+
|
|
54
|
+
@Prop({ type: MongooseSchema.Types.ObjectId, ref: 'Action', required: true })
|
|
55
|
+
actionId: Types.ObjectId | Action;
|
|
56
|
+
|
|
57
|
+
@Prop({ type: MongooseSchema.Types.ObjectId, required: false })
|
|
58
|
+
contentId?: Types.ObjectId;
|
|
59
|
+
|
|
60
|
+
@Prop({ type: String, required: false })
|
|
61
|
+
primetagId?: string;
|
|
62
|
+
|
|
63
|
+
@Prop({ type: String, enum: JOB_STATUSES, required: true })
|
|
64
|
+
status: JobStatus;
|
|
65
|
+
|
|
66
|
+
@Prop({ type: MongooseSchema.Types.Mixed, required: false })
|
|
67
|
+
input?: unknown;
|
|
68
|
+
|
|
69
|
+
@Prop({ type: MongooseSchema.Types.Mixed, required: false })
|
|
70
|
+
response?: unknown;
|
|
71
|
+
|
|
72
|
+
@Prop({ type: MongooseSchema.Types.Mixed, required: false })
|
|
73
|
+
result?: unknown;
|
|
74
|
+
|
|
75
|
+
@Prop({ type: String, required: false })
|
|
76
|
+
error?: string;
|
|
77
|
+
|
|
78
|
+
@Prop({ type: Date, required: true, default: Date.now })
|
|
79
|
+
startedAt: Date;
|
|
80
|
+
|
|
81
|
+
@Prop({ type: Date, required: false })
|
|
82
|
+
finishedAt?: Date;
|
|
83
|
+
|
|
84
|
+
@Prop({ default: Date.now, required: false })
|
|
85
|
+
createdAt?: Date;
|
|
86
|
+
|
|
87
|
+
@Prop({ default: Date.now, required: false })
|
|
88
|
+
updatedAt?: Date;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export const JobSchema = SchemaFactory.createForClass(Job);
|
|
92
|
+
|
|
93
|
+
// Reentrega da mesma mensagem atualiza a mesma linha.
|
|
94
|
+
JobSchema.index(
|
|
95
|
+
{ runId: 1, requestId: 1, worker: 1, contentId: 1, primetagId: 1 },
|
|
96
|
+
{ unique: true },
|
|
97
|
+
);
|
|
98
|
+
// Trava do trigger: última rodada de uma action.
|
|
99
|
+
JobSchema.index({ actionId: 1, worker: 1, origin: 1, startedAt: -1 });
|
|
100
|
+
|
|
101
|
+
export const JobModel = MongooseModel('Job', JobSchema);
|