fixing platform admin
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# Features & Priorities — RentFlow
|
||||
# Features & Priorities — RentalDriveGo
|
||||
|
||||
## MVP (Phase 1) — Must Ship Before Launch
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
- [x] Offer performance stats (redemptions, revenue impact)
|
||||
- [x] Offer banner image upload
|
||||
|
||||
### Global Marketplace (rentflow.com/explore)
|
||||
### Global Marketplace (RentalDriveGo.com/explore)
|
||||
- [x] Featured offers carousel on /explore home
|
||||
- [x] Search vehicles by city, dates, category, price range
|
||||
- [x] Company cards (logo, rating, offer badge)
|
||||
@@ -67,12 +67,12 @@
|
||||
### Branding & White-Label Public Site
|
||||
- [x] Company display name, logo, tagline, hero image
|
||||
- [x] Primary brand color picker
|
||||
- [x] Subdomain: `{slug}.rentflow.com` (claimed during onboarding)
|
||||
- [x] Subdomain: `{slug}.RentalDriveGo.com` (claimed during onboarding)
|
||||
- [x] Real-time subdomain availability check
|
||||
- [x] Vercel wildcard domain routing (`*.rentflow.com`)
|
||||
- [x] Vercel wildcard domain routing (`*.RentalDriveGo.com`)
|
||||
- [x] Company public site: home with offers, vehicle listing, vehicle detail, booking, confirmation
|
||||
- [x] Offers page on public site
|
||||
- [x] "Powered by RentFlow" badge (removable on Pro)
|
||||
- [x] "Powered by RentalDriveGo" badge (removable on Pro)
|
||||
- [x] Site language + currency preference
|
||||
|
||||
### Payments — Rental (AmanPay + PayPal)
|
||||
@@ -117,7 +117,7 @@
|
||||
- [x] Company employee auth via Clerk
|
||||
- [x] Renter auth via own JWT (separate)
|
||||
- [x] Onboarding step 2: branding + subdomain
|
||||
- [x] Onboarding step 4: "Your vehicles now appear on the RentFlow marketplace"
|
||||
- [x] Onboarding step 4: "Your vehicles now appear on the RentalDriveGo marketplace"
|
||||
- [x] Role system: OWNER / MANAGER / AGENT
|
||||
|
||||
|
||||
@@ -129,7 +129,7 @@
|
||||
- [x] TOTP 2FA: setup with QR code, verify, enforce for ADMIN+ roles
|
||||
- [x] Role hierarchy: VIEWER < FINANCE < SUPPORT < ADMIN < SUPER_ADMIN
|
||||
- [x] Admin role access matrix: 17 dashboard features × 5 roles
|
||||
- [x] `admin.rentflow.com` separate app (Next.js)
|
||||
- [x] `admin.RentalDriveGo.com` separate app (Next.js)
|
||||
- [x] **Company management**: list, search/filter, create, edit, suspend, reactivate, delete
|
||||
- [x] **Company staff management**: list employees per company, add employee, edit (name/email/role), deactivate/reactivate, reset password
|
||||
- [x] **Impersonation**: ADMIN+ can log in as any company employee (Clerk impersonation session), with dashboard banner
|
||||
|
||||
@@ -30,7 +30,7 @@ app.use('/api/v1/team', teamRouter)
|
||||
## 2. Install the Clerk webhook (Clerk Dashboard → Webhooks)
|
||||
|
||||
1. Go to **clerk.com** → your app → **Webhooks** → **Add endpoint**
|
||||
2. URL: `https://api.rentflow.com/webhooks/clerk`
|
||||
2. URL: `https://api.RentalDriveGo.com/webhooks/clerk`
|
||||
3. Events to subscribe: `user.created`
|
||||
4. Copy the **Signing Secret** and add to `.env`:
|
||||
|
||||
@@ -54,10 +54,10 @@ CLERK_SECRET_KEY=sk_live_...
|
||||
CLERK_WEBHOOK_SECRET=whsec_...
|
||||
|
||||
# Frontend
|
||||
NEXT_PUBLIC_API_URL=https://api.rentflow.com/api/v1
|
||||
NEXT_PUBLIC_API_URL=https://api.RentalDriveGo.com/api/v1
|
||||
|
||||
# Dashboard URL (used in invite redirect)
|
||||
DASHBOARD_URL=https://app.rentflow.com
|
||||
DASHBOARD_URL=https://app.RentalDriveGo.com
|
||||
```
|
||||
|
||||
---
|
||||
@@ -111,7 +111,7 @@ router.post(
|
||||
When a user clicks the magic link in their invitation email, Clerk redirects them to:
|
||||
|
||||
```
|
||||
https://app.rentflow.com/onboarding/accept-invite?__clerk_ticket=...
|
||||
https://app.RentalDriveGo.com/onboarding/accept-invite?__clerk_ticket=...
|
||||
```
|
||||
|
||||
Create this page in your Next.js app:
|
||||
|
||||
+15
-15
@@ -1,8 +1,8 @@
|
||||
# Pages Specification — RentFlow
|
||||
# Pages Specification — RentalDriveGo
|
||||
|
||||
---
|
||||
|
||||
## LAYER 1A — Marketing Site (rentflow.com)
|
||||
## LAYER 1A — Marketing Site (RentalDriveGo.com)
|
||||
|
||||
### `/` — Home
|
||||
Sections:
|
||||
@@ -11,7 +11,7 @@ Sections:
|
||||
3. Social proof bar
|
||||
4. Pain points (for companies)
|
||||
5. Features grid — fleet, photos, offers, site, CRM, analytics
|
||||
6. **Marketplace callout** — "Your vehicle photos appear on the RentFlow global marketplace automatically"
|
||||
6. **Marketplace callout** — "Your vehicle photos appear on the RentalDriveGo global marketplace automatically"
|
||||
7. How it works — 3 steps
|
||||
8. Pricing teaser (AmanPay / PayPal accepted badges shown)
|
||||
9. Testimonials
|
||||
@@ -28,7 +28,7 @@ Sections:
|
||||
|
||||
---
|
||||
|
||||
## LAYER 1B — Global Marketplace (rentflow.com/explore)
|
||||
## LAYER 1B — Global Marketplace (RentalDriveGo.com/explore)
|
||||
|
||||
> **Design principle:** This is a DISCOVERY layer. No booking form, no payment form.
|
||||
> Every CTA leads to the company's own site.
|
||||
@@ -59,7 +59,7 @@ Sections:
|
||||
- Daily rate + currency
|
||||
- Active offer badge (if applicable, e.g. "20% OFF until July 31")
|
||||
- Star rating from reviews
|
||||
- **"Book at [Company Name] →"** — on click: redirect to `{slug}.rentflow.com/book?vehicleId=X&from=Y&to=Z&ref=marketplace`
|
||||
- **"Book at [Company Name] →"** — on click: redirect to `{slug}.RentalDriveGo.com/book?vehicleId=X&from=Y&to=Z&ref=marketplace`
|
||||
- Filter panel: category, transmission, fuel type, price range, city, offer only
|
||||
- Sort: price (low-high, high-low), rating, newest
|
||||
|
||||
@@ -79,7 +79,7 @@ Sections:
|
||||
- Availability indicator on each card ("3 available for your dates" vs "Check availability")
|
||||
|
||||
### `/explore/[slug]` — Company Marketplace Profile
|
||||
This is the company's listing on the RentFlow marketplace (RentFlow-styled, not their branded site).
|
||||
This is the company's listing on the RentalDriveGo marketplace (RentalDriveGo-styled, not their branded site).
|
||||
|
||||
Sections:
|
||||
1. Company header — logo, display name, city/country, rating, phone, "Save" heart
|
||||
@@ -88,7 +88,7 @@ Sections:
|
||||
- Each card: photo(s), specs, daily rate, offer badge, **"Book at [Company Name] →"** redirect button
|
||||
4. **Reviews** — renter reviews with star ratings + company replies
|
||||
5. Contact info — email, phone, WhatsApp link (opens `wa.me/...`)
|
||||
6. "Visit their website →" link to `{slug}.rentflow.com`
|
||||
6. "Visit their website →" link to `{slug}.RentalDriveGo.com`
|
||||
|
||||
### `/explore/[slug]/vehicles/[id]` — Vehicle Detail (Marketplace)
|
||||
- **Photo gallery** (all `Vehicle.photos[]` uploaded by company)
|
||||
@@ -97,7 +97,7 @@ Sections:
|
||||
- Availability calendar (shows blocked dates — unavailable for booking)
|
||||
- Company info sidebar: logo, name, rating, phone, WhatsApp
|
||||
- **BIG CTA: "Book at [Company Name] →"**
|
||||
- Redirects to: `{slug}.rentflow.com/book?vehicleId=[id]&from=[startDate]&to=[endDate]&ref=marketplace`
|
||||
- Redirects to: `{slug}.RentalDriveGo.com/book?vehicleId=[id]&from=[startDate]&to=[endDate]&ref=marketplace`
|
||||
- Opens in same tab
|
||||
|
||||
### No `/explore/[slug]/book` page
|
||||
@@ -127,7 +127,7 @@ Standard auth pages. Login with Google optional.
|
||||
|
||||
---
|
||||
|
||||
## LAYER 2 — Company Dashboard (app.rentflow.com)
|
||||
## LAYER 2 — Company Dashboard (app.RentalDriveGo.com)
|
||||
|
||||
### Auth
|
||||
|
||||
@@ -145,7 +145,7 @@ Standard auth pages. Login with Google optional.
|
||||
1. Company profile (address, phone)
|
||||
2. Branding (logo, color, subdomain)
|
||||
3. **Add first vehicle + upload photos** — emphasize: "Photos appear on the global marketplace"
|
||||
4. Launch: "Your site is live at [slug].rentflow.com" + "Your vehicles are now visible on rentflow.com/explore"
|
||||
4. Launch: "Your site is live at [slug].RentalDriveGo.com" + "Your vehicles are now visible on RentalDriveGo.com/explore"
|
||||
|
||||
### Dashboard Pages
|
||||
|
||||
@@ -192,7 +192,7 @@ Standard auth pages. Login with Google optional.
|
||||
|
||||
---
|
||||
|
||||
## LAYER 3 — Company Public Site ({slug}.rentflow.com)
|
||||
## LAYER 3 — Company Public Site ({slug}.RentalDriveGo.com)
|
||||
|
||||
> All booking and payment happens here. Company's brand. Company's AmanPay/PayPal.
|
||||
|
||||
@@ -201,7 +201,7 @@ Standard auth pages. Login with Google optional.
|
||||
- Hero: tagline + hero image + "Browse Our Vehicles" CTA
|
||||
- **Active Offers section** — offer banners with countdown (valid until X days)
|
||||
- Vehicle grid (all published vehicles with photos)
|
||||
- Footer: contact + social + "Powered by RentFlow" (Pro removes)
|
||||
- Footer: contact + social + "Powered by RentalDriveGo" (Pro removes)
|
||||
|
||||
### `/vehicles/[id]` — Vehicle Detail
|
||||
- Photo gallery (all company-uploaded photos, full lightbox)
|
||||
@@ -228,7 +228,7 @@ When `ref=marketplace` is present, the reservation is tagged as source=MARKETPLA
|
||||
**Step 2 — Your Details**
|
||||
- First name, last name, email, phone (required)
|
||||
- Driver license (optional, company-configurable)
|
||||
- Renter account login prompt (optional — "Save this booking to your RentFlow account")
|
||||
- Renter account login prompt (optional — "Save this booking to your RentalDriveGo account")
|
||||
|
||||
**Step 3 — Payment**
|
||||
- Order summary card
|
||||
@@ -255,9 +255,9 @@ When `ref=marketplace` is present, the reservation is tagged as source=MARKETPLA
|
||||
|
||||
---
|
||||
|
||||
## Admin Panel (admin.rentflow.com — internal)
|
||||
## Admin Panel (admin.RentalDriveGo.com — internal)
|
||||
|
||||
> Separate app from the company dashboard. Own auth (JWT + TOTP 2FA). Only RentFlow staff.
|
||||
> Separate app from the company dashboard. Own auth (JWT + TOTP 2FA). Only RentalDriveGo staff.
|
||||
|
||||
### Auth
|
||||
- `/admin/login` — email + password + optional 2FA code field (shown if 2FA enabled)
|
||||
|
||||
+10
-10
@@ -6,10 +6,10 @@
|
||||
- A fully private dashboard (zero data overlap with any other company)
|
||||
- Fleet management with vehicle photo upload (photos auto-appear on global marketplace)
|
||||
- Promotional offers management
|
||||
- A white-label site at `company.rentflow.com` where renters book and pay
|
||||
- A white-label site at `company.RentalDriveGo.com` where renters book and pay
|
||||
|
||||
**Renters (B2C)** — free account, can:
|
||||
- Browse ALL companies' vehicles and offers on `rentflow.com/explore`
|
||||
- Browse ALL companies' vehicles and offers on `RentalDriveGo.com/explore`
|
||||
- Click a vehicle → **redirected to the company's site** to book and pay
|
||||
- Receive full notifications (Email + SMS + WhatsApp + Push + In-App)
|
||||
- Track all bookings across companies in one account
|
||||
@@ -24,14 +24,14 @@
|
||||
| **PayPal** | Secondary. Global coverage. |
|
||||
|
||||
**Two payment contexts:**
|
||||
1. Company pays RentalDriveGosubscription → RentFlow's own AmanPay/PayPal account
|
||||
1. Company pays RentalDriveGosubscription → RentalDriveGo's own AmanPay/PayPal account
|
||||
2. Renter pays company for rental → Company's own AmanPay merchant + PayPal account (direct, no intermediary)
|
||||
|
||||
---
|
||||
|
||||
## 🌐 Marketplace is Discovery Only — No Booking on rentflow.com/explore
|
||||
## 🌐 Marketplace is Discovery Only — No Booking on RentalDriveGo.com/explore
|
||||
|
||||
The global marketplace shows all vehicles with photos from all companies. When a renter clicks "Book this vehicle", they are **redirected to the company's branded site** (`{slug}.rentflow.com/book?vehicleId=X&from=Y&to=Z&ref=marketplace`). The booking form is pre-filled. All payment happens on the company site using the company's own payment accounts.
|
||||
The global marketplace shows all vehicles with photos from all companies. When a renter clicks "Book this vehicle", they are **redirected to the company's branded site** (`{slug}.RentalDriveGo.com/book?vehicleId=X&from=Y&to=Z&ref=marketplace`). The booking form is pre-filled. All payment happens on the company site using the company's own payment accounts.
|
||||
|
||||
---
|
||||
|
||||
@@ -51,11 +51,11 @@ Company uploads photos in /dashboard/fleet
|
||||
## 🏗 Five-Layer Architecture
|
||||
|
||||
```
|
||||
Layer 1A: rentflow.com — B2B marketing site
|
||||
Layer 1B: rentflow.com/explore — B2C marketplace (discovery + redirect only)
|
||||
Layer 2: app.rentflow.com — Company dashboard (private, subscription-gated)
|
||||
Layer 3: {slug}.rentflow.com — Company branded site (booking + payment here)
|
||||
Layer 4: api.rentflow.com — REST API
|
||||
Layer 1A: RentalDriveGo.com — B2B marketing site
|
||||
Layer 1B: RentalDriveGo.com/explore — B2C marketplace (discovery + redirect only)
|
||||
Layer 2: app.RentalDriveGo.com — Company dashboard (private, subscription-gated)
|
||||
Layer 3: {slug}.RentalDriveGo.com — Company branded site (booking + payment here)
|
||||
Layer 4: api.RentalDriveGo.com — REST API
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
---
|
||||
name: rental-car-advanced-features
|
||||
description: Build advanced rental operations features for RentFlow. Use this skill when the user asks about: vehicle damage diagrams/inspection (contract car layout), insurance policies and charges, second driver (additional driver) with optional charge, driver license validation (expiry check, 3-month rule, flagging), age-based pricing rules (25+ discount, license+5 surcharge), gasoline/fuel policies (FULL_TO_FULL etc.), billing period reporting (weekly/monthly/yearly export for accountants), or the platform admin panel (managing tenants, staff, roles, permissions). This skill works alongside document-service.md and schema.md.
|
||||
description: Build advanced rental operations features for RentalDriveGo. Use this skill when the user asks about: vehicle damage diagrams/inspection (contract car layout), insurance policies and charges, second driver (additional driver) with optional charge, driver license validation (expiry check, 3-month rule, flagging), age-based pricing rules (25+ discount, license+5 surcharge), gasoline/fuel policies (FULL_TO_FULL etc.), billing period reporting (weekly/monthly/yearly export for accountants), or the platform admin panel (managing tenants, staff, roles, permissions). This skill works alongside document-service.md and schema.md.
|
||||
---
|
||||
|
||||
# Skill: RentFlow Advanced Features
|
||||
# Skill: RentalDriveGo Advanced Features
|
||||
|
||||
## Features Covered
|
||||
|
||||
@@ -1074,7 +1074,7 @@ Located at `/dashboard/reports` (new page).
|
||||
|
||||
## 8. Platform Admin Panel
|
||||
|
||||
The platform administrator (RentFlow team) manages all companies and their staff.
|
||||
The platform administrator (RentalDriveGo team) manages all companies and their staff.
|
||||
|
||||
### Admin model
|
||||
|
||||
@@ -1124,8 +1124,8 @@ model AdminAuditLog {
|
||||
### Admin API routes
|
||||
|
||||
```
|
||||
Base: https://admin.rentflow.com/api/v1/ (separate app)
|
||||
OR: https://api.rentflow.com/api/v1/admin/ (preferred — same API, admin middleware)
|
||||
Base: https://admin.RentalDriveGo.com/api/v1/ (separate app)
|
||||
OR: https://api.RentalDriveGo.com/api/v1/admin/ (preferred — same API, admin middleware)
|
||||
|
||||
Middleware: requireAdminAuth → attaches req.admin (AdminUser)
|
||||
```
|
||||
@@ -1168,7 +1168,7 @@ Admins can impersonate any company employee for support purposes:
|
||||
// Returns a short-lived JWT that grants dashboard access as the company OWNER
|
||||
// Duration: 30 minutes max
|
||||
// All actions logged in AdminAuditLog
|
||||
// Dashboard shows "⚠️ Impersonation Mode — RentFlow Admin" banner
|
||||
// Dashboard shows "⚠️ Impersonation Mode — RentalDriveGo Admin" banner
|
||||
|
||||
async function impersonateCompany(req, res) {
|
||||
const company = await prisma.company.findUniqueOrThrow({
|
||||
@@ -1197,7 +1197,7 @@ async function impersonateCompany(req, res) {
|
||||
}
|
||||
```
|
||||
|
||||
### Admin UI (admin.rentflow.com)
|
||||
### Admin UI (admin.RentalDriveGo.com)
|
||||
|
||||
Separate Next.js app with its own auth (email + password, NO Clerk).
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# API Routes Inventory — RentFlow (Complete)
|
||||
# API Routes Inventory — RentalDriveGo (Complete)
|
||||
|
||||
Base URL: `https://api.rentflow.com/api/v1`
|
||||
Base URL: `https://api.RentalDriveGo.com/api/v1`
|
||||
|
||||
## Middleware Legend
|
||||
- 🔒 `requireCompanyAuth` — valid Clerk JWT (Employee)
|
||||
@@ -8,7 +8,7 @@ Base URL: `https://api.rentflow.com/api/v1`
|
||||
- 💳 `requireSubscription` — blocks SUSPENDED/PENDING companies
|
||||
- 🎫 `requireRenterAuth` — valid Renter JWT
|
||||
- 🔑 `requireApiKey` — company public API key in `x-api-key` header
|
||||
- 👑 `requireAdmin` — RentFlow super-admin role
|
||||
- 👑 `requireAdmin` — RentalDriveGo super-admin role
|
||||
|
||||
> **Tenant isolation rule:** Every 🏢 route must use `where: { companyId: req.companyId }` in every query.
|
||||
|
||||
@@ -41,7 +41,7 @@ Base URL: `https://api.rentflow.com/api/v1`
|
||||
|
||||
---
|
||||
|
||||
## Subscriptions (AmanPay/PayPal subscription — RentFlow collects)
|
||||
## Subscriptions (AmanPay/PayPal subscription — RentalDriveGo collects)
|
||||
|
||||
| Method | Path | Auth | Description |
|
||||
|--------|------|------|-------------|
|
||||
@@ -233,7 +233,7 @@ Base URL: `https://api.rentflow.com/api/v1`
|
||||
|
||||
## Company Public Site API (slug-resolved, no user auth)
|
||||
|
||||
> Used by SSR pages on `{slug}.rentflow.com`. Never subscription-gated.
|
||||
> Used by SSR pages on `{slug}.RentalDriveGo.com`. Never subscription-gated.
|
||||
|
||||
| Method | Path | Auth | Description |
|
||||
|--------|------|------|-------------|
|
||||
@@ -249,7 +249,7 @@ Base URL: `https://api.rentflow.com/api/v1`
|
||||
|
||||
---
|
||||
|
||||
## Admin (RentFlow internal)
|
||||
## Admin (RentalDriveGo internal)
|
||||
|
||||
| Method | Path | Auth | Description |
|
||||
|--------|------|------|-------------|
|
||||
@@ -349,7 +349,7 @@ Base URL: `https://api.rentflow.com/api/v1`
|
||||
|
||||
---
|
||||
|
||||
## Admin Panel Routes (admin.rentflow.com → api.rentflow.com/admin)
|
||||
## Admin Panel Routes (admin.RentalDriveGo.com → api.RentalDriveGo.com/admin)
|
||||
|
||||
> All require admin JWT. Role hierarchy: VIEWER < FINANCE < SUPPORT < ADMIN < SUPER_ADMIN
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.1 MiB |
@@ -1,4 +1,4 @@
|
||||
# Prisma Schema — RentFlow (Complete)
|
||||
# Prisma Schema — RentalDriveGo (Complete)
|
||||
|
||||
> Stripe has been removed. Payments use AmanPay and PayPal.
|
||||
|
||||
@@ -25,7 +25,7 @@ model Company {
|
||||
address Json?
|
||||
status CompanyStatus @default(PENDING)
|
||||
|
||||
// RentFlow billing — company pays subscription via AmanPay or PayPal
|
||||
// RentalDriveGo billing — company pays subscription via AmanPay or PayPal
|
||||
// No third-party customer ID needed — we manage payment references ourselves
|
||||
subscriptionPaymentRef String? // last AmanPay/PayPal transaction ref
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ export interface InvitePayload {
|
||||
role: 'MANAGER' | 'AGENT'
|
||||
}
|
||||
|
||||
const API_BASE = process.env.NEXT_PUBLIC_API_URL ?? 'https://api.rentflow.com/api/v1'
|
||||
const API_BASE = process.env.NEXT_PUBLIC_API_URL ?? 'https://api.RentalDriveGo.com/api/v1'
|
||||
|
||||
async function apiFetch<T>(
|
||||
path: string,
|
||||
|
||||
Reference in New Issue
Block a user