import { Body, Controller, Get, Param, Patch, Post, UseInterceptors } from "@nestjs/common"; import { ApiHeader, ApiOperation, ApiTags } from "@nestjs/swagger"; import { UpdateBusinessDomainDto } from "./DTO/business-domain.dto"; import { BusinessSlugParamDto } from "./DTO/business-slug-param.dto"; import { UpdateBusinessSettingsDto } from "./DTO/update-business-settings.dto"; import { Business } from "./entities/business.entity"; import { BusinessesService } from "./services/businesses.service"; import { DomainVerificationService } from "./services/domain-verification.service"; import { AuthGuards } from "../../common/decorators/auth-guard.decorator"; import { BusinessDec } from "../../common/decorators/business.decorator"; import { BusinessInterceptor } from "../../core/interceptors/business.interceptor"; @Controller("business") @ApiHeader({ name: "x-business-id", description: "Business ID" }) @ApiTags("Business") @UseInterceptors(BusinessInterceptor) export class BusinessesController { constructor( private readonly businessesService: BusinessesService, private readonly domainVerificationService: DomainVerificationService, ) {} @Get("slug/:slug") @ApiOperation({ summary: "Get business by slug" }) getBusinessBySlug(@Param() params: BusinessSlugParamDto) { return this.businessesService.getBusinessBySlug(params.slug); } @Patch("settings") @ApiOperation({ summary: "Update business settings" }) @AuthGuards() updateBusinessSettings(@BusinessDec("id") businessId: string, @Body() settingsDto: UpdateBusinessSettingsDto) { return this.businessesService.updateBusinessSettings(businessId, settingsDto); } @Get("settings") @ApiOperation({ summary: "Get business settings" }) @AuthGuards() getBusinessSettings(@BusinessDec("id") businessId: string) { return this.businessesService.getBusinessSettings(businessId); } // Domain management endpoints - simplified flow @Post("domain") @ApiOperation({ summary: "Set/update business domain and get verification instructions" }) @AuthGuards() setDomain(@BusinessDec() business: Business, @Body() domainDto: UpdateBusinessDomainDto) { return this.domainVerificationService.setDomain(business.id, domainDto); } @Post("domain/verify") @ApiOperation({ summary: "Verify domain ownership and connection" }) @AuthGuards() verifyDomain(@BusinessDec() business: Business) { return this.domainVerificationService.verifyDomain(business.id); } @Get("domain/status") @ApiOperation({ summary: "Get current domain status" }) @AuthGuards() getDomainStatus(@BusinessDec() business: Business) { return this.domainVerificationService.getDomainStatus(business.id); } @Post("domain/update-dns-records") @ApiOperation({ summary: "Get detailed instructions for updating DNS records" }) @AuthGuards() getDetailedDnsInstructions(@BusinessDec() business: Business) { // This endpoint provides detailed DNS setup instructions for various DNS providers if (!business.domain) { return { success: false, message: "No domain configured for this business", }; } return { success: true, domain: business.domain, instructions: { title: "راهنمای تنظیم رکوردهای DNS برای دامنه شما", description: "برای اتصال دامنه خود به سرویس دی‌زون، لطفا یکی از روش‌های زیر را انتخاب کنید:", methods: [ { title: "روش A: استفاده از رکورد A (آدرس IP)", description: "این روش برای همه ارائه‌دهندگان DNS کار می‌کند و برای دامنه اصلی مناسب است.", steps: [ "۱. وارد پنل مدیریت DNS خود شوید", "۲. یک رکورد A جدید ایجاد کنید", "۳. در فیلد Host یا Name، @ را وارد کنید (برای دامنه اصلی)", `۴. در فیلد Value یا Points to، آدرس IP سرور ما را وارد کنید: 194.5.192.20`, "۵. TTL را روی 3600 (یک ساعت) یا کمترین مقدار ممکن تنظیم کنید", "۶. تغییرات را ذخیره کنید", ], }, { title: "روش B: استفاده از رکورد CNAME (نام مستعار)", description: "این روش برای زیردامنه‌ها مانند www توصیه می‌شود.", steps: [ "۱. وارد پنل مدیریت DNS خود شوید", "۲. یک رکورد CNAME جدید ایجاد کنید", "۳. در فیلد Host یا Name، www را وارد کنید (یا زیردامنه دلخواه)", `۴. در فیلد Value یا Points to، آدرس سرور ما را وارد کنید: app.dzone.danakcorp.com`, "۵. TTL را روی 3600 (یک ساعت) یا کمترین مقدار ممکن تنظیم کنید", "۶. تغییرات را ذخیره کنید", ], note: "توجه: برخی ارائه‌دهندگان DNS اجازه استفاده از CNAME برای دامنه اصلی (@) را نمی‌دهند. در این صورت از روش A استفاده کنید.", }, ], providerSpecific: [ { provider: "Cloudflare", instructions: [ "۱. حالت ابری (پروکسی) را خاموش کنید و فقط از DNS استفاده کنید", "۲. برای دامنه اصلی (@) از رکورد A استفاده کنید", "۳. برای زیردامنه www از رکورد CNAME استفاده کنید", ], }, { provider: "cPanel", instructions: [ "۱. به بخش Zone Editor بروید", "۲. روی دامنه خود کلیک کنید", "۳. برای دامنه اصلی، رکورد A با مقدار 194.5.192.20 اضافه کنید", "۴. برای www، رکورد CNAME با مقدار app.dzone.danakcorp.com اضافه کنید", ], }, { provider: "سایر ارائه‌دهندگان", instructions: [ "اگر نمی‌توانید CNAME برای دامنه اصلی تنظیم کنید، از رکورد A استفاده کنید", "برخی ارائه‌دهندگان از رکوردهای ANAME یا ALIAS برای دامنه اصلی پشتیبانی می‌کنند", "اگر در تنظیم رکوردها مشکل دارید، با پشتیبانی ارائه‌دهنده DNS خود تماس بگیرید", ], }, ], troubleshooting: [ "- تغییرات DNS ممکن است بین ۱۵ دقیقه تا ۴۸ ساعت طول بکشد تا در سراسر اینترنت منتشر شود", "- اگر پس از ۴۸ ساعت هنوز مشکل دارید، مطمئن شوید که رکوردها را درست تنظیم کرده‌اید", "- برای بررسی وضعیت رکوردهای DNS خود می‌توانید از ابزارهایی مانند dnschecker.org استفاده کنید", "- اگر همچنان مشکل دارید، با پشتیبانی ما تماس بگیرید", ], }, }; } @Post("domain/configure-caprover") @ApiOperation({ summary: "Manually configure domain in Caprover (Admin use only)" }) @AuthGuards() async manualCaproverConfig(@BusinessDec() business: Business) { if (!business.domain) { return { success: false, message: "No domain configured for this business", }; } if (!business.isDomainVerified) { return { success: false, message: "Domain must be verified before configuring in Caprover", domain: business.domain, }; } try { const result = await this.domainVerificationService.configureCaproverDomain(business.domain); return { success: result, message: result ? `Domain ${business.domain} successfully configured in Caprover` : `Failed to configure domain ${business.domain} in Caprover`, domain: business.domain, }; } catch (error: unknown) { return { success: false, message: `Error configuring domain in Caprover: ${error instanceof Error ? error.message : String(error)}`, domain: business.domain, }; } } }