commit show calenda
This commit is contained in:
1176
docs/setup/uat-system-flow.html
Normal file
1176
docs/setup/uat-system-flow.html
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,13 +1,13 @@
|
|||||||
organization_code,workflow_code,step_number,role_code,role_name,approval_mode,is_required,sla_hours,calendar_mode,timeout_action
|
organization_code,workflow_code,step_number,role_code,role_name,approval_mode,is_required,sla_hours,calendar_mode,timeout_action
|
||||||
ALLA,quotation_standard,1,sales_manager,Sales Manager,sequential,true,24,calendar_days,auto_escalate
|
ALLA,quotation_standard,1,sales_manager,Sales Manager,sequential,true,24,calendar_days,escalate
|
||||||
ALLA,quotation_manager_review,1,sales_manager,Sales Manager,sequential,true,24,calendar_days,auto_escalate
|
ALLA,quotation_manager_review,1,sales_manager,Sales Manager,sequential,true,24,calendar_days,escalate
|
||||||
ALLA,quotation_manager_review,2,department_manager,Department Manager,sequential,true,48,calendar_days,auto_escalate
|
ALLA,quotation_manager_review,2,department_manager,Department Manager,sequential,true,48,calendar_days,escalate
|
||||||
ALLA,quotation_executive_review,1,sales_manager,Sales Manager,sequential,true,24,calendar_days,auto_escalate
|
ALLA,quotation_executive_review,1,sales_manager,Sales Manager,sequential,true,24,calendar_days,escalate
|
||||||
ALLA,quotation_executive_review,2,department_manager,Department Manager,sequential,true,48,calendar_days,auto_escalate
|
ALLA,quotation_executive_review,2,department_manager,Department Manager,sequential,true,48,calendar_days,escalate
|
||||||
ALLA,quotation_executive_review,3,top_manager,Top Manager,sequential,true,72,calendar_days,none
|
ALLA,quotation_executive_review,3,top_manager,Top Manager,sequential,true,72,calendar_days,none
|
||||||
ONVALLA,quotation_standard,1,sales_manager,Sales Manager,sequential,true,24,calendar_days,auto_escalate
|
ONVALLA,quotation_standard,1,sales_manager,Sales Manager,sequential,true,24,calendar_days,escalate
|
||||||
ONVALLA,quotation_manager_review,1,sales_manager,Sales Manager,sequential,true,24,calendar_days,auto_escalate
|
ONVALLA,quotation_manager_review,1,sales_manager,Sales Manager,sequential,true,24,calendar_days,escalate
|
||||||
ONVALLA,quotation_manager_review,2,department_manager,Department Manager,sequential,true,48,calendar_days,auto_escalate
|
ONVALLA,quotation_manager_review,2,department_manager,Department Manager,sequential,true,48,calendar_days,escalate
|
||||||
ONVALLA,quotation_executive_review,1,sales_manager,Sales Manager,sequential,true,24,calendar_days,auto_escalate
|
ONVALLA,quotation_executive_review,1,sales_manager,Sales Manager,sequential,true,24,calendar_days,escalate
|
||||||
ONVALLA,quotation_executive_review,2,department_manager,Department Manager,sequential,true,48,calendar_days,auto_escalate
|
ONVALLA,quotation_executive_review,2,department_manager,Department Manager,sequential,true,48,calendar_days,escalate
|
||||||
ONVALLA,quotation_executive_review,3,top_manager,Top Manager,sequential,true,72,calendar_days,none
|
ONVALLA,quotation_executive_review,3,top_manager,Top Manager,sequential,true,72,calendar_days,none
|
||||||
|
|||||||
|
@@ -1,6 +1,13 @@
|
|||||||
organization_code,branch_code,product_type_code,document_type,prefix,period,current_number,padding_length,format,reset_policy,is_active
|
organization_code,branch_code,product_type_code,document_type,prefix,period,current_number,padding_length,format,reset_policy,is_active
|
||||||
ALLA,head_office,crane,customer,CUS,yearly,0,4,{prefix}-{yyyy}-{running},period,true
|
ALLA,head_office,,customer,CUS,2607,0,3,{prefix}{period}-{running},period,true
|
||||||
ALLA,head_office,crane,lead,LD,yearly,0,4,{prefix}-{yyyy}-{running},period,true
|
ALLA,head_office,,crm_lead,LD,2607,0,3,{prefix}{period}-{running},period,true
|
||||||
ALLA,head_office,crane,opportunity,OP,yearly,0,4,{prefix}-{yyyy}-{running},period,true
|
ALLA,head_office,,opportunity,OP,2607,0,3,{prefix}{period}-{running},period,true
|
||||||
ALLA,head_office,crane,quotation,QT-AL-CR,monthly,0,4,{prefix}-{yy}{MM}-{running},period,true
|
ALLA,head_office,,crm_opportunity,EN,2607,0,3,{prefix}{period}-{running},period,true
|
||||||
ONVALLA,head_office,crane,quotation,QT-ON-CR,monthly,0,4,{prefix}-{yy}{MM}-{running},period,true
|
ALLA,head_office,crane,quotation,QT-AL-CR,2607,0,4,{prefix}{period}-{running},period,true
|
||||||
|
ALLA,head_office,dockdoor,quotation,QT-AL-DK,2607,0,4,{prefix}{period}-{running},period,true
|
||||||
|
ONVALLA,head_office,,customer,CUS,2607,0,3,{prefix}{period}-{running},period,true
|
||||||
|
ONVALLA,head_office,,crm_lead,LD,2607,0,3,{prefix}{period}-{running},period,true
|
||||||
|
ONVALLA,head_office,,opportunity,OP,2607,0,3,{prefix}{period}-{running},period,true
|
||||||
|
ONVALLA,head_office,,crm_opportunity,EN,2607,0,3,{prefix}{period}-{running},period,true
|
||||||
|
ONVALLA,head_office,crane,quotation,QT-ON-CR,2607,0,4,{prefix}{period}-{running},period,true
|
||||||
|
ONVALLA,head_office,solarcell,quotation,QT-ON-SC,2607,0,4,{prefix}{period}-{running},period,true
|
||||||
|
|||||||
|
@@ -1,4 +1,16 @@
|
|||||||
organization_code,category,code,label,value,parent_category,parent_code,sort_order,is_active,metadata_json
|
organization_code,category,code,label,value,parent_category,parent_code,sort_order,is_active,metadata_json
|
||||||
|
ALLA,crm_currency,thb,Thai Baht,THB,,,1,true,{}
|
||||||
|
ONVALLA,crm_currency,thb,Thai Baht,THB,,,1,true,{}
|
||||||
|
ALLA,crm_lead_status,new_job,New Job,new_job,,,1,true,{}
|
||||||
|
ALLA,crm_lead_status,follow_up,Follow Up,follow_up,,,2,true,{}
|
||||||
|
ALLA,crm_lead_status,assigned,Assigned,assigned,,,3,true,{}
|
||||||
|
ALLA,crm_lead_status,closed_lost,Closed Lost,closed_lost,,,4,true,{}
|
||||||
|
ALLA,crm_lead_status,cancel,Cancel,cancel,,,5,true,{}
|
||||||
|
ONVALLA,crm_lead_status,new_job,New Job,new_job,,,1,true,{}
|
||||||
|
ONVALLA,crm_lead_status,follow_up,Follow Up,follow_up,,,2,true,{}
|
||||||
|
ONVALLA,crm_lead_status,assigned,Assigned,assigned,,,3,true,{}
|
||||||
|
ONVALLA,crm_lead_status,closed_lost,Closed Lost,closed_lost,,,4,true,{}
|
||||||
|
ONVALLA,crm_lead_status,cancel,Cancel,cancel,,,5,true,{}
|
||||||
ALLA,crm_customer_group,construction,Construction,,,,1,true,{}
|
ALLA,crm_customer_group,construction,Construction,,,,1,true,{}
|
||||||
ALLA,crm_customer_group,industrial,Industrial,,,,2,true,{}
|
ALLA,crm_customer_group,industrial,Industrial,,,,2,true,{}
|
||||||
|
|
||||||
|
|||||||
|
@@ -1,25 +1,29 @@
|
|||||||
import KBar from '@/components/kbar';
|
import KBar from "@/components/kbar";
|
||||||
import AppSidebar from '@/components/layout/app-sidebar';
|
import AppSidebar from "@/components/layout/app-sidebar";
|
||||||
import Header from '@/components/layout/header';
|
import Header from "@/components/layout/header";
|
||||||
import { InfoSidebar } from '@/components/layout/info-sidebar';
|
import { InfoSidebar } from "@/components/layout/info-sidebar";
|
||||||
import { InfobarProvider } from '@/components/ui/infobar';
|
import { InfobarProvider } from "@/components/ui/infobar";
|
||||||
import { SidebarInset, SidebarProvider } from '@/components/ui/sidebar';
|
import { SidebarInset, SidebarProvider } from "@/components/ui/sidebar";
|
||||||
import type { Metadata } from 'next';
|
import type { Metadata } from "next";
|
||||||
import { cookies } from 'next/headers';
|
import { cookies } from "next/headers";
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: 'Next Shadcn Dashboard Starter',
|
title: "ALLA OS",
|
||||||
description: 'Basic dashboard with Next.js and Shadcn',
|
description: "ALLA OS",
|
||||||
robots: {
|
robots: {
|
||||||
index: false,
|
index: false,
|
||||||
follow: false
|
follow: false,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default async function DashboardLayout({ children }: { children: React.ReactNode }) {
|
export default async function DashboardLayout({
|
||||||
|
children,
|
||||||
|
}: {
|
||||||
|
children: React.ReactNode;
|
||||||
|
}) {
|
||||||
// Persisting the sidebar state in the cookie.
|
// Persisting the sidebar state in the cookie.
|
||||||
const cookieStore = await cookies();
|
const cookieStore = await cookies();
|
||||||
const defaultOpen = cookieStore.get('sidebar_state')?.value === 'true';
|
const defaultOpen = cookieStore.get("sidebar_state")?.value === "true";
|
||||||
return (
|
return (
|
||||||
<KBar>
|
<KBar>
|
||||||
<SidebarProvider defaultOpen={defaultOpen}>
|
<SidebarProvider defaultOpen={defaultOpen}>
|
||||||
@@ -28,7 +32,7 @@ export default async function DashboardLayout({ children }: { children: React.Re
|
|||||||
<Header />
|
<Header />
|
||||||
<InfobarProvider defaultOpen={false}>
|
<InfobarProvider defaultOpen={false}>
|
||||||
{children}
|
{children}
|
||||||
<InfoSidebar side='right' />
|
<InfoSidebar side="right" />
|
||||||
</InfobarProvider>
|
</InfobarProvider>
|
||||||
</SidebarInset>
|
</SidebarInset>
|
||||||
</SidebarProvider>
|
</SidebarProvider>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { db } from '@/lib/db';
|
|||||||
import { AuthError } from '@/lib/auth/session';
|
import { AuthError } from '@/lib/auth/session';
|
||||||
import { generateNextDocumentCode } from '@/features/foundation/document-sequence/service';
|
import { generateNextDocumentCode } from '@/features/foundation/document-sequence/service';
|
||||||
import { getActiveOptionsByCategory } from '@/features/foundation/master-options/service';
|
import { getActiveOptionsByCategory } from '@/features/foundation/master-options/service';
|
||||||
|
import { drainProjectionOutboxBestEffort } from '@/features/foundation/projections/server/best-effort-drain';
|
||||||
import {
|
import {
|
||||||
CRM_ACTIVITY_ENTITY_TYPES,
|
CRM_ACTIVITY_ENTITY_TYPES,
|
||||||
CRM_ACTIVITY_PERMISSIONS,
|
CRM_ACTIVITY_PERMISSIONS,
|
||||||
@@ -677,6 +678,7 @@ export async function createActivity(
|
|||||||
return createdRow;
|
return createdRow;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await drainProjectionOutboxBestEffort();
|
||||||
const activity = await getActivityById(created.id, organizationId, context);
|
const activity = await getActivityById(created.id, organizationId, context);
|
||||||
|
|
||||||
return activity;
|
return activity;
|
||||||
@@ -810,6 +812,7 @@ correlationId
|
|||||||
return nextActivity;
|
return nextActivity;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await drainProjectionOutboxBestEffort();
|
||||||
const activity = await getActivityById(activityEventRecord.id, organizationId, context);
|
const activity = await getActivityById(activityEventRecord.id, organizationId, context);
|
||||||
|
|
||||||
return activity;
|
return activity;
|
||||||
@@ -846,6 +849,7 @@ actorUserId: userId
|
|||||||
return nextActivity;
|
return nextActivity;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await drainProjectionOutboxBestEffort();
|
||||||
const activity = await getActivityById(completedEventRecord.id, organizationId, context);
|
const activity = await getActivityById(completedEventRecord.id, organizationId, context);
|
||||||
return activity;
|
return activity;
|
||||||
}
|
}
|
||||||
@@ -880,6 +884,7 @@ actorUserId: userId
|
|||||||
return nextActivity;
|
return nextActivity;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await drainProjectionOutboxBestEffort();
|
||||||
const activity = await getActivityById(cancelledEventRecord.id, organizationId, context);
|
const activity = await getActivityById(cancelledEventRecord.id, organizationId, context);
|
||||||
return activity;
|
return activity;
|
||||||
}
|
}
|
||||||
@@ -917,7 +922,8 @@ actorUserId: userId
|
|||||||
return nextActivity;
|
return nextActivity;
|
||||||
});
|
});
|
||||||
|
|
||||||
const activity = await getActivityById(assignedEventRecord.id, organizationId, context);
|
await drainProjectionOutboxBestEffort();
|
||||||
|
const activity = await getActivityById(assignedEventRecord.id, organizationId, context);
|
||||||
return activity;
|
return activity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -964,6 +970,7 @@ actorUserId: userId
|
|||||||
return nextActivity;
|
return nextActivity;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await drainProjectionOutboxBestEffort();
|
||||||
const activity = await getActivityById(rescheduledEventRecord.id, organizationId, context);
|
const activity = await getActivityById(rescheduledEventRecord.id, organizationId, context);
|
||||||
return activity;
|
return activity;
|
||||||
}
|
}
|
||||||
@@ -991,4 +998,6 @@ activity: current,
|
|||||||
actorUserId: userId
|
actorUserId: userId
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await drainProjectionOutboxBestEffort();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import type { BusinessEvent } from '../business-events/types.ts';
|
import type { BusinessEvent } from '../business-events/types.ts';
|
||||||
|
import { calendarProjectionConsumer as crmCalendarProjectionConsumer } from '../../crm/calendar/server/consumer.ts';
|
||||||
import { getProjectionDefinition } from './registry.ts';
|
import { getProjectionDefinition } from './registry.ts';
|
||||||
import type { ProjectionConsumer, ProjectionHandleResult } from './types.ts';
|
import type { ProjectionConsumer, ProjectionHandleResult } from './types.ts';
|
||||||
|
|
||||||
@@ -21,7 +22,7 @@ function createNoopConsumer(projectionName: string): ProjectionConsumer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const timelineProjectionConsumer = createNoopConsumer('Timeline');
|
export const timelineProjectionConsumer = createNoopConsumer('Timeline');
|
||||||
export const calendarProjectionConsumer = createNoopConsumer('Calendar');
|
export const calendarProjectionConsumer = crmCalendarProjectionConsumer;
|
||||||
export const dashboardProjectionConsumer = createNoopConsumer('Dashboard');
|
export const dashboardProjectionConsumer = createNoopConsumer('Dashboard');
|
||||||
export const notificationProjectionConsumer = createNoopConsumer('Notification');
|
export const notificationProjectionConsumer = createNoopConsumer('Notification');
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import { INITIAL_PROJECTION_CONSUMERS } from '../consumers.ts';
|
||||||
|
import { ProjectionOutboxWorker } from '../worker.ts';
|
||||||
|
import { DrizzleProjectionRuntimeStore } from './store.ts';
|
||||||
|
|
||||||
|
export async function drainProjectionOutboxBestEffort(): Promise<void> {
|
||||||
|
try {
|
||||||
|
const worker = new ProjectionOutboxWorker({
|
||||||
|
store: new DrizzleProjectionRuntimeStore(),
|
||||||
|
consumers: INITIAL_PROJECTION_CONSUMERS,
|
||||||
|
config: {
|
||||||
|
enabled: true,
|
||||||
|
batchSize: 25,
|
||||||
|
maxConcurrentEvents: 1,
|
||||||
|
maxConcurrentConsumers: 4,
|
||||||
|
workerId: `inline-projection-${crypto.randomUUID().slice(0, 8)}`
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await worker.drainOnce();
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[projections] best-effort inline drain failed', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { and, eq, sql } from 'drizzle-orm';
|
import { and, asc, eq, inArray, lte, or } from 'drizzle-orm';
|
||||||
import {
|
import {
|
||||||
businessEventOutbox,
|
businessEventOutbox,
|
||||||
projectionConsumerCheckpoints,
|
projectionConsumerCheckpoints,
|
||||||
@@ -51,37 +51,47 @@ export class DrizzleProjectionRuntimeStore implements ProjectionRuntimeStore {
|
|||||||
async claimAvailableEvents(
|
async claimAvailableEvents(
|
||||||
input: ClaimBusinessEventDeliveriesInput
|
input: ClaimBusinessEventDeliveriesInput
|
||||||
): Promise<BusinessEventDeliveryRecord[]> {
|
): Promise<BusinessEventDeliveryRecord[]> {
|
||||||
const result = await db.execute(sql`
|
const claimable = await db
|
||||||
WITH claimable AS (
|
.select({ id: businessEventOutbox.id })
|
||||||
SELECT id
|
.from(businessEventOutbox)
|
||||||
FROM business_event_outbox
|
.where(
|
||||||
WHERE
|
or(
|
||||||
(
|
and(
|
||||||
delivery_status IN ('pending', 'retry_scheduled')
|
inArray(businessEventOutbox.deliveryStatus, ['pending', 'retry_scheduled']),
|
||||||
AND available_at <= ${input.now}
|
lte(businessEventOutbox.availableAt, input.now)
|
||||||
|
),
|
||||||
|
and(
|
||||||
|
inArray(businessEventOutbox.deliveryStatus, ['claimed', 'processing']),
|
||||||
|
lte(businessEventOutbox.claimExpiresAt, input.now)
|
||||||
)
|
)
|
||||||
OR (
|
)
|
||||||
delivery_status IN ('claimed', 'processing')
|
|
||||||
AND claim_expires_at IS NOT NULL
|
|
||||||
AND claim_expires_at <= ${input.now}
|
|
||||||
)
|
|
||||||
ORDER BY available_at ASC, created_at ASC, id ASC
|
|
||||||
LIMIT ${input.batchSize}
|
|
||||||
FOR UPDATE SKIP LOCKED
|
|
||||||
)
|
)
|
||||||
UPDATE business_event_outbox
|
.orderBy(
|
||||||
SET
|
asc(businessEventOutbox.availableAt),
|
||||||
delivery_status = 'claimed',
|
asc(businessEventOutbox.createdAt),
|
||||||
claimed_by = ${input.workerId},
|
asc(businessEventOutbox.id)
|
||||||
claimed_at = ${input.now},
|
)
|
||||||
claim_expires_at = ${input.leaseExpiresAt},
|
.limit(input.batchSize);
|
||||||
updated_at = ${input.now}
|
|
||||||
FROM claimable
|
if (claimable.length === 0) return [];
|
||||||
WHERE business_event_outbox.id = claimable.id
|
|
||||||
RETURNING business_event_outbox.*
|
const rows = await db
|
||||||
`);
|
.update(businessEventOutbox)
|
||||||
|
.set({
|
||||||
|
deliveryStatus: 'claimed',
|
||||||
|
claimedBy: input.workerId,
|
||||||
|
claimedAt: input.now,
|
||||||
|
claimExpiresAt: input.leaseExpiresAt,
|
||||||
|
updatedAt: input.now
|
||||||
|
})
|
||||||
|
.where(
|
||||||
|
inArray(
|
||||||
|
businessEventOutbox.id,
|
||||||
|
claimable.map((item) => item.id)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.returning();
|
||||||
|
|
||||||
const rows = result as unknown as Array<typeof businessEventOutbox.$inferSelect>;
|
|
||||||
return rows.map((row) => mapDelivery(row));
|
return rows.map((row) => mapDelivery(row));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,27 +266,49 @@ export class DrizzleProjectionRuntimeStore implements ProjectionRuntimeStore {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async recordHealthSnapshot(input: ProjectionHealthSnapshotInput): Promise<void> {
|
async recordHealthSnapshot(input: ProjectionHealthSnapshotInput): Promise<void> {
|
||||||
await db.insert(projectionHealthSnapshots).values({
|
const values = {
|
||||||
id: crypto.randomUUID(),
|
id: crypto.randomUUID(),
|
||||||
organizationId: input.organizationId,
|
organizationId: input.organizationId,
|
||||||
projectionName: input.projectionName,
|
projectionName: input.projectionName,
|
||||||
consumerName: input.consumerName,
|
consumerName: input.consumerName,
|
||||||
status: input.status,
|
status: input.status,
|
||||||
lastProcessedEventId: input.lastProcessedEventId ?? null,
|
lastProcessedEventId: input.lastProcessedEventId ?? null,
|
||||||
lastSuccessfulProcessingAt: input.lastSuccessfulProcessingAt
|
lastSuccessfulProcessingAt: input.lastSuccessfulProcessingAt
|
||||||
? new Date(input.lastSuccessfulProcessingAt)
|
? new Date(input.lastSuccessfulProcessingAt)
|
||||||
: null,
|
: null,
|
||||||
pendingCount: input.pendingCount ?? 0,
|
pendingCount: input.pendingCount ?? 0,
|
||||||
retryCount: input.retryCount ?? 0,
|
retryCount: input.retryCount ?? 0,
|
||||||
deadLetterCount: input.deadLetterCount ?? 0,
|
deadLetterCount: input.deadLetterCount ?? 0,
|
||||||
unsupportedVersionCount: input.unsupportedVersionCount ?? 0,
|
unsupportedVersionCount: input.unsupportedVersionCount ?? 0,
|
||||||
processingLagMs: input.processingLagMs ?? 0,
|
processingLagMs: input.processingLagMs ?? 0,
|
||||||
averageProcessingDurationMs: input.averageProcessingDurationMs ?? 0,
|
averageProcessingDurationMs: input.averageProcessingDurationMs ?? 0,
|
||||||
lastRebuildAt: input.lastRebuildAt ? new Date(input.lastRebuildAt) : null,
|
lastRebuildAt: input.lastRebuildAt ? new Date(input.lastRebuildAt) : null,
|
||||||
rebuildSource: input.rebuildSource ?? null
|
rebuildSource: input.rebuildSource ?? null
|
||||||
});
|
};
|
||||||
}
|
|
||||||
|
await db
|
||||||
|
.insert(projectionHealthSnapshots)
|
||||||
|
.values(values)
|
||||||
|
.onConflictDoUpdate({
|
||||||
|
target: [projectionHealthSnapshots.organizationId, projectionHealthSnapshots.consumerName],
|
||||||
|
set: {
|
||||||
|
projectionName: values.projectionName,
|
||||||
|
status: values.status,
|
||||||
|
lastProcessedEventId: values.lastProcessedEventId,
|
||||||
|
lastSuccessfulProcessingAt: values.lastSuccessfulProcessingAt,
|
||||||
|
pendingCount: values.pendingCount,
|
||||||
|
retryCount: values.retryCount,
|
||||||
|
deadLetterCount: values.deadLetterCount,
|
||||||
|
unsupportedVersionCount: values.unsupportedVersionCount,
|
||||||
|
processingLagMs: values.processingLagMs,
|
||||||
|
averageProcessingDurationMs: values.averageProcessingDurationMs,
|
||||||
|
lastRebuildAt: values.lastRebuildAt,
|
||||||
|
rebuildSource: values.rebuildSource,
|
||||||
|
updatedAt: new Date()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private async getDelivery(eventId: string): Promise<BusinessEventDeliveryRecord | null> {
|
private async getDelivery(eventId: string): Promise<BusinessEventDeliveryRecord | null> {
|
||||||
const [row] = await db
|
const [row] = await db
|
||||||
|
|||||||
Reference in New Issue
Block a user