单库多租户:tenant_id 加全局作用域隔离读写与路由模型绑定,跨租户访问返回 404
saas-starter-laravel — Vue SaaS模板
作者 kevinmakwana
基于 Laravel 与 Inertia + Vue 3 + TypeScript 的多租户 SaaS 启动模板,内置团队、角色、邀请、套餐限制、可切换的假支付网关与 Stripe 测试网关,以及审计日志。
看看你的网站会是什么样
浏览真实页面截图,比较内容排版与手机效果。点击下方缩略图切换,放大查看整页细节。
目前有 1 张原始预览,可打开完整图片查看设计细节。
截图用于了解视觉与布局,交互效果请以实际项目为准。
值得关注的模板亮点
从已有项目资料中,快速了解它的特点。
Owner、Admin、Member 三种角色,配合策略控制角色管理、计费、邀请与审计日志的访问
签名邀请链接 7 天过期、绑定受邀邮箱、单次使用,邮件经 Redis 队列发送
Free/Pro/Business 三档套餐,项目与成员限制在策略中强制执行,并提供升级提示
计费网关可切换:默认假网关无需付费密钥,配置 Stripe 测试密钥后启用 Stripe 网关
Stripe webhook 校验签名、按事件 ID 幂等去重,并在 webhooks 队列上处理
模板详细介绍
这是一个多租户 SaaS 启动模板,后端使用 Laravel,前端通过 Inertia 结合 Vue 3 与 TypeScript,样式基于 Tailwind。它把常见的 SaaS 基础能力预先搭好:注册登录、创建与切换团队、Owner/Admin/Member 三种角色与对应策略、签名且 7 天过期的单次邀请链接、Free/Pro/Business 三档套餐及项目与成员数量限制、功能开关(如审计日志仅 Business 可用),以及团队范围内的审计日志。
租户模型采用单库方案:租户拥有的数据表带 tenant_id,通过全局作用域隔离,当前租户即用户当前所属团队,成员关系会被重新校验,因此移除成员后其访问立即失效;路由模型绑定同样经过该作用域,访问其他租户的记录会返回 404。
计费默认使用假网关,无需付费密钥即可在本地运行;设置 BILLING_GATEWAY=stripe 并填入 Stripe 测试密钥后切换到 Stripe 网关。Stripe webhook 端点会校验签名、按事件 ID 去重并放入队列处理。README 明确说明 Stripe 路径尚未在真实 Stripe 环境验证过,假网关与 webhook 流程有测试覆盖。
本地运行依赖 Docker 与 make,一条命令启动应用、MySQL、Redis、Mailpit 和队列 worker,并执行迁移与种子数据;默认端口均绑定在 127.0.0.1。测试使用 Pest,代码风格用 Pint,静态分析用 Larastan(level 6),前端构建包含 vue-tsc 类型检查,CI 在每次推送和 PR 时运行这些检查。
适合你的项目吗?
适用场景
- 需要快速搭建带团队与角色体系的多租户 SaaS 后台骨架
- 希望在本地不接入真实支付的情况下演示订阅、换套餐与取消流程
- 需要验证租户数据隔离、邀请流程、套餐限制与 webhook 幂等性的实现方式
- 作为学习 Inertia + Vue 3 + TypeScript 与 Laravel 结合的项目参考
适合人群
- 熟悉 Laravel 与 Vue 的开发者或小团队
- 需要多租户、角色权限与订阅计费基础结构的 SaaS 项目
- 希望以 MIT 许可代码为基础进行二次开发的团队
上手与定制指南
结合仓库当前版本的说明,按下面的资料检查内容、配置与运行要求。
- 1
本地运行需要 Docker 与 make,执行 make up 会启动应用、MySQL 8、Redis、Mailpit 与队列 worker 并完成迁移和种子数据
- 2
演示账号:[email protected](Owner)、[email protected](Admin)、[email protected](Member),密码均为 password
- 3
默认端口冲突时可在 .env 中调整 APP_PORT、FORWARD_DB_PORT、FORWARD_REDIS_PORT、FORWARD_MAILPIT_PORT、FORWARD_MAILPIT_DASHBOARD_PORT、VITE_PORT
- 4
首次启动后若修改 DB_DATABASE 或 DB_USERNAME,需先执行 ./vendor/bin/sail down -v 让 MySQL 重新初始化
- 5
启用真实 Stripe 测试模式需设置 BILLING_GATEWAY=stripe 及 STRIPE_KEY、STRIPE_SECRET、STRIPE_WEBHOOK_SECRET、STRIPE_PRICE_PRO、STRIPE_PRICE_BUSINESS,并用 stripe listen 转发事件
授权与来源资料
使用条件与限制
免费使用 · 保留许可声明本次收录的是公开仓库中采用 MIT 许可的免费版本;免费范围为该版本代码,不代表外部服务或第三方素材免费。
使用时需要遵守
- 允许免费使用、修改、商用和分发该版本代码。
- 分发代码副本或实质性部分时,保留原作者版权声明和完整 MIT 许可声明。
- 代码按现状提供;担保与责任限制以原许可证及适用法律为准。
额外费用与待核对事项
- 演示图片、字体、图标及其他第三方素材需按各自许可核对,不能仅凭代码的 MIT 许可判断。
- 域名、托管、数据库、支付或 AI 等外部服务可能另外收费。
- 本地运行无需付费密钥,默认使用假支付网关;只有接入 Stripe 测试密钥时才切换到 Stripe 网关。
- 接入真实 Stripe 测试密钥属于可选项,不配置也能使用假网关运行。
- Stripe 支付路径未在真实 Stripe 环境验证过,仅假网关与 webhook 流程有测试覆盖,不能视为生产可用。
- 本地运行依赖 Docker 与 make 工具。
- 启用 Stripe 时需通过 stripe listen 将事件转发到本地 webhook 端点。
- 首次启动后若修改数据库名或用户名,需先执行 sail down -v 让 MySQL 重新初始化。
- 所有端口仅绑定到 127.0.0.1,默认不对外网开放。
- 审计日志功能仅 Business 套餐可用。
查看原文依据
Permission is hereby granted, free of charge
许可证原文
It runs locally with **zero paid keys**: billing uses a fake gateway unless you add Stripe test keys.
README 原文
### Using real Stripe test keys (optional)
README 原文
The Stripe path has not been exercised against live Stripe in this repo (see below); the fake gateway and the webhook pipeline are covered by tests.
README 原文
Requires Docker (and `make`).
README 原文
Forward events with `stripe listen --forward-to localhost:8080/webhooks/stripe`.
README 原文
If you change `DB_DATABASE` or `DB_USERNAME` after the first start, run `./vendor/bin/sail down -v` first so MySQL re-initialises.
README 原文
All ports bind to `127.0.0.1` only.
README 原文
https://github.com/kevinmakwana/saas-starter-laravel/blob/main/LICENSEhttps://github.com/kevinmakwana/saas-starter-laravel/blob/main/README.md`audit_log` is Business only.
README 原文
DeepSeek 根据仓库许可证和 README 整理 ·2026-10-11。结果仅覆盖已读取资料,依赖、图片、字体及后续条款变更以各自原文为准。
项目核对记录与介绍依据
模板资料
- 来源平台
- GitHub
- 资料与维护参考分
- 资料一般 · 73 / 100
- 技术栈
- Vue · Laravel
- 网站类型
- SaaS · 启动器
这个分数如何计算
本站按许可资料(最高30分)、演示链接(12分)、预览图(10分)、Star数(15分)、记录的维护时间(15分)、描述完整度(8分)、功能记录(5分)和分类资料(5分)计算。它不是代码、安全或性能测试,也不是 Google 评分;有链接不代表已实测可用。
这个项目需要核对什么
- 记录的仓库更新时间
- 2026-10-11
- 截图检查日期
- 2026-10-11
目前没有记录演示链接。请依据仓库说明在本地评估;仅凭截图无法确认交互行为。
目录记录的主要技术栈是 Vue。请通过依赖清单和锁文件核对实际版本与托管要求。这些说明基于收录资料,不代表代码审计或部署实测。
查看具体选型方法 →介绍的制作与核对状态
介绍由 AI 辅助整理目录与仓库资料。仓库作者不等于这篇介绍的审核者。
审核声明: [email protected] · 2026-10-11
查看当时使用的来源资料
SHA-256: a411332c2ef2293d3a4863c96dc41e607435f8a778ee773a7cc06526ad5a24d0
2026-10-11T13:27:34.601Z
来源文件 / 仓库# Acme SaaS Starter (Laravel) A multi-tenant SaaS starter built on Laravel 12, Inertia, Vue 3 and TypeScript. Teams, roles, signed invitations, plan limits, feature flags and an audit log work out of the box. It runs locally with **zero paid keys**: billing uses a fake gateway unless you add Stripe test keys. [](https://github.com/kevinmakwana/saas-starter-laravel/actions/workflows/ci.yml)  ## Quick start Requires Docker (and `make`). One command starts the app, MySQL 8, Redis, Mailpit and a queue worker, then migrates and seeds: ```bash make up ``` | What | Where | | --- | --- | | App | <http://localhost:8080> | | Mailpit (all outgoing mail) | <http://localhost:8025> | **Demo login:** `[email protected]` / `password` (owner of the *Acme Demo* team on the Business plan). Also seeded with the same password: `[email protected]` (Admin) and `[email protected]` (Member). Host ports are configurable in `.env` (`APP_PORT`, `FORWARD_DB_PORT`, `FORWARD_REDIS_PORT`, `FORWARD_MAILPIT_PORT`, `FORWARD_MAILPIT_DASHBOARD_PORT`, `VITE_PORT`) in case the defaults are busy. All ports bind to `127.0.0.1` only. If you change `DB_DATABASE` or `DB_USERNAME` after the first start, run `./vendor/bin/sail down -v` first so MySQL re-initialises. Other commands: `make dev` (Vite HMR), `make test`, `make fresh`, `make logs`, `make down`. ## How it fits together ```mermaid flowchart LR U[User] -->|current_team_id| T[(Team = tenant)] U -->|request| M[EnsureHasTeam middleware] M --> C[TenantContext] C -->|tenant id| S[TenantScope<br/>global scope] S --> P[(projects, tasks,<br/>audit_logs)] P -.->|route model binding<br/>goes through the scope| N[404 for other tenants] T -->|plan| L[PlanLimits + FeatureGate] L -->|402 upgrade prompt| UI[Billing page] UI -->|subscribe / change / cancel| G{BillingGateway} G -->|no Stripe keys| F[FakeGateway] G -->|Stripe test keys| ST[StripeGateway<br/>Cashier 16] ST -->|events| W[POST /webhooks/stripe] W -->|verify signature| I[(processed_webhook_events<br/>unique event id)] I -->|first delivery only| Q[[Redis queue: webhooks]] Q --> J[ProcessStripeWebhook] -->|sets plan| T ``` **Tenancy.** One database; tenant-owned tables carry `tenant_id`. The `BelongsToTenant` trait adds a global scope and refuses writes for any other tenant. The current tenant is the user's current team, and membership is re-checked, so removing someone from a team cuts access immediately. With no tenant the scope matches nothing. Route model binding goes through the same scope, so another tenant's record is a plain 404. ## Features - **Auth and teams:** register, log in, create teams, switch teams (Breeze, Inertia, Vue 3, TypeScript, Tailwind). - **Roles and policies:** Owner, Admin and Member. Owners manage roles, billing and ownership transfer. Admins invite members and see the audit log. - **Invitations:** signed, expiring links (7 days), bound to the invited email, single use. Emails are queued on Redis and show up in Mailpit. - **Billing:** Free, Pro and Business plans (limits and prices in `config/billing.php`). Subscribe, change plan, cancel and resume. `FakeGateway` by default, `StripeGateway` (Cashier 16) when `BILLING_GATEWAY=stripe` and Stripe test keys are set. - **Webhooks:** `POST /webhooks/stripe` verifies the signature, stores each event id once (idempotent) and processes it on the `webhooks` queue. - **Plan limits:** project and member limits enforced in policies, with a friendly upgrade prompt. - **Feature flags:** `FeatureGate` and a `feature:` route middleware. For example `audit_log` is Business only. - **Projects and tasks:** CRUD with search, status filter and pagination. - **Audit log:** team-scoped "who did what", visible to Owners and Admins on Business. ### Using real Stripe test keys (optional) ```dotenv BILLING_GATEWAY=stripe STRIPE_KEY=pk_test_... STRIPE_SECRET=sk_test_... STRIPE_WEBHOOK_SECRET=whsec_... STRIPE_PRICE_PRO=price_... STRIPE_PRICE_BUSINESS=price_... ``` Forward events with `stripe listen --forward-to localhost:8080/webhooks/stripe`. The Stripe path has not been exercised against live Stripe in this repo (see below); the fake gateway and the webhook pipeline are covered by tests. ## Testing and quality ```bash make test # Pest feature + unit tests (inside Sail) vendor/bin/pint --test # code style vendor/bin/phpstan analyse # Larastan, level 6 npm run build # vue-tsc type check + Vite build ``` Tests cover tenancy isolation (reads, writes, route model binding), role policies, the invitation flow, plan limits, webhook signature and idempotency, feature gates, and the seeder. CI (GitHub Actions) runs Pint, Larastan and Pest against a MySQL 8.4 service container on every push and pull request. ## What I'd do next in production - Add Stripe Checkout and Customer Portal coverage and test the `StripeGateway` against Stripe's test mode in CI. - Handle dunning: `invoice.payment_failed`, grace periods, and email notices to the owner. - Move large tenants to per-tenant database or schema isolation if needed, and add DB-level row security as a second line of defence. - Add rate limiting on invitations and auth, 2FA, and SSO for Business. - Make audit logs append-only and exportable, with retention rules. - Observability: structured logs, Sentry, queue and failed-job alerts, Horizon for Redis queues. - Add seat-based billing and proration instead of fixed per-plan limits. - Browser end-to-end tests (Playwright) for the main flows, and zero-downtime deploys with migration safety checks. ## License [MIT](LICENSE) © Kevin Makwana. "Acme" is a fictional brand used for demonstration.
看看同类模板
对比同技术栈与用途的模板,找到更适合的视觉与内容结构。

vitesse
🏕 Opinionated Vite + Vue Starter Template
Vue · 启动器

vitesse-webext
⚡️ WebExtension Vite Starter Template
Vue · 启动器

laravel-vue-spa
A Laravel-Vue SPA starter kit.
Vue · 启动器

vue3-h5-template
vue3-h5-template 是一个面向移动端 H5 项目的启动模板,基于 Vue3、Vite 和 Vant4 构建,同时集成了 TypeScript、Tailwindcss、Pinia、Vue-router 等常用…
Vue · 启动器

tov-template
vite + vue3 + ts 开箱即用现代开发模板 | vite + vue3 + ts out-of-the-box modern development template
Vue · 启动器

shadcn-vue-landing-page
New design 🎉 Vue + Shadcn-vue + TypeScript + Tailwind. Landing page template ease-to-use
Vue · 企业官网
