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. + + + + +## 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 @@ + + +
+ + +<%= typeof message !== 'undefined' ? message : 'You do not have permission to access this page.' %>
+ Go to Dashboard +