global.isStrikeRunning = false; require('dotenv').config(); const express = require('express'); const mongoose = require('mongoose'); const cors = require('cors'); const { generateKUS } = require('./utils/kusGenerator'); const authRoute = require('./routes/auth'); const marketRoute = require('./routes/market'); const adminRoute = require('./routes/admin'); // Import Models const User = require('./models/User'); const Transaction = require('./models/Transaction'); const Asset = require('./models/Asset'); const notificationRoute = require('./routes/notification'); const startStrike = require('./jobs/strike'); const logTransaction = require('./utils/ledgerLogger'); const { sendToUser } = require('./utils/sendPush'); startStrike(); // Starts the internal clock const app = express(); // Middleware app.use(cors()); app.use(express.json()); // Allows us to read JSON from the iPhone // Route Middlewares app.use('/api/auth', authRoute); app.use('/api/market', marketRoute); app.use('/api/admin', adminRoute); app.use('/api/notifications', notificationRoute); app.use("/api/strike", require("./routes/strike")); app.use('/api/fairness', require('./routes/fairness')); // ------------------------------------------------------------------ // ROUTE 1: Health Check (To see if server is alive) // ------------------------------------------------------------------ app.get('/', (req, res) => { res.send('KoshX System: Securely Running....'); }); // ------------------------------------------------------------------ // ROUTE 2: The Payment Webhook (Where the iPhone talks to us) // ------------------------------------------------------------------ app.post('/api/webhook/sms-capture', async (req, res) => { try { // 1. Security Gate const secret = req.headers['x-admin-secret']; if (secret !== process.env.ADMIN_SECRET) { console.log('Unauthorized Webhook Attempt'); return res.status(403).json({ error: "Access Denied" }); } // 2. Extract Data const { utr, amount } = req.body; console.log(`[Webhook] Received UTR: ${utr}`); // 3. Find the Pending Transaction // NOTE: In a real flow, the user creates a "Pending" transaction via the App first. // If you are just testing the Webhook without the App, we might not find a transaction yet. // For now, let's assume the App created it. const transaction = await Transaction.findOne({ utr: utr, status: 'Pending' }); if (!transaction) { return res.status(404).json({ message: "Transaction not found or already verified." }); } // 4. Generate the Asset const newKUS = await generateKUS(transaction.tier); // 5. Assign to User const newAsset = new Asset({ owner_id: transaction.user_id, kus_id: newKUS, tier: transaction.tier }); await newAsset.save(); // 6. Update Transaction Status transaction.status = 'Verified'; await transaction.save(); // 7. Referral Logic (Check if First Purchase) const assetCount = await Asset.countDocuments({ owner_id: tx.user_id }); if (assetCount === 1) { const user = await User.findById(tx.user_id); if (user.referred_by) { const referrer = await User.findOne({ referral_code: user.referred_by }); if (referrer) { let reward = 0; if (tx.tier === 'Silver') reward = 100; if (tx.tier === 'Gold') reward = 150; if (tx.tier === 'Platinum') reward = 250; let userReward = 0; if (tx.tier === 'Silver') reward = 50; if (tx.tier === 'Gold') reward = 75; if (tx.tier === 'Platinum') reward = 125; referrer.points += reward; await referrer.save(); user.points += userReward; await user.save(); await logTransaction(referrer._id, 'REFERRAL_BONUS', reward, 'INR', `Referral Bonus Tier: ${tx.tier}`); await sendToUser(referrer._id, "Referral Bonus Credited", `${reward} points credited to your account.`, "/profile"); await logTransaction(user._id, 'REFERRAL_BONUS', userReward, 'INR', `Referral Bonus Tier: ${tx.tier}`); await sendToUser(user._id, "Referral Bonus Credited", `${userReward} points credited to your account.`, "/profile"); console.log(`[Referral] ${reward} points added to ${referrer.name}`); } } } console.log(`[Success] Asset ${newKUS} generated for UTR ${utr}`); res.status(200).json({ success: true, kus: newKUS }); } catch (error) { console.error("Webhook Error:", error); res.status(500).json({ error: "Server Internal Error" }); } }); // Database Connection & Server Start mongoose.connect(process.env.MONGO_URI) .then(() => { console.log('✅ Connected to MongoDB Atlas'); app.listen(process.env.PORT, '0.0.0.0', () => { console.log(`🚀 Server running on port ${process.env.PORT}`); }); }) .catch((err) => console.error('❌ DB Connection Error:', err));