Skip to content

Dashboard Sub-Application

The dashboard/ directory is a semi-independent Express sub-application that powers analytics endpoints (post insights, follower growth, engagement metrics) and a small set of cron-driven sync jobs that fetch metrics from social platforms. It can run standalone for local development or be mounted into the main API process for production.


Layout

dashboard/
├── server.js          # Standalone Express server (port 6001)
├── conf.js            # Environment-specific DB config
├── package.json       # Independent dependency list
├── README.md          # Submodule / git workflow notes
├── routes/
│   └── index.js       # 22 analytics endpoints
├── services/          # Cron jobs that ingest social platform metrics
│   ├── job_account_insights.js
│   ├── job_growth_insights.js
│   └── job_post_insights.js
└── mock/              # Local-development stand-ins for the parent app
    ├── action.js
    ├── helper.js
    ├── server.js
    ├── routes.js
    └── middlewares/auth.js

Production: Mounted Into the Main App

In production the dashboard is not a separate process. The main server.js mounts dashboard/routes/index.js at the /auth path:

// server.js
app.use('/auth', require('./dashboard/routes/index'));

The dashboard inherits the parent's: - MySQL connection (sync con from routes/routes.js) - Authentication middleware (middlewares/auth.js) - Socket.IO instance via App.socket - All Express middleware (CORS, body-parser, helmet-where-applied)

There is no second port, no second DB pool, no separate auth chain in production.


Local Development: Standalone Mode

dashboard/server.js boots an independent Express app on port 6001 with its own session middleware and CORS. When NODE_ENV === "development", the routes use dashboard/mock/routes.js instead of importing from the parent app, so the dashboard can run without the rest of the API.

Mock files in dashboard/mock/:

File Replaces
mock/action.js /actions/actions.js (CRUD layer)
mock/helper.js /helper/helper.js
mock/server.js The parent App object and exports
mock/routes.js The parent's con / downloadimages exports
mock/middlewares/auth.js Authentication middleware (typically a passthrough)

To run standalone:

cd dashboard
NODE_ENV=development node server.js

The mock layer exists specifically so a frontend developer can iterate against the analytics API without standing up the full backend, MySQL, and OAuth providers.


Endpoints

All routes are GET and live under dashboard/routes/index.js. When mounted in production they are reachable at /auth/<path>.

Account-level insights

Path Description
/getAccountInsights/:startTime/:endTime/:pId Aggregated follower/engagement totals across platforms
/getAccountFollowers/:startTime/:endTime/:pId Follower-growth time series per platform
/getRoiViews Return-on-investment view counts
/reach/getAccountStats/:pId Reach + impression stats
/reach/getAccountNetGrowth/:pId? Net follower growth (account-wide)
/reach/activityMeter Posting frequency / activity score
/leaderboard/:pId Top-performing members or posts

Post-level insights

Path Description
/getTopPostsInsights/:startTime/:endTime/:pId/:cId Top posts by engagement in date range
/getPostInsights/:startTime/:endTime/:pId Detailed per-post analytics
/getPostsLikes/:startTime/:endTime/:pId Post-level likes
/getPostsViews/:startTime/:endTime/:pId Post view counts over time
/getPostsEngagements/:startTime/:endTime/:pId Likes + comments + shares per post
/getPostsTotalEngagements/:startTime/:endTime/:pId Aggregated engagement across all posts

Member-level insights

Path Description
/member-followers-graph/:memberId Member's follower-growth chart data
/accountActiveMembersPlatforms/:accountId Active members and their platform connections
/membersSocialGrowth/:memberId/:fromDate/:toDate Member growth summary in date range
/getMembersPostInsights/:memberId/:startTime/:endTime/:pId Member's per-post analytics
/getMembersfollowersGrowth/:memberId/:startTime/:endTime/:pId Member follower-growth timeline
/getMembersPostLikes/:memberId/:startTime/:endTime/:pId Member's post likes
/getMembersPostViews/:memberId/:startTime/:endTime/:pId Member's post views
/getMembersPostEngagement/:memberId/:startTime/:endTime/:pId Member's engagement metrics
/getMembersTopPosts/:memberId/:startTime?/:endTime?/:cId/:pId? Member's top-performing posts

Path parameter glossary

Param Meaning
pId Provider ID (1=Facebook, 3=Instagram, 4=LinkedIn, 6=TikTok). See Integration Inventory
cId Category ID (content category from tDefaultCategories)
accountId Account row ID
memberId Individual user/member row ID
startTime / endTime Date range, format depends on the route — check the handler

For the canonical list of endpoints across the whole API, see API Inventory.


Cron Services (dashboard/services/)

These three jobs ingest metrics from social platforms into the database. They are PM2-managed daemons registered in ecosystem.config.js and run independently of HTTP traffic.

job_account_insights.js

  • Schedule: every 30 seconds
  • Purpose: snapshot follower / engagement totals at the account level for each connected social platform
  • Per-platform handlers: fb_accounts_insights(), ig_accounts_insights(), ln_profile_insights() (LinkedIn personal profiles, aType = 1), ln_accounts_insights() (LinkedIn company pages, aType = 2), tt_accounts_insights()
  • Reads: tMemberAuth, tDefaultAccount
  • Writes: tSAccountIns (one row per snapshot, with capture timestamp)

job_growth_insights.js

  • Schedule: every 12 hours at minute :10
  • Purpose: compute delta metrics by comparing the latest tSPostInsights row with the prior snapshot of the same post
  • Calculates: glikes, gcomments, gshares, gviews, gimpressions, gclicks, gengagement
  • Scope: posts from the last 7 days, only for accounts with active subscriptions
  • Batch size: 10 posts per tick

job_post_insights.js

  • Schedule: every 12 hours at the hour ("0 */12 * * *") — not every 30 seconds as previous versions of this doc claimed
  • Purpose: fetch per-post metrics from the social platform APIs
  • Per-platform calls: fb_video_insights(), ig_post_insights(), plus LinkedIn / TikTok equivalents
  • Reads: tMemberAuth (access tokens), tSPosts
  • Writes: raw metrics (likes, comments, shares, views, impressions, clicks) into tSPostInsights

PM2 path bug: ecosystem.config.js references ./job_account_insights.js and ./job_post_insights.js at the project root, but the files actually live in dashboard/services/. See Jobs Inventory → Known Discrepancies.

Schedule investigation needed: earlier versions of this doc claimed job_post_insights.js runs every 30 seconds. The actual cron is "0 */12 * * *" (every 12 hours at hour boundary). Either the cron was changed without doc update, or the doc was wrong from the start. If 30s was the intended frequency, per-post insights are currently being collected far less frequently than expected — investigate whether this is intentional or an operational regression.


Database Tables

Tables touched by the dashboard sub-app (full schemas in Data Model):

Table Used by
tMemberAuth services — read social access tokens
tDefaultAccount services — find default account for a member
tSAccounts routes — list connected social accounts
tSAccountIns services write, routes read — account-level insight snapshots
tSPosts services + routes — published posts
tSPostInsights services write, routes read — per-post analytics
tContentPlanner routes — scheduled / posted content metadata
tSubscriptions services — gate processing to active subscribers

Configuration

dashboard/conf.js loads its own .env from the dashboard directory. Required keys:

Key Purpose
host, user, password, dbPort, database MySQL connection (standalone mode only — production uses parent's con)

When mounted in production, these values are unused.

dashboard/package.json lists its own dependencies (independent from the parent): - express, express-session - crypto-js, jsonwebtoken - moment - node-cron - sync-mysql


Operational Notes

  • No independent deployment — in production the dashboard runs in the main API process. There is no separate Docker container or PM2 app for the HTTP routes (the services are separate PM2 apps, but their HTTP routes are mounted into the main app).
  • Mock-mode is dev-only — never deploy with NODE_ENV=development; the mock data layer doesn't talk to MySQL.
  • No socket emission — the analytics routes are pull-based. They don't push live updates via Socket.IO; the frontend polls.
  • Path bug in PM2 config — see Jobs Inventory before running pm2 start ecosystem.config.js from a fresh checkout.