diff --git a/prisma/import-users.ts b/prisma/import-users.ts index c1b61db..9719d45 100644 --- a/prisma/import-users.ts +++ b/prisma/import-users.ts @@ -35,6 +35,11 @@ const FORCE_KHANEGI: Array<{ domain?: string; name?: string; externalId?: number { 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' }, +]; + /** Canonical public domains after migrations */ const DOMAIN_OVERRIDES: Record = { '24gold.app': { @@ -87,6 +92,19 @@ function classifyProduct(row: SourceUser, domains: string[]): { confident: boolean; reason: string; } { + const forcedHamkar = FORCE_HAMKAR.find((item) => { + if (item.externalId && item.externalId === row.id) return true; + if (item.domain && domains.includes(item.domain)) return true; + return false; + }); + if (forcedHamkar) { + return { + product: 'hamkar', + confident: true, + reason: `manual override hamkar (${forcedHamkar.domain || forcedHamkar.externalId})`, + }; + } + const forced = FORCE_KHANEGI.find((item) => { if (item.externalId && item.externalId === row.id) return true; if (item.domain && domains.includes(item.domain)) return true; @@ -96,7 +114,7 @@ function classifyProduct(row: SourceUser, domains: string[]): { return { product: 'khanegi', confident: true, - reason: `manual override (${forced.domain || forced.externalId})`, + reason: `manual override khanegi (${forced.domain || forced.externalId})`, }; } diff --git a/scripts/fix-gholaktala-to-hamkar.mjs b/scripts/fix-gholaktala-to-hamkar.mjs new file mode 100644 index 0000000..fb3a6a1 --- /dev/null +++ b/scripts/fix-gholaktala-to-hamkar.mjs @@ -0,0 +1,114 @@ +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() + })