Sergei e1b32560ff Add Node.js backend with Stripe integration and admin panel
Backend features:
- Express.js API server
- Supabase database integration
- Stripe Checkout for payments ($249 kit + $9.99/mo premium)
- Stripe webhooks for payment events
- Admin panel with order management
- Auth middleware with JWT
- Email service via Brevo

API endpoints:
- /api/stripe/* - Payment processing
- /api/webhook/stripe - Stripe webhooks
- /api/admin/* - Admin operations
- /function/well-api/api - Legacy API proxy

Database migrations:
- orders, subscriptions, push_tokens tables

Schemes updated:
- Removed updatedAt from all schemes
- Updated credentials section with live values
- Added Stripe configuration details

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-19 09:49:24 -08:00

180 lines
6.0 KiB
JavaScript

const express = require('express');
const router = express.Router();
// Old API proxy for endpoints we don't handle
const OLD_API_URL = 'https://eluxnetworks.net/function/well-api/api';
async function proxyToOldApi(req, res) {
try {
const params = new URLSearchParams(req.body);
const response = await fetch(OLD_API_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: params.toString()
});
const data = await response.json();
return res.json(data);
} catch (error) {
return res.status(500).json({ error: 'Proxy error: ' + error.message });
}
}
// Controllers
const authController = require('../controllers/auth');
const dashboardController = require('../controllers/dashboard');
const deploymentController = require('../controllers/deployment');
const deviceController = require('../controllers/device');
const beneficiaryController = require('../controllers/beneficiary');
const caretakerController = require('../controllers/caretaker');
const sensorController = require('../controllers/sensor');
const alarmController = require('../controllers/alarm');
const voiceController = require('../controllers/voice');
// Function router - routes based on 'function' parameter
router.post('/', async (req, res) => {
const { function: func } = req.body;
try {
switch (func) {
// Auth
case 'credentials':
return authController.credentials(req, res);
case 'new_user_form':
return authController.newUserForm(req, res);
case 'forgot_password':
return authController.forgotPassword(req, res);
case 'reset_password':
return authController.resetPassword(req, res);
// Dashboard
case 'dashboard_list':
return dashboardController.list(req, res);
case 'dashboard_single':
return dashboardController.single(req, res);
// Deployments
case 'deployments_list':
return deploymentController.list(req, res);
case 'get_deployment':
return deploymentController.get(req, res);
case 'deployment_form':
return deploymentController.form(req, res);
case 'deployment_delete':
return deploymentController.delete(req, res);
case 'set_deployment':
return deploymentController.set(req, res);
case 'find_deployments':
return deploymentController.find(req, res);
// Devices
case 'device_list':
return deviceController.list(req, res);
case 'device_list_4_gui':
return deviceController.listForGui(req, res);
case 'device_list_by_deployment':
return deviceController.listByDeployment(req, res);
case 'get_device':
return deviceController.get(req, res);
case 'device_form':
return deviceController.form(req, res);
case 'device_set_group':
return deviceController.setGroup(req, res);
case 'device_get_live':
return deviceController.getLive(req, res);
case 'device_reboot':
return deviceController.reboot(req, res);
case 'device_set_well_id':
return deviceController.setWellId(req, res);
case 'device_set_network_id':
return deviceController.setNetworkId(req, res);
case 'request_devices':
return deviceController.requestDevices(req, res);
// Beneficiaries
case 'beneficiaries_list':
return beneficiaryController.list(req, res);
case 'get_beneficiary':
return beneficiaryController.get(req, res);
case 'beneficiary_form':
return beneficiaryController.form(req, res);
// Caretakers
case 'caretakers_list':
return caretakerController.list(req, res);
case 'get_caretaker':
return caretakerController.get(req, res);
case 'caretaker_form':
return caretakerController.form(req, res);
// Sensor Data - PROXY TO OLD API
case 'get_presence_data':
case 'get_raw_data':
case 'get_sensor_data_by_deployment_id':
case 'get_sensor_bucketed_data_by_room_sensor':
case 'get_time_deltas':
case 'request_single_slice':
case 'request_single_radar_slice':
case 'request_proximity':
case 'activities_report_details':
return proxyToOldApi(req, res);
// Alarms
case 'alarm_on_off':
return alarmController.onOff(req, res);
case 'get_alarm_state':
return alarmController.getState(req, res);
case 'store_alarms':
return alarmController.store(req, res);
case 'send_walarm':
return alarmController.sendWalarm(req, res);
case 'activity_detected':
return alarmController.activityDetected(req, res);
// Maps/Layout
case 'get_floor_layout':
return deploymentController.getFloorLayout(req, res);
case 'set_floor_layout':
return deploymentController.setFloorLayout(req, res);
case 'request_deployment_map_new':
return deploymentController.requestMap(req, res);
case 'get_devices_locations':
return deviceController.getLocations(req, res);
// Voice AI - PROXY TO OLD API
case 'voice_ask':
return proxyToOldApi(req, res);
// Maps/Images/Downloads - PROXY TO OLD API
case 'get_image_file':
case 'download':
case 'get_full_location_map':
case 'get_sensors_map':
case 'request_deployment_map_new':
case 'get_photo':
return proxyToOldApi(req, res);
// Messages
case 'messages_age':
return res.json({ success: true, messages: [] });
// Node-RED
case 'store_flow':
return res.json({ success: true });
case 'get_node_red_port':
return res.json({ port: 1880 });
case 'request_node_red':
return res.json({ success: true });
default:
// Unknown function - try old API
console.log(`Unknown function "${func}" - proxying to old API`);
return proxyToOldApi(req, res);
}
} catch (error) {
console.error(`Error in ${func}:`, error);
return res.status(500).json({ error: error.message });
}
});
module.exports = router;