Skip to main content

πŸ“¦ InstaSites Module

🎯 Overview​

The InstaSites module powers DashClicks' rapid website fulfillment pipeline. It exposes internal REST endpoints used by the dashboard and queue manager to create InstaSites from CRM contacts, manage template catalogs, trigger Duda publishes/unpublishes, send launch notifications, and surface reporting. All business logic lives under internal/api/v1/instasites, with controllers delegating to services and shared utilities.

πŸ“ Directory Structure​

internal/api/v1/instasites/
β”œβ”€β”€ README.md
β”œβ”€β”€ controllers/
β”‚ β”œβ”€β”€ categories.controller.js # GET categories and their template counts
β”‚ β”œβ”€β”€ index.js # Exports controller functions
β”‚ β”œβ”€β”€ is-template-import.js # Seed data used once for bulk template import
β”‚ β”œβ”€β”€ reporting.controller.js # Reporting endpoints (status, industries, logs)
β”‚ └── templates.controller.js # Template list/create handlers
β”œβ”€β”€ routes/
β”‚ β”œβ”€β”€ categories.route.js # /categories wiring
β”‚ β”œβ”€β”€ index.js # Primary router mounting sub-routes
β”‚ β”œβ”€β”€ reporting.route.js # /reporting wiring
β”‚ └── templates.route.js # /templates wiring
β”œβ”€β”€ services/
β”‚ β”œβ”€β”€ categories.service.js # Category aggregation logic
β”‚ β”œβ”€β”€ index.js # Core InstaSites operations (queue, Duda, notifications)
β”‚ β”œβ”€β”€ reporting.service.js # KPI aggregation helpers
β”‚ └── templates.service.js # Template fetch & creation logic
β”œβ”€β”€ tests/
β”‚ β”œβ”€β”€ _constants.js
β”‚ β”œβ”€β”€ categories.test.js
β”‚ β”œβ”€β”€ instasites.test.js
β”‚ β”œβ”€β”€ reporting.test.js
β”‚ β”œβ”€β”€ templates.test.js
β”‚ └── __mocks__/notifications.mock.js
β”œβ”€β”€ utils/
β”‚ β”œβ”€β”€ create-business.js # Contact + business creation for CSV imports
β”‚ β”œβ”€β”€ cvs-to-json.js # Wasabi CSV parsing helper
β”‚ β”œβ”€β”€ generateFileBuffer.js # Fetches Wasabi objects as mail attachments
β”‚ β”œβ”€β”€ saveQueueData.js # Background CSV ingestion worker
β”‚ β”œβ”€β”€ sendNotifications.js # Email/SMS blast helper consumed by queue manager
β”‚ └── templates.js # Puppeteer screenshot + Wasabi upload utilities
└── validations/
β”œβ”€β”€ custom.validation.js
β”œβ”€β”€ instasite.validation.js # Queue, analytics, SSO, association validators
└── templates.validation.js # Template filters + create payload

πŸ—„οΈ MongoDB Collections​

πŸ“š Full schema specs live in Database Collections Documentation

Primary​

  • instasites (shared/models/instasite.js) β€” canonical site record, including builder IDs, publish state, certificate status, and cached Duda content metadata.
  • instasites.additional_information (shared/models/instasites-additional-information.js) β€” per-site notification metadata, recipient lists, email/SMS event IDs, and lifecycle timestamps.
  • queue (shared/models/instasite-queue.js) β€” generalized queue collection; InstaSites writes type: instasite, instasite-csv, and instasite-notifications jobs here.

Supporting collections​

  • instasites.templates (shared/models/instasite-template.js) β€” template definitions, preview assets, global/account ownership.
  • instasites.templates.categories (shared/models/instasite-template-category.js) β€” main/sub category taxonomy powering filters.
  • crm.contacts β€” source of businesses/people used to build InstaSites and enforce visibility rules.
  • communications β€” mail/SMS delivery logs used to update resend metadata.
  • agency-websites β€” agency-owned Duda sites included in β€œactive sites” responses.
  • _store.products β€” pricing references for bundling Stripe price IDs alongside template returns.
  • _users β€” lookups for creator details when listing InstaSites.

πŸ—οΈ Architecture Overview​

Key responsibilities​

  • Ingest CRM contacts and queue site builds (services/index.js#addToQueue).
  • Orchestrate CSV imports into queued builds (addCSVToQueue, saveQueueData).
  • Maintain template catalog and categories derived from Duda (templates.service.js, categories.service.js).
  • Proxy critical Duda operations (publish, unpublish, plan changes, analytics, SSO) with scoped auth.
  • Broadcast launch notifications via the notifications queue (processNotificationQueue, sendNotifications).
  • Provide reporting endpoints for build/view/purchase funnels (reporting.service.js).

Design decisions​

  • Queue-first fulfillment. Site creation is always asynchronous via queue records; synchronous work stops once records are enqueued.
  • Contact visibility filtering. Aggregations respect account preferences (owner_followers, entire) to shield restricted contacts when listing sites or statuses.
  • Duda caching. Site fetches refresh content from Duda only when a cached refresh_at timestamp expires to avoid hammering the API.
  • Shared utilities. Attachments, template thumbnails, and CSV imports delegate to reusable utilities (generateFileBuffer, templates.js, create-business.js) that are shared with queue workers.

πŸ”— Submodules​

Core services​

  • πŸ“˜ Core InstaSites Service β€” Queuing, notification, Duda publish, analytics, and record retrieval.
  • πŸ“— Template Service β€” Template listing and creation via Duda, Stripe pricing hydration.

Supporting services​

  • πŸ“˜ Category Service β€” Category/main-category aggregations and counts.
  • πŸ“— Reporting Service β€” Daily funnel metrics, industry breakdowns, and CSV import logs.

πŸ”„ Data Flow​

flowchart TD
A["Client request<br/>(REST endpoint)"] --> B{"Validation layer<br/>(Joi schemas)"}
B -->|valid| C["Service logic"]
C --> D["Queue mutations<br/>(queue collection)"]
C --> E[("Instasite docs<br/>+ metadata")]
D --> F["Queue Manager workers<br/>(saveQueueData & Duda builders)"]
F --> G["Duda API<br/>publish/forms/analytics"]
F --> H["Notifications<br/>(Mail/SMS)"]
style A fill:#e1f5ff
style G fill:#fff4d2
style H fill:#ffe9e9

πŸ” Configuration & Dependencies​

VariableDescriptionRequired
DUDA_TOKENBuilder token forwarded to Duda internal API calls and queue jobsβœ…
DUDA_INTERNAL_ENDPOINTBase URL for the internal Duda proxy (e.g. https://duda-proxy/...)βœ…
APP_SECRETSigning key for short-lived JWTs issued in processNotificationQueueβœ…
SHORT_URL_SERVICEURL shortener endpoint used in email/SMS notificationsβœ… (for notifications)
SHORT_DOMAINPublic domain paired with the shortener response codeβœ…
WASABI_PUBLIC_IMAGE_DOWNLOADBase URL to fetch Wasabi-hosted attachmentsβœ… (when attachments enabled)
WASABI_*Credentials + region consumed by utils/templates.js for thumbnail capture❌ (only when capturing thumbnails)

πŸš€ Quick Start​

Typical workflow for an internal consumer:

  1. List candidate contacts the dashboard selects as businesses.
  2. POST /instasites/queue with business IDs, template ID, and notification payload β€” queues one job per business.
  3. Queue manager picks up type: instasite entries, builds via Duda, sends notifications, and updates InstasitesAdditionalInformation.
  4. Publish/unpublish via PUT /instasites/:id/publish or /unpublish once the client approves.
  5. Monitor status through /instasites/reporting/status and /instasites/reporting/logs.

All Read endpoints return success, message, and module-specific payloads consistent with other internal services.

πŸ”„ Background Jobs​

Queue TypeProducerWorkerNotes
instasiteaddToQueue & CSV workerQueue Manager (Duda builder)Builds sites, updates instasites + emits notifications
instasite-csvaddCSVToQueuesaveQueueData (within this module)Parses uploaded CSV, creates contacts, and enqueues instasite jobs
instasite-notificationsQueue Manager when notifications need retryprocessNotificationQueueRetries Mail/SMS with 5-attempt cap

πŸ§ͺ Testing Notes​

  • Unit tests reside in internal/api/v1/instasites/tests. They mock notification delivery and assert controller/service paths.
  • Use pnpm test --filter instasites (workspace-aware) to run module-specific suites.

⚠️ Important Notes​

  • 🚨 Contact visibility enforcement: All aggregations that surface contact-bound data must call getStatuses or getInstasites helpers to keep logic consistent with account preference rules.
  • πŸ’‘ Refresh cadence: getSiteById refreshes from Duda hourly; avoid redundant manual refreshes unless refresh_at is overdue.
  • πŸ› Notification queue: processNotificationQueue increments tries before ensuring a queue item exists. Be mindful when manually inserting jobs.
πŸ’¬

Documentation Assistant

Ask me anything about the docs

Hi! I'm your documentation assistant. Ask me anything about the docs!

I can help you with:
- Code examples
- Configuration details
- Troubleshooting
- Best practices

Try asking: How do I configure the API?
09:31 AM