create-fullstack-boilerplate 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/README.md +390 -0
  2. package/index.js +78 -0
  3. package/lib/addDB.js +77 -0
  4. package/lib/addRoute.js +264 -0
  5. package/lib/copyProject.js +25 -0
  6. package/lib/dataTypes.js +79 -0
  7. package/lib/installDeps.js +11 -0
  8. package/lib/prompts.js +289 -0
  9. package/lib/setupExtraDB.js +172 -0
  10. package/lib/setupMainDB.js +9 -0
  11. package/lib/testDBConnection.js +31 -0
  12. package/lib/utils.js +39 -0
  13. package/package.json +45 -0
  14. package/template/Backend/.env +7 -0
  15. package/template/Backend/DB/DBInit.js +28 -0
  16. package/template/Backend/DB/dbConfigs.js +4 -0
  17. package/template/Backend/Models/index.js +54 -0
  18. package/template/Backend/README.md +535 -0
  19. package/template/Backend/middleware/authMiddleware.js +19 -0
  20. package/template/Backend/package-lock.json +2997 -0
  21. package/template/Backend/package.json +32 -0
  22. package/template/Backend/routes/authRoutes.js +15 -0
  23. package/template/Backend/routes/dashboardRoutes.js +13 -0
  24. package/template/Backend/routes/index.js +15 -0
  25. package/template/Backend/routes/settingsRoutes.js +9 -0
  26. package/template/Backend/server.js +70 -0
  27. package/template/Backend/services/authService.js +68 -0
  28. package/template/Backend/services/cryptoService.js +14 -0
  29. package/template/Backend/services/dashboardService.js +39 -0
  30. package/template/Backend/services/settingsService.js +43 -0
  31. package/template/Frontend/.env +3 -0
  32. package/template/Frontend/README.md +576 -0
  33. package/template/Frontend/eslint.config.js +29 -0
  34. package/template/Frontend/index.html +13 -0
  35. package/template/Frontend/package-lock.json +3690 -0
  36. package/template/Frontend/package.json +39 -0
  37. package/template/Frontend/public/PMDLogo.png +0 -0
  38. package/template/Frontend/public/pp.jpg +0 -0
  39. package/template/Frontend/public/tabicon.png +0 -0
  40. package/template/Frontend/src/App.jsx +71 -0
  41. package/template/Frontend/src/assets/fonts/ArticulatCFDemiBold/font.woff +0 -0
  42. package/template/Frontend/src/assets/fonts/ArticulatCFDemiBold/font.woff2 +0 -0
  43. package/template/Frontend/src/assets/fonts/ArticulatCFNormal/font.woff +0 -0
  44. package/template/Frontend/src/assets/fonts/ArticulatCFNormal/font.woff2 +0 -0
  45. package/template/Frontend/src/assets/fonts/ArticulatCFRegular/font.woff +0 -0
  46. package/template/Frontend/src/assets/fonts/ArticulatCFRegular/font.woff2 +0 -0
  47. package/template/Frontend/src/assets/fonts/MixtaProRegularItalic/font.woff +0 -0
  48. package/template/Frontend/src/assets/fonts/MixtaProRegularItalic/font.woff2 +0 -0
  49. package/template/Frontend/src/assets/fonts/fonts_sohne/OTF/S/303/266hneMono-Buch.otf +0 -0
  50. package/template/Frontend/src/assets/fonts/fonts_sohne/OTF/S/303/266hneMono-Leicht.otf +0 -0
  51. package/template/Frontend/src/assets/fonts/fonts_sohne/WOFF2/soehne-mono-buch.woff2 +0 -0
  52. package/template/Frontend/src/assets/fonts/fonts_sohne/WOFF2/soehne-mono-leicht.woff2 +0 -0
  53. package/template/Frontend/src/components/Layout.jsx +61 -0
  54. package/template/Frontend/src/components/Loader.jsx +19 -0
  55. package/template/Frontend/src/components/ProtectedRoute.jsx +19 -0
  56. package/template/Frontend/src/components/Sidebar.jsx +286 -0
  57. package/template/Frontend/src/components/ThemeToggle.jsx +30 -0
  58. package/template/Frontend/src/config/axiosClient.js +46 -0
  59. package/template/Frontend/src/config/encryption.js +11 -0
  60. package/template/Frontend/src/config/routes.js +65 -0
  61. package/template/Frontend/src/contexts/AuthContext.jsx +144 -0
  62. package/template/Frontend/src/contexts/ThemeContext.jsx +69 -0
  63. package/template/Frontend/src/index.css +88 -0
  64. package/template/Frontend/src/main.jsx +11 -0
  65. package/template/Frontend/src/pages/Dashboard.jsx +137 -0
  66. package/template/Frontend/src/pages/Login.jsx +195 -0
  67. package/template/Frontend/src/pages/NotFound.jsx +70 -0
  68. package/template/Frontend/src/pages/Settings.jsx +69 -0
  69. package/template/Frontend/tailwind.config.js +90 -0
  70. package/template/Frontend/vite.config.js +37 -0
  71. package/template/Readme.md +0 -0
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "report_consolidation_backend",
3
+ "version": "1.0.0",
4
+ "description": "Backend For Reort Consolidation Platform for PMD",
5
+ "main": "server.js",
6
+ "scripts": {
7
+ "start": "node server.js",
8
+ "dev": "nodemon server.js"
9
+ },
10
+ "dependencies": {
11
+ "axios": "^1.12.2",
12
+ "axios-cookiejar-support": "^6.0.4",
13
+ "bcryptjs": "^2.4.3",
14
+ "cheerio": "^1.1.2",
15
+ "colors": "^1.4.0",
16
+ "cors": "^2.8.5",
17
+ "crypto-js": "^4.2.0",
18
+ "dotenv": "^16.3.1",
19
+ "express": "^4.18.2",
20
+ "form-data": "^4.0.4",
21
+ "jsonwebtoken": "^9.0.2",
22
+ "mysql2": "^3.15.2",
23
+ "node-fetch": "^3.3.2",
24
+ "sequelize": "^6.37.7",
25
+ "sequelize-cli": "^6.6.3",
26
+ "tough-cookie": "^6.0.0",
27
+ "xml2js": "^0.6.2"
28
+ },
29
+ "devDependencies": {
30
+ "nodemon": "^3.0.1"
31
+ }
32
+ }
@@ -0,0 +1,15 @@
1
+ const express = require('express');
2
+ const router = express.Router();
3
+ const authService = require('../services/authService');
4
+ const { authenticateToken } = require('../middleware/authMiddleware')
5
+
6
+ // Login
7
+ router.post('/login', authService.login);
8
+
9
+ // Get current user
10
+ router.get('/me', authenticateToken, authService.getCurrentUser);
11
+
12
+ // Logout
13
+ router.post('/logout', authenticateToken, authService.logout);
14
+
15
+ module.exports = router;
@@ -0,0 +1,13 @@
1
+ const express = require('express');
2
+ const router = express.Router();
3
+ const dashboardService = require('../services/dashboardService');
4
+
5
+ // Main route to get all network information
6
+ router.get('/getDashboardHealth', dashboardService.getDashboardRoutesHealth);
7
+
8
+ // Get only user details
9
+ router.post('/getDashboardInformation', dashboardService.getDashInfo);
10
+
11
+ // Implement Your Own Endpoints Here
12
+
13
+ module.exports = router;
@@ -0,0 +1,15 @@
1
+ const express = require('express');
2
+ const router = express.Router();
3
+
4
+ const { authenticateToken } = require('../middleware/authMiddleware')
5
+
6
+ const authRoutes = require('./authRoutes');
7
+ const dashboardRoutes = require('./dashboardRoutes');
8
+ const settingsRoutes = require('./settingsRoutes');
9
+
10
+ // Mount feature routers
11
+ router.use('/auth', authRoutes);
12
+ router.use('/dashboard', authenticateToken, dashboardRoutes);
13
+ router.use('/settings', authenticateToken, settingsRoutes);
14
+
15
+ module.exports = router;
@@ -0,0 +1,9 @@
1
+ const express = require('express');
2
+ const router = express.Router();
3
+ const settingsService = require('../services/settingsService');
4
+ const {authenticateToken} = require('../middleware/authMiddleware')
5
+
6
+ router.get('/getSettingsHealth', authenticateToken, settingsService.getSettingsRoutesHealth);
7
+ router.post('/saveProfileDetails',authenticateToken, settingsService.getSettingsInfo);
8
+
9
+ module.exports = router;
@@ -0,0 +1,70 @@
1
+ require('colors');
2
+ require('dotenv').config();
3
+ const express = require('express');
4
+ const cors = require('cors');
5
+ const databases = require('./Models'); // all DBs exported from Models/index.js
6
+ const { initializeDatabaseConnection } = require('./DB/DBInit');
7
+
8
+ const mainRouter = require('./routes/index');
9
+
10
+ const app = express();
11
+ const PORT = process.env.PORT || 3000;
12
+
13
+ // Middleware
14
+ app.use(cors({
15
+ origin: process.env.CLIENT_URL,
16
+ credentials: true
17
+ }));
18
+ app.use(express.json());
19
+
20
+ // Health check
21
+ app.get('/api/health', (req, res) => {
22
+ res.json({ status: 'ok', message: 'Server is running' });
23
+ });
24
+
25
+ // Use all routers
26
+ app.use('/api', mainRouter);
27
+
28
+ // Error handling middleware
29
+ app.use((err, req, res, next) => {
30
+ console.error(err.stack);
31
+ res.status(500).json({ message: 'Something went wrong!' });
32
+ });
33
+
34
+ const startServer = async () => {
35
+ console.log("\n[+] ========== Starting Server & Initializing DBs ========== \n");
36
+
37
+ // Initialize all databases exported from Models
38
+ const dbKeys = Object.keys(databases || {});
39
+ for (const key of dbKeys) {
40
+ try {
41
+ const db = databases[key];
42
+ if (!db || !db.sequelize) {
43
+ console.log(`[!] - Skipping ${key}: no sequelize instance found.`.yellow);
44
+ continue;
45
+ }
46
+
47
+ console.log(`[~] Initializing ${key}...`.cyan);
48
+ await initializeDatabaseConnection(db.sequelize, key);
49
+ console.log(`[✅] ${key} initialized successfully.`.green);
50
+ } catch (err) {
51
+ // initializeDatabaseConnection may throw after its retries — log and continue
52
+ console.error(`[❌] Failed to initialize ${key}:`.red, err.message || err);
53
+ console.error(err);
54
+ }
55
+ }
56
+
57
+ // Start server regardless of DB init status
58
+ app.listen(PORT, () => {
59
+ console.log(`\n🚀 Server is running on port ${PORT}`.bold);
60
+ console.log("\n[+] ========== Server started (DB initialization attempted) ========== \n");
61
+ });
62
+ };
63
+
64
+ startServer().catch(err => {
65
+ console.error("[!] Unhandled error in startServer:".red, err);
66
+ // Still attempt to start the server in case DB init threw unexpectedly
67
+ app.listen(PORT, () => {
68
+ console.log(`\n🚀 Server is running on port ${PORT} (after uncaught init error)`.bold);
69
+ });
70
+ });
@@ -0,0 +1,68 @@
1
+ const bcrypt = require('bcryptjs');
2
+ const jwt = require('jsonwebtoken');
3
+ const { decrypt } = require('./cryptoService')
4
+
5
+ const JWT_SECRET = process.env.JWT_SECRET;
6
+
7
+ // Mock user database
8
+ const users = [
9
+ {
10
+ id: '1',
11
+ email: 'admin@npmjs.com',
12
+ password: '$2a$10$yFJXKioLIdFeUhsbat75..AEiEmyQhwM5Enj/9P3AXY5ReVC.lu1C'
13
+ // email: 'dev@pmdpk.com',
14
+ // password: '$2a$10$q62ZJw20xdKWvqtV7pFpbevPBysE9TvrLJX2WocDH.Clpk.43X.Ue', // 'pmd@786'
15
+ },
16
+ {
17
+ id: '2',
18
+ email: 'networks@pmdpk.com',
19
+ password: '$2a$10$kObr3k/8AeIOEwdcM79K0utCi0WKMBoqx4ewuFkb9UKznoAZ1dHi6', // 'pmd@123'
20
+ }
21
+ ];
22
+
23
+ exports.login = async (req, res) => {
24
+ try {
25
+ const { email, password } = req.body;
26
+
27
+ if (!email || !password) {
28
+ return res.status(400).json({ message: 'Email and password are required' });
29
+ }
30
+
31
+ const user = users.find(u => u.email.toLowerCase() === email.toLowerCase());
32
+ if (!user) {
33
+ return res.status(401).json({ message: 'Invalid email or password' });
34
+ }
35
+
36
+ const isValidPassword = await bcrypt.compare(decrypt(password), user.password);
37
+ if (!isValidPassword) {
38
+ return res.status(401).json({ message: 'Invalid email or password' });
39
+ }
40
+
41
+ const token = jwt.sign(
42
+ { id: user.id, email: user.email },
43
+ JWT_SECRET,
44
+ { expiresIn: '24h' }
45
+ );
46
+
47
+ res.json({
48
+ message: 'Login successful',
49
+ token,
50
+ user: { id: user.id, email: user.email }
51
+ });
52
+ } catch (error) {
53
+ console.error('Login error:', error);
54
+ res.status(500).json({ message: 'Internal server error' });
55
+ }
56
+ };
57
+
58
+ exports.getCurrentUser = (req, res) => {
59
+ const user = users.find(u => u.id === req.user.id);
60
+ if (!user) {
61
+ return res.status(404).json({ message: 'User not found' });
62
+ }
63
+ res.json({ user: { id: user.id, email: user.email } });
64
+ };
65
+
66
+ exports.logout = (req, res) => {
67
+ res.json({ message: 'Logout successful' });
68
+ };
@@ -0,0 +1,14 @@
1
+ const CryptoJS = require('crypto-js');
2
+
3
+ const AES_KEY = process.env.PASSWORD_ENCRYPTION_KEY;
4
+
5
+ if (!AES_KEY) {
6
+ console.warn('PASSWORD_ENCRYPTION_KEY not set in env. Decryption will fail.');
7
+ }
8
+
9
+ exports.decrypt = (encryptedString) => {
10
+ if (!AES_KEY) throw new Error('Server encryption key is not configured');
11
+ const bytes = CryptoJS.AES.decrypt(encryptedString, AES_KEY);
12
+ const decrypted = bytes.toString(CryptoJS.enc.Utf8);
13
+ return decrypted;
14
+ };
@@ -0,0 +1,39 @@
1
+ exports.getDashboardRoutesHealth = async (req, res) => {
2
+ const dashboardInfo = [
3
+ {
4
+ title: "Frontend Structure (React + Vite)",
5
+ items: [
6
+ "src/pages → Application Screens & Views",
7
+ "src/components → Reusable UI Components",
8
+ "src/contexts → Auth & Theme Providers",
9
+ "src/config → Axios Clients & Env Configurations"
10
+ ],
11
+ icon: "💻"
12
+ },
13
+ {
14
+ title: "Backend Structure (Node.js + Express + Sequelize)",
15
+ items: [
16
+ "routes/ → Define API Endpoints",
17
+ "services/ → Business Logic Layer",
18
+ "Models/ → Database Models & Associations",
19
+ "DB/ → DB Connection Settings"
20
+ ],
21
+ icon: "🛠️"
22
+ },
23
+ {
24
+ title: "Authentication",
25
+ items: [
26
+ "All /dashboard routes are protected by JWT.",
27
+ "Use Authorization: Bearer <token>"
28
+ ],
29
+ icon: "🔐"
30
+ },
31
+ ];
32
+
33
+ return res.status(200).json(dashboardInfo);
34
+ };
35
+
36
+
37
+ exports.getDashInfo = async (req, res) => {
38
+ res.status(200).send("Dashboard Information Endpoint")
39
+ }
@@ -0,0 +1,43 @@
1
+ exports.getSettingsRoutesHealth = async (req, res) => {
2
+ const settingsInfo = [
3
+ {
4
+ title: "Purpose of Settings Module",
5
+ icon: "⚙️",
6
+ items: [
7
+ "This area handles user preferences & personalization.",
8
+ "Used to manage account, profile, and application behavior."
9
+ ],
10
+ },
11
+ {
12
+ title: "Where to Add New Settings Logic",
13
+ icon: "🧩",
14
+ items: [
15
+ "Backend/routes/settingsRoutes.js → Define new API endpoints.",
16
+ "Backend/services/settingsService.js → Add business logic functions.",
17
+ ],
18
+ },
19
+ {
20
+ title: "Frontend Integration",
21
+ icon: "🎨",
22
+ items: [
23
+ "Use axiosSettingsClient for all requests.",
24
+ "Component path: Frontend/src/pages/Settings.jsx",
25
+ ],
26
+ },
27
+ {
28
+ title: "Security",
29
+ icon: "🔐",
30
+ items: [
31
+ "All /settings routes are protected using JWT middleware.",
32
+ ],
33
+ },
34
+ ];
35
+
36
+ return res.status(200).json(settingsInfo);
37
+ };
38
+
39
+
40
+
41
+ exports.getSettingsInfo = async (req, res) => {
42
+ res.status(200).send("Settings Information Endpoint")
43
+ }
@@ -0,0 +1,3 @@
1
+ VITE_API_BASE_URL=http://localhost:5000/api
2
+
3
+ VITE_PASSWORD_ENCRYPTION_KEY=A35_5YM37R1C_3NCRYP710N_K3Y_PMD