Add stable keys for special groups and SSL sync agent hooks.

English keys on store/website specials stay unique per business; domain-admin can trigger dashboard SSL sync.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Alireza Hassani
2026-08-03 00:06:44 +03:30
co-authored by Cursor
parent 43e3912662
commit f233665d13
15 changed files with 263 additions and 6 deletions
@@ -29,6 +29,13 @@ export class DomainAdminController {
return this.service.list(query, user);
}
@Post('ssl-sync')
@HttpCode(202)
@UseGuards(JwtAuthGuard)
syncSsl(@CurrentUser() user: AuthUser) {
return this.service.syncSsl(user);
}
@Post(':domainId/deploy')
@HttpCode(202)
@UseGuards(JwtAuthGuard)
+40
View File
@@ -100,6 +100,46 @@ export class DomainAdminService {
return { items, total: totalRow[0]?.total ?? 0, page, pageSize };
}
async syncSsl(actor: AuthUser) {
await this.assertSuperAdmin(actor);
const agentUrl = this.config.get<string>('SSL_SYNC_AGENT_URL')?.trim();
const token = this.config.get<string>('SSL_SYNC_AGENT_TOKEN')?.trim();
if (!agentUrl || !token) {
throw new ServiceUnavailableException('SSL sync agent is not configured');
}
let response: Response;
try {
response = await fetch(agentUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-SSL-Sync-Agent-Token': token,
},
body: '{}',
});
} catch {
throw new ServiceUnavailableException('Could not reach SSL sync agent');
}
if (response.status === 409) {
throw new ConflictException('SSL sync is already running');
}
if (!response.ok) {
const text = await response.text().catch(() => '');
throw new ServiceUnavailableException(
`SSL sync agent rejected request (${response.status})${text ? `: ${text}` : ''}`,
);
}
return {
status: 'accepted' as const,
message: 'SSL sync started on dashboards server',
};
}
async deploy(domainIdRaw: string, actor: AuthUser) {
await this.assertSuperAdmin(actor);