From 859530a669b08b5fce8ec4332b371a87e32da22f Mon Sep 17 00:00:00 2001 From: Mahdi Date: Tue, 11 Aug 2026 17:40:13 +0330 Subject: [PATCH] fix: new.gholaktala.ir is Khanegi modular, not Hamkar Revert wrong FORCE_HAMKAR classification; lock domain in FORCE_KHANEGI and keep Hamkar/Khanegi overrides separate. Co-authored-by: Cursor --- prisma/import-users.ts | 7 +- scripts/fix-gholaktala-to-hamkar.mjs | 114 ------------------------- scripts/fix-gholaktala-to-khanegi.mjs | 117 ++++++++++++++++++++++++++ 3 files changed, 120 insertions(+), 118 deletions(-) delete mode 100644 scripts/fix-gholaktala-to-hamkar.mjs create mode 100644 scripts/fix-gholaktala-to-khanegi.mjs diff --git a/prisma/import-users.ts b/prisma/import-users.ts index 9719d45..be26cf6 100644 --- a/prisma/import-users.ts +++ b/prisma/import-users.ts @@ -30,15 +30,14 @@ const FORCE_KHANEGI: Array<{ domain?: string; name?: string; externalId?: number { domain: 'abaeigold.ir' }, { domain: 'niazitala.ir' }, { domain: 'garoosigholaktala.ir' }, + { domain: 'new.gholaktala.ir' }, { domain: 'kh.kashkolgold.ir' }, { domain: 'goldsun.zaarbox.ir' }, { domain: 'goldaliii.com' }, ]; -/** Never mix with FORCE_KHANEGI — these sold versions are Hamkar (site/* APIs). */ -const FORCE_HAMKAR: Array<{ domain?: string; name?: string; externalId?: number }> = [ - { domain: 'new.gholaktala.ir' }, -]; +/** Manual Hamkar locks — never put Khanegi domains here. */ +const FORCE_HAMKAR: Array<{ domain?: string; name?: string; externalId?: number }> = []; /** Canonical public domains after migrations */ const DOMAIN_OVERRIDES: Record = { diff --git a/scripts/fix-gholaktala-to-hamkar.mjs b/scripts/fix-gholaktala-to-hamkar.mjs deleted file mode 100644 index fb3a6a1..0000000 --- a/scripts/fix-gholaktala-to-hamkar.mjs +++ /dev/null @@ -1,114 +0,0 @@ -import { PrismaClient } from '@prisma/client' - -/** - * Fix misclassified tenant: new.gholaktala.ir is Hamkar (user calls /site/settings), - * not Khanegi modular. Run on production API host: - * set -a && . ./.env && set +a && node scripts/fix-gholaktala-to-hamkar.mjs - */ -const prisma = new PrismaClient() -const APPLY = process.argv.includes('--apply') -const DOMAIN = 'new.gholaktala.ir' - -function bumpAppVersion(current) { - const v = String(current || '1').trim() || '1' - if (/^\d+$/.test(v)) return String(Number(v) + 1) - const semver = v.match(/^(\d+)\.(\d+)\.(\d+)$/) - if (semver) return `${semver[1]}.${semver[2]}.${Number(semver[3]) + 1}` - return String(Date.now()) -} - -async function main() { - const tenants = await prisma.tenant.findMany({ - where: { - OR: [ - { domain: { contains: 'gholaktala', mode: 'insensitive' } }, - { domains: { string_contains: 'gholaktala' } }, - { slug: { contains: 'gholak', mode: 'insensitive' } }, - ], - }, - select: { - id: true, - nameFa: true, - domain: true, - domains: true, - slug: true, - product: true, - uiVariant: true, - appVersion: true, - nodeServer: true, - notes: true, - }, - }) - - console.log( - 'MATCHES', - JSON.stringify( - tenants.map((t) => ({ - id: t.id, - domain: t.domain, - product: t.product, - uiVariant: t.uiVariant, - appVersion: t.appVersion, - })), - null, - 2, - ), - ) - - const tenant = - tenants.find((t) => String(t.domain).toLowerCase() === DOMAIN) || - tenants.find((t) => String(t.domain).toLowerCase().includes('new.gholaktala')) - - if (!tenant) throw new Error(`Tenant not found for ${DOMAIN}`) - - console.log('SELECTED', tenant) - - if (!APPLY) { - console.log('DRY_RUN — re-run with --apply to set product=hamkar') - return - } - - const nextVersion = bumpAppVersion(tenant.appVersion) - const full = await prisma.tenant.findUnique({ where: { id: tenant.id } }) - const ui = full?.appUiConfig - const keepUi = - ui && typeof ui === 'object' && !Array.isArray(ui) && ui.kind === 'hamkar' - ? ui - : null - - const updated = await prisma.tenant.update({ - where: { id: tenant.id }, - data: { - product: 'hamkar', - appUiConfig: keepUi, - appVersion: nextVersion, - notes: [ - String(tenant.notes || '') - .replace(/\s*\|?\s*misclassified-as-khanegi/g, '') - .trim(), - 'product=hamkar (fixed; was wrongly khanegi/modular)', - ] - .filter(Boolean) - .join(' | '), - }, - }) - - console.log('UPDATED', { - id: updated.id, - domain: updated.domain, - product: updated.product, - appVersion: updated.appVersion, - }) - console.log( - 'NOTE: Live frontend is Hamkar (/site/settings). Server must be Hamkar Laravel too — Khanegi api/get_settings alone is not enough.', - ) -} - -main() - .catch((e) => { - console.error(e) - process.exitCode = 1 - }) - .finally(async () => { - await prisma.$disconnect() - }) diff --git a/scripts/fix-gholaktala-to-khanegi.mjs b/scripts/fix-gholaktala-to-khanegi.mjs new file mode 100644 index 0000000..0468a91 --- /dev/null +++ b/scripts/fix-gholaktala-to-khanegi.mjs @@ -0,0 +1,117 @@ +import { PrismaClient } from '@prisma/client' + +/** + * Ensure new.gholaktala.ir stays Khanegi modular (not Hamkar). + * set -a && . ./.env && set +a && node scripts/fix-gholaktala-to-khanegi.mjs --apply + */ +const prisma = new PrismaClient() +const APPLY = process.argv.includes('--apply') +const DOMAIN = 'new.gholaktala.ir' + +function bumpAppVersion(current) { + const v = String(current || '1').trim() || '1' + if (/^\d+$/.test(v)) return String(Number(v) + 1) + const semver = v.match(/^(\d+)\.(\d+)\.(\d+)$/) + if (semver) return `${semver[1]}.${semver[2]}.${Number(semver[3]) + 1}` + return String(Date.now()) +} + +async function main() { + const tenants = await prisma.tenant.findMany({ + where: { + OR: [ + { domain: { equals: DOMAIN, mode: 'insensitive' } }, + { domains: { string_contains: DOMAIN } }, + { domain: { contains: 'gholaktala', mode: 'insensitive' } }, + ], + }, + select: { + id: true, + nameFa: true, + domain: true, + product: true, + uiVariant: true, + appVersion: true, + notes: true, + }, + }) + + console.log('MATCHES', JSON.stringify(tenants, null, 2)) + + const tenant = + tenants.find((t) => String(t.domain).toLowerCase() === DOMAIN) || tenants[0] + + if (!tenant) throw new Error(`Tenant not found for ${DOMAIN}`) + + const alreadyOk = + tenant.product === 'khanegi' && String(tenant.uiVariant || 'modular') !== 'newTheme' + + console.log('SELECTED', { + ...tenant, + alreadyOk, + expected: { product: 'khanegi', uiVariant: 'modular', frontend: 'userModular', api: '/api/get_settings' }, + }) + + if (!APPLY) { + console.log('DRY_RUN — re-run with --apply to force product=khanegi uiVariant=modular') + return + } + + if (alreadyOk && tenant.product === 'khanegi') { + const updated = await prisma.tenant.update({ + where: { id: tenant.id }, + data: { + product: 'khanegi', + uiVariant: 'modular', + notes: [ + String(tenant.notes || '') + .replace(/\s*\|\s*product=hamkar[^\|]*/g, '') + .trim(), + 'product=khanegi modular (confirmed)', + ] + .filter(Boolean) + .join(' | '), + }, + }) + console.log('CONFIRMED', { + id: updated.id, + product: updated.product, + uiVariant: updated.uiVariant, + appVersion: updated.appVersion, + }) + return + } + + const updated = await prisma.tenant.update({ + where: { id: tenant.id }, + data: { + product: 'khanegi', + uiVariant: 'modular', + appVersion: bumpAppVersion(tenant.appVersion), + notes: [ + String(tenant.notes || '') + .replace(/\s*\|\s*product=hamkar[^\|]*/g, '') + .trim(), + 'product=khanegi modular (restored; not hamkar)', + ] + .filter(Boolean) + .join(' | '), + }, + }) + + console.log('UPDATED', { + id: updated.id, + product: updated.product, + uiVariant: updated.uiVariant, + appVersion: updated.appVersion, + }) +} + +main() + .catch((e) => { + console.error(e) + process.exitCode = 1 + }) + .finally(async () => { + await prisma.$disconnect() + })