Reporting Service
internal/api/v1/instasites/services/reporting.service.js powers /instasites/reporting/* endpoints. It aggregates site status trends, industry performance, and CSV upload history used in dashboard analytics widgets.
๐ Overviewโ
Responsibilities:
- Daily status funnel metrics (
viewed,built,purchased,failed) for a date range. - Industry breakdowns keyed by template categories.
- Paginated CSV import log retrieval for back-office audit trails.
๐๏ธ Collections Usedโ
instasitesโ
- Operations: Read
- Model:
shared/models/instasite.js - Usage: Source of lifecycle metrics (status, viewed flag, created timestamp) for both status and industry reports.
queueโ
- Operations: Read
- Model:
shared/models/instasite-queue.js - Usage: Stores
type: instasite-csvjobs;getLogsexposes these records and supports pagination.
instasites.templatesโ
- Operations: Read
- Model:
shared/models/instasite-template.js - Usage: Joined in
getIndustriesto determine the category associated with each site.
instasites.templates.categoriesโ
- Operations: Read
- Model:
shared/models/instasite-template-category.js - Usage: Supplies industry names when consolidating template lookups.
๐ง Function Referenceโ
getStatus({ account_id, startDate, endDate })โ
Purpose: Returns daily InstaSite funnel metrics for a single account, plus aggregate totals.
Inputs:
account_idโ Account whose InstaSites should be analyzed.startDateโ ISO or date string; default validations ensure presence before service call.endDateโ Optional; defaults to one month ahead when omitted.
Business Logic Flow:
- Normalize
startDateandendDateboundaries withmoment, capturing both day start/end. - Aggregate
instasitesvia$matchonaccount_idandcreatedrange; deserialize to iterate in-memory. - Iterate each day between start/end (inclusive):
- Build a daily object keyed by formatted date.
- Tally
viewed,built,purchased, andfailedbased on InstaSite status flags. - Track running totals for the entire range.
- Handle timezone edge cases by merging overflows into the last bucket.
- Run a second aggregation (
totalCountsQuery) to compute overall counts regardless of date window:- Separate facets for
total_built,total_viewed,total_purchased,total_failed. - Convert missing counts to zero via
$ifNull. - Note:
total_builtin the return payload sumsNOT_PUBLISHED_YET+UNPUBLISHED+PUBLISHEDstatuses.
- Separate facets for
- Return
{ data, total_by_date, total }.
Key Rules:
total.total_builtis redefined to include published sites in addition to the unfinished total from aggregation.- The returned
dataarray is sorted chronologically by construction of the iteration loop. - Invalid dates raise validation errors before reaching the service.
getIndustries({ parent_account, startDate, endDate })โ
Purpose: Produces an industry summary showing how each template category performs during a time window.
Inputs:
parent_accountโ Account whose sites should be analyzed (often agency-level).startDate,endDateโ Date range boundaries (inclusive) applied to sitecreatedtimestamps.
Business Logic Flow:
- Run an aggregation on
instasitesto filter byparent_accountand date window. $lookuptemplate documents to fetchcategory_id, then$lookupcategories for display titles.- Iterate the result set client-side:
- Build a unique set of category titles.
- For each category, count sites in each status bucket (
built,purchased,viewed,failed).
- Return array of
{ industry, built, purchased, viewed, failed }objects.
Key Rules:
- A site marked
PUBLISHEDincrements bothbuiltandpurchasedcounters. - Unpublished states (
UNPUBLISHED,NOT_PUBLISHED_YET) incrementbuiltonly. - Missing category titles surface as
undefined; controllers typically filter these out before rendering.
getLogs({ account_id, skip, limit })โ
Purpose: Retrieves paginated CSV import jobs for auditing.
Inputs:
account_idโ Filters queue documents to a single account.skip,limitโ Numeric pagination controls (validated prior to invocation).
Business Logic Flow:
- Build query
{ account_id, type: 'instasite-csv' }. - Execute
Promise.allto fetch bothcountDocumentsand the latest documents (sort: {_id: -1}) within provided bounds. - Return
[totalCount, docs], matching the controller expectation.
Key Rules:
- Errors propagate; controllers handle rejected promises and convert to API responses.
- Consumers should convert the tuple into
{ total, data }before returning to clients for clarity.
โ๏ธ Configurationโ
- Relies on the same date parsing format enforced by the validation layer (
reporting.validation.js). - No additional environment variables beyond Mongo and the shared timezone assumptions.
๐งช Testing Touchpointsโ
internal/api/v1/instasites/tests/reporting.test.jscovers status and industry aggregation scenarios.- Tests seed fixture data to validate date iteration, facet totals, and CSV log pagination.