ponch-mcp-server 1.0.88 → 1.0.90
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.js +81 -43
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -171,29 +171,36 @@ var Session = class {
|
|
|
171
171
|
this.context.brandId = brandId;
|
|
172
172
|
}
|
|
173
173
|
/**
|
|
174
|
-
* Cambia la brand activa SIN cambiar tenant. Disponible para
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
*
|
|
174
|
+
* Cambia la brand activa SIN cambiar tenant. Disponible para:
|
|
175
|
+
* - User Modo B con multi-brand (brands.length > 1) — agency mode.
|
|
176
|
+
* - Super_admin Modo A (canSwitchTenant=true) — service account
|
|
177
|
+
* puede operar cualquier brand dentro del tenant activo seteado
|
|
178
|
+
* previamente vía set_context.
|
|
179
|
+
*
|
|
180
|
+
* DEUDA 3 sesión 211.1 H/I + fix J post-smoke 1.0.88.
|
|
178
181
|
*
|
|
179
182
|
* Lanza si:
|
|
180
|
-
* - El user no tiene multi-brand
|
|
181
|
-
* - El brandId
|
|
182
|
-
*
|
|
183
|
-
*
|
|
183
|
+
* - El user no es super_admin Y no tiene multi-brand.
|
|
184
|
+
* - El brandId NO está en lista del user (defensa cross-brand Modo B).
|
|
185
|
+
* Para super_admin Modo A se delega validación al helper (Firestore
|
|
186
|
+
* existence check) — no hay "lista accesible" porque tiene acceso
|
|
187
|
+
* total al tenant.
|
|
184
188
|
*/
|
|
185
189
|
setBrand(brandId) {
|
|
186
190
|
const brands = this._authContext.brands ?? [];
|
|
187
|
-
|
|
191
|
+
const isSuperAdmin = this._authContext.canSwitchTenant;
|
|
192
|
+
if (!isSuperAdmin && brands.length <= 1) {
|
|
188
193
|
throw new Error(
|
|
189
|
-
`select_brand requires multi-brand access. This user has access to ${brands.length} brand(s).`
|
|
194
|
+
`select_brand requires multi-brand access or super_admin. This user has access to ${brands.length} brand(s) and is not super_admin.`
|
|
190
195
|
);
|
|
191
196
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
+
if (!isSuperAdmin) {
|
|
198
|
+
const allowed = brands.some((b) => b.id === brandId);
|
|
199
|
+
if (!allowed) {
|
|
200
|
+
throw new Error(
|
|
201
|
+
`Brand "${brandId}" is not in the user's accessible brands list [${brands.map((b) => b.id).join(", ")}].`
|
|
202
|
+
);
|
|
203
|
+
}
|
|
197
204
|
}
|
|
198
205
|
this.context.brandId = brandId;
|
|
199
206
|
this._authContext.brandId = brandId;
|
|
@@ -1525,7 +1532,7 @@ var ORIGENES_CONTENIDO = [
|
|
|
1525
1532
|
"imported"
|
|
1526
1533
|
// sync Shopify/WordPress
|
|
1527
1534
|
];
|
|
1528
|
-
var
|
|
1535
|
+
var ESTADO_CONTENIDO = {
|
|
1529
1536
|
BORRADOR: "borrador",
|
|
1530
1537
|
GENERADO: "generado",
|
|
1531
1538
|
PENDIENTE_APROBACION: "pendiente_aprobacion",
|
|
@@ -1723,7 +1730,7 @@ var ESTADOS_FOTO = [
|
|
|
1723
1730
|
var ESTRATEGIAS_EDICION = ["gemini_edit", "tal_cual"];
|
|
1724
1731
|
var FotoEstadoEnum = import_zod13.z.enum(ESTADOS_FOTO);
|
|
1725
1732
|
var FotoEstrategiaEdicionEnum = import_zod13.z.enum(ESTRATEGIAS_EDICION);
|
|
1726
|
-
var
|
|
1733
|
+
var ESTADO_FOTO = {
|
|
1727
1734
|
NUEVA: "nueva",
|
|
1728
1735
|
PROCESANDO: "procesando",
|
|
1729
1736
|
EDITADA: "editada",
|
|
@@ -9967,7 +9974,10 @@ function wrapWithContract(contract, helper, options = {}) {
|
|
|
9967
9974
|
state: "denied_role"
|
|
9968
9975
|
};
|
|
9969
9976
|
}
|
|
9970
|
-
const
|
|
9977
|
+
const cleanInput = input && typeof input === "object" && !Array.isArray(input) ? Object.fromEntries(
|
|
9978
|
+
Object.entries(input).filter(([, v]) => v !== null)
|
|
9979
|
+
) : input;
|
|
9980
|
+
const parseResult = contract.paramsSchema.safeParse(cleanInput);
|
|
9971
9981
|
if (!parseResult.success) {
|
|
9972
9982
|
const validationErrors = parseResult.error.issues.map((i) => {
|
|
9973
9983
|
const issue = i;
|
|
@@ -11869,7 +11879,7 @@ async function calendarSlotUpdater(input) {
|
|
|
11869
11879
|
const contenidoQuery = await db.collection("tenants").doc(tenantId).collection("marketing_contenido").where("brandId", "==", brandId).where("calendarioItemRef", "==", oldContenidoRef).limit(10).get();
|
|
11870
11880
|
contenidosADescartar = contenidoQuery.docs.filter((c) => {
|
|
11871
11881
|
const data = c.data();
|
|
11872
|
-
return data.estado !== "descartado" && data.estado !==
|
|
11882
|
+
return data.estado !== "descartado" && data.estado !== ESTADO_CONTENIDO.PUBLICADO;
|
|
11873
11883
|
});
|
|
11874
11884
|
}
|
|
11875
11885
|
if (accionContenidoExistente === "nuevo_slot") {
|
|
@@ -12784,7 +12794,7 @@ async function contenidoApprover(input) {
|
|
|
12784
12794
|
}
|
|
12785
12795
|
const data = snap.data();
|
|
12786
12796
|
const estadoActual = typeof data.estado === "string" ? data.estado : "";
|
|
12787
|
-
if (!esTransicionValida(estadoActual,
|
|
12797
|
+
if (!esTransicionValida(estadoActual, ESTADO_CONTENIDO.APROBADO)) {
|
|
12788
12798
|
return {
|
|
12789
12799
|
ok: false,
|
|
12790
12800
|
code: "INVALID_STATE_TRANSITION",
|
|
@@ -12792,7 +12802,7 @@ async function contenidoApprover(input) {
|
|
|
12792
12802
|
};
|
|
12793
12803
|
}
|
|
12794
12804
|
await ref.update({
|
|
12795
|
-
estado:
|
|
12805
|
+
estado: ESTADO_CONTENIDO.APROBADO,
|
|
12796
12806
|
aprobadoAt: import_firebase_admin8.firestore.FieldValue.serverTimestamp(),
|
|
12797
12807
|
aprobadoPorId: actor.uid,
|
|
12798
12808
|
aprobadoPorNombre: actor.nombre,
|
|
@@ -12803,7 +12813,7 @@ async function contenidoApprover(input) {
|
|
|
12803
12813
|
ok: true,
|
|
12804
12814
|
contenidoId,
|
|
12805
12815
|
estadoAnterior: estadoActual,
|
|
12806
|
-
nuevoEstado:
|
|
12816
|
+
nuevoEstado: ESTADO_CONTENIDO.APROBADO
|
|
12807
12817
|
};
|
|
12808
12818
|
}
|
|
12809
12819
|
var ParamsSchema12 = import_zod47.z.object({
|
|
@@ -12873,7 +12883,7 @@ async function contenidoRejecter(input) {
|
|
|
12873
12883
|
}
|
|
12874
12884
|
const data = snap.data();
|
|
12875
12885
|
const estadoActual = typeof data.estado === "string" ? data.estado : "";
|
|
12876
|
-
if (!esTransicionValida(estadoActual,
|
|
12886
|
+
if (!esTransicionValida(estadoActual, ESTADO_CONTENIDO.RECHAZADO)) {
|
|
12877
12887
|
return {
|
|
12878
12888
|
ok: false,
|
|
12879
12889
|
code: "INVALID_STATE_TRANSITION",
|
|
@@ -12881,7 +12891,7 @@ async function contenidoRejecter(input) {
|
|
|
12881
12891
|
};
|
|
12882
12892
|
}
|
|
12883
12893
|
await ref.update({
|
|
12884
|
-
estado:
|
|
12894
|
+
estado: ESTADO_CONTENIDO.RECHAZADO,
|
|
12885
12895
|
rechazadoAt: import_firebase_admin9.firestore.FieldValue.serverTimestamp(),
|
|
12886
12896
|
rechazadoMotivo: motivo,
|
|
12887
12897
|
rechazadoPorId: actor.uid,
|
|
@@ -12893,7 +12903,7 @@ async function contenidoRejecter(input) {
|
|
|
12893
12903
|
ok: true,
|
|
12894
12904
|
contenidoId,
|
|
12895
12905
|
estadoAnterior: estadoActual,
|
|
12896
|
-
nuevoEstado:
|
|
12906
|
+
nuevoEstado: ESTADO_CONTENIDO.RECHAZADO,
|
|
12897
12907
|
motivo
|
|
12898
12908
|
};
|
|
12899
12909
|
}
|
|
@@ -12958,7 +12968,7 @@ var contenidoRejecterContract = MartinContractSchema.parse(
|
|
|
12958
12968
|
rawContract13
|
|
12959
12969
|
);
|
|
12960
12970
|
async function photoBriefingWriter(input) {
|
|
12961
|
-
const { db, tenantId, brandId, semana, necesidades } = input;
|
|
12971
|
+
const { db, tenantId, brandId, semana, necesidades, actor } = input;
|
|
12962
12972
|
const docId = `${tenantId}_${brandId}_${semana}`;
|
|
12963
12973
|
const ref = db.collection("tenants").doc(tenantId).collection("marketing_fotobriefings").doc(docId);
|
|
12964
12974
|
const snap = await ref.get();
|
|
@@ -12998,9 +13008,23 @@ async function photoBriefingWriter(input) {
|
|
|
12998
13008
|
estado,
|
|
12999
13009
|
generadoEn: existing?.generadoEn ?? null
|
|
13000
13010
|
});
|
|
13011
|
+
const isCreate = !snap.exists;
|
|
13012
|
+
const actorFields = {
|
|
13013
|
+
actualizadoPorId: actor.uid,
|
|
13014
|
+
actualizadoPorNombre: actor.nombre,
|
|
13015
|
+
actualizadoPorClient: actor.clientType,
|
|
13016
|
+
actualizadoPorClientMetadata: actor.clientMetadata ?? null
|
|
13017
|
+
};
|
|
13018
|
+
if (isCreate) {
|
|
13019
|
+
actorFields.creadoPorId = actor.uid;
|
|
13020
|
+
actorFields.creadoPorNombre = actor.nombre;
|
|
13021
|
+
actorFields.creadoPorClient = actor.clientType;
|
|
13022
|
+
actorFields.creadoPorClientMetadata = actor.clientMetadata ?? null;
|
|
13023
|
+
}
|
|
13001
13024
|
await ref.set(
|
|
13002
13025
|
{
|
|
13003
13026
|
...doc,
|
|
13027
|
+
...actorFields,
|
|
13004
13028
|
generadoEn: existing?.generadoEn ?? import_firebase_admin10.firestore.FieldValue.serverTimestamp(),
|
|
13005
13029
|
fechaActualizacion: import_firebase_admin10.firestore.FieldValue.serverTimestamp()
|
|
13006
13030
|
},
|
|
@@ -13027,7 +13051,13 @@ var ParamsSchema14 = import_zod49.z.object({
|
|
|
13027
13051
|
tenantId: import_zod49.z.string().min(1).describe('Tenant identifier. Example: "your-tenant-id".'),
|
|
13028
13052
|
brandId: import_zod49.z.string().min(1).describe('Brand identifier within the tenant. Example: "your-brand-id".'),
|
|
13029
13053
|
semana: import_zod49.z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "semana debe ser ISO YYYY-MM-DD del lunes").describe('Week identifier (ISO date of Monday). Example: "2026-05-11".'),
|
|
13030
|
-
necesidades: import_zod49.z.array(NecesidadInputSchema).min(1).describe("Array of photo needs (at least 1). Each is merged by tema.")
|
|
13054
|
+
necesidades: import_zod49.z.array(NecesidadInputSchema).min(1).describe("Array of photo needs (at least 1). Each is merged by tema."),
|
|
13055
|
+
actor: import_zod49.z.object({
|
|
13056
|
+
uid: import_zod49.z.string().min(1).describe('User id creating/updating the briefing. Example: "your-user-uid".'),
|
|
13057
|
+
nombre: import_zod49.z.string().min(1).describe('Human-readable user name. Example: "Daniel Gonz\xE1lez".'),
|
|
13058
|
+
clientType: import_zod49.z.string().min(1).describe('Client surface origin. Example: one of "mcp_client" | "martin" | "web" | "admin".'),
|
|
13059
|
+
clientMetadata: import_zod49.z.record(import_zod49.z.string(), import_zod49.z.unknown()).nullable().optional().describe("Optional metadata about the client (session id, device, etc.).")
|
|
13060
|
+
}).describe("Actor (user) creating/updating the briefing \u2014 extracted by the server.tool from ctx.user (\xA79.2).")
|
|
13031
13061
|
});
|
|
13032
13062
|
var OutputSchema14 = import_zod49.z.object({
|
|
13033
13063
|
ok: import_zod49.z.literal(true),
|
|
@@ -13178,7 +13208,7 @@ async function photoDescarter(input) {
|
|
|
13178
13208
|
}
|
|
13179
13209
|
const data = snap.data();
|
|
13180
13210
|
const estadoActual = typeof data.estado === "string" ? data.estado : "";
|
|
13181
|
-
if (!validarTransicionFoto(estadoActual,
|
|
13211
|
+
if (!validarTransicionFoto(estadoActual, ESTADO_FOTO.DESCARTADA)) {
|
|
13182
13212
|
return {
|
|
13183
13213
|
ok: false,
|
|
13184
13214
|
code: "INVALID_STATE_TRANSITION",
|
|
@@ -13186,7 +13216,7 @@ async function photoDescarter(input) {
|
|
|
13186
13216
|
};
|
|
13187
13217
|
}
|
|
13188
13218
|
await ref.update({
|
|
13189
|
-
estado:
|
|
13219
|
+
estado: ESTADO_FOTO.DESCARTADA,
|
|
13190
13220
|
descartadaAt: import_firebase_admin11.firestore.FieldValue.serverTimestamp(),
|
|
13191
13221
|
descartadaPorId: actor.uid,
|
|
13192
13222
|
descartadaPorNombre: actor.nombre,
|
|
@@ -13197,7 +13227,7 @@ async function photoDescarter(input) {
|
|
|
13197
13227
|
ok: true,
|
|
13198
13228
|
fotoId,
|
|
13199
13229
|
estadoAnterior: estadoActual,
|
|
13200
|
-
nuevoEstado:
|
|
13230
|
+
nuevoEstado: ESTADO_FOTO.DESCARTADA
|
|
13201
13231
|
};
|
|
13202
13232
|
}
|
|
13203
13233
|
var ParamsSchema16 = import_zod51.z.object({
|
|
@@ -13268,7 +13298,7 @@ async function photoEditadaMarker(input) {
|
|
|
13268
13298
|
const data = snap.data();
|
|
13269
13299
|
const estadoActual = typeof data.estado === "string" ? data.estado : "";
|
|
13270
13300
|
const archivoOriginal = typeof data.archivoOriginal === "string" ? data.archivoOriginal : null;
|
|
13271
|
-
if (!validarTransicionFoto(estadoActual,
|
|
13301
|
+
if (!validarTransicionFoto(estadoActual, ESTADO_FOTO.EDITADA)) {
|
|
13272
13302
|
return {
|
|
13273
13303
|
ok: false,
|
|
13274
13304
|
code: "INVALID_STATE_TRANSITION",
|
|
@@ -13279,7 +13309,7 @@ async function photoEditadaMarker(input) {
|
|
|
13279
13309
|
return { ok: false, code: "FOTO_SIN_ARCHIVO_ORIGINAL", estadoActual };
|
|
13280
13310
|
}
|
|
13281
13311
|
await ref.update({
|
|
13282
|
-
estado:
|
|
13312
|
+
estado: ESTADO_FOTO.EDITADA,
|
|
13283
13313
|
archivoEditado: archivoOriginal,
|
|
13284
13314
|
fechaEdicion: import_firebase_admin12.firestore.FieldValue.serverTimestamp(),
|
|
13285
13315
|
marcadaEditadaPorId: actor.uid,
|
|
@@ -13291,7 +13321,7 @@ async function photoEditadaMarker(input) {
|
|
|
13291
13321
|
ok: true,
|
|
13292
13322
|
fotoId,
|
|
13293
13323
|
estadoAnterior: estadoActual,
|
|
13294
|
-
nuevoEstado:
|
|
13324
|
+
nuevoEstado: ESTADO_FOTO.EDITADA,
|
|
13295
13325
|
archivoEditado: archivoOriginal
|
|
13296
13326
|
};
|
|
13297
13327
|
}
|
|
@@ -13444,7 +13474,7 @@ async function photoAssigner(input) {
|
|
|
13444
13474
|
return { ok: false, error: `Foto ${fotoId} no encontrada`, code: "PHOTO_NOT_FOUND" };
|
|
13445
13475
|
}
|
|
13446
13476
|
const foto = fotoQuery.docs[0].data();
|
|
13447
|
-
if (foto.estado !==
|
|
13477
|
+
if (foto.estado !== ESTADO_FOTO.EDITADA && foto.estado !== "usada") {
|
|
13448
13478
|
return {
|
|
13449
13479
|
ok: false,
|
|
13450
13480
|
error: `Foto en estado "${foto.estado}", debe ser "editada"`,
|
|
@@ -13861,7 +13891,7 @@ async function marketingPlanBuilder(input) {
|
|
|
13861
13891
|
}
|
|
13862
13892
|
const productosQ = await db.collection("productos").where("tenantId", "==", tenantId).limit(100).get();
|
|
13863
13893
|
const productos = productosQ.docs.map((d) => d.data());
|
|
13864
|
-
const histQ = await db.collection("tenants").doc(tenantId).collection("marketing_contenido").where("brandId", "==", brandId).where("estado", "==",
|
|
13894
|
+
const histQ = await db.collection("tenants").doc(tenantId).collection("marketing_contenido").where("brandId", "==", brandId).where("estado", "==", ESTADO_CONTENIDO.PUBLICADO).limit(20).get();
|
|
13865
13895
|
const historial = histQ.docs.map((d) => d.data());
|
|
13866
13896
|
const lastImportId = await resolveLastImportId(db, tenantId, brandId);
|
|
13867
13897
|
let colecciones = [];
|
|
@@ -14182,7 +14212,7 @@ async function contenidoWriter(input) {
|
|
|
14182
14212
|
tipo: tipo ?? "post",
|
|
14183
14213
|
keyword: keyword ?? null,
|
|
14184
14214
|
languageCode,
|
|
14185
|
-
estado:
|
|
14215
|
+
estado: ESTADO_CONTENIDO.PENDIENTE_APROBACION,
|
|
14186
14216
|
fotoId: fotoId ?? null,
|
|
14187
14217
|
mediaUrl: null,
|
|
14188
14218
|
calendarioItemRef: calendarioItemRef ?? null,
|
|
@@ -14308,7 +14338,7 @@ async function contenidoWriter(input) {
|
|
|
14308
14338
|
return {
|
|
14309
14339
|
ok: true,
|
|
14310
14340
|
contenidoId: id,
|
|
14311
|
-
estado:
|
|
14341
|
+
estado: ESTADO_CONTENIDO.PENDIENTE_APROBACION,
|
|
14312
14342
|
plataforma,
|
|
14313
14343
|
descartados,
|
|
14314
14344
|
pipelineLinked
|
|
@@ -14542,7 +14572,7 @@ async function weeklyContentBuilder(input) {
|
|
|
14542
14572
|
}
|
|
14543
14573
|
};
|
|
14544
14574
|
}
|
|
14545
|
-
const fotosQ = await db.collection("tenants").doc(tenantId).collection("marketing_fotos").where("brandId", "==", brandId).where("estado", "==",
|
|
14575
|
+
const fotosQ = await db.collection("tenants").doc(tenantId).collection("marketing_fotos").where("brandId", "==", brandId).where("estado", "==", ESTADO_FOTO.EDITADA).limit(20).get();
|
|
14546
14576
|
const fotosDisponibles = fotosQ.docs.map((d) => d.data());
|
|
14547
14577
|
const histQ = await db.collection("tenants").doc(tenantId).collection("marketing_contenido").where("brandId", "==", brandId).limit(20).get();
|
|
14548
14578
|
const historial = histQ.docs.map((d) => d.data());
|
|
@@ -14552,7 +14582,7 @@ async function weeklyContentBuilder(input) {
|
|
|
14552
14582
|
const blogStrategy = brand.blogStrategy;
|
|
14553
14583
|
const blogs = blogStrategy?.blogs ?? [];
|
|
14554
14584
|
const idiomas = brand.idiomas;
|
|
14555
|
-
const articulosQ = await db.collection("tenants").doc(tenantId).collection("marketing_contenido").where("brandId", "==", brandId).where("plataforma", "==", "shopify_blog").where("estado", "==",
|
|
14585
|
+
const articulosQ = await db.collection("tenants").doc(tenantId).collection("marketing_contenido").where("brandId", "==", brandId).where("plataforma", "==", "shopify_blog").where("estado", "==", ESTADO_CONTENIDO.PUBLICADO).limit(20).get();
|
|
14556
14586
|
const articulosExistentes = articulosQ.docs.map(
|
|
14557
14587
|
(d) => d.data()
|
|
14558
14588
|
);
|
|
@@ -16108,8 +16138,8 @@ async function buildTenantContext(db, tenantId, brandId) {
|
|
|
16108
16138
|
if (!configSnap.exists) return "";
|
|
16109
16139
|
const brand = configSnap.data();
|
|
16110
16140
|
const [fotosQ, contenidoQ, productosQ] = await Promise.all([
|
|
16111
|
-
db.collection("tenants").doc(tenantId).collection("marketing_fotos").where("brandId", "==", brandId).where("estado", "==",
|
|
16112
|
-
db.collection("tenants").doc(tenantId).collection("marketing_contenido").where("brandId", "==", brandId).where("estado", "==",
|
|
16141
|
+
db.collection("tenants").doc(tenantId).collection("marketing_fotos").where("brandId", "==", brandId).where("estado", "==", ESTADO_FOTO.EDITADA).limit(10).get(),
|
|
16142
|
+
db.collection("tenants").doc(tenantId).collection("marketing_contenido").where("brandId", "==", brandId).where("estado", "==", ESTADO_CONTENIDO.PUBLICADO).limit(10).get(),
|
|
16113
16143
|
db.collection("productos").where("tenantId", "==", tenantId).limit(50).get()
|
|
16114
16144
|
]);
|
|
16115
16145
|
const fotosEditadas = fotosQ.docs.map((d) => d.data());
|
|
@@ -16576,7 +16606,9 @@ function registerContextTools(server, session) {
|
|
|
16576
16606
|
}
|
|
16577
16607
|
);
|
|
16578
16608
|
}
|
|
16579
|
-
|
|
16609
|
+
const isMultiBrand = session.brands && session.brands.length > 1;
|
|
16610
|
+
const isSuperAdmin = session.canSwitchTenant;
|
|
16611
|
+
if (isMultiBrand || isSuperAdmin) {
|
|
16580
16612
|
server.tool(
|
|
16581
16613
|
"select_brand",
|
|
16582
16614
|
"Switch the active brand within your tenant. Use when you have multi-brand access (agency mode) and want to work with a different brand without passing brandId on every tool call. Does NOT change tenant.",
|
|
@@ -17490,11 +17522,17 @@ IMPORTANT \u2014 'razon' field: the tenant sees this in the app. Write in friend
|
|
|
17490
17522
|
const tenantId = session.requireTenant();
|
|
17491
17523
|
const brandId = inputBrandId ?? session.requireBrand();
|
|
17492
17524
|
const ctx = await buildContext(session, brandId);
|
|
17525
|
+
const actor = {
|
|
17526
|
+
uid: ctx.user.uid,
|
|
17527
|
+
nombre: ctx.user.nombre ?? ctx.user.uid,
|
|
17528
|
+
clientType: ctx.user.clientType ?? "mcp_client",
|
|
17529
|
+
clientMetadata: ctx.user.clientMetadata ?? null
|
|
17530
|
+
};
|
|
17493
17531
|
const result = await dispatchWithContract({
|
|
17494
17532
|
contract: photoBriefingWriterContract,
|
|
17495
17533
|
helper: photoBriefingWriter,
|
|
17496
17534
|
callable: callPhotoBriefingWriter,
|
|
17497
|
-
input: { tenantId, brandId, semana, necesidades },
|
|
17535
|
+
input: { tenantId, brandId, semana, necesidades, actor },
|
|
17498
17536
|
ctx
|
|
17499
17537
|
});
|
|
17500
17538
|
let payload;
|