@grapadigital/shared-schemas 1.0.204 → 1.0.207

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 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 }),
@@ -133,9 +133,10 @@ export declare class Client extends Party {
133
133
  hasGenIAAnalysis: boolean;
134
134
  /**
135
135
  * Client de organização (ex.: "Oma Creators"): representa a organização
136
- * inteira, não uma marca. Com `hasGenIAAnalysis`, liga a análise GenIA pra
137
- * todas as actions dessa organização e, no hub, mostra todas elas
138
- * independentemente do client (marca) de cada action.
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`.
139
140
  */
140
141
  organization?: Types.ObjectId;
141
142
  reportResponsable?: Responsable;
@@ -199,6 +199,7 @@ export declare class Content {
199
199
  createdAt?: Date;
200
200
  updatedAt?: Date;
201
201
  primetagId?: string;
202
+ captureRunId?: string;
202
203
  sentimentAnalysis?: SentimentAnalysis | null;
203
204
  thumbnailUrl?: string;
204
205
  mediaUrl?: string;
@@ -417,6 +417,10 @@ __decorate([
417
417
  (0, mongoose_1.Prop)({ type: String, required: false }),
418
418
  __metadata("design:type", String)
419
419
  ], Content.prototype, "primetagId", void 0);
420
+ __decorate([
421
+ (0, mongoose_1.Prop)({ type: String, required: false }),
422
+ __metadata("design:type", String)
423
+ ], Content.prototype, "captureRunId", void 0);
420
424
  __decorate([
421
425
  (0, mongoose_1.Prop)({ type: exports.SentimentAnalysisSchema, required: false, default: null }),
422
426
  __metadata("design:type", Object)
@@ -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,118 @@
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
+ // A trilha guarda o payload bruto de cada rodada e cresce rápido: o Mongo
114
+ // apaga sozinho as linhas com mais de 180 dias.
115
+ exports.JobSchema.index({ createdAt: 1 }, { expireAfterSeconds: 180 * 24 * 60 * 60 });
116
+ // Raw mais recente de uma publication (linhas do content-capture).
117
+ exports.JobSchema.index({ actionId: 1, worker: 1, primetagId: 1, startedAt: -1 });
118
+ exports.JobModel = (0, mongoose_2.model)('Job', exports.JobSchema);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grapadigital/shared-schemas",
3
- "version": "1.0.204",
3
+ "version": "1.0.207",
4
4
  "description": "Shared Mongoose Schemas",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
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[];
@@ -139,9 +139,10 @@ export class Client extends Party {
139
139
 
140
140
  /**
141
141
  * Client de organização (ex.: "Oma Creators"): representa a organização
142
- * inteira, não uma marca. Com `hasGenIAAnalysis`, liga a análise GenIA pra
143
- * todas as actions dessa organização e, no hub, mostra todas elas
144
- * independentemente do client (marca) de cada action.
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`.
145
146
  */
146
147
  @Prop({ type: MongooseSchema.Types.ObjectId, ref: 'Organization', required: false })
147
148
  organization?: Types.ObjectId;
@@ -348,6 +348,12 @@ export class Content {
348
348
  @Prop({ type: String, required: false })
349
349
  primetagId?: string;
350
350
 
351
+ // runId da última captura que tocou o conteúdo (não o da rodada que o
352
+ // criou) — a aprovação e a reclassificação reaproveitam esse runId pra
353
+ // continuar na mesma trilha da coleção `jobs`.
354
+ @Prop({ type: String, required: false })
355
+ captureRunId?: string;
356
+
351
357
  @Prop({ type: SentimentAnalysisSchema, required: false, default: null })
352
358
  sentimentAnalysis?: SentimentAnalysis | null;
353
359
 
@@ -0,0 +1,106 @@
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
+ // A trilha guarda o payload bruto de cada rodada e cresce rápido: o Mongo
101
+ // apaga sozinho as linhas com mais de 180 dias.
102
+ JobSchema.index({ createdAt: 1 }, { expireAfterSeconds: 180 * 24 * 60 * 60 });
103
+ // Raw mais recente de uma publication (linhas do content-capture).
104
+ JobSchema.index({ actionId: 1, worker: 1, primetagId: 1, startedAt: -1 });
105
+
106
+ export const JobModel = MongooseModel('Job', JobSchema);