diff --git a/README.md b/README.md new file mode 100644 index 0000000..be5c266 --- /dev/null +++ b/README.md @@ -0,0 +1,161 @@ +# ๐Ÿš› FreightDesk + +**India's Freight Marketplace Platform** โ€” Connect shippers with truck drivers, manage loads, track payments through escrow, and grow your freight business. + +![FreightDesk](https://img.shields.io/badge/Node.js-20-green?style=flat-square) +![License](https://img.shields.io/badge/license-MIT-blue?style=flat-stack) + +## Features + +### For Everyone +- ๐ŸŒ Public landing page with registration +- ๐Ÿ” Secure authentication (admin + portal users) +- ๐Ÿ“ฑ Mobile-responsive design +- ๐ŸŒ™ Dark mode + +### Admin Panel +- ๐Ÿ“Š Dashboard with Recharts visualizations +- ๐Ÿš› Load management (CRUD + WhatsApp parser) +- ๐Ÿข Shipper & vehicle management +- ๐Ÿ’ณ Payment tracking & commission calculator +- ๐Ÿ“‹ Reports & audit logs +- ๐Ÿงพ Invoice PDF generation +- ๐Ÿ›ก๏ธ User moderation (verify, dispute resolution) +- ๐Ÿ“ˆ Prometheus metrics + Pino logging + +### Shipper Portal +- ๐Ÿ“ฆ Post loads to marketplace +- ๐Ÿ’ฐ Deposit funds to escrow +- ๐Ÿ“Š View bids, accept/counter-offer +- ๐Ÿ’ธ Release payment after delivery +- ๐Ÿ“ Rate drivers +- ๐Ÿ”” Real-time notifications + +### Driver Portal +- ๐Ÿ” Browse & filter available loads +- ๐Ÿ’ต Place bids on loads +- ๐Ÿ“ GPS location tracking +- ๐Ÿ“Š Earnings dashboard +- ๐Ÿ’ธ Request payouts (UPI/Bank) +- โญ View ratings & reviews + +### Marketplace +- ๐Ÿช Browse loads with filters (city, type, budget) +- ๐Ÿ’ฒ Bidding system with negotiation +- ๐Ÿ”” Real-time notifications +- ๐Ÿ“Š Bid comparison with driver profiles + +## Tech Stack + +| Layer | Technology | +|-------|-----------| +| Backend | Node.js + Express | +| Frontend | EJS server-rendered + React (Recharts via CDN) | +| Database | Supabase PostgreSQL | +| Auth | bcrypt + express-session | +| Security | Helmet + CSRF + rate limiting | +| Logging | Pino structured logging | +| Metrics | Prometheus | +| Testing | Jest + Supertest | +| Deployment | Docker + Coolify + Forgejo CI/CD | + +## Quick Start + +### Prerequisites +- Node.js 20+ +- Supabase project (self-hosted or cloud) + +### 1. Clone & Install +```bash +git clone http://forgejo-vil3xyowqk0qsh4hiqy77e3h.187.127.178.110.sslip.io/iamcoolvivek007/freightdesk.git +cd freightdesk/webapp +npm install +``` + +### 2. Configure +```bash +cp .env.example .env +# Edit .env with your Supabase credentials +``` + +### 3. Run Migrations +Run `supabase/migrations/001_initial_schema.sql` through `007_location_tracking.sql` in your Supabase SQL editor. + +### 4. Create Admin Account +Visit `http://localhost:3000/setup` + +### 5. Seed Demo Data (optional) +```bash +node scripts/seed-demo.js +``` + +### 6. Start +```bash +npm run dev # Development with nodemon +npm start # Production +``` + +## Docker + +```bash +cd webapp +docker build -t freightdesk . +docker run -p 3000:3000 --env-file .env freightdesk +``` + +## Project Structure + +``` +freightdesk/ +โ”œโ”€โ”€ .github/workflows/deploy.yml # CI/CD pipeline +โ”œโ”€โ”€ DEPLOYMENT.md # Full deployment guide +โ”œโ”€โ”€ supabase/migrations/ # 7 migrations (001-007) +โ””โ”€โ”€ webapp/ + โ”œโ”€โ”€ Dockerfile + โ”œโ”€โ”€ package.json + โ”œโ”€โ”€ scripts/seed-demo.js # Demo data seeder + โ””โ”€โ”€ src/ + โ”œโ”€โ”€ server.js # Express app entry + โ”œโ”€โ”€ config/env.js # Environment config + โ”œโ”€โ”€ middleware/ # CSRF, auth, security + โ”œโ”€โ”€ routes/ # 14 route files + โ”‚ โ”œโ”€โ”€ dashboard.js + โ”‚ โ”œโ”€โ”€ loads.js + โ”‚ โ”œโ”€โ”€ payments.js # Escrow payments + โ”‚ โ”œโ”€โ”€ marketplace.js # Bidding system + โ”‚ โ”œโ”€โ”€ admin-moderation.js + โ”‚ โ””โ”€โ”€ ... + โ”œโ”€โ”€ services/ # Business logic + โ”‚ โ”œโ”€โ”€ supabase.js + โ”‚ โ”œโ”€โ”€ parser.js # WhatsApp parser + โ”‚ โ”œโ”€โ”€ invoice-pdf.js + โ”‚ โ”œโ”€โ”€ logger.js + โ”‚ โ””โ”€โ”€ metrics.js + โ”œโ”€โ”€ views/pages/ # EJS templates + โ”‚ โ”œโ”€โ”€ public/ # Landing, register + โ”‚ โ”œโ”€โ”€ marketplace/ # Browse, post, bid + โ”‚ โ”œโ”€โ”€ portal/ # Shipper/driver portal + โ”‚ โ”œโ”€โ”€ payments/ # Deposit, payout + โ”‚ โ””โ”€โ”€ admin/ # Moderation + โ”œโ”€โ”€ public/ # Static assets + โ”‚ โ””โ”€โ”€ css/style.css # Govt-app aesthetic + โ””โ”€โ”€ lib/ # India locale helpers +``` + +## Database Schema + +7 migrations totaling ~20 tables: + +| Migration | Tables Added | +|-----------|-------------| +| 001 | loads, shippers, vehicles, payments, portal_users | +| 002 | parser config, city list | +| 003 | soft-delete columns | +| 004 | audit_logs | +| 005 | bids, negotiations, ratings, notifications, load_views | +| 006 | escrow_accounts, escrow_transactions, payout_requests, disputes, platform_config | +| 007 | vehicle_locations, GPS columns on vehicles | + +## License + +MIT diff --git a/webapp/.dockerignore b/webapp/.dockerignore new file mode 100644 index 0000000..5b003a4 --- /dev/null +++ b/webapp/.dockerignore @@ -0,0 +1,11 @@ +node_modules +npm-debug.log +.env +.git +.gitignore +README.md +DEPLOYMENT.md +.DS_Store +*.md +docker-compose*.yml +.github diff --git a/webapp/.env.example b/webapp/.env.example index 23a28b6..ff73862 100644 --- a/webapp/.env.example +++ b/webapp/.env.example @@ -1,9 +1,25 @@ +# FreightDesk โ€” Environment Variables +# Copy to .env and fill in values + +# Server NODE_ENV=development PORT=3000 APP_URL=http://localhost:3000 -SUPABASE_URL=https://your-project.supabase.co -SUPABASE_KEY=your-anon-key -SUPABASE_SERVICE_KEY=your-service-role-key - +# Session secret (generate: node -e "console.log(require('crypto').randomBytes(32).toString('hex'))") SESSION_SECRET=change-this-to-a-random-string-in-production + +# Supabase +SUPABASE_URL=https://your-project.supabase.co +SUPABASE_SERVICE_KEY=your-service-role-key +SUPABASE_KEY=your-anon-key + +# Payment Gateway (production โ€” Razorpay) +RAZORPAY_KEY_ID= +RAZORPAY_KEY_SECRET= + +# Email (optional) +SMTP_HOST= +SMTP_PORT=587 +SMTP_USER= +SMTP_PASS= diff --git a/webapp/src/routes/public.js b/webapp/src/routes/public.js index dc69d60..4a1b8f5 100644 --- a/webapp/src/routes/public.js +++ b/webapp/src/routes/public.js @@ -9,7 +9,7 @@ const { asyncHandler } = require('../middleware/security'); // ============================================================ // GET /register/shipper -router.get('/shipper', (req, res) => { +router.get('/register/shipper', (req, res) => { if (req.session.portalUser) { return res.redirect('/portal/dashboard'); } @@ -17,7 +17,7 @@ router.get('/shipper', (req, res) => { }); // POST /register/shipper -router.post('/shipper', asyncHandler(async (req, res) => { +router.post('/register/shipper', asyncHandler(async (req, res) => { const { name, email, phone, password, confirm_password, company_name, gst_number, city, state, pincode } = req.body; // Validation @@ -104,7 +104,7 @@ router.post('/shipper', asyncHandler(async (req, res) => { -- ============================================================ // GET /register/driver -router.get('/driver', (req, res) => { +router.get('/register/driver', (req, res) => { if (req.session.portalUser) { return res.redirect('/portal/dashboard'); } @@ -112,7 +112,7 @@ router.get('/driver', (req, res) => { }); // POST /register/driver -router.post('/driver', asyncHandler(async (req, res) => { +router.post('/register/driver', asyncHandler(async (req, res) => { const { name, email, phone, password, confirm_password, vehicle_number, vehicle_type, capacity_tons, driver_license, current_city } = req.body; // Validation diff --git a/webapp/src/server.js b/webapp/src/server.js index f5347e2..d8cda55 100644 --- a/webapp/src/server.js +++ b/webapp/src/server.js @@ -203,7 +203,6 @@ app.use('/setup', require('./routes/setup')); app.use('/loads', require('./routes/loads')); app.use('/shippers', require('./routes/shippers')); app.use('/vehicles', require('./routes/vehicles')); -app.use('/payments', require('./routes/payments')); app.use('/reports', require('./routes/reports')); app.use('/audit-logs', require('./routes/audit')); app.use('/portal', require('./routes/portal')); diff --git a/webapp/src/services/supabase.js b/webapp/src/services/supabase.js index 2c92612..a5458e4 100644 --- a/webapp/src/services/supabase.js +++ b/webapp/src/services/supabase.js @@ -2,10 +2,10 @@ const { createClient } = require('@supabase/supabase-js'); const config = require('../config/env'); const supabaseUrl = config.supabase.url; -const supabaseKey = config.supabase.key; +const supabaseKey = config.supabase.serviceKey || config.supabase.key; if (!supabaseUrl || !supabaseKey) { - console.error('Missing SUPABASE_URL or SUPABASE_KEY. Check .env file.'); + console.error('Missing SUPABASE_URL or SUPABASE_SERVICE_KEY. Check .env file.'); process.exit(1); } diff --git a/webapp/src/views/pages/errors/403.ejs b/webapp/src/views/pages/errors/403.ejs new file mode 100644 index 0000000..05d0019 --- /dev/null +++ b/webapp/src/views/pages/errors/403.ejs @@ -0,0 +1,17 @@ + + + + + + Access Denied โ€” FreightDesk + + + +
+
🔒
+

Access Denied

+

<%= typeof message !== 'undefined' ? message : 'You do not have permission to access this page.' %>

+ Go to Dashboard +
+ +