fixing platform admin

This commit is contained in:
root
2026-05-06 22:58:23 -04:00
parent 695a7f7cc7
commit 750ae56a29
175 changed files with 31249 additions and 328 deletions
+7 -7
View File
@@ -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
+4 -4
View File
@@ -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
View File
@@ -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
View File
@@ -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
```
---
+7 -7
View File
@@ -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).
+7 -7
View File
@@ -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

+2 -2
View File
@@ -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
+1 -1
View File
@@ -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,