@open-mercato/core 0.6.6-develop.6429.1.2fba7258d1 → 0.6.6-develop.6450.1.b493fb430c
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/.turbo/turbo-build.log +1 -1
- package/dist/modules/customers/api/people/[id]/route.js +73 -2
- package/dist/modules/customers/api/people/[id]/route.js.map +2 -2
- package/dist/modules/planner/commands/shared.js +1 -8
- package/dist/modules/planner/commands/shared.js.map +2 -2
- package/dist/modules/resources/commands/shared.js +1 -7
- package/dist/modules/resources/commands/shared.js.map +2 -2
- package/dist/modules/shipping_carriers/api/cancel/route.js +2 -2
- package/dist/modules/shipping_carriers/api/cancel/route.js.map +2 -2
- package/dist/modules/shipping_carriers/api/points/route.js +2 -2
- package/dist/modules/shipping_carriers/api/points/route.js.map +2 -2
- package/dist/modules/shipping_carriers/api/rates/route.js +2 -2
- package/dist/modules/shipping_carriers/api/rates/route.js.map +2 -2
- package/dist/modules/shipping_carriers/api/shipments/route.js +2 -2
- package/dist/modules/shipping_carriers/api/shipments/route.js.map +2 -2
- package/dist/modules/shipping_carriers/api/tracking/refresh/route.js +2 -2
- package/dist/modules/shipping_carriers/api/tracking/refresh/route.js.map +2 -2
- package/dist/modules/shipping_carriers/api/tracking/route.js +2 -2
- package/dist/modules/shipping_carriers/api/tracking/route.js.map +2 -2
- package/dist/modules/shipping_carriers/lib/upstream-error-response.js +13 -0
- package/dist/modules/shipping_carriers/lib/upstream-error-response.js.map +7 -0
- package/dist/modules/staff/commands/activities.js +46 -8
- package/dist/modules/staff/commands/activities.js.map +2 -2
- package/dist/modules/staff/commands/addresses.js +40 -7
- package/dist/modules/staff/commands/addresses.js.map +2 -2
- package/dist/modules/staff/commands/comments.js +46 -8
- package/dist/modules/staff/commands/comments.js.map +2 -2
- package/dist/modules/staff/commands/job-histories.js +40 -7
- package/dist/modules/staff/commands/job-histories.js.map +2 -2
- package/dist/modules/staff/commands/leave-requests.js +31 -9
- package/dist/modules/staff/commands/leave-requests.js.map +2 -2
- package/dist/modules/staff/commands/shared.js +56 -7
- package/dist/modules/staff/commands/shared.js.map +2 -2
- package/dist/modules/staff/commands/tag-assignments.js +18 -7
- package/dist/modules/staff/commands/tag-assignments.js.map +2 -2
- package/dist/modules/staff/commands/team-members.js +16 -5
- package/dist/modules/staff/commands/team-members.js.map +2 -2
- package/dist/modules/staff/commands/team-roles.js +16 -5
- package/dist/modules/staff/commands/team-roles.js.map +2 -2
- package/dist/modules/staff/commands/teams.js +16 -5
- package/dist/modules/staff/commands/teams.js.map +2 -2
- package/dist/modules/staff/commands/timesheets-entries.js +17 -5
- package/dist/modules/staff/commands/timesheets-entries.js.map +2 -2
- package/dist/modules/staff/commands/timesheets-projects.js +22 -9
- package/dist/modules/staff/commands/timesheets-projects.js.map +2 -2
- package/dist/modules/sync_excel/lib/upload-storage.js +9 -6
- package/dist/modules/sync_excel/lib/upload-storage.js.map +2 -2
- package/dist/modules/translations/api/get/locales.js +2 -1
- package/dist/modules/translations/api/get/locales.js.map +2 -2
- package/dist/modules/translations/api/put/locales.js +1 -1
- package/dist/modules/translations/api/put/locales.js.map +2 -2
- package/dist/modules/workflows/examples/sales-pipeline-definition.json +8 -8
- package/dist/modules/workflows/lib/activity-executor.js +39 -3
- package/dist/modules/workflows/lib/activity-executor.js.map +2 -2
- package/package.json +7 -7
- package/src/modules/customers/api/people/[id]/route.ts +107 -2
- package/src/modules/planner/commands/shared.ts +2 -11
- package/src/modules/resources/commands/shared.ts +2 -10
- package/src/modules/shipping_carriers/api/cancel/route.ts +2 -2
- package/src/modules/shipping_carriers/api/points/route.ts +2 -2
- package/src/modules/shipping_carriers/api/rates/route.ts +2 -2
- package/src/modules/shipping_carriers/api/shipments/route.ts +2 -2
- package/src/modules/shipping_carriers/api/tracking/refresh/route.ts +2 -2
- package/src/modules/shipping_carriers/api/tracking/route.ts +2 -2
- package/src/modules/shipping_carriers/i18n/de.json +1 -0
- package/src/modules/shipping_carriers/i18n/en.json +1 -0
- package/src/modules/shipping_carriers/i18n/es.json +1 -0
- package/src/modules/shipping_carriers/i18n/pl.json +1 -0
- package/src/modules/shipping_carriers/lib/upstream-error-response.ts +11 -0
- package/src/modules/staff/commands/activities.ts +46 -8
- package/src/modules/staff/commands/addresses.ts +40 -7
- package/src/modules/staff/commands/comments.ts +46 -8
- package/src/modules/staff/commands/job-histories.ts +40 -7
- package/src/modules/staff/commands/leave-requests.ts +36 -9
- package/src/modules/staff/commands/shared.ts +71 -8
- package/src/modules/staff/commands/tag-assignments.ts +18 -7
- package/src/modules/staff/commands/team-members.ts +16 -5
- package/src/modules/staff/commands/team-roles.ts +16 -5
- package/src/modules/staff/commands/teams.ts +16 -5
- package/src/modules/staff/commands/timesheets-entries.ts +17 -5
- package/src/modules/staff/commands/timesheets-projects.ts +22 -9
- package/src/modules/sync_excel/lib/upload-storage.ts +8 -6
- package/src/modules/translations/api/get/locales.ts +1 -0
- package/src/modules/translations/api/put/locales.ts +1 -1
- package/src/modules/workflows/AGENTS.md +2 -1
- package/src/modules/workflows/examples/sales-pipeline-definition.json +8 -8
- package/src/modules/workflows/lib/activity-executor.ts +49 -5
|
@@ -7,8 +7,12 @@ import {
|
|
|
7
7
|
} from "../data/validators.js";
|
|
8
8
|
import { staffTeamMemberAddressCrudEvents } from "../lib/crud.js";
|
|
9
9
|
import {
|
|
10
|
+
applyScopeToWhere,
|
|
11
|
+
commandActorScope,
|
|
12
|
+
commandInputScope,
|
|
10
13
|
ensureOrganizationScope,
|
|
11
14
|
ensureTenantScope,
|
|
15
|
+
explicitStaffCommandScope,
|
|
12
16
|
extractUndoPayload,
|
|
13
17
|
requireTeamMember
|
|
14
18
|
} from "./shared.js";
|
|
@@ -56,8 +60,14 @@ const createAddressCommand = {
|
|
|
56
60
|
const parsed = staffTeamMemberAddressCreateSchema.parse(rawInput);
|
|
57
61
|
ensureTenantScope(ctx, parsed.tenantId);
|
|
58
62
|
ensureOrganizationScope(ctx, parsed.organizationId);
|
|
63
|
+
const scope = commandInputScope(ctx, parsed.tenantId, parsed.organizationId);
|
|
59
64
|
const em = ctx.container.resolve("em").fork();
|
|
60
|
-
const member = await requireTeamMember(
|
|
65
|
+
const member = await requireTeamMember(
|
|
66
|
+
em,
|
|
67
|
+
parsed.entityId,
|
|
68
|
+
scope,
|
|
69
|
+
"Team member not found"
|
|
70
|
+
);
|
|
61
71
|
ensureTenantScope(ctx, member.tenantId);
|
|
62
72
|
ensureOrganizationScope(ctx, member.organizationId);
|
|
63
73
|
const address = em.create(StaffTeamMemberAddress, {
|
|
@@ -141,7 +151,12 @@ const createAddressCommand = {
|
|
|
141
151
|
throw new CrudHttpError(400, { error: "[internal] redo snapshot unavailable for address create" });
|
|
142
152
|
}
|
|
143
153
|
const em = ctx.container.resolve("em").fork();
|
|
144
|
-
const member = await requireTeamMember(
|
|
154
|
+
const member = await requireTeamMember(
|
|
155
|
+
em,
|
|
156
|
+
after.memberId,
|
|
157
|
+
explicitStaffCommandScope(after.tenantId, after.organizationId),
|
|
158
|
+
"Team member not found"
|
|
159
|
+
);
|
|
145
160
|
let address = await em.findOne(StaffTeamMemberAddress, { id: after.id });
|
|
146
161
|
if (!address) {
|
|
147
162
|
address = em.create(StaffTeamMemberAddress, {
|
|
@@ -216,12 +231,16 @@ const updateAddressCommand = {
|
|
|
216
231
|
async execute(rawInput, ctx) {
|
|
217
232
|
const parsed = staffTeamMemberAddressUpdateSchema.parse(rawInput);
|
|
218
233
|
const em = ctx.container.resolve("em").fork();
|
|
219
|
-
const
|
|
234
|
+
const scope = commandActorScope(ctx);
|
|
235
|
+
const address = await em.findOne(
|
|
236
|
+
StaffTeamMemberAddress,
|
|
237
|
+
applyScopeToWhere({ id: parsed.id }, scope)
|
|
238
|
+
);
|
|
220
239
|
if (!address) throw new CrudHttpError(404, { error: "Address not found" });
|
|
221
240
|
ensureTenantScope(ctx, address.tenantId);
|
|
222
241
|
ensureOrganizationScope(ctx, address.organizationId);
|
|
223
242
|
if (parsed.entityId !== void 0) {
|
|
224
|
-
const member = await requireTeamMember(em, parsed.entityId, "Team member not found");
|
|
243
|
+
const member = await requireTeamMember(em, parsed.entityId, scope, "Team member not found");
|
|
225
244
|
ensureTenantScope(ctx, member.tenantId);
|
|
226
245
|
ensureOrganizationScope(ctx, member.organizationId);
|
|
227
246
|
address.member = member;
|
|
@@ -315,7 +334,12 @@ const updateAddressCommand = {
|
|
|
315
334
|
if (!before) return;
|
|
316
335
|
const em = ctx.container.resolve("em").fork();
|
|
317
336
|
let address = await em.findOne(StaffTeamMemberAddress, { id: before.id });
|
|
318
|
-
const member = await requireTeamMember(
|
|
337
|
+
const member = await requireTeamMember(
|
|
338
|
+
em,
|
|
339
|
+
before.memberId,
|
|
340
|
+
explicitStaffCommandScope(before.tenantId, before.organizationId),
|
|
341
|
+
"Team member not found"
|
|
342
|
+
);
|
|
319
343
|
if (!address) {
|
|
320
344
|
address = em.create(StaffTeamMemberAddress, {
|
|
321
345
|
id: before.id,
|
|
@@ -388,7 +412,11 @@ const deleteAddressCommand = {
|
|
|
388
412
|
async execute(input, ctx) {
|
|
389
413
|
const id = requireId(input, "Address id required");
|
|
390
414
|
const em = ctx.container.resolve("em").fork();
|
|
391
|
-
const
|
|
415
|
+
const scope = commandActorScope(ctx);
|
|
416
|
+
const address = await em.findOne(
|
|
417
|
+
StaffTeamMemberAddress,
|
|
418
|
+
applyScopeToWhere({ id }, scope)
|
|
419
|
+
);
|
|
392
420
|
if (!address) throw new CrudHttpError(404, { error: "Address not found" });
|
|
393
421
|
ensureTenantScope(ctx, address.tenantId);
|
|
394
422
|
ensureOrganizationScope(ctx, address.organizationId);
|
|
@@ -434,7 +462,12 @@ const deleteAddressCommand = {
|
|
|
434
462
|
const before = payload?.before;
|
|
435
463
|
if (!before) return;
|
|
436
464
|
const em = ctx.container.resolve("em").fork();
|
|
437
|
-
const member = await requireTeamMember(
|
|
465
|
+
const member = await requireTeamMember(
|
|
466
|
+
em,
|
|
467
|
+
before.memberId,
|
|
468
|
+
explicitStaffCommandScope(before.tenantId, before.organizationId),
|
|
469
|
+
"Team member not found"
|
|
470
|
+
);
|
|
438
471
|
let address = await em.findOne(StaffTeamMemberAddress, { id: before.id });
|
|
439
472
|
if (!address) {
|
|
440
473
|
address = em.create(StaffTeamMemberAddress, {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/modules/staff/commands/addresses.ts"],
|
|
4
|
-
"sourcesContent": ["import { registerCommand } from '@open-mercato/shared/lib/commands'\nimport type { CommandHandler } from '@open-mercato/shared/lib/commands'\nimport { emitCrudSideEffects, emitCrudUndoSideEffects, buildChanges, requireId } from '@open-mercato/shared/lib/commands/helpers'\nimport type { DataEngine } from '@open-mercato/shared/lib/data/engine'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { StaffTeamMemberAddress } from '../data/entities'\nimport {\n staffTeamMemberAddressCreateSchema,\n staffTeamMemberAddressUpdateSchema,\n type StaffTeamMemberAddressCreateInput,\n type StaffTeamMemberAddressUpdateInput,\n} from '../data/validators'\nimport { staffTeamMemberAddressCrudEvents } from '../lib/crud'\nimport {\n ensureOrganizationScope,\n ensureTenantScope,\n extractUndoPayload,\n requireTeamMember,\n} from './shared'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { resolveRedoSnapshot } from '@open-mercato/shared/lib/commands/redo'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport type { CrudIndexerConfig } from '@open-mercato/shared/lib/crud/types'\nimport { E } from '#generated/entities.ids.generated'\n\nconst addressCrudIndexer: CrudIndexerConfig<StaffTeamMemberAddress> = {\n entityType: E.staff.staff_team_member_address,\n}\n\ntype AddressSnapshot = {\n id: string\n organizationId: string\n tenantId: string\n memberId: string\n name: string | null\n purpose: string | null\n companyName: string | null\n addressLine1: string\n addressLine2: string | null\n buildingNumber: string | null\n flatNumber: string | null\n city: string | null\n region: string | null\n postalCode: string | null\n country: string | null\n latitude: number | null\n longitude: number | null\n isPrimary: boolean\n}\n\ntype AddressUndoPayload = {\n before?: AddressSnapshot | null\n after?: AddressSnapshot | null\n}\n\nasync function loadAddressSnapshot(em: EntityManager, id: string): Promise<AddressSnapshot | null> {\n const address = await em.findOne(StaffTeamMemberAddress, { id })\n if (!address) return null\n return {\n id: address.id,\n organizationId: address.organizationId,\n tenantId: address.tenantId,\n memberId: typeof address.member === 'string' ? address.member : address.member.id,\n name: address.name ?? null,\n purpose: address.purpose ?? null,\n companyName: address.companyName ?? null,\n addressLine1: address.addressLine1,\n addressLine2: address.addressLine2 ?? null,\n buildingNumber: address.buildingNumber ?? null,\n flatNumber: address.flatNumber ?? null,\n city: address.city ?? null,\n region: address.region ?? null,\n postalCode: address.postalCode ?? null,\n country: address.country ?? null,\n latitude: address.latitude ?? null,\n longitude: address.longitude ?? null,\n isPrimary: address.isPrimary,\n }\n}\n\nasync function enforcePrimaryAddress(em: EntityManager, memberId: string, addressId: string): Promise<void> {\n await em.nativeUpdate(\n StaffTeamMemberAddress,\n { member: memberId, id: { $ne: addressId }, isPrimary: true },\n { isPrimary: false }\n )\n}\n\nconst createAddressCommand: CommandHandler<StaffTeamMemberAddressCreateInput, { addressId: string }> = {\n id: 'staff.team-member-addresses.create',\n async execute(rawInput, ctx) {\n const parsed = staffTeamMemberAddressCreateSchema.parse(rawInput)\n ensureTenantScope(ctx, parsed.tenantId)\n ensureOrganizationScope(ctx, parsed.organizationId)\n\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const member = await requireTeamMember(em, parsed.entityId, 'Team member not found')\n ensureTenantScope(ctx, member.tenantId)\n ensureOrganizationScope(ctx, member.organizationId)\n\n const address = em.create(StaffTeamMemberAddress, {\n organizationId: parsed.organizationId,\n tenantId: parsed.tenantId,\n member,\n name: parsed.name ?? null,\n purpose: parsed.purpose ?? null,\n companyName: parsed.companyName ?? null,\n addressLine1: parsed.addressLine1,\n addressLine2: parsed.addressLine2 ?? null,\n buildingNumber: parsed.buildingNumber ?? null,\n flatNumber: parsed.flatNumber ?? null,\n city: parsed.city ?? null,\n region: parsed.region ?? null,\n postalCode: parsed.postalCode ?? null,\n country: parsed.country ?? null,\n latitude: parsed.latitude ?? null,\n longitude: parsed.longitude ?? null,\n isPrimary: parsed.isPrimary ?? false,\n createdAt: new Date(),\n updatedAt: new Date(),\n })\n em.persist(address)\n await em.flush()\n\n if (address.isPrimary) {\n await enforcePrimaryAddress(em, member.id, address.id)\n await em.flush()\n }\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'created',\n entity: address,\n identifiers: {\n id: address.id,\n organizationId: address.organizationId,\n tenantId: address.tenantId,\n },\n events: staffTeamMemberAddressCrudEvents,\n indexer: addressCrudIndexer,\n })\n\n return { addressId: address.id }\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return await loadAddressSnapshot(em, result.addressId)\n },\n buildLog: async ({ result, snapshots }) => {\n const { translate } = await resolveTranslations()\n const snapshot = snapshots.after as AddressSnapshot | undefined\n return {\n actionLabel: translate('staff.audit.teamMemberAddresses.create', 'Create address'),\n resourceKind: 'staff.team_member_address',\n resourceId: result.addressId,\n parentResourceKind: 'staff.teamMember',\n parentResourceId: snapshot?.memberId ?? null,\n tenantId: snapshot?.tenantId ?? null,\n organizationId: snapshot?.organizationId ?? null,\n snapshotAfter: snapshot ?? null,\n payload: {\n undo: {\n after: snapshot ?? null,\n } satisfies AddressUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const addressId = logEntry?.resourceId ?? null\n if (!addressId) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const address = await em.findOne(StaffTeamMemberAddress, { id: addressId })\n if (address) {\n em.remove(address)\n await em.flush()\n }\n },\n redo: async ({ logEntry, ctx }) => {\n const after = resolveRedoSnapshot<AddressSnapshot>(logEntry)\n if (!after) {\n throw new CrudHttpError(400, { error: '[internal] redo snapshot unavailable for address create' })\n }\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const member = await requireTeamMember(em, after.memberId, 'Team member not found')\n let address = await em.findOne(StaffTeamMemberAddress, { id: after.id })\n if (!address) {\n address = em.create(StaffTeamMemberAddress, {\n id: after.id,\n organizationId: after.organizationId,\n tenantId: after.tenantId,\n member,\n name: after.name,\n purpose: after.purpose,\n companyName: after.companyName,\n addressLine1: after.addressLine1,\n addressLine2: after.addressLine2,\n buildingNumber: after.buildingNumber,\n flatNumber: after.flatNumber,\n city: after.city,\n region: after.region,\n postalCode: after.postalCode,\n country: after.country,\n latitude: after.latitude,\n longitude: after.longitude,\n isPrimary: after.isPrimary,\n createdAt: new Date(),\n updatedAt: new Date(),\n })\n em.persist(address)\n } else {\n address.member = member\n address.name = after.name\n address.purpose = after.purpose\n address.companyName = after.companyName\n address.addressLine1 = after.addressLine1\n address.addressLine2 = after.addressLine2\n address.buildingNumber = after.buildingNumber\n address.flatNumber = after.flatNumber\n address.city = after.city\n address.region = after.region\n address.postalCode = after.postalCode\n address.country = after.country\n address.latitude = after.latitude\n address.longitude = after.longitude\n address.isPrimary = after.isPrimary\n }\n await em.flush()\n if (after.isPrimary) {\n await enforcePrimaryAddress(em, after.memberId, after.id)\n await em.flush()\n }\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'created',\n entity: address,\n identifiers: {\n id: address.id,\n organizationId: address.organizationId,\n tenantId: address.tenantId,\n },\n events: staffTeamMemberAddressCrudEvents,\n indexer: addressCrudIndexer,\n })\n\n return { addressId: address.id }\n },\n}\n\nconst updateAddressCommand: CommandHandler<StaffTeamMemberAddressUpdateInput, { addressId: string }> = {\n id: 'staff.team-member-addresses.update',\n async prepare(rawInput, ctx) {\n const parsed = staffTeamMemberAddressUpdateSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager)\n const snapshot = await loadAddressSnapshot(em, parsed.id)\n return snapshot ? { before: snapshot } : {}\n },\n async execute(rawInput, ctx) {\n const parsed = staffTeamMemberAddressUpdateSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const address = await em.findOne(StaffTeamMemberAddress, { id: parsed.id })\n if (!address) throw new CrudHttpError(404, { error: 'Address not found' })\n ensureTenantScope(ctx, address.tenantId)\n ensureOrganizationScope(ctx, address.organizationId)\n\n if (parsed.entityId !== undefined) {\n const member = await requireTeamMember(em, parsed.entityId, 'Team member not found')\n ensureTenantScope(ctx, member.tenantId)\n ensureOrganizationScope(ctx, member.organizationId)\n address.member = member\n }\n if (parsed.name !== undefined) address.name = parsed.name ?? null\n if (parsed.purpose !== undefined) address.purpose = parsed.purpose ?? null\n if (parsed.companyName !== undefined) address.companyName = parsed.companyName ?? null\n if (parsed.addressLine1 !== undefined) address.addressLine1 = parsed.addressLine1\n if (parsed.addressLine2 !== undefined) address.addressLine2 = parsed.addressLine2 ?? null\n if (parsed.buildingNumber !== undefined) address.buildingNumber = parsed.buildingNumber ?? null\n if (parsed.flatNumber !== undefined) address.flatNumber = parsed.flatNumber ?? null\n if (parsed.city !== undefined) address.city = parsed.city ?? null\n if (parsed.region !== undefined) address.region = parsed.region ?? null\n if (parsed.postalCode !== undefined) address.postalCode = parsed.postalCode ?? null\n if (parsed.country !== undefined) address.country = parsed.country ?? null\n if (parsed.latitude !== undefined) address.latitude = parsed.latitude ?? null\n if (parsed.longitude !== undefined) address.longitude = parsed.longitude ?? null\n if (parsed.isPrimary !== undefined) address.isPrimary = parsed.isPrimary\n\n await em.flush()\n\n if (address.isPrimary) {\n await enforcePrimaryAddress(em, typeof address.member === 'string' ? address.member : address.member.id, address.id)\n await em.flush()\n }\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'updated',\n entity: address,\n identifiers: {\n id: address.id,\n organizationId: address.organizationId,\n tenantId: address.tenantId,\n },\n events: staffTeamMemberAddressCrudEvents,\n indexer: addressCrudIndexer,\n })\n\n return { addressId: address.id }\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return await loadAddressSnapshot(em, result.addressId)\n },\n buildLog: async ({ snapshots }) => {\n const { translate } = await resolveTranslations()\n const before = snapshots.before as AddressSnapshot | undefined\n if (!before) return null\n const afterSnapshot = snapshots.after as AddressSnapshot | undefined\n const changes =\n afterSnapshot && before\n ? buildChanges(\n before as unknown as Record<string, unknown>,\n afterSnapshot as unknown as Record<string, unknown>,\n [\n 'memberId',\n 'name',\n 'purpose',\n 'companyName',\n 'addressLine1',\n 'addressLine2',\n 'buildingNumber',\n 'flatNumber',\n 'city',\n 'region',\n 'postalCode',\n 'country',\n 'latitude',\n 'longitude',\n 'isPrimary',\n ],\n )\n : {}\n return {\n actionLabel: translate('staff.audit.teamMemberAddresses.update', 'Update address'),\n resourceKind: 'staff.team_member_address',\n resourceId: before.id,\n parentResourceKind: 'staff.teamMember',\n parentResourceId: before.memberId ?? null,\n tenantId: before.tenantId,\n organizationId: before.organizationId,\n snapshotBefore: before,\n snapshotAfter: afterSnapshot ?? null,\n changes,\n payload: {\n undo: {\n before,\n after: afterSnapshot ?? null,\n } satisfies AddressUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<AddressUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n let address = await em.findOne(StaffTeamMemberAddress, { id: before.id })\n const member = await requireTeamMember(em, before.memberId, 'Team member not found')\n\n if (!address) {\n address = em.create(StaffTeamMemberAddress, {\n id: before.id,\n organizationId: before.organizationId,\n tenantId: before.tenantId,\n member,\n name: before.name,\n purpose: before.purpose,\n companyName: before.companyName,\n addressLine1: before.addressLine1,\n addressLine2: before.addressLine2,\n buildingNumber: before.buildingNumber,\n flatNumber: before.flatNumber,\n city: before.city,\n region: before.region,\n postalCode: before.postalCode,\n country: before.country,\n latitude: before.latitude,\n longitude: before.longitude,\n isPrimary: before.isPrimary,\n createdAt: new Date(),\n updatedAt: new Date(),\n })\n em.persist(address)\n } else {\n address.member = member\n address.name = before.name\n address.purpose = before.purpose\n address.companyName = before.companyName\n address.addressLine1 = before.addressLine1\n address.addressLine2 = before.addressLine2\n address.buildingNumber = before.buildingNumber\n address.flatNumber = before.flatNumber\n address.city = before.city\n address.region = before.region\n address.postalCode = before.postalCode\n address.country = before.country\n address.latitude = before.latitude\n address.longitude = before.longitude\n address.isPrimary = before.isPrimary\n }\n await em.flush()\n if (before.isPrimary) {\n await enforcePrimaryAddress(em, before.memberId, before.id)\n await em.flush()\n }\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudUndoSideEffects({\n dataEngine: de,\n action: 'updated',\n entity: address,\n identifiers: {\n id: address.id,\n organizationId: address.organizationId,\n tenantId: address.tenantId,\n },\n events: staffTeamMemberAddressCrudEvents,\n indexer: addressCrudIndexer,\n })\n },\n}\n\nconst deleteAddressCommand: CommandHandler<{ body?: Record<string, unknown>; query?: Record<string, unknown> }, { addressId: string }> =\n {\n id: 'staff.team-member-addresses.delete',\n async prepare(input, ctx) {\n const id = requireId(input, 'Address id required')\n const em = (ctx.container.resolve('em') as EntityManager)\n const snapshot = await loadAddressSnapshot(em, id)\n return snapshot ? { before: snapshot } : {}\n },\n async execute(input, ctx) {\n const id = requireId(input, 'Address id required')\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const address = await em.findOne(StaffTeamMemberAddress, { id })\n if (!address) throw new CrudHttpError(404, { error: 'Address not found' })\n ensureTenantScope(ctx, address.tenantId)\n ensureOrganizationScope(ctx, address.organizationId)\n em.remove(address)\n await em.flush()\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'deleted',\n entity: address,\n identifiers: {\n id: address.id,\n organizationId: address.organizationId,\n tenantId: address.tenantId,\n },\n events: staffTeamMemberAddressCrudEvents,\n indexer: addressCrudIndexer,\n })\n return { addressId: address.id }\n },\n buildLog: async ({ snapshots }) => {\n const before = snapshots.before as AddressSnapshot | undefined\n if (!before) return null\n const { translate } = await resolveTranslations()\n return {\n actionLabel: translate('staff.audit.teamMemberAddresses.delete', 'Delete address'),\n resourceKind: 'staff.team_member_address',\n resourceId: before.id,\n parentResourceKind: 'staff.teamMember',\n parentResourceId: before.memberId ?? null,\n tenantId: before.tenantId,\n organizationId: before.organizationId,\n snapshotBefore: before,\n payload: {\n undo: {\n before,\n } satisfies AddressUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<AddressUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const member = await requireTeamMember(em, before.memberId, 'Team member not found')\n let address = await em.findOne(StaffTeamMemberAddress, { id: before.id })\n if (!address) {\n address = em.create(StaffTeamMemberAddress, {\n id: before.id,\n organizationId: before.organizationId,\n tenantId: before.tenantId,\n member,\n name: before.name,\n purpose: before.purpose,\n companyName: before.companyName,\n addressLine1: before.addressLine1,\n addressLine2: before.addressLine2,\n buildingNumber: before.buildingNumber,\n flatNumber: before.flatNumber,\n city: before.city,\n region: before.region,\n postalCode: before.postalCode,\n country: before.country,\n latitude: before.latitude,\n longitude: before.longitude,\n isPrimary: before.isPrimary,\n createdAt: new Date(),\n updatedAt: new Date(),\n })\n em.persist(address)\n } else {\n address.member = member\n address.name = before.name\n address.purpose = before.purpose\n address.companyName = before.companyName\n address.addressLine1 = before.addressLine1\n address.addressLine2 = before.addressLine2\n address.buildingNumber = before.buildingNumber\n address.flatNumber = before.flatNumber\n address.city = before.city\n address.region = before.region\n address.postalCode = before.postalCode\n address.country = before.country\n address.latitude = before.latitude\n address.longitude = before.longitude\n address.isPrimary = before.isPrimary\n }\n await em.flush()\n if (before.isPrimary) {\n await enforcePrimaryAddress(em, before.memberId, before.id)\n await em.flush()\n }\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudUndoSideEffects({\n dataEngine: de,\n action: 'created',\n entity: address,\n identifiers: {\n id: address.id,\n organizationId: address.organizationId,\n tenantId: address.tenantId,\n },\n events: staffTeamMemberAddressCrudEvents,\n indexer: addressCrudIndexer,\n })\n },\n }\n\nregisterCommand(createAddressCommand)\nregisterCommand(updateAddressCommand)\nregisterCommand(deleteAddressCommand)\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import { registerCommand } from '@open-mercato/shared/lib/commands'\nimport type { CommandHandler } from '@open-mercato/shared/lib/commands'\nimport { emitCrudSideEffects, emitCrudUndoSideEffects, buildChanges, requireId } from '@open-mercato/shared/lib/commands/helpers'\nimport type { DataEngine } from '@open-mercato/shared/lib/data/engine'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { StaffTeamMemberAddress } from '../data/entities'\nimport {\n staffTeamMemberAddressCreateSchema,\n staffTeamMemberAddressUpdateSchema,\n type StaffTeamMemberAddressCreateInput,\n type StaffTeamMemberAddressUpdateInput,\n} from '../data/validators'\nimport { staffTeamMemberAddressCrudEvents } from '../lib/crud'\nimport {\n applyScopeToWhere,\n commandActorScope,\n commandInputScope,\n ensureOrganizationScope,\n ensureTenantScope,\n explicitStaffCommandScope,\n extractUndoPayload,\n requireTeamMember,\n} from './shared'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { resolveRedoSnapshot } from '@open-mercato/shared/lib/commands/redo'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport type { CrudIndexerConfig } from '@open-mercato/shared/lib/crud/types'\nimport { E } from '#generated/entities.ids.generated'\n\nconst addressCrudIndexer: CrudIndexerConfig<StaffTeamMemberAddress> = {\n entityType: E.staff.staff_team_member_address,\n}\n\ntype AddressSnapshot = {\n id: string\n organizationId: string\n tenantId: string\n memberId: string\n name: string | null\n purpose: string | null\n companyName: string | null\n addressLine1: string\n addressLine2: string | null\n buildingNumber: string | null\n flatNumber: string | null\n city: string | null\n region: string | null\n postalCode: string | null\n country: string | null\n latitude: number | null\n longitude: number | null\n isPrimary: boolean\n}\n\ntype AddressUndoPayload = {\n before?: AddressSnapshot | null\n after?: AddressSnapshot | null\n}\n\nasync function loadAddressSnapshot(em: EntityManager, id: string): Promise<AddressSnapshot | null> {\n const address = await em.findOne(StaffTeamMemberAddress, { id })\n if (!address) return null\n return {\n id: address.id,\n organizationId: address.organizationId,\n tenantId: address.tenantId,\n memberId: typeof address.member === 'string' ? address.member : address.member.id,\n name: address.name ?? null,\n purpose: address.purpose ?? null,\n companyName: address.companyName ?? null,\n addressLine1: address.addressLine1,\n addressLine2: address.addressLine2 ?? null,\n buildingNumber: address.buildingNumber ?? null,\n flatNumber: address.flatNumber ?? null,\n city: address.city ?? null,\n region: address.region ?? null,\n postalCode: address.postalCode ?? null,\n country: address.country ?? null,\n latitude: address.latitude ?? null,\n longitude: address.longitude ?? null,\n isPrimary: address.isPrimary,\n }\n}\n\nasync function enforcePrimaryAddress(em: EntityManager, memberId: string, addressId: string): Promise<void> {\n await em.nativeUpdate(\n StaffTeamMemberAddress,\n { member: memberId, id: { $ne: addressId }, isPrimary: true },\n { isPrimary: false }\n )\n}\n\nconst createAddressCommand: CommandHandler<StaffTeamMemberAddressCreateInput, { addressId: string }> = {\n id: 'staff.team-member-addresses.create',\n async execute(rawInput, ctx) {\n const parsed = staffTeamMemberAddressCreateSchema.parse(rawInput)\n ensureTenantScope(ctx, parsed.tenantId)\n ensureOrganizationScope(ctx, parsed.organizationId)\n const scope = commandInputScope(ctx, parsed.tenantId, parsed.organizationId)\n\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const member = await requireTeamMember(\n em,\n parsed.entityId,\n scope,\n 'Team member not found',\n )\n ensureTenantScope(ctx, member.tenantId)\n ensureOrganizationScope(ctx, member.organizationId)\n\n const address = em.create(StaffTeamMemberAddress, {\n organizationId: parsed.organizationId,\n tenantId: parsed.tenantId,\n member,\n name: parsed.name ?? null,\n purpose: parsed.purpose ?? null,\n companyName: parsed.companyName ?? null,\n addressLine1: parsed.addressLine1,\n addressLine2: parsed.addressLine2 ?? null,\n buildingNumber: parsed.buildingNumber ?? null,\n flatNumber: parsed.flatNumber ?? null,\n city: parsed.city ?? null,\n region: parsed.region ?? null,\n postalCode: parsed.postalCode ?? null,\n country: parsed.country ?? null,\n latitude: parsed.latitude ?? null,\n longitude: parsed.longitude ?? null,\n isPrimary: parsed.isPrimary ?? false,\n createdAt: new Date(),\n updatedAt: new Date(),\n })\n em.persist(address)\n await em.flush()\n\n if (address.isPrimary) {\n await enforcePrimaryAddress(em, member.id, address.id)\n await em.flush()\n }\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'created',\n entity: address,\n identifiers: {\n id: address.id,\n organizationId: address.organizationId,\n tenantId: address.tenantId,\n },\n events: staffTeamMemberAddressCrudEvents,\n indexer: addressCrudIndexer,\n })\n\n return { addressId: address.id }\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return await loadAddressSnapshot(em, result.addressId)\n },\n buildLog: async ({ result, snapshots }) => {\n const { translate } = await resolveTranslations()\n const snapshot = snapshots.after as AddressSnapshot | undefined\n return {\n actionLabel: translate('staff.audit.teamMemberAddresses.create', 'Create address'),\n resourceKind: 'staff.team_member_address',\n resourceId: result.addressId,\n parentResourceKind: 'staff.teamMember',\n parentResourceId: snapshot?.memberId ?? null,\n tenantId: snapshot?.tenantId ?? null,\n organizationId: snapshot?.organizationId ?? null,\n snapshotAfter: snapshot ?? null,\n payload: {\n undo: {\n after: snapshot ?? null,\n } satisfies AddressUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const addressId = logEntry?.resourceId ?? null\n if (!addressId) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const address = await em.findOne(StaffTeamMemberAddress, { id: addressId })\n if (address) {\n em.remove(address)\n await em.flush()\n }\n },\n redo: async ({ logEntry, ctx }) => {\n const after = resolveRedoSnapshot<AddressSnapshot>(logEntry)\n if (!after) {\n throw new CrudHttpError(400, { error: '[internal] redo snapshot unavailable for address create' })\n }\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const member = await requireTeamMember(\n em,\n after.memberId,\n explicitStaffCommandScope(after.tenantId, after.organizationId),\n 'Team member not found',\n )\n let address = await em.findOne(StaffTeamMemberAddress, { id: after.id })\n if (!address) {\n address = em.create(StaffTeamMemberAddress, {\n id: after.id,\n organizationId: after.organizationId,\n tenantId: after.tenantId,\n member,\n name: after.name,\n purpose: after.purpose,\n companyName: after.companyName,\n addressLine1: after.addressLine1,\n addressLine2: after.addressLine2,\n buildingNumber: after.buildingNumber,\n flatNumber: after.flatNumber,\n city: after.city,\n region: after.region,\n postalCode: after.postalCode,\n country: after.country,\n latitude: after.latitude,\n longitude: after.longitude,\n isPrimary: after.isPrimary,\n createdAt: new Date(),\n updatedAt: new Date(),\n })\n em.persist(address)\n } else {\n address.member = member\n address.name = after.name\n address.purpose = after.purpose\n address.companyName = after.companyName\n address.addressLine1 = after.addressLine1\n address.addressLine2 = after.addressLine2\n address.buildingNumber = after.buildingNumber\n address.flatNumber = after.flatNumber\n address.city = after.city\n address.region = after.region\n address.postalCode = after.postalCode\n address.country = after.country\n address.latitude = after.latitude\n address.longitude = after.longitude\n address.isPrimary = after.isPrimary\n }\n await em.flush()\n if (after.isPrimary) {\n await enforcePrimaryAddress(em, after.memberId, after.id)\n await em.flush()\n }\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'created',\n entity: address,\n identifiers: {\n id: address.id,\n organizationId: address.organizationId,\n tenantId: address.tenantId,\n },\n events: staffTeamMemberAddressCrudEvents,\n indexer: addressCrudIndexer,\n })\n\n return { addressId: address.id }\n },\n}\n\nconst updateAddressCommand: CommandHandler<StaffTeamMemberAddressUpdateInput, { addressId: string }> = {\n id: 'staff.team-member-addresses.update',\n async prepare(rawInput, ctx) {\n const parsed = staffTeamMemberAddressUpdateSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager)\n const snapshot = await loadAddressSnapshot(em, parsed.id)\n return snapshot ? { before: snapshot } : {}\n },\n async execute(rawInput, ctx) {\n const parsed = staffTeamMemberAddressUpdateSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const scope = commandActorScope(ctx)\n const address = await em.findOne(\n StaffTeamMemberAddress,\n applyScopeToWhere<StaffTeamMemberAddress>({ id: parsed.id }, scope),\n )\n if (!address) throw new CrudHttpError(404, { error: 'Address not found' })\n ensureTenantScope(ctx, address.tenantId)\n ensureOrganizationScope(ctx, address.organizationId)\n\n if (parsed.entityId !== undefined) {\n const member = await requireTeamMember(em, parsed.entityId, scope, 'Team member not found')\n ensureTenantScope(ctx, member.tenantId)\n ensureOrganizationScope(ctx, member.organizationId)\n address.member = member\n }\n if (parsed.name !== undefined) address.name = parsed.name ?? null\n if (parsed.purpose !== undefined) address.purpose = parsed.purpose ?? null\n if (parsed.companyName !== undefined) address.companyName = parsed.companyName ?? null\n if (parsed.addressLine1 !== undefined) address.addressLine1 = parsed.addressLine1\n if (parsed.addressLine2 !== undefined) address.addressLine2 = parsed.addressLine2 ?? null\n if (parsed.buildingNumber !== undefined) address.buildingNumber = parsed.buildingNumber ?? null\n if (parsed.flatNumber !== undefined) address.flatNumber = parsed.flatNumber ?? null\n if (parsed.city !== undefined) address.city = parsed.city ?? null\n if (parsed.region !== undefined) address.region = parsed.region ?? null\n if (parsed.postalCode !== undefined) address.postalCode = parsed.postalCode ?? null\n if (parsed.country !== undefined) address.country = parsed.country ?? null\n if (parsed.latitude !== undefined) address.latitude = parsed.latitude ?? null\n if (parsed.longitude !== undefined) address.longitude = parsed.longitude ?? null\n if (parsed.isPrimary !== undefined) address.isPrimary = parsed.isPrimary\n\n await em.flush()\n\n if (address.isPrimary) {\n await enforcePrimaryAddress(em, typeof address.member === 'string' ? address.member : address.member.id, address.id)\n await em.flush()\n }\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'updated',\n entity: address,\n identifiers: {\n id: address.id,\n organizationId: address.organizationId,\n tenantId: address.tenantId,\n },\n events: staffTeamMemberAddressCrudEvents,\n indexer: addressCrudIndexer,\n })\n\n return { addressId: address.id }\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return await loadAddressSnapshot(em, result.addressId)\n },\n buildLog: async ({ snapshots }) => {\n const { translate } = await resolveTranslations()\n const before = snapshots.before as AddressSnapshot | undefined\n if (!before) return null\n const afterSnapshot = snapshots.after as AddressSnapshot | undefined\n const changes =\n afterSnapshot && before\n ? buildChanges(\n before as unknown as Record<string, unknown>,\n afterSnapshot as unknown as Record<string, unknown>,\n [\n 'memberId',\n 'name',\n 'purpose',\n 'companyName',\n 'addressLine1',\n 'addressLine2',\n 'buildingNumber',\n 'flatNumber',\n 'city',\n 'region',\n 'postalCode',\n 'country',\n 'latitude',\n 'longitude',\n 'isPrimary',\n ],\n )\n : {}\n return {\n actionLabel: translate('staff.audit.teamMemberAddresses.update', 'Update address'),\n resourceKind: 'staff.team_member_address',\n resourceId: before.id,\n parentResourceKind: 'staff.teamMember',\n parentResourceId: before.memberId ?? null,\n tenantId: before.tenantId,\n organizationId: before.organizationId,\n snapshotBefore: before,\n snapshotAfter: afterSnapshot ?? null,\n changes,\n payload: {\n undo: {\n before,\n after: afterSnapshot ?? null,\n } satisfies AddressUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<AddressUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n let address = await em.findOne(StaffTeamMemberAddress, { id: before.id })\n const member = await requireTeamMember(\n em,\n before.memberId,\n explicitStaffCommandScope(before.tenantId, before.organizationId),\n 'Team member not found',\n )\n\n if (!address) {\n address = em.create(StaffTeamMemberAddress, {\n id: before.id,\n organizationId: before.organizationId,\n tenantId: before.tenantId,\n member,\n name: before.name,\n purpose: before.purpose,\n companyName: before.companyName,\n addressLine1: before.addressLine1,\n addressLine2: before.addressLine2,\n buildingNumber: before.buildingNumber,\n flatNumber: before.flatNumber,\n city: before.city,\n region: before.region,\n postalCode: before.postalCode,\n country: before.country,\n latitude: before.latitude,\n longitude: before.longitude,\n isPrimary: before.isPrimary,\n createdAt: new Date(),\n updatedAt: new Date(),\n })\n em.persist(address)\n } else {\n address.member = member\n address.name = before.name\n address.purpose = before.purpose\n address.companyName = before.companyName\n address.addressLine1 = before.addressLine1\n address.addressLine2 = before.addressLine2\n address.buildingNumber = before.buildingNumber\n address.flatNumber = before.flatNumber\n address.city = before.city\n address.region = before.region\n address.postalCode = before.postalCode\n address.country = before.country\n address.latitude = before.latitude\n address.longitude = before.longitude\n address.isPrimary = before.isPrimary\n }\n await em.flush()\n if (before.isPrimary) {\n await enforcePrimaryAddress(em, before.memberId, before.id)\n await em.flush()\n }\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudUndoSideEffects({\n dataEngine: de,\n action: 'updated',\n entity: address,\n identifiers: {\n id: address.id,\n organizationId: address.organizationId,\n tenantId: address.tenantId,\n },\n events: staffTeamMemberAddressCrudEvents,\n indexer: addressCrudIndexer,\n })\n },\n}\n\nconst deleteAddressCommand: CommandHandler<{ body?: Record<string, unknown>; query?: Record<string, unknown> }, { addressId: string }> =\n {\n id: 'staff.team-member-addresses.delete',\n async prepare(input, ctx) {\n const id = requireId(input, 'Address id required')\n const em = (ctx.container.resolve('em') as EntityManager)\n const snapshot = await loadAddressSnapshot(em, id)\n return snapshot ? { before: snapshot } : {}\n },\n async execute(input, ctx) {\n const id = requireId(input, 'Address id required')\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const scope = commandActorScope(ctx)\n const address = await em.findOne(\n StaffTeamMemberAddress,\n applyScopeToWhere<StaffTeamMemberAddress>({ id }, scope),\n )\n if (!address) throw new CrudHttpError(404, { error: 'Address not found' })\n ensureTenantScope(ctx, address.tenantId)\n ensureOrganizationScope(ctx, address.organizationId)\n em.remove(address)\n await em.flush()\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'deleted',\n entity: address,\n identifiers: {\n id: address.id,\n organizationId: address.organizationId,\n tenantId: address.tenantId,\n },\n events: staffTeamMemberAddressCrudEvents,\n indexer: addressCrudIndexer,\n })\n return { addressId: address.id }\n },\n buildLog: async ({ snapshots }) => {\n const before = snapshots.before as AddressSnapshot | undefined\n if (!before) return null\n const { translate } = await resolveTranslations()\n return {\n actionLabel: translate('staff.audit.teamMemberAddresses.delete', 'Delete address'),\n resourceKind: 'staff.team_member_address',\n resourceId: before.id,\n parentResourceKind: 'staff.teamMember',\n parentResourceId: before.memberId ?? null,\n tenantId: before.tenantId,\n organizationId: before.organizationId,\n snapshotBefore: before,\n payload: {\n undo: {\n before,\n } satisfies AddressUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<AddressUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const member = await requireTeamMember(\n em,\n before.memberId,\n explicitStaffCommandScope(before.tenantId, before.organizationId),\n 'Team member not found',\n )\n let address = await em.findOne(StaffTeamMemberAddress, { id: before.id })\n if (!address) {\n address = em.create(StaffTeamMemberAddress, {\n id: before.id,\n organizationId: before.organizationId,\n tenantId: before.tenantId,\n member,\n name: before.name,\n purpose: before.purpose,\n companyName: before.companyName,\n addressLine1: before.addressLine1,\n addressLine2: before.addressLine2,\n buildingNumber: before.buildingNumber,\n flatNumber: before.flatNumber,\n city: before.city,\n region: before.region,\n postalCode: before.postalCode,\n country: before.country,\n latitude: before.latitude,\n longitude: before.longitude,\n isPrimary: before.isPrimary,\n createdAt: new Date(),\n updatedAt: new Date(),\n })\n em.persist(address)\n } else {\n address.member = member\n address.name = before.name\n address.purpose = before.purpose\n address.companyName = before.companyName\n address.addressLine1 = before.addressLine1\n address.addressLine2 = before.addressLine2\n address.buildingNumber = before.buildingNumber\n address.flatNumber = before.flatNumber\n address.city = before.city\n address.region = before.region\n address.postalCode = before.postalCode\n address.country = before.country\n address.latitude = before.latitude\n address.longitude = before.longitude\n address.isPrimary = before.isPrimary\n }\n await em.flush()\n if (before.isPrimary) {\n await enforcePrimaryAddress(em, before.memberId, before.id)\n await em.flush()\n }\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudUndoSideEffects({\n dataEngine: de,\n action: 'created',\n entity: address,\n identifiers: {\n id: address.id,\n organizationId: address.organizationId,\n tenantId: address.tenantId,\n },\n events: staffTeamMemberAddressCrudEvents,\n indexer: addressCrudIndexer,\n })\n },\n }\n\nregisterCommand(createAddressCommand)\nregisterCommand(updateAddressCommand)\nregisterCommand(deleteAddressCommand)\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -8,7 +8,16 @@ import {
|
|
|
8
8
|
staffTeamMemberCommentUpdateSchema
|
|
9
9
|
} from "../data/validators.js";
|
|
10
10
|
import { staffTeamMemberCommentCrudEvents } from "../lib/crud.js";
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
applyScopeToWhere,
|
|
13
|
+
commandActorScope,
|
|
14
|
+
commandInputScope,
|
|
15
|
+
ensureOrganizationScope,
|
|
16
|
+
ensureTenantScope,
|
|
17
|
+
explicitStaffCommandScope,
|
|
18
|
+
extractUndoPayload,
|
|
19
|
+
requireTeamMember
|
|
20
|
+
} from "./shared.js";
|
|
12
21
|
import { makeCreateRedo } from "@open-mercato/shared/lib/commands/redo";
|
|
13
22
|
import { E } from "../../../generated/entities.ids.generated.js";
|
|
14
23
|
const commentCrudIndexer = {
|
|
@@ -34,9 +43,15 @@ const createCommentCommand = {
|
|
|
34
43
|
const parsed = staffTeamMemberCommentCreateSchema.parse(rawInput);
|
|
35
44
|
ensureTenantScope(ctx, parsed.tenantId);
|
|
36
45
|
ensureOrganizationScope(ctx, parsed.organizationId);
|
|
46
|
+
const scope = commandInputScope(ctx, parsed.tenantId, parsed.organizationId);
|
|
37
47
|
const normalizedAuthor = normalizeAuthorUserId(parsed.authorUserId, ctx.auth);
|
|
38
48
|
const em = ctx.container.resolve("em").fork();
|
|
39
|
-
const member = await requireTeamMember(
|
|
49
|
+
const member = await requireTeamMember(
|
|
50
|
+
em,
|
|
51
|
+
parsed.entityId,
|
|
52
|
+
scope,
|
|
53
|
+
"Team member not found"
|
|
54
|
+
);
|
|
40
55
|
ensureTenantScope(ctx, member.tenantId);
|
|
41
56
|
ensureOrganizationScope(ctx, member.organizationId);
|
|
42
57
|
const comment = em.create(StaffTeamMemberComment, {
|
|
@@ -114,7 +129,12 @@ const createCommentCommand = {
|
|
|
114
129
|
appearanceColor: snapshot.appearanceColor
|
|
115
130
|
}),
|
|
116
131
|
beforeRestore: async ({ em, snapshot }) => {
|
|
117
|
-
const member = await requireTeamMember(
|
|
132
|
+
const member = await requireTeamMember(
|
|
133
|
+
em,
|
|
134
|
+
snapshot.memberId,
|
|
135
|
+
explicitStaffCommandScope(snapshot.tenantId, snapshot.organizationId),
|
|
136
|
+
"Team member not found"
|
|
137
|
+
);
|
|
118
138
|
return { member };
|
|
119
139
|
},
|
|
120
140
|
buildResult: (entity) => ({ commentId: entity.id, authorUserId: entity.authorUserId ?? null })
|
|
@@ -131,12 +151,16 @@ const updateCommentCommand = {
|
|
|
131
151
|
async execute(rawInput, ctx) {
|
|
132
152
|
const parsed = staffTeamMemberCommentUpdateSchema.parse(rawInput);
|
|
133
153
|
const em = ctx.container.resolve("em").fork();
|
|
134
|
-
const
|
|
154
|
+
const scope = commandActorScope(ctx);
|
|
155
|
+
const comment = await em.findOne(
|
|
156
|
+
StaffTeamMemberComment,
|
|
157
|
+
applyScopeToWhere({ id: parsed.id }, scope)
|
|
158
|
+
);
|
|
135
159
|
if (!comment) throw new CrudHttpError(404, { error: "Comment not found" });
|
|
136
160
|
ensureTenantScope(ctx, comment.tenantId);
|
|
137
161
|
ensureOrganizationScope(ctx, comment.organizationId);
|
|
138
162
|
if (parsed.entityId !== void 0) {
|
|
139
|
-
const member = await requireTeamMember(em, parsed.entityId, "Team member not found");
|
|
163
|
+
const member = await requireTeamMember(em, parsed.entityId, scope, "Team member not found");
|
|
140
164
|
ensureTenantScope(ctx, member.tenantId);
|
|
141
165
|
ensureOrganizationScope(ctx, member.organizationId);
|
|
142
166
|
comment.member = member;
|
|
@@ -200,7 +224,12 @@ const updateCommentCommand = {
|
|
|
200
224
|
if (!before) return;
|
|
201
225
|
const em = ctx.container.resolve("em").fork();
|
|
202
226
|
let comment = await em.findOne(StaffTeamMemberComment, { id: before.id });
|
|
203
|
-
const member = await requireTeamMember(
|
|
227
|
+
const member = await requireTeamMember(
|
|
228
|
+
em,
|
|
229
|
+
before.memberId,
|
|
230
|
+
explicitStaffCommandScope(before.tenantId, before.organizationId),
|
|
231
|
+
"Team member not found"
|
|
232
|
+
);
|
|
204
233
|
if (!comment) {
|
|
205
234
|
comment = em.create(StaffTeamMemberComment, {
|
|
206
235
|
id: before.id,
|
|
@@ -249,7 +278,11 @@ const deleteCommentCommand = {
|
|
|
249
278
|
async execute(input, ctx) {
|
|
250
279
|
const id = requireId(input, "Comment id required");
|
|
251
280
|
const em = ctx.container.resolve("em").fork();
|
|
252
|
-
const
|
|
281
|
+
const scope = commandActorScope(ctx);
|
|
282
|
+
const comment = await em.findOne(
|
|
283
|
+
StaffTeamMemberComment,
|
|
284
|
+
applyScopeToWhere({ id }, scope)
|
|
285
|
+
);
|
|
253
286
|
if (!comment) throw new CrudHttpError(404, { error: "Comment not found" });
|
|
254
287
|
ensureTenantScope(ctx, comment.tenantId);
|
|
255
288
|
ensureOrganizationScope(ctx, comment.organizationId);
|
|
@@ -295,7 +328,12 @@ const deleteCommentCommand = {
|
|
|
295
328
|
const before = payload?.before;
|
|
296
329
|
if (!before) return;
|
|
297
330
|
const em = ctx.container.resolve("em").fork();
|
|
298
|
-
const member = await requireTeamMember(
|
|
331
|
+
const member = await requireTeamMember(
|
|
332
|
+
em,
|
|
333
|
+
before.memberId,
|
|
334
|
+
explicitStaffCommandScope(before.tenantId, before.organizationId),
|
|
335
|
+
"Team member not found"
|
|
336
|
+
);
|
|
299
337
|
let comment = await em.findOne(StaffTeamMemberComment, { id: before.id });
|
|
300
338
|
if (!comment) {
|
|
301
339
|
comment = em.create(StaffTeamMemberComment, {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/modules/staff/commands/comments.ts"],
|
|
4
|
-
"sourcesContent": ["import { registerCommand } from '@open-mercato/shared/lib/commands'\nimport type { CommandHandler } from '@open-mercato/shared/lib/commands'\nimport { emitCrudSideEffects, emitCrudUndoSideEffects, buildChanges, requireId, normalizeAuthorUserId } from '@open-mercato/shared/lib/commands/helpers'\nimport type { DataEngine } from '@open-mercato/shared/lib/data/engine'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport type { CrudIndexerConfig } from '@open-mercato/shared/lib/crud/types'\nimport { StaffTeamMemberComment } from '../data/entities'\nimport {\n staffTeamMemberCommentCreateSchema,\n staffTeamMemberCommentUpdateSchema,\n type StaffTeamMemberCommentCreateInput,\n type StaffTeamMemberCommentUpdateInput,\n} from '../data/validators'\nimport { staffTeamMemberCommentCrudEvents } from '../lib/crud'\nimport { ensureOrganizationScope, ensureTenantScope, extractUndoPayload, requireTeamMember } from './shared'\nimport { makeCreateRedo } from '@open-mercato/shared/lib/commands/redo'\nimport { E } from '#generated/entities.ids.generated'\n\nconst commentCrudIndexer: CrudIndexerConfig<StaffTeamMemberComment> = {\n entityType: E.staff.staff_team_member_comment,\n}\n\ntype CommentSnapshot = {\n id: string\n organizationId: string\n tenantId: string\n memberId: string\n body: string\n authorUserId: string | null\n appearanceIcon: string | null\n appearanceColor: string | null\n}\n\ntype CommentUndoPayload = {\n before?: CommentSnapshot | null\n after?: CommentSnapshot | null\n}\n\nasync function loadCommentSnapshot(em: EntityManager, id: string): Promise<CommentSnapshot | null> {\n const comment = await em.findOne(StaffTeamMemberComment, { id })\n if (!comment) return null\n return {\n id: comment.id,\n organizationId: comment.organizationId,\n tenantId: comment.tenantId,\n memberId: typeof comment.member === 'string' ? comment.member : comment.member.id,\n body: comment.body,\n authorUserId: comment.authorUserId ?? null,\n appearanceIcon: comment.appearanceIcon ?? null,\n appearanceColor: comment.appearanceColor ?? null,\n }\n}\n\nconst createCommentCommand: CommandHandler<\n StaffTeamMemberCommentCreateInput,\n { commentId: string; authorUserId: string | null }\n> = {\n id: 'staff.team-member-comments.create',\n async execute(rawInput, ctx) {\n const parsed = staffTeamMemberCommentCreateSchema.parse(rawInput)\n ensureTenantScope(ctx, parsed.tenantId)\n ensureOrganizationScope(ctx, parsed.organizationId)\n const normalizedAuthor = normalizeAuthorUserId(parsed.authorUserId, ctx.auth)\n\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const member = await requireTeamMember(em, parsed.entityId, 'Team member not found')\n ensureTenantScope(ctx, member.tenantId)\n ensureOrganizationScope(ctx, member.organizationId)\n\n const comment = em.create(StaffTeamMemberComment, {\n organizationId: parsed.organizationId,\n tenantId: parsed.tenantId,\n member,\n body: parsed.body,\n authorUserId: normalizedAuthor,\n appearanceIcon: parsed.appearanceIcon ?? null,\n appearanceColor: parsed.appearanceColor ?? null,\n createdAt: new Date(),\n updatedAt: new Date(),\n })\n em.persist(comment)\n await em.flush()\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'created',\n entity: comment,\n identifiers: {\n id: comment.id,\n organizationId: comment.organizationId,\n tenantId: comment.tenantId,\n },\n events: staffTeamMemberCommentCrudEvents,\n indexer: commentCrudIndexer,\n })\n\n return { commentId: comment.id, authorUserId: comment.authorUserId ?? null }\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return await loadCommentSnapshot(em, result.commentId)\n },\n buildLog: async ({ result, snapshots }) => {\n const { translate } = await resolveTranslations()\n const snapshot = snapshots.after as CommentSnapshot | undefined\n return {\n actionLabel: translate('staff.audit.teamMemberComments.create', 'Create note'),\n resourceKind: 'staff.team_member_comment',\n resourceId: result.commentId,\n parentResourceKind: 'staff.teamMember',\n parentResourceId: snapshot?.memberId ?? null,\n tenantId: snapshot?.tenantId ?? null,\n organizationId: snapshot?.organizationId ?? null,\n snapshotAfter: snapshot ?? null,\n payload: {\n undo: {\n after: snapshot ?? null,\n } satisfies CommentUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const commentId = logEntry?.resourceId ?? null\n if (!commentId) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const existing = await em.findOne(StaffTeamMemberComment, { id: commentId })\n if (existing) {\n em.remove(existing)\n await em.flush()\n }\n },\n redo: makeCreateRedo<\n StaffTeamMemberComment,\n CommentSnapshot,\n StaffTeamMemberCommentCreateInput,\n { commentId: string; authorUserId: string | null }\n >({\n entityClass: StaffTeamMemberComment,\n events: staffTeamMemberCommentCrudEvents,\n indexer: commentCrudIndexer,\n seedFromSnapshot: (snapshot) => ({\n id: snapshot.id,\n organizationId: snapshot.organizationId,\n tenantId: snapshot.tenantId,\n body: snapshot.body,\n authorUserId: snapshot.authorUserId,\n appearanceIcon: snapshot.appearanceIcon,\n appearanceColor: snapshot.appearanceColor,\n }),\n beforeRestore: async ({ em, snapshot }) => {\n const member = await requireTeamMember(em, snapshot.memberId, 'Team member not found')\n return { member }\n },\n buildResult: (entity) => ({ commentId: entity.id, authorUserId: entity.authorUserId ?? null }),\n }),\n}\n\nconst updateCommentCommand: CommandHandler<StaffTeamMemberCommentUpdateInput, { commentId: string }> = {\n id: 'staff.team-member-comments.update',\n async prepare(rawInput, ctx) {\n const parsed = staffTeamMemberCommentUpdateSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager)\n const snapshot = await loadCommentSnapshot(em, parsed.id)\n return snapshot ? { before: snapshot } : {}\n },\n async execute(rawInput, ctx) {\n const parsed = staffTeamMemberCommentUpdateSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const comment = await em.findOne(StaffTeamMemberComment, { id: parsed.id })\n if (!comment) throw new CrudHttpError(404, { error: 'Comment not found' })\n ensureTenantScope(ctx, comment.tenantId)\n ensureOrganizationScope(ctx, comment.organizationId)\n\n if (parsed.entityId !== undefined) {\n const member = await requireTeamMember(em, parsed.entityId, 'Team member not found')\n ensureTenantScope(ctx, member.tenantId)\n ensureOrganizationScope(ctx, member.organizationId)\n comment.member = member\n }\n if (parsed.body !== undefined) comment.body = parsed.body\n if (parsed.authorUserId !== undefined) comment.authorUserId = parsed.authorUserId ?? null\n if (parsed.appearanceIcon !== undefined) comment.appearanceIcon = parsed.appearanceIcon ?? null\n if (parsed.appearanceColor !== undefined) comment.appearanceColor = parsed.appearanceColor ?? null\n\n await em.flush()\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'updated',\n entity: comment,\n identifiers: {\n id: comment.id,\n organizationId: comment.organizationId,\n tenantId: comment.tenantId,\n },\n events: staffTeamMemberCommentCrudEvents,\n indexer: commentCrudIndexer,\n })\n\n return { commentId: comment.id }\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return await loadCommentSnapshot(em, result.commentId)\n },\n buildLog: async ({ snapshots }) => {\n const { translate } = await resolveTranslations()\n const before = snapshots.before as CommentSnapshot | undefined\n if (!before) return null\n const afterSnapshot = snapshots.after as CommentSnapshot | undefined\n const changes =\n afterSnapshot && before\n ? buildChanges(\n before as unknown as Record<string, unknown>,\n afterSnapshot as unknown as Record<string, unknown>,\n ['memberId', 'body', 'authorUserId', 'appearanceIcon', 'appearanceColor']\n )\n : {}\n return {\n actionLabel: translate('staff.audit.teamMemberComments.update', 'Update note'),\n resourceKind: 'staff.team_member_comment',\n resourceId: before.id,\n parentResourceKind: 'staff.teamMember',\n parentResourceId: before.memberId ?? null,\n tenantId: before.tenantId,\n organizationId: before.organizationId,\n snapshotBefore: before,\n snapshotAfter: afterSnapshot ?? null,\n changes,\n payload: {\n undo: {\n before,\n after: afterSnapshot ?? null,\n } satisfies CommentUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<CommentUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n let comment = await em.findOne(StaffTeamMemberComment, { id: before.id })\n const member = await requireTeamMember(em, before.memberId, 'Team member not found')\n\n if (!comment) {\n comment = em.create(StaffTeamMemberComment, {\n id: before.id,\n organizationId: before.organizationId,\n tenantId: before.tenantId,\n member,\n body: before.body,\n authorUserId: before.authorUserId,\n appearanceIcon: before.appearanceIcon,\n appearanceColor: before.appearanceColor,\n createdAt: new Date(),\n updatedAt: new Date(),\n })\n em.persist(comment)\n } else {\n comment.member = member\n comment.body = before.body\n comment.authorUserId = before.authorUserId\n comment.appearanceIcon = before.appearanceIcon\n comment.appearanceColor = before.appearanceColor\n }\n await em.flush()\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudUndoSideEffects({\n dataEngine: de,\n action: 'updated',\n entity: comment,\n identifiers: {\n id: comment.id,\n organizationId: comment.organizationId,\n tenantId: comment.tenantId,\n },\n events: staffTeamMemberCommentCrudEvents,\n indexer: commentCrudIndexer,\n })\n },\n}\n\nconst deleteCommentCommand: CommandHandler<{ body?: Record<string, unknown>; query?: Record<string, unknown> }, { commentId: string }> =\n {\n id: 'staff.team-member-comments.delete',\n async prepare(input, ctx) {\n const id = requireId(input, 'Comment id required')\n const em = (ctx.container.resolve('em') as EntityManager)\n const snapshot = await loadCommentSnapshot(em, id)\n return snapshot ? { before: snapshot } : {}\n },\n async execute(input, ctx) {\n const id = requireId(input, 'Comment id required')\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const comment = await em.findOne(StaffTeamMemberComment, { id })\n if (!comment) throw new CrudHttpError(404, { error: 'Comment not found' })\n ensureTenantScope(ctx, comment.tenantId)\n ensureOrganizationScope(ctx, comment.organizationId)\n em.remove(comment)\n await em.flush()\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'deleted',\n entity: comment,\n identifiers: {\n id: comment.id,\n organizationId: comment.organizationId,\n tenantId: comment.tenantId,\n },\n events: staffTeamMemberCommentCrudEvents,\n indexer: commentCrudIndexer,\n })\n return { commentId: comment.id }\n },\n buildLog: async ({ snapshots }) => {\n const before = snapshots.before as CommentSnapshot | undefined\n if (!before) return null\n const { translate } = await resolveTranslations()\n return {\n actionLabel: translate('staff.audit.teamMemberComments.delete', 'Delete note'),\n resourceKind: 'staff.team_member_comment',\n resourceId: before.id,\n parentResourceKind: 'staff.teamMember',\n parentResourceId: before.memberId ?? null,\n tenantId: before.tenantId,\n organizationId: before.organizationId,\n snapshotBefore: before,\n payload: {\n undo: {\n before,\n } satisfies CommentUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<CommentUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const member = await requireTeamMember(em, before.memberId, 'Team member not found')\n let comment = await em.findOne(StaffTeamMemberComment, { id: before.id })\n if (!comment) {\n comment = em.create(StaffTeamMemberComment, {\n id: before.id,\n organizationId: before.organizationId,\n tenantId: before.tenantId,\n member,\n body: before.body,\n authorUserId: before.authorUserId,\n appearanceIcon: before.appearanceIcon,\n appearanceColor: before.appearanceColor,\n createdAt: new Date(),\n updatedAt: new Date(),\n })\n em.persist(comment)\n } else {\n comment.member = member\n comment.body = before.body\n comment.authorUserId = before.authorUserId\n comment.appearanceIcon = before.appearanceIcon\n comment.appearanceColor = before.appearanceColor\n }\n await em.flush()\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudUndoSideEffects({\n dataEngine: de,\n action: 'created',\n entity: comment,\n identifiers: {\n id: comment.id,\n organizationId: comment.organizationId,\n tenantId: comment.tenantId,\n },\n events: staffTeamMemberCommentCrudEvents,\n indexer: commentCrudIndexer,\n })\n },\n }\n\nregisterCommand(createCommentCommand)\nregisterCommand(updateCommentCommand)\nregisterCommand(deleteCommentCommand)\n"],
|
|
5
|
-
"mappings": "AAAA,SAAS,uBAAuB;AAEhC,SAAS,qBAAqB,yBAAyB,cAAc,WAAW,6BAA6B;AAG7G,SAAS,qBAAqB;AAC9B,SAAS,2BAA2B;AAEpC,SAAS,8BAA8B;AACvC;AAAA,EACE;AAAA,EACA;AAAA,OAGK;AACP,SAAS,wCAAwC;AACjD,
|
|
4
|
+
"sourcesContent": ["import { registerCommand } from '@open-mercato/shared/lib/commands'\nimport type { CommandHandler } from '@open-mercato/shared/lib/commands'\nimport { emitCrudSideEffects, emitCrudUndoSideEffects, buildChanges, requireId, normalizeAuthorUserId } from '@open-mercato/shared/lib/commands/helpers'\nimport type { DataEngine } from '@open-mercato/shared/lib/data/engine'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport type { CrudIndexerConfig } from '@open-mercato/shared/lib/crud/types'\nimport { StaffTeamMemberComment } from '../data/entities'\nimport {\n staffTeamMemberCommentCreateSchema,\n staffTeamMemberCommentUpdateSchema,\n type StaffTeamMemberCommentCreateInput,\n type StaffTeamMemberCommentUpdateInput,\n} from '../data/validators'\nimport { staffTeamMemberCommentCrudEvents } from '../lib/crud'\nimport {\n applyScopeToWhere,\n commandActorScope,\n commandInputScope,\n ensureOrganizationScope,\n ensureTenantScope,\n explicitStaffCommandScope,\n extractUndoPayload,\n requireTeamMember,\n} from './shared'\nimport { makeCreateRedo } from '@open-mercato/shared/lib/commands/redo'\nimport { E } from '#generated/entities.ids.generated'\n\nconst commentCrudIndexer: CrudIndexerConfig<StaffTeamMemberComment> = {\n entityType: E.staff.staff_team_member_comment,\n}\n\ntype CommentSnapshot = {\n id: string\n organizationId: string\n tenantId: string\n memberId: string\n body: string\n authorUserId: string | null\n appearanceIcon: string | null\n appearanceColor: string | null\n}\n\ntype CommentUndoPayload = {\n before?: CommentSnapshot | null\n after?: CommentSnapshot | null\n}\n\nasync function loadCommentSnapshot(em: EntityManager, id: string): Promise<CommentSnapshot | null> {\n const comment = await em.findOne(StaffTeamMemberComment, { id })\n if (!comment) return null\n return {\n id: comment.id,\n organizationId: comment.organizationId,\n tenantId: comment.tenantId,\n memberId: typeof comment.member === 'string' ? comment.member : comment.member.id,\n body: comment.body,\n authorUserId: comment.authorUserId ?? null,\n appearanceIcon: comment.appearanceIcon ?? null,\n appearanceColor: comment.appearanceColor ?? null,\n }\n}\n\nconst createCommentCommand: CommandHandler<\n StaffTeamMemberCommentCreateInput,\n { commentId: string; authorUserId: string | null }\n> = {\n id: 'staff.team-member-comments.create',\n async execute(rawInput, ctx) {\n const parsed = staffTeamMemberCommentCreateSchema.parse(rawInput)\n ensureTenantScope(ctx, parsed.tenantId)\n ensureOrganizationScope(ctx, parsed.organizationId)\n const scope = commandInputScope(ctx, parsed.tenantId, parsed.organizationId)\n const normalizedAuthor = normalizeAuthorUserId(parsed.authorUserId, ctx.auth)\n\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const member = await requireTeamMember(\n em,\n parsed.entityId,\n scope,\n 'Team member not found',\n )\n ensureTenantScope(ctx, member.tenantId)\n ensureOrganizationScope(ctx, member.organizationId)\n\n const comment = em.create(StaffTeamMemberComment, {\n organizationId: parsed.organizationId,\n tenantId: parsed.tenantId,\n member,\n body: parsed.body,\n authorUserId: normalizedAuthor,\n appearanceIcon: parsed.appearanceIcon ?? null,\n appearanceColor: parsed.appearanceColor ?? null,\n createdAt: new Date(),\n updatedAt: new Date(),\n })\n em.persist(comment)\n await em.flush()\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'created',\n entity: comment,\n identifiers: {\n id: comment.id,\n organizationId: comment.organizationId,\n tenantId: comment.tenantId,\n },\n events: staffTeamMemberCommentCrudEvents,\n indexer: commentCrudIndexer,\n })\n\n return { commentId: comment.id, authorUserId: comment.authorUserId ?? null }\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return await loadCommentSnapshot(em, result.commentId)\n },\n buildLog: async ({ result, snapshots }) => {\n const { translate } = await resolveTranslations()\n const snapshot = snapshots.after as CommentSnapshot | undefined\n return {\n actionLabel: translate('staff.audit.teamMemberComments.create', 'Create note'),\n resourceKind: 'staff.team_member_comment',\n resourceId: result.commentId,\n parentResourceKind: 'staff.teamMember',\n parentResourceId: snapshot?.memberId ?? null,\n tenantId: snapshot?.tenantId ?? null,\n organizationId: snapshot?.organizationId ?? null,\n snapshotAfter: snapshot ?? null,\n payload: {\n undo: {\n after: snapshot ?? null,\n } satisfies CommentUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const commentId = logEntry?.resourceId ?? null\n if (!commentId) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const existing = await em.findOne(StaffTeamMemberComment, { id: commentId })\n if (existing) {\n em.remove(existing)\n await em.flush()\n }\n },\n redo: makeCreateRedo<\n StaffTeamMemberComment,\n CommentSnapshot,\n StaffTeamMemberCommentCreateInput,\n { commentId: string; authorUserId: string | null }\n >({\n entityClass: StaffTeamMemberComment,\n events: staffTeamMemberCommentCrudEvents,\n indexer: commentCrudIndexer,\n seedFromSnapshot: (snapshot) => ({\n id: snapshot.id,\n organizationId: snapshot.organizationId,\n tenantId: snapshot.tenantId,\n body: snapshot.body,\n authorUserId: snapshot.authorUserId,\n appearanceIcon: snapshot.appearanceIcon,\n appearanceColor: snapshot.appearanceColor,\n }),\n beforeRestore: async ({ em, snapshot }) => {\n const member = await requireTeamMember(\n em,\n snapshot.memberId,\n explicitStaffCommandScope(snapshot.tenantId, snapshot.organizationId),\n 'Team member not found',\n )\n return { member }\n },\n buildResult: (entity) => ({ commentId: entity.id, authorUserId: entity.authorUserId ?? null }),\n }),\n}\n\nconst updateCommentCommand: CommandHandler<StaffTeamMemberCommentUpdateInput, { commentId: string }> = {\n id: 'staff.team-member-comments.update',\n async prepare(rawInput, ctx) {\n const parsed = staffTeamMemberCommentUpdateSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager)\n const snapshot = await loadCommentSnapshot(em, parsed.id)\n return snapshot ? { before: snapshot } : {}\n },\n async execute(rawInput, ctx) {\n const parsed = staffTeamMemberCommentUpdateSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const scope = commandActorScope(ctx)\n const comment = await em.findOne(\n StaffTeamMemberComment,\n applyScopeToWhere<StaffTeamMemberComment>({ id: parsed.id }, scope),\n )\n if (!comment) throw new CrudHttpError(404, { error: 'Comment not found' })\n ensureTenantScope(ctx, comment.tenantId)\n ensureOrganizationScope(ctx, comment.organizationId)\n\n if (parsed.entityId !== undefined) {\n const member = await requireTeamMember(em, parsed.entityId, scope, 'Team member not found')\n ensureTenantScope(ctx, member.tenantId)\n ensureOrganizationScope(ctx, member.organizationId)\n comment.member = member\n }\n if (parsed.body !== undefined) comment.body = parsed.body\n if (parsed.authorUserId !== undefined) comment.authorUserId = parsed.authorUserId ?? null\n if (parsed.appearanceIcon !== undefined) comment.appearanceIcon = parsed.appearanceIcon ?? null\n if (parsed.appearanceColor !== undefined) comment.appearanceColor = parsed.appearanceColor ?? null\n\n await em.flush()\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'updated',\n entity: comment,\n identifiers: {\n id: comment.id,\n organizationId: comment.organizationId,\n tenantId: comment.tenantId,\n },\n events: staffTeamMemberCommentCrudEvents,\n indexer: commentCrudIndexer,\n })\n\n return { commentId: comment.id }\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return await loadCommentSnapshot(em, result.commentId)\n },\n buildLog: async ({ snapshots }) => {\n const { translate } = await resolveTranslations()\n const before = snapshots.before as CommentSnapshot | undefined\n if (!before) return null\n const afterSnapshot = snapshots.after as CommentSnapshot | undefined\n const changes =\n afterSnapshot && before\n ? buildChanges(\n before as unknown as Record<string, unknown>,\n afterSnapshot as unknown as Record<string, unknown>,\n ['memberId', 'body', 'authorUserId', 'appearanceIcon', 'appearanceColor']\n )\n : {}\n return {\n actionLabel: translate('staff.audit.teamMemberComments.update', 'Update note'),\n resourceKind: 'staff.team_member_comment',\n resourceId: before.id,\n parentResourceKind: 'staff.teamMember',\n parentResourceId: before.memberId ?? null,\n tenantId: before.tenantId,\n organizationId: before.organizationId,\n snapshotBefore: before,\n snapshotAfter: afterSnapshot ?? null,\n changes,\n payload: {\n undo: {\n before,\n after: afterSnapshot ?? null,\n } satisfies CommentUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<CommentUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n let comment = await em.findOne(StaffTeamMemberComment, { id: before.id })\n const member = await requireTeamMember(\n em,\n before.memberId,\n explicitStaffCommandScope(before.tenantId, before.organizationId),\n 'Team member not found',\n )\n\n if (!comment) {\n comment = em.create(StaffTeamMemberComment, {\n id: before.id,\n organizationId: before.organizationId,\n tenantId: before.tenantId,\n member,\n body: before.body,\n authorUserId: before.authorUserId,\n appearanceIcon: before.appearanceIcon,\n appearanceColor: before.appearanceColor,\n createdAt: new Date(),\n updatedAt: new Date(),\n })\n em.persist(comment)\n } else {\n comment.member = member\n comment.body = before.body\n comment.authorUserId = before.authorUserId\n comment.appearanceIcon = before.appearanceIcon\n comment.appearanceColor = before.appearanceColor\n }\n await em.flush()\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudUndoSideEffects({\n dataEngine: de,\n action: 'updated',\n entity: comment,\n identifiers: {\n id: comment.id,\n organizationId: comment.organizationId,\n tenantId: comment.tenantId,\n },\n events: staffTeamMemberCommentCrudEvents,\n indexer: commentCrudIndexer,\n })\n },\n}\n\nconst deleteCommentCommand: CommandHandler<{ body?: Record<string, unknown>; query?: Record<string, unknown> }, { commentId: string }> =\n {\n id: 'staff.team-member-comments.delete',\n async prepare(input, ctx) {\n const id = requireId(input, 'Comment id required')\n const em = (ctx.container.resolve('em') as EntityManager)\n const snapshot = await loadCommentSnapshot(em, id)\n return snapshot ? { before: snapshot } : {}\n },\n async execute(input, ctx) {\n const id = requireId(input, 'Comment id required')\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const scope = commandActorScope(ctx)\n const comment = await em.findOne(\n StaffTeamMemberComment,\n applyScopeToWhere<StaffTeamMemberComment>({ id }, scope),\n )\n if (!comment) throw new CrudHttpError(404, { error: 'Comment not found' })\n ensureTenantScope(ctx, comment.tenantId)\n ensureOrganizationScope(ctx, comment.organizationId)\n em.remove(comment)\n await em.flush()\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'deleted',\n entity: comment,\n identifiers: {\n id: comment.id,\n organizationId: comment.organizationId,\n tenantId: comment.tenantId,\n },\n events: staffTeamMemberCommentCrudEvents,\n indexer: commentCrudIndexer,\n })\n return { commentId: comment.id }\n },\n buildLog: async ({ snapshots }) => {\n const before = snapshots.before as CommentSnapshot | undefined\n if (!before) return null\n const { translate } = await resolveTranslations()\n return {\n actionLabel: translate('staff.audit.teamMemberComments.delete', 'Delete note'),\n resourceKind: 'staff.team_member_comment',\n resourceId: before.id,\n parentResourceKind: 'staff.teamMember',\n parentResourceId: before.memberId ?? null,\n tenantId: before.tenantId,\n organizationId: before.organizationId,\n snapshotBefore: before,\n payload: {\n undo: {\n before,\n } satisfies CommentUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<CommentUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const member = await requireTeamMember(\n em,\n before.memberId,\n explicitStaffCommandScope(before.tenantId, before.organizationId),\n 'Team member not found',\n )\n let comment = await em.findOne(StaffTeamMemberComment, { id: before.id })\n if (!comment) {\n comment = em.create(StaffTeamMemberComment, {\n id: before.id,\n organizationId: before.organizationId,\n tenantId: before.tenantId,\n member,\n body: before.body,\n authorUserId: before.authorUserId,\n appearanceIcon: before.appearanceIcon,\n appearanceColor: before.appearanceColor,\n createdAt: new Date(),\n updatedAt: new Date(),\n })\n em.persist(comment)\n } else {\n comment.member = member\n comment.body = before.body\n comment.authorUserId = before.authorUserId\n comment.appearanceIcon = before.appearanceIcon\n comment.appearanceColor = before.appearanceColor\n }\n await em.flush()\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudUndoSideEffects({\n dataEngine: de,\n action: 'created',\n entity: comment,\n identifiers: {\n id: comment.id,\n organizationId: comment.organizationId,\n tenantId: comment.tenantId,\n },\n events: staffTeamMemberCommentCrudEvents,\n indexer: commentCrudIndexer,\n })\n },\n }\n\nregisterCommand(createCommentCommand)\nregisterCommand(updateCommentCommand)\nregisterCommand(deleteCommentCommand)\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -7,8 +7,12 @@ import {
|
|
|
7
7
|
} from "../data/validators.js";
|
|
8
8
|
import { staffTeamMemberJobHistoryCrudEvents } from "../lib/crud.js";
|
|
9
9
|
import {
|
|
10
|
+
applyScopeToWhere,
|
|
11
|
+
commandActorScope,
|
|
12
|
+
commandInputScope,
|
|
10
13
|
ensureOrganizationScope,
|
|
11
14
|
ensureTenantScope,
|
|
15
|
+
explicitStaffCommandScope,
|
|
12
16
|
extractUndoPayload,
|
|
13
17
|
requireTeamMember
|
|
14
18
|
} from "./shared.js";
|
|
@@ -46,8 +50,14 @@ const createJobHistoryCommand = {
|
|
|
46
50
|
const parsed = staffTeamMemberJobHistoryCreateSchema.parse(rawInput);
|
|
47
51
|
ensureTenantScope(ctx, parsed.tenantId);
|
|
48
52
|
ensureOrganizationScope(ctx, parsed.organizationId);
|
|
53
|
+
const scope = commandInputScope(ctx, parsed.tenantId, parsed.organizationId);
|
|
49
54
|
const em = ctx.container.resolve("em").fork();
|
|
50
|
-
const member = await requireTeamMember(
|
|
55
|
+
const member = await requireTeamMember(
|
|
56
|
+
em,
|
|
57
|
+
parsed.entityId,
|
|
58
|
+
scope,
|
|
59
|
+
"Team member not found"
|
|
60
|
+
);
|
|
51
61
|
ensureTenantScope(ctx, member.tenantId);
|
|
52
62
|
ensureOrganizationScope(ctx, member.organizationId);
|
|
53
63
|
const record = em.create(StaffTeamMemberJobHistory, {
|
|
@@ -118,7 +128,12 @@ const createJobHistoryCommand = {
|
|
|
118
128
|
throw new CrudHttpError(400, { error: "[internal] redo snapshot unavailable for job history create" });
|
|
119
129
|
}
|
|
120
130
|
const em = ctx.container.resolve("em").fork();
|
|
121
|
-
const member = await requireTeamMember(
|
|
131
|
+
const member = await requireTeamMember(
|
|
132
|
+
em,
|
|
133
|
+
after.memberId,
|
|
134
|
+
explicitStaffCommandScope(after.tenantId, after.organizationId),
|
|
135
|
+
"Team member not found"
|
|
136
|
+
);
|
|
122
137
|
let record = await em.findOne(StaffTeamMemberJobHistory, { id: after.id });
|
|
123
138
|
if (!record) {
|
|
124
139
|
record = em.create(StaffTeamMemberJobHistory, {
|
|
@@ -171,7 +186,11 @@ const updateJobHistoryCommand = {
|
|
|
171
186
|
async execute(rawInput, ctx) {
|
|
172
187
|
const parsed = staffTeamMemberJobHistoryUpdateSchema.parse(rawInput);
|
|
173
188
|
const em = ctx.container.resolve("em").fork();
|
|
174
|
-
const
|
|
189
|
+
const scope = commandActorScope(ctx);
|
|
190
|
+
const record = await em.findOne(
|
|
191
|
+
StaffTeamMemberJobHistory,
|
|
192
|
+
applyScopeToWhere({ id: parsed.id }, scope)
|
|
193
|
+
);
|
|
175
194
|
if (!record) {
|
|
176
195
|
enforceRecordGoneIsConflict({
|
|
177
196
|
resourceKind: JOB_HISTORY_LOCK_RESOURCE_KIND,
|
|
@@ -191,7 +210,7 @@ const updateJobHistoryCommand = {
|
|
|
191
210
|
request: ctx.request ?? null
|
|
192
211
|
});
|
|
193
212
|
if (parsed.entityId !== void 0) {
|
|
194
|
-
const member = await requireTeamMember(em, parsed.entityId, "Team member not found");
|
|
213
|
+
const member = await requireTeamMember(em, parsed.entityId, scope, "Team member not found");
|
|
195
214
|
ensureTenantScope(ctx, member.tenantId);
|
|
196
215
|
ensureOrganizationScope(ctx, member.organizationId);
|
|
197
216
|
record.member = member;
|
|
@@ -256,7 +275,12 @@ const updateJobHistoryCommand = {
|
|
|
256
275
|
if (!before) return;
|
|
257
276
|
const em = ctx.container.resolve("em").fork();
|
|
258
277
|
let record = await em.findOne(StaffTeamMemberJobHistory, { id: before.id });
|
|
259
|
-
const member = await requireTeamMember(
|
|
278
|
+
const member = await requireTeamMember(
|
|
279
|
+
em,
|
|
280
|
+
before.memberId,
|
|
281
|
+
explicitStaffCommandScope(before.tenantId, before.organizationId),
|
|
282
|
+
"Team member not found"
|
|
283
|
+
);
|
|
260
284
|
if (!record) {
|
|
261
285
|
record = em.create(StaffTeamMemberJobHistory, {
|
|
262
286
|
id: before.id,
|
|
@@ -308,7 +332,11 @@ const deleteJobHistoryCommand = {
|
|
|
308
332
|
const id = requireId(input, "Job history id required");
|
|
309
333
|
const expectedUpdatedAt = typeof input.updatedAt === "string" ? input.updatedAt : void 0;
|
|
310
334
|
const em = ctx.container.resolve("em").fork();
|
|
311
|
-
const
|
|
335
|
+
const scope = commandActorScope(ctx);
|
|
336
|
+
const record = await em.findOne(
|
|
337
|
+
StaffTeamMemberJobHistory,
|
|
338
|
+
applyScopeToWhere({ id }, scope)
|
|
339
|
+
);
|
|
312
340
|
if (!record) {
|
|
313
341
|
enforceRecordGoneIsConflict({
|
|
314
342
|
resourceKind: JOB_HISTORY_LOCK_RESOURCE_KIND,
|
|
@@ -369,7 +397,12 @@ const deleteJobHistoryCommand = {
|
|
|
369
397
|
const before = payload?.before;
|
|
370
398
|
if (!before) return;
|
|
371
399
|
const em = ctx.container.resolve("em").fork();
|
|
372
|
-
const member = await requireTeamMember(
|
|
400
|
+
const member = await requireTeamMember(
|
|
401
|
+
em,
|
|
402
|
+
before.memberId,
|
|
403
|
+
explicitStaffCommandScope(before.tenantId, before.organizationId),
|
|
404
|
+
"Team member not found"
|
|
405
|
+
);
|
|
373
406
|
let record = await em.findOne(StaffTeamMemberJobHistory, { id: before.id });
|
|
374
407
|
if (!record) {
|
|
375
408
|
record = em.create(StaffTeamMemberJobHistory, {
|