Skip to content

refractor: move all api endpoints from dashboard to api service#21

Open
Adhish-Krishna wants to merge 11 commits into
developmentfrom
20-move-dashboard-api-endpoints-to-api-service
Open

refractor: move all api endpoints from dashboard to api service#21
Adhish-Krishna wants to merge 11 commits into
developmentfrom
20-move-dashboard-api-endpoints-to-api-service

Conversation

@Adhish-Krishna

@Adhish-Krishna Adhish-Krishna commented Jul 4, 2026

Copy link
Copy Markdown
Member

Key changes

  1. Move dashboard endpoints to api service and remove the db models form dashboard
  2. Centralized api calls and error handling using axios
  3. Add auth middleware to admin channels and plugins router in api service
  4. Make the mcp-server package to make all the api calls to api service alone and removed dashboard url from auth headers.
  5. Upgraded mcp-server to version 1.1.0. So all versions >= 1.1 requires no dashboard url in the auth headers but all versions below requires it.
  6. Make the dashboard to correctly the fetch the WEBHOOK_HOST and WEBHOOK_PORT env values correctly using runtime _config.js file. This exposes the dashboard host and port to the web browser but this is not a serious security issue

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 813865fb85

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

client_id: clientId,
channel: selectedChannels,
recipient: { ...recipientData },
webhook_url: `http://${WEBHOOK_HOST}:${WEBHOOK_PORT}/api/webhook`

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep webhook URL injection server-side

When dashboard send requests are now proxied straight to the core API, this webhook_url is trusted from the browser instead of being overwritten by the removed /api/send server route. In any authenticated dashboard session, a tampered request can redirect delivery-status callbacks to an arbitrary URL or make them fail; the proxy/server should inject the configured callback URL rather than accepting it from the client. The same issue exists in the batch form.

Useful? React with 👍 / 👎.

…d request management

- Replaced fetch-based API request implementation with Axios.
- Added centralized error handling through Axios interceptors.
- Introduced ApiError class for better error representation.
- Updated service modules (auth, notification, template, alert, plugin, admin channel, dashboard) to utilize the new Axios-based client.
- Enhanced AdminChannelFormData to include a config field and added AdminChannelProviderMeta interface for provider metadata.
- Updated package.json and package-lock.json to include Axios as a dependency.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR migrates “dashboard-owned” API functionality (notifications management, alerts, dashboard analytics, and admin-channel CRUD) into the core Express API service, then updates the Next.js dashboard and the MCP server to call the core API directly with centralized client logic and consistent authentication.

Changes:

  • Added new authenticated core API routes/controllers for notifications management, alerts, and dashboard analytics, and wired them into src/api/server.ts.
  • Refactored the dashboard to remove DB models/Next API routes and instead call the core API through a centralized Axios client + middleware proxy.
  • Updated the MCP server to remove the Dashboard URL requirement (v1.1.0) and route requests to the core API with auth headers.

Reviewed changes

Copilot reviewed 67 out of 69 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
tests/integration/api/notification.controller.test.ts Updates integration test import to the renamed notification controller module.
tests/integration/api/dashboard_api.test.ts Adds integration tests for the migrated dashboard-related core API routes (notifications mgmt, alerts, admin-channels, dashboard analytics).
src/api/server.ts Registers new authenticated routers for notifications mgmt, alerts, and dashboard analytics; adds auth to plugins/admin-channels.
src/api/routes/notifications-management.routes.ts New router for CRUD-ish notification management endpoints.
src/api/routes/notification.routes.ts Updates controller import path to the renamed notification controller.
src/api/routes/dashboard.routes.ts New router exposing dashboard analytics endpoints from the core API.
src/api/routes/alerts.routes.ts New router exposing alerts endpoints from the core API.
src/api/routes/admin-channels.routes.ts Extends router with admin-channel CRUD endpoints.
src/api/controllers/notifications-management.controller.ts New controller implementing notification listing/recent/detail/delete/retry on the core API.
src/api/controllers/notification.controller.ts New notification ingest controller file (single + batch).
src/api/controllers/dashboard.controller.ts New controller implementing /api/dashboard/stats and /api/dashboard/trends in core API.
src/api/controllers/alerts.controller.ts New controller implementing alerts list/dismiss/resolve/bulk-resolve in core API.
src/api/controllers/admin-channels-crud.controller.ts New controller implementing admin-channel CRUD in core API (with config encryption).
packages/mcp-server/src/auth.ts Removes Dashboard URL requirement from credential extraction and stdio creds (still needs minor cleanup).
packages/mcp-server/src/api-client.ts Routes “dashboard” client calls to core URL and ensures auth header is sent for /api/plugins.
packages/mcp-server/README.md Documents the v1.1 change: Dashboard URL header/env no longer required.
packages/mcp-server/package.json Bumps MCP server package version to 1.1.0.
dashboard/package.json Adds Axios dependency and removes mongoose dependency from dashboard.
dashboard/package-lock.json Updates lockfile for removed mongoose + added axios (and related dependency graph changes).
dashboard/middleware.ts Proxies non-local /api/* requests to the core API and injects the Bearer API key header.
dashboard/lib/utils.ts Extends runtime config typing (basePath + webhook host/port support).
dashboard/lib/types.ts Adjusts admin-channel form typing to support provider-driven credential schemas (config).
dashboard/lib/models/system-config.ts Removes dashboard DB model (dashboard no longer connects directly to MongoDB).
dashboard/lib/models/outbox.ts Removes dashboard outbox DB model.
dashboard/lib/models/notification.ts Removes dashboard notification DB model.
dashboard/lib/models/alert.ts Removes dashboard alert DB model.
dashboard/lib/models/admin-channel.ts Removes dashboard admin-channel DB model.
dashboard/lib/encryption.ts Removes dashboard-side encryption utilities (moved to core service).
dashboard/lib/db.ts Removes dashboard MongoDB connection logic.
dashboard/lib/api-config.ts Simplifies dashboard API config exports to core base URL + API key.
dashboard/lib/api-client.ts Adds centralized Axios client, interceptors, and typed service modules for dashboard usage.
dashboard/entrypoint.sh Adjusts comments/intent toward runtime configuration injection.
dashboard/components/send/single-notification-form.tsx Switches to centralized client services; currently hard-codes webhook URL (needs follow-up).
dashboard/components/send/batch-notification-form.tsx Switches to centralized client services; currently hard-codes webhook URL (needs follow-up).
dashboard/components/logout-button.tsx Uses authService.logout() instead of manual fetch.
dashboard/components/layout/dashboard-layout.tsx Uses Axios client fetcher for SWR instead of raw fetch wrapper.
dashboard/components/dashboard/stats-cards.tsx Uses Axios client fetcher for SWR.
dashboard/components/dashboard/recent-activity.tsx Uses Axios client fetcher for SWR.
dashboard/components/auth-provider.tsx Uses authService.getSession() and authService.logout().
dashboard/components/admin-alerts/add-channel-dialog.tsx Uses adminChannelService for providers/test/create and improves error handling.
dashboard/app/templates/page.tsx Uses Axios client fetcher and templateService for deletes/details.
dashboard/app/templates/editor/page.tsx Uses Axios client fetcher + templateService for get/create/update.
dashboard/app/plugins/page.tsx Uses Axios client fetcher and adds external docs link for plugin install guidance.
dashboard/app/payload-studio/page.tsx Uses Axios client fetcher and adds external docs link for plugin install guidance.
dashboard/app/login/page.tsx Uses authService.login() and improved error handling.
dashboard/app/failed/page.tsx Uses Axios fetcher + notificationService.retry() for retry action.
dashboard/app/events/page.tsx Uses Axios client fetcher for SWR.
dashboard/app/events/[id]/page.tsx Uses Axios fetcher + notificationService.retry/delete() for actions.
dashboard/app/api/templates/route.ts Removes dashboard Next API proxy route (now handled via middleware proxy + direct core API).
dashboard/app/api/templates/[template_id]/route.ts Removes dashboard Next API proxy route.
dashboard/app/api/send/route.ts Removes dashboard send proxy route (previously injected webhook URL).
dashboard/app/api/plugins/route.ts Removes dashboard Next API proxy route.
dashboard/app/api/notifications/route.ts Removes dashboard DB-backed notifications list endpoint.
dashboard/app/api/notifications/recent/route.ts Removes dashboard DB-backed recent notifications endpoint.
dashboard/app/api/notifications/[id]/route.ts Removes dashboard DB-backed notification detail/delete endpoint.
dashboard/app/api/notifications/[id]/retry/route.ts Removes dashboard DB-backed retry endpoint.
dashboard/app/api/dashboard/trends/route.ts Removes dashboard DB-backed dashboard trends endpoint.
dashboard/app/api/dashboard/stats/route.ts Removes dashboard DB-backed dashboard stats endpoint.
dashboard/app/api/alerts/route.ts Removes dashboard DB-backed alerts list endpoint.
dashboard/app/api/alerts/bulk-resolve/route.ts Removes dashboard DB-backed alerts bulk-resolve endpoint.
dashboard/app/api/alerts/[id]/route.ts Removes dashboard DB-backed alerts dismiss endpoint.
dashboard/app/api/alerts/[id]/resolve/route.ts Removes dashboard DB-backed alerts resolve endpoint.
dashboard/app/api/admin-channels/test/route.ts Removes dashboard Next API proxy route for admin-channel test.
dashboard/app/api/admin-channels/route.ts Removes dashboard DB-backed admin-channels list/create endpoint.
dashboard/app/api/admin-channels/providers/route.ts Removes dashboard Next API proxy route for providers.
dashboard/app/api/admin-channels/[id]/route.ts Removes dashboard DB-backed admin-channel get/update/delete endpoint.
dashboard/app/analytics/page.tsx Uses Axios client fetcher for SWR.
dashboard/app/alerts/page.tsx Uses alertService methods for list/resolve/bulkResolve/delete.
dashboard/app/admin-alerts/page.tsx Uses Axios fetcher + adminChannelService.update/delete() for actions.
Files not reviewed (1)
  • dashboard/package-lock.json: Generated file

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 320 to 324
channel: selectedChannels,
recipient: { ...recipientData },
//hard-coded the webhook url as the simplest solution. This url may not be correct all the times. Nop issues, the worker just fire and forgets while sending webhook, it does not retires
webhook_url: "http://localhost:3002/api/webhook"
};
Comment on lines 393 to 400
const payload: Record<string, any> = {
type: "batch",
client_id: clientId,
channel: selectedChannels,
recipients: processedRecipients,
//hard-coded the webhook url as the simplest solution. This url may not be correct all the times. Nop issues, the worker just fire and forgets while sending webhook, it does not retires
webhook_url: "http://localhost:3002/api/webhook"
};
Comment on lines +109 to +129
export const alertService = {
list: (page: number, limit: number, type?: string): Promise<{
alerts: Alert[];
count: number;
byType: Record<string, number>;
page: number;
limit: number;
totalPages: number;
}> =>
apiClient.get('/api/alerts', {
params: { page, limit, type },
}),
get: (id: string): Promise<Alert> =>
apiClient.get(`/api/alerts/${id}`),
resolve: (id: string, payload: { appendWarning?: boolean }): Promise<{ success: boolean }> =>
apiClient.post(`/api/alerts/${id}/resolve`, payload),
bulkResolve: (payload: { appendWarning?: boolean; limit?: number }): Promise<{ success: boolean; message: string }> =>
apiClient.post('/api/alerts/bulk-resolve', payload),
delete: (id: string): Promise<{ success: boolean }> =>
apiClient.delete(`/api/alerts/${id}`),
};
Comment on lines +150 to +154
export const dashboardService = {
getStats: (): Promise<DashboardStats> => apiClient.get('/api/dashboard/stats'),
getTrends: (hours?: number): Promise<TrendDataPoint[]> =>
apiClient.get('/api/dashboard/trends', { params: { hours } }),
};
Comment on lines 21 to 24
const apiKey = req.headers['x-simplens-api-key'] as string | undefined;
const coreUrl = req.headers['x-simplens-core-url'] as string | undefined;
const dashboardUrl = req.headers['x-simplens-dashboard-url'] as string | undefined;

Comment thread src/api/routes/dashboard.routes.ts Outdated
Comment on lines 52 to 55
return {
apiKey: SIMPLENS_API_KEY,
coreUrl: SIMPLENS_CORE_URL,
dashboardUrl: SIMPLENS_DASHBOARD_URL,
coreUrl: SIMPLENS_CORE_URL
};

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 67 out of 69 changed files in this pull request and generated 8 comments.

Files not reviewed (1)
  • dashboard/package-lock.json: Generated file

} else if (content.message) {
content.message = String(content.message) + warningMessage;
}
}
} else if (content.message) {
content.message = String(content.message) + warningMessage;
}
}
Comment on lines 321 to 324
recipient: { ...recipientData },
//hard-coded the webhook url as the simplest solution. This url may not be correct all the times. Nop issues, the worker just fire and forgets while sending webhook, it does not retires
webhook_url: "http://localhost:3002/api/webhook"
};
Comment on lines 393 to 400
const payload: Record<string, any> = {
type: "batch",
client_id: clientId,
channel: selectedChannels,
recipients: processedRecipients,
//hard-coded the webhook url as the simplest solution. This url may not be correct all the times. Nop issues, the worker just fire and forgets while sending webhook, it does not retires
webhook_url: "http://localhost:3002/api/webhook"
};
Comment thread dashboard/entrypoint.sh
Comment on lines +4 to 6
# Get configuration from environment
BASE_PATH="${BASE_PATH:-}"

Comment on lines +53 to +65
for (const field of schema) {
const value = config[field.name];
if (field.required && (!value || value.trim() === '')) {
errors.push(`${field.label} is required`);
continue;
}
if (value && field.pattern) {
const regex = new RegExp(field.pattern);
if (!regex.test(value)) {
errors.push(`${field.label} has invalid format`);
}
}
}
Comment on lines +165 to +177
for (const field of schema) {
const value = body.config[field.name];
if (field.required && (!value || value.trim() === '')) {
errors.push(`${field.label} is required`);
continue;
}
if (value && field.pattern) {
const regex = new RegExp(field.pattern);
if (!regex.test(value)) {
errors.push(`${field.label} has invalid format`);
}
}
}
Comment on lines +92 to +96
// Aggregate by hour for 24h, by day for 7d/30d
const groupBy = period === '24h'
? { $hour: '$created_at' }
: { $dayOfYear: '$created_at' };

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants