# 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 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