mirror of
https://git.meshkee.com/Meshkee/backend.git
synced 2026-08-11 22:30:59 +04:30
Allow storefront provision when editing a domain git URL.
Edit Domain can wire deploy_slug the same way as Add Domain so existing businesses get a Deploy button without recreating the domain. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
co-authored by
Cursor
parent
d933aef40b
commit
7d123502f8
@@ -55,6 +55,8 @@ type BusinessRow = {
|
|||||||
domainId: bigint | null;
|
domainId: bigint | null;
|
||||||
domain: string | null;
|
domain: string | null;
|
||||||
sslEnabled: boolean | null;
|
sslEnabled: boolean | null;
|
||||||
|
gitRepoUrl: string | null;
|
||||||
|
deploySlug: string | null;
|
||||||
ownerUserId: bigint | null;
|
ownerUserId: bigint | null;
|
||||||
ownerName: string | null;
|
ownerName: string | null;
|
||||||
ownerNameEn: string | null;
|
ownerNameEn: string | null;
|
||||||
@@ -134,6 +136,8 @@ export class BusinessAdminService {
|
|||||||
dom.id AS "domainId",
|
dom.id AS "domainId",
|
||||||
dom.host AS "domain",
|
dom.host AS "domain",
|
||||||
dom.ssl_enabled AS "sslEnabled",
|
dom.ssl_enabled AS "sslEnabled",
|
||||||
|
dom.git_repo_url AS "gitRepoUrl",
|
||||||
|
dom.deploy_slug AS "deploySlug",
|
||||||
own."ownerUserId" AS "ownerUserId",
|
own."ownerUserId" AS "ownerUserId",
|
||||||
own."ownerName" AS "ownerName",
|
own."ownerName" AS "ownerName",
|
||||||
own."ownerNameEn" AS "ownerNameEn",
|
own."ownerNameEn" AS "ownerNameEn",
|
||||||
@@ -144,7 +148,7 @@ export class BusinessAdminService {
|
|||||||
b.settings->'modules'->'charts' AS "homeCharts"
|
b.settings->'modules'->'charts' AS "homeCharts"
|
||||||
FROM businesses b
|
FROM businesses b
|
||||||
LEFT JOIN LATERAL (
|
LEFT JOIN LATERAL (
|
||||||
SELECT d.id, d.host, d.ssl_enabled
|
SELECT d.id, d.host, d.ssl_enabled, d.git_repo_url, d.deploy_slug
|
||||||
FROM domains d
|
FROM domains d
|
||||||
WHERE d.business_id = b.id
|
WHERE d.business_id = b.id
|
||||||
ORDER BY d.is_primary DESC, d.created_at DESC
|
ORDER BY d.is_primary DESC, d.created_at DESC
|
||||||
@@ -548,12 +552,19 @@ export class BusinessAdminService {
|
|||||||
|
|
||||||
const businessId = BigInt(businessIdRaw);
|
const businessId = BigInt(businessIdRaw);
|
||||||
const domainId = BigInt(domainIdRaw);
|
const domainId = BigInt(domainIdRaw);
|
||||||
const host = dto.host.trim();
|
const host = dto.host.trim().toLowerCase();
|
||||||
|
const gitRepoUrl = dto.gitRepoUrl?.trim() || null;
|
||||||
|
|
||||||
if (!host) {
|
if (!host) {
|
||||||
throw new BadRequestException('host is required');
|
throw new BadRequestException('host is required');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gitRepoUrl && !isValidGitRepoUrl(gitRepoUrl)) {
|
||||||
|
throw new BadRequestException(
|
||||||
|
'gitRepoUrl must be an SSH git URL (e.g. git@git.meshkee.com:Meshkee-Websites/oaktasty.git)',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const domain = await this.prisma.domain.findFirst({
|
const domain = await this.prisma.domain.findFirst({
|
||||||
where: { id: domainId, businessId },
|
where: { id: domainId, businessId },
|
||||||
});
|
});
|
||||||
@@ -567,10 +578,55 @@ export class BusinessAdminService {
|
|||||||
throw new ConflictException('Domain host is already taken');
|
throw new ConflictException('Domain host is already taken');
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.prisma.domain.update({
|
let deploySlug = domain.deploySlug;
|
||||||
|
let provisionError: string | null = null;
|
||||||
|
let nextGitRepoUrl = domain.gitRepoUrl;
|
||||||
|
|
||||||
|
if (gitRepoUrl) {
|
||||||
|
const slug = domain.deploySlug?.trim() || deploySlugFromHost(host);
|
||||||
|
if (!slug) {
|
||||||
|
throw new BadRequestException('Could not derive deploy slug from host');
|
||||||
|
}
|
||||||
|
|
||||||
|
const slugTaken = await this.prisma.domain.findFirst({
|
||||||
|
where: { deploySlug: slug, NOT: { id: domainId } },
|
||||||
|
select: { id: true },
|
||||||
|
});
|
||||||
|
if (slugTaken) {
|
||||||
|
throw new ConflictException(`Deploy slug "${slug}" is already in use`);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await this.websiteDeployAgent.provision({
|
||||||
|
slug,
|
||||||
|
host,
|
||||||
|
gitRepoUrl,
|
||||||
|
});
|
||||||
|
deploySlug = slug;
|
||||||
|
nextGitRepoUrl = gitRepoUrl;
|
||||||
|
} catch (err) {
|
||||||
|
if (err && typeof err === 'object' && 'message' in err && typeof err.message === 'string') {
|
||||||
|
provisionError = err.message;
|
||||||
|
} else {
|
||||||
|
provisionError = 'Storefront provision failed on websites server';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const updated = await this.prisma.domain.update({
|
||||||
where: { id: domainId },
|
where: { id: domainId },
|
||||||
data: { host },
|
data: {
|
||||||
|
host,
|
||||||
|
...(gitRepoUrl && !provisionError
|
||||||
|
? { deploySlug, gitRepoUrl: nextGitRepoUrl }
|
||||||
|
: {}),
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
...updated,
|
||||||
|
provisionError,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async disable(businessIdRaw: string, dto: DisableBusinessDto, actor: AuthUser) {
|
async disable(businessIdRaw: string, dto: DisableBusinessDto, actor: AuthUser) {
|
||||||
|
|||||||
@@ -1,7 +1,16 @@
|
|||||||
import { IsString, MinLength } from 'class-validator';
|
import { IsOptional, IsString, Matches, MinLength } from 'class-validator';
|
||||||
|
|
||||||
export class UpdateDomainDto {
|
export class UpdateDomainDto {
|
||||||
@IsString()
|
@IsString()
|
||||||
@MinLength(1)
|
@MinLength(1)
|
||||||
host!: string;
|
host!: string;
|
||||||
|
|
||||||
|
/** SSH git URL — when set, provisions storefront deploy on the websites VM. */
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
@Matches(/^(?:git@[\w.-]+:[\w./-]+\.git|ssh:\/\/git@[\w.-]+(?::\d+)?\/[\w./-]+\.git)$/i, {
|
||||||
|
message:
|
||||||
|
'gitRepoUrl must be an SSH git URL (e.g. git@git.meshkee.com:Meshkee-Websites/oaktasty.git)',
|
||||||
|
})
|
||||||
|
gitRepoUrl?: string;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user