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;
|
||||
domain: string | null;
|
||||
sslEnabled: boolean | null;
|
||||
gitRepoUrl: string | null;
|
||||
deploySlug: string | null;
|
||||
ownerUserId: bigint | null;
|
||||
ownerName: string | null;
|
||||
ownerNameEn: string | null;
|
||||
@@ -134,6 +136,8 @@ export class BusinessAdminService {
|
||||
dom.id AS "domainId",
|
||||
dom.host AS "domain",
|
||||
dom.ssl_enabled AS "sslEnabled",
|
||||
dom.git_repo_url AS "gitRepoUrl",
|
||||
dom.deploy_slug AS "deploySlug",
|
||||
own."ownerUserId" AS "ownerUserId",
|
||||
own."ownerName" AS "ownerName",
|
||||
own."ownerNameEn" AS "ownerNameEn",
|
||||
@@ -144,7 +148,7 @@ export class BusinessAdminService {
|
||||
b.settings->'modules'->'charts' AS "homeCharts"
|
||||
FROM businesses b
|
||||
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
|
||||
WHERE d.business_id = b.id
|
||||
ORDER BY d.is_primary DESC, d.created_at DESC
|
||||
@@ -548,12 +552,19 @@ export class BusinessAdminService {
|
||||
|
||||
const businessId = BigInt(businessIdRaw);
|
||||
const domainId = BigInt(domainIdRaw);
|
||||
const host = dto.host.trim();
|
||||
const host = dto.host.trim().toLowerCase();
|
||||
const gitRepoUrl = dto.gitRepoUrl?.trim() || null;
|
||||
|
||||
if (!host) {
|
||||
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({
|
||||
where: { id: domainId, businessId },
|
||||
});
|
||||
@@ -567,10 +578,55 @@ export class BusinessAdminService {
|
||||
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 },
|
||||
data: { host },
|
||||
data: {
|
||||
host,
|
||||
...(gitRepoUrl && !provisionError
|
||||
? { deploySlug, gitRepoUrl: nextGitRepoUrl }
|
||||
: {}),
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
...updated,
|
||||
provisionError,
|
||||
};
|
||||
}
|
||||
|
||||
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 {
|
||||
@IsString()
|
||||
@MinLength(1)
|
||||
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