diff --git a/apps/super-admin/src/pages/BusinessesPage.tsx b/apps/super-admin/src/pages/BusinessesPage.tsx
index b4cf6f8..5e5d700 100644
--- a/apps/super-admin/src/pages/BusinessesPage.tsx
+++ b/apps/super-admin/src/pages/BusinessesPage.tsx
@@ -244,6 +244,7 @@ export function BusinessesPage() {
const [domainId, setDomainId] = useState(null)
const [domainHost, setDomainHost] = useState('')
const [domainGitRepoUrl, setDomainGitRepoUrl] = useState('')
+ const [domainUpdateDns, setDomainUpdateDns] = useState(false)
const [domainSubmitting, setDomainSubmitting] = useState(false)
const [domainError, setDomainError] = useState('')
@@ -635,6 +636,7 @@ export function BusinessesPage() {
setDomainId(b.domainId)
setDomainHost(b.domain ?? '')
setDomainGitRepoUrl(b.gitRepoUrl ?? '')
+ setDomainUpdateDns(!b.domainId)
setDomainError('')
setDomainOpen(true)
}
@@ -827,6 +829,7 @@ export function BusinessesPage() {
setDomainId(null)
setDomainHost('')
setDomainGitRepoUrl('')
+ setDomainUpdateDns(false)
setDomainError('')
}
@@ -844,6 +847,7 @@ export function BusinessesPage() {
if (domainId) {
const updated = (await updateBusinessDomain(businessId, domainId, {
host,
+ updateDns: domainUpdateDns,
...(gitRepoUrl ? { gitRepoUrl } : {}),
})) as {
id: number
@@ -892,6 +896,7 @@ export function BusinessesPage() {
const created = (await addBusinessDomain(businessId, {
host,
isPrimary: true,
+ updateDns: domainUpdateDns,
...(gitRepoUrl ? { gitRepoUrl } : {}),
})) as {
id: number
@@ -946,6 +951,7 @@ export function BusinessesPage() {
setDomainId(null)
setDomainHost('')
setDomainGitRepoUrl('')
+ setDomainUpdateDns(false)
setDomainError('')
} catch (err) {
if (submitId !== domainSubmitGenRef.current) return
@@ -1456,9 +1462,11 @@ export function BusinessesPage() {
{domainError}
) : null}
- {domainSubmitting && domainGitRepoUrl.trim() ? (
+ {domainSubmitting && (domainGitRepoUrl.trim() || domainUpdateDns) ? (
- Saving domain and setting up storefront on the websites server…
+ {domainGitRepoUrl.trim()
+ ? 'Saving domain and setting up storefront on the websites server…'
+ : 'Saving domain and updating Arvan DNS…'}
) : null}
@@ -1489,6 +1497,21 @@ export function BusinessesPage() {
+
+ setDomainUpdateDns(e.target.checked)}
+ disabled={domainSubmitting}
+ />
+ Update DNS records
+
+
+ When checked, upserts Arvan records: @ ANAME → ns.meshkee.com, plus www,
+ business, customer, and api CNAMEs.
+
+
(null)
const [editFirstName, setEditFirstName] = useState('')
const [editLastName, setEditLastName] = useState('')
+ const [editFirstNameEn, setEditFirstNameEn] = useState('')
+ const [editLastNameEn, setEditLastNameEn] = useState('')
const [editEmail, setEditEmail] = useState('')
const [editCell, setEditCell] = useState('')
const [editSubmitting, setEditSubmitting] = useState(false)
@@ -419,6 +422,8 @@ export function UsersPage() {
setEditUser(user)
setEditFirstName(user.firstName ?? '')
setEditLastName(user.lastName ?? '')
+ setEditFirstNameEn(user.firstNameEn ?? '')
+ setEditLastNameEn(user.lastNameEn ?? '')
setEditEmail('')
setEditCell(user.cellNumber)
setEditError('')
@@ -433,6 +438,8 @@ export function UsersPage() {
await updateUser(editUser.id, {
firstName: editFirstName.trim(),
lastName: editLastName.trim(),
+ firstNameEn: editFirstNameEn.trim(),
+ lastNameEn: editLastNameEn.trim(),
cellNumber: editCell.trim(),
...(editEmail.trim() ? { email: editEmail.trim() } : {}),
})
@@ -449,6 +456,8 @@ export function UsersPage() {
...item,
firstName: editFirstName.trim(),
lastName: editLastName.trim(),
+ firstNameEn: editFirstNameEn.trim() || null,
+ lastNameEn: editLastNameEn.trim() || null,
cellNumber: editCell.trim(),
}
: item,
@@ -817,20 +826,52 @@ export function UsersPage() {
) : null}
- First name
+ First name (FA)
setEditFirstName(e.target.value)}
+ placeholder="نام"
+ dir="rtl"
+ lang="fa"
disabled={editSubmitting}
/>
- Last name
+ Last name (FA)
setEditLastName(e.target.value)}
+ placeholder="نام خانوادگی"
+ dir="rtl"
+ lang="fa"
+ disabled={editSubmitting}
+ />
+
+
+ First name (EN)
+ setEditFirstNameEn(e.target.value)}
+ placeholder="First name"
+ dir="ltr"
+ lang="en"
+ disabled={editSubmitting}
+ />
+
+
+ Last name (EN)
+ setEditLastNameEn(e.target.value)}
+ placeholder="Last name"
+ dir="ltr"
+ lang="en"
disabled={editSubmitting}
/>
diff --git a/apps/super-admin/src/pages/WebsitesPage.tsx b/apps/super-admin/src/pages/WebsitesPage.tsx
index 42f2da6..1e7999c 100644
--- a/apps/super-admin/src/pages/WebsitesPage.tsx
+++ b/apps/super-admin/src/pages/WebsitesPage.tsx
@@ -100,6 +100,7 @@ export function WebsitesPage() {
const [editDomain, setEditDomain] = useState
(null)
const [editHost, setEditHost] = useState('')
const [editExpiresAt, setEditExpiresAt] = useState('')
+ const [editUpdateDns, setEditUpdateDns] = useState(false)
const [editSubmitting, setEditSubmitting] = useState(false)
const [editError, setEditError] = useState('')
@@ -168,6 +169,7 @@ export function WebsitesPage() {
setEditDomain(domain)
setEditHost(domain.host)
setEditExpiresAt(domain.expiresAt ? domain.expiresAt.slice(0, 10) : '')
+ setEditUpdateDns(false)
setEditError('')
setEditOpen(true)
}
@@ -177,13 +179,25 @@ export function WebsitesPage() {
setEditSubmitting(true)
setEditError('')
try {
- await updateDomain(editDomain.id, {
+ const updated = (await updateDomain(editDomain.id, {
host: editHost.trim(),
+ updateDns: editUpdateDns,
...(editExpiresAt ? { expiresAt: new Date(editExpiresAt).toISOString() } : {}),
- })
+ })) as { dnsError?: string | null }
setEditOpen(false)
setEditDomain(null)
- showToast(`"${editHost.trim()}" has been updated.`, 'success')
+ setEditUpdateDns(false)
+ if (updated.dnsError) {
+ showToast(`"${editHost.trim()}" was updated, but Arvan DNS failed.`, 'error')
+ showToast(updated.dnsError, 'error')
+ } else {
+ showToast(
+ editUpdateDns
+ ? `"${editHost.trim()}" has been updated and DNS records synced.`
+ : `"${editHost.trim()}" has been updated.`,
+ 'success',
+ )
+ }
setData((prev) => {
if (!prev) return prev
return {
@@ -711,6 +725,7 @@ export function WebsitesPage() {
onClose={() => {
setEditOpen(false)
setEditDomain(null)
+ setEditUpdateDns(false)
setEditError('')
}}
>
@@ -740,6 +755,21 @@ export function WebsitesPage() {
/>
+
+ setEditUpdateDns(e.target.checked)}
+ disabled={editSubmitting}
+ />
+ Update DNS records
+
+
+ When checked, upserts Arvan records: @ ANAME → ns.meshkee.com, plus www,
+ business, customer, and api CNAMEs.
+
+
**For AI agents:** Read this file at the start of a new chat before making changes.
> Update this document when a major feature is completed or architecture changes.
-Last updated: August 19, 2026
+Last updated: August 20, 2026
---
@@ -138,11 +138,11 @@ Add to `/etc/hosts` (one line per tenant):
|------|------|
| `/login` | Login |
| `/` | Home |
-| `/businesses` | Businesses list (migrate-from-old + delete-data for portfolios/blogs(+news)/customers + categories; single-select). **Add domain** accepts optional Git repo URL → provisions storefront on websites VM and sets `deploy_slug`. Also upserts Arvan DNS (`@` ANAME → `ns.meshkee.com`, `www` CNAME → apex, `business`/`customer`/`api` CNAMEs). |
+| `/businesses` | Businesses list (migrate-from-old + delete-data for portfolios/blogs(+news)/customers + categories; single-select). **Add/Edit domain** accepts optional Git repo URL → provisions storefront on websites VM and sets `deploy_slug`. Optional **Update DNS records** checkbox upserts Arvan DNS (`@` ANAME → `ns.meshkee.com`, `www` CNAME → apex, `business`/`customer`/`api` CNAMEs). |
| `/businesses/:businessId/invoices` | Business invoices list |
| `/businesses/:businessId/invoices/new` | Issue invoice (full page) |
| `/users` | Users (business filter: Customer vs Manager → Admin/Editor/Viewer; Admin assignable by super-admin only; owners locked) |
-| `/websites` | Websites / domains (Deploy when `deploy_slug` set) |
+| `/websites` | Websites / domains (Deploy when `deploy_slug` set). Edit domain can optionally update Arvan DNS. |
| `/settings` | Platform settings (invoice templates + item templates) |
| `/settings/invoice-templates/new` | Create invoice template |
| `/settings/invoice-templates/:templateId` | Edit invoice template |