π¦ 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 writestype: instasite,instasite-csv, andinstasite-notificationsjobs 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
queuerecords; 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_attimestamp 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β
| Variable | Description | Required |
|---|---|---|
DUDA_TOKEN | Builder token forwarded to Duda internal API calls and queue jobs | β |
DUDA_INTERNAL_ENDPOINT | Base URL for the internal Duda proxy (e.g. https://duda-proxy/...) | β |
APP_SECRET | Signing key for short-lived JWTs issued in processNotificationQueue | β |
SHORT_URL_SERVICE | URL shortener endpoint used in email/SMS notifications | β (for notifications) |
SHORT_DOMAIN | Public domain paired with the shortener response code | β |
WASABI_PUBLIC_IMAGE_DOWNLOAD | Base 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:
- List candidate contacts the dashboard selects as businesses.
- POST
/instasites/queuewith business IDs, template ID, and notification payload β queues one job per business. - Queue manager picks up
type: instasiteentries, builds via Duda, sends notifications, and updatesInstasitesAdditionalInformation. - Publish/unpublish via
PUT /instasites/:id/publishor/unpublishonce the client approves. - Monitor status through
/instasites/reporting/statusand/instasites/reporting/logs.
All Read endpoints return success, message, and module-specific payloads consistent with other internal services.
π Background Jobsβ
| Queue Type | Producer | Worker | Notes |
|---|---|---|---|
instasite | addToQueue & CSV worker | Queue Manager (Duda builder) | Builds sites, updates instasites + emits notifications |
instasite-csv | addCSVToQueue | saveQueueData (within this module) | Parses uploaded CSV, creates contacts, and enqueues instasite jobs |
instasite-notifications | Queue Manager when notifications need retry | processNotificationQueue | Retries 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
getStatusesorgetInstasiteshelpers to keep logic consistent with account preference rules. - π‘ Refresh cadence:
getSiteByIdrefreshes from Duda hourly; avoid redundant manual refreshes unlessrefresh_atis overdue. - π Notification queue:
processNotificationQueueincrementstriesbefore ensuring a queue item exists. Be mindful when manually inserting jobs.
π Related Documentationβ
- Queue Manager Overview
- Notifications Service
- Shared Utilities β logger, mail, sms, pagination helpers