Commit Graph
61 Commits
Author SHA1 Message Date
mohmdsdgandCursor c4b814727a fix(replicas): GRANT SELECT on publisher tables to repl_user
settings/setting_templates were created after replica setup, so the
subscription COPY user could not read them and tablesync looped.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-18 16:01:29 +03:30
mohmdsdgandCursor 810d1672a5 fix(replicas): never REFRESH with copy_data=true after a data copy
A second logical copy unique-conflicts on existing PKs and leaves
tablesync workers stuck, so live UPDATEs never apply on slaves.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-18 15:45:25 +03:30
mohmdsdgandCursor d055c50b94 fix(replicas): connect publisher via unix socket or postgres user
TCP 127.0.0.1:15432 is often closed; dump/count now fall back to the
cluster socket and runuser -u postgres, which already works on master.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-18 15:10:06 +03:30
mohmdsdgandCursor 82f63d224e fix(replicas): reach publisher via unix socket or sudo postgres
TCP 127.0.0.1:15432 is often closed; the cluster listens on a unix
socket. Fall back to /var/run/postgresql then runuser -u postgres.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-18 12:59:45 +03:30
mohmdsdgandCursor 1cc5e09b5f fix(replicas): parse Prisma DATABASE_URL and dump tables by name
Passwords with @ broke libpq URIs; convert to keyword conninfo.
pg_dump -t public."table" produced empty dumps so replicas stayed at 0.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-18 12:55:39 +03:30
mohmdsdgandCursor 26630cecf6 fix(replicas): use PUBLISHER_DSN when DATABASE_URL breaks pg_dump
Prisma DATABASE_URL passwords with @ confuse libpq URI parsing (host
Montime@127.0.0.1). Repair scripts now prefer explicit PUBLISHER_DSN.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-18 12:41:23 +03:30
mohmdsdgandCursor 693b1ef93e fix(replicas): do not flock on manual repair-data
Operator --repair was blocked when pm2 watch owned /tmp lock file.
Only --repair-if-needed uses flock; lock path moved under deploy/.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-18 12:39:45 +03:30
mohmdsdgandCursor 16d562caa5 feat(replicas): auto-heal slave data drift and no-store public settings
Add sync-replica-data repair on deploy, a publisher-side replica watch
(60s + after tenant/settings writes), REFRESH PUBLICATION after migrate,
and Cache-Control no-store on program-settings and get_version.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-18 12:32:30 +03:30
mohmdsdgandCursor 668bbcc1db fix(program-settings): skip deploy_const keys in Khanegi import preview
Catalog keys are compiled into the API bundle so import no longer depends on an incomplete templates table or missing JSON on the server.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-17 21:51:48 +03:30
mohmdsdgandCursor 357c4fef59 fix(program-settings): log into Khanegi via /auth/login like the admin panel
Import was posting to /admin/login without provider=user, so no token came back even with valid credentials.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-17 21:39:45 +03:30
mohmdsdgandCursor d57ce0a3cb feat(settings): store Khanegi keys in settings tables instead of tenant JSON
Template defaults seed from deploy_settings_const; new tenants copy them, import decides per key, and /get_settings reads the per-tenant rows.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-17 20:14:17 +03:30
mohmdsdgandCursor 8f9988eb15 feat(program-settings): expose tenant settings APIs and merge PATCH by key
Sold apps can read settings from /get_settings; Super Admin saves only changed keys so huge runtime logs are not sent in the body.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-17 17:07:46 +03:30
mohmdsdgandCursor 25c0a4e941 fix(api): allow nest build of program-settings and cleaner replica --check
Cast stored JSON through asSettingsArray so tsc accepts the snapshot payload, and strip Prisma ?schema= from DATABASE_URL before psql.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-17 16:01:55 +03:30
mohmdsdgandCursor f2cf8c9035 feat(tenants): store Khanegi deploy settings snapshot on tenants.setting
Import can_edit=0 settings via the sold version's admin login + get_settings, for Super Admin program-settings UI.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-17 15:02:22 +03:30
Mahdi 48649a6a79 fix(settings-proxy): prefer SMS shared secret for product push auth 2026-08-14 17:44:53 +03:30
MahdiandCursor 9cfd38ef99 feat(get_user): expose subscription_alerts for admin expiry modals
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-14 16:31:44 +03:30
MahdiandCursor 9bdecdf00a chore: ignore local gholak SMS zero script
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-13 12:27:05 +03:30
mohmdsdgandCursor 515e39d420 feat(deploy): sync schema to replication subscribers before migrating
Logical replication carries rows but not DDL, so a migration that adds a
column stalls every subscriber with "missing replicated columns" until the
column exists there too. _prisma_migrations is replicated, so migrate deploy
on a subscriber reports nothing pending while its tables lag behind.

sync-replica-schema.sh applies pending migrations to each subscriber first,
tracking them locally in _replica_ddl_applied, then migrates the publisher.
--check reports subscription state and columns missing on any replica.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-11 21:34:02 +03:30
MahdiandCursor aec5e08a1e fix(settings-proxy): send SMS shared secret as Bearer for CDN
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-11 19:53:30 +03:30
MahdiandCursor 8fe7d59c1b fix(settings-proxy): push kill-switch with SMS shared HMAC
When remoteApiToken is empty, sign SuperAdmin→product /super/settings
with the same SMS_REMOTE_SHARED_SECRET + domain headers used by SMS.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-11 19:33:13 +03:30
MahdiandCursor 5a268faa94 fix: lock new.gholaktala.ir as Khanegi newTheme (userTheme)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-11 17:55:01 +03:30
MahdiandCursor dd4850d9fa fix: lock new.gholaktala.ir as Khanegi newTheme (userTheme)
Correct prior modular/Hamkar misclassification. Protect locked newTheme domains from bulk-modular brand overrides.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-11 17:53:04 +03:30
MahdiandCursor 859530a669 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 <cursoragent@cursor.com>
2026-08-11 17:40:13 +03:30
MahdiandCursor 0aeb17bd1b fix: keep new.gholaktala.ir as Hamkar, not Khanegi
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-11 17:26:00 +03:30
MahdiandCursor 51e350405a feat: per-tenant server access kill switch
Add Tenant.serverAccessBlocked, toggle API with appVersion bump and settings push, and expose stealth server_reachable in get_user.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-11 16:05:04 +03:30
MahdiandCursor af1e217a68 feat(auth): add module read/write admin RBAC
Introduce permission catalog, PermissionsGuard, JWT/me payload with
role+permissions, and gate all module controllers. Admins CRUD accepts
role/permissions with safety rules; migrate existing users to super_admin.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-10 15:29:04 +03:30
MahdiandCursor 4b3a8a1d6c docs: record SuperAdmin-only git push policy in AGENTS.md
Khanegi/Hamkar product repos require explicit approval before commit/push.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-10 14:28:59 +03:30
MahdiandCursor e9067eb70e fix: allow localhost/LAN CORS for SuperAdmin public APIs
Local Vite frontends can call production adm.montzar.ir get_user/get_version without running a local API.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-10 13:30:22 +03:30
MahdiandCursor a589c7f0c2 fix: normalize Khanegi newTheme ui config for userTheme schema
Map sidebar+bottom→both, products→buyProduct, ensure header.variant. Repair script + get_user normalize so colors apply instead of Zod fallback.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-10 12:34:07 +03:30
MahdiandCursor 425eb3c714 feat: bulk apply Niazi modular brand colors to Khanegi tenants
Add prisma:bulk-khanegi-modular-brand (skip Aygin/newTheme). Palette: header #0a1b37, accent #e0be7f, bg #ffffff; bumps appVersion.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-10 11:42:31 +03:30
MahdiandCursor e025496595 feat: bump appVersion when branding changes to invalidate get_user cache
Appearance/avatar/name/uiVariant updates auto-increment Tenant.appVersion so clients refetch get_user only after get_version changes.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-09 17:42:50 +03:30
MahdiandCursor 501bcd0894 fix: prefer primary Tenant.domain in get_user/get_version matching
When multiple tenants claim the same host via domains aliases, resolve the tenant whose primary domain matches first so branding edits apply to the expected version.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-09 16:36:10 +03:30
MahdiandCursor be50c99f65 feat: public GET /manifest.json from tenant branding
Serve PWA/APK web manifest per domain (name, theme colors, multi-size icons from avatar), exclude from api prefix, and proxy via nginx.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-09 15:41:50 +03:30
MahdiandCursor 1adaef5d18 Add Khanegi uiVariant modular/newTheme with get_user payload split.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-09 12:58:45 +03:30
MahdiandCursor 2f0e39edbb Add bulk copy of Khanegi SMS price and charge info from pilot.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-08 16:00:54 +03:30
MahdiandCursor 039a2a606b Fix SMS batch apply dry-run env and add rollout tracker.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-08 15:34:45 +03:30
MahdiandCursor 448dc444c9 Add Khanegi SMS sync inventory, batch import, and rollout helpers.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-08 15:30:43 +03:30
MahdiandCursor b9a33505e4 Allow negative SMS auto-block threshold in API.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-08 14:55:15 +03:30
MahdiandCursor 26f7b7e69e Fix auto-block migration SQL for PostgreSQL.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-08 14:42:39 +03:30
MahdiandCursor 8eba9a9b8f Add optional SMS auto-block threshold below balance.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-08 14:12:29 +03:30
MahdiandCursor f9b77ceaac Show SMS money labels in tomans; keep remote APIs in rials.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-08 13:27:31 +03:30
MahdiandCursor db66a44527 Add support subscription panel API with optional free periods.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-08 11:20:25 +03:30
MahdiandCursor f61d10e07b Allow multiple hosting servers per sold version.
Drop unique tenant_id on server_accounts and add create/update/delete/renew APIs per server account, with list/expiring using the worst status.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-06 19:23:37 +03:30
MahdiandCursor c6d90ea262 Fix SMS tenant copy target matching; add list-tenants helper.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-06 17:17:56 +03:30
MahdiandCursor 7ebee7fa4e Add script to copy SMS wallet between SuperAdmin tenants.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-06 16:58:19 +03:30
MahdiandCursor 2d21813c7b Fix SMS import tableExists to use selected database name.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-06 15:39:59 +03:30
MahdiandCursor 12513e4967 Allow SMS send with negative balance; only block switch stops sending.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-05 22:24:20 +03:30
MahdiandCursor 17a54774ae Add remote SMS panel sync API and product MySQL import script.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-05 20:53:59 +03:30
MahdiandCursor 57654e295c Add shared HMAC+domain auth for remote SMS wallet API.
Products can authenticate with one shared secret and tenant domain instead of per-version tokens; Bearer token remains as fallback.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-05 17:11:55 +03:30
Mahdi 14d9c5d143 Implementing SMS panel in Super Admin 2026-08-05 14:13:44 +03:30