# SP Auto — AI-Powered Vehicle Marketplace SaaS

SP Auto is a multi-tenant SaaS platform for Indonesian car and motorcycle dealers. Each dealer gets their own public storefront at `{slug}.sp-auto.ai`, an AI listing generator, and a full management dashboard — all from a single codebase.

**Core value prop:** From photo + voice to a professional vehicle listing in under 3 minutes.

---

## Features

- **Multi-tenant subdomains** — each dealer gets `{slug}.sp-auto.ai` with full data isolation
- **AI Listing Generator** — text or voice input → structured listing via self-hosted Ollama (Llama 3.2) or Anthropic Claude
- **Vehicle Listing Management** — full CRUD with photo upload, watermarking, and media management
- **Public Storefront** — Blade-rendered, SEO-friendly public website per tenant with WhatsApp CTA
- **Theme System** — 3-step customization wizard (template → theme → color)
- **Analytics Dashboard** — inventory, sales performance, and AI usage metrics
- **Subscription & Billing** — plan management via Midtrans payment gateway
- **Google OAuth** — social login alongside email/password auth
- **Admin Panel** — platform-level tenant, theme, and template management

---

## Tech Stack

| Layer | Technology |
|---|---|
| Backend | Laravel 12, PHP 8.2 |
| Frontend (Dashboard) | Inertia.js + React 18 + TypeScript |
| Frontend (Public) | Blade (SEO-friendly, server-rendered) |
| Styling | Tailwind CSS v3 |
| AI (default) | Ollama — self-hosted Llama 3.2 |
| AI (optional) | Anthropic Claude (via `AI_DRIVER=anthropic`) |
| Database | SQLite (dev) / PostgreSQL (production) |
| File Storage | Cloudflare R2 (S3-compatible) |
| Payments | Midtrans |
| Auth | Laravel Sanctum + Laravel Socialite (Google) |
| Queue | Database queue driver |
| Rich Text | Tiptap editor |
| Charts | Recharts |
| PDF | barryvdh/laravel-dompdf |

---

## Requirements

- PHP 8.2+
- Node.js 20+ (see `.nvmrc`)
- Composer 2
- SQLite (dev) or PostgreSQL (production)
- [Ollama](https://ollama.ai) running locally with `llama3.2` pulled (for AI features)

---

## Local Setup

```bash
# 1. Clone and enter the app directory
git clone <repo-url>
cd app

# 2. Run the setup script (installs deps, generates key, runs migrations, builds assets)
composer setup

# 3. Copy and configure environment
cp .env.example .env
# Edit .env — at minimum set APP_KEY (done by setup), DB config, and OLLAMA_BASE_URL
```

### Start the dev server

```bash
composer dev
```

This runs four processes concurrently:
- `php artisan serve` — Laravel app
- `php artisan queue:listen` — background job worker
- `php artisan pail` — log viewer
- `npm run dev` — Vite HMR

---

## Key Environment Variables

```dotenv
# App
APP_URL=http://localhost
AGGREGATOR_DOMAIN=sp-auto.ai       # root domain for tenant subdomains
APP_DOMAIN=app.sp-auto.ai          # dashboard domain

# AI — choose driver
AI_DRIVER=ollama                   # or: anthropic
OLLAMA_BASE_URL=http://localhost:11434
OLLAMA_MODEL=llama3.2

# Anthropic (only needed if AI_DRIVER=anthropic)
ANTHROPIC_API_KEY=
ANTHROPIC_MODEL=claude-sonnet-4-6

# Storage (Cloudflare R2)
FILESYSTEM_DISK=r2
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_BUCKET=
AWS_ENDPOINT=

# Payments
MIDTRANS_SERVER_KEY=
MIDTRANS_CLIENT_KEY=
MIDTRANS_IS_PRODUCTION=false

# Google OAuth
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
GOOGLE_REDIRECT_URI=http://localhost/auth/google/callback
```

---

## Docker

A multi-stage Dockerfile is included for production builds (Node → Composer → PHP-FPM + Nginx + Supervisor).

```bash
docker build -t sp-auto .
docker run -p 80:80 --env-file .env sp-auto
```

Runtime config files live in `docker/`:
- `nginx.conf`
- `supervisord.conf`
- `php.ini`
- `entrypoint.sh`

---

## Running Tests

```bash
composer test
```

---

## Project Structure

```
app/
├── app/
│   ├── Console/Commands/     # Artisan commands
│   ├── Enums/                # PlanType, SubscriptionStatus
│   ├── Http/
│   │   ├── Controllers/
│   │   │   ├── Admin/        # Platform admin
│   │   │   ├── Aggregator/   # Public marketplace
│   │   │   ├── Auth/         # Login, register, Google OAuth
│   │   │   ├── Marketing/    # Landing pages
│   │   │   ├── Public/       # Tenant public storefront
│   │   │   └── Tenant/       # Dealer dashboard
│   │   ├── Middleware/       # Tenant resolution, plan limits, role checks
│   │   └── Resources/        # API resources (listings, themes, AI reports)
│   ├── Jobs/                 # Queue jobs (AI generation, billing, onboarding emails)
│   ├── Mail/                 # Transactional emails
│   └── Models/               # Eloquent models
├── resources/
│   ├── js/                   # React + TypeScript (Inertia dashboard)
│   └── views/                # Blade templates (public storefront + emails)
├── routes/                   # web.php, api.php, console.php
├── database/
│   ├── migrations/
│   └── seeders/
└── docker/                   # Production runtime config
```

---

## Multi-Tenant Architecture

Tenancy is handled via subdomain routing with `tenant_id` scoping on all dealer data — no separate databases per tenant. The middleware stack resolves the tenant from the subdomain on every request.

- `ResolveTenant` — resolves tenant from subdomain on public routes
- `ResolveTenantFromUser` — resolves tenant from authenticated user on dashboard routes
- `EnsureTenantActive` — blocks access if subscription is inactive
- `EnforcePlanLimits` — enforces listing/feature limits per plan

---

## AI Listing Generator

The AI generator accepts text or voice input and produces a structured vehicle listing. It is driver-based — swap between Ollama (self-hosted, no cost) and Anthropic Claude via `AI_DRIVER` in `.env`. All AI requests are logged to `ai_requests` for usage tracking and cost attribution.

---

## License

Private — all rights reserved.
# Webhook Test 1780315384
