Initial commit: Meshkee CMS API

NestJS backend with Prisma, Docker Compose for Postgres/Redis, and deploy docs for the production VM.
This commit is contained in:
Ali Reza
2026-07-21 17:52:36 +03:30
commit bb59d5e9ba
254 changed files with 37031 additions and 0 deletions
@@ -0,0 +1,119 @@
import { Prisma } from '@prisma/client';
import {
normalizeBusinessPrimaryColorId,
} from './business-primary-colors';
import {
BusinessSettings,
DEFAULT_BUSINESS_SETTINGS,
DEFAULT_ORDER_PROCESS_STEPS,
OrderProcessStep,
} from './business-settings.types';
import {
defaultOrderStepColor,
normalizeOrderStepColor,
} from './order-step-colors';
function isRecord(value: unknown): value is Record<string, unknown> {
return typeof value === 'object' && value !== null && !Array.isArray(value);
}
function readBoolean(value: unknown, fallback: boolean) {
return typeof value === 'boolean' ? value : fallback;
}
function readOrderProcessSteps(value: unknown): OrderProcessStep[] {
if (!Array.isArray(value)) {
return DEFAULT_ORDER_PROCESS_STEPS;
}
const steps = value
.map((item, index) => {
if (!isRecord(item)) return null;
const id = typeof item.id === 'string' ? item.id.trim() : '';
const label = typeof item.label === 'string' ? item.label.trim() : '';
if (!id || !label) return null;
return {
id,
label,
color: normalizeOrderStepColor(
item.color,
defaultOrderStepColor(id, index),
),
};
})
.filter((step): step is OrderProcessStep => step !== null);
return steps.length ? steps : DEFAULT_ORDER_PROCESS_STEPS;
}
export function normalizeBusinessSettings(raw: unknown): BusinessSettings {
const source = isRecord(raw) ? raw : {};
const branding = isRecord(source.branding) ? source.branding : {};
const dashboard = isRecord(source.dashboard) ? source.dashboard : {};
const comments = isRecord(dashboard.comments) ? dashboard.comments : {};
const expertReviews = isRecord(dashboard.expertReviews)
? dashboard.expertReviews
: {};
const store = isRecord(source.store) ? source.store : {};
return {
branding: {
primaryColor: normalizeBusinessPrimaryColorId(branding.primaryColor),
},
dashboard: {
comments: {
autoApprove: readBoolean(
comments.autoApprove,
DEFAULT_BUSINESS_SETTINGS.dashboard.comments.autoApprove,
),
},
expertReviews: {
autoApprove: readBoolean(
expertReviews.autoApprove,
DEFAULT_BUSINESS_SETTINGS.dashboard.expertReviews.autoApprove,
),
},
},
store: {
onlineSellEnabled: readBoolean(
store.onlineSellEnabled,
DEFAULT_BUSINESS_SETTINGS.store.onlineSellEnabled,
),
orderProcessSteps: readOrderProcessSteps(store.orderProcessSteps),
},
};
}
export function mergeBusinessSettings(
current: BusinessSettings,
patch: Partial<BusinessSettings>,
): BusinessSettings {
return {
branding: {
primaryColor:
patch.branding?.primaryColor ?? current.branding.primaryColor,
},
dashboard: {
comments: {
autoApprove:
patch.dashboard?.comments?.autoApprove ??
current.dashboard.comments.autoApprove,
},
expertReviews: {
autoApprove:
patch.dashboard?.expertReviews?.autoApprove ??
current.dashboard.expertReviews.autoApprove,
},
},
store: {
onlineSellEnabled:
patch.store?.onlineSellEnabled ?? current.store.onlineSellEnabled,
orderProcessSteps:
patch.store?.orderProcessSteps ?? current.store.orderProcessSteps,
},
};
}
export function toPrismaJson(settings: BusinessSettings): Prisma.InputJsonValue {
return settings as Prisma.InputJsonValue;
}