Enterprise SaaS Starter
May 12, 2026 Β· View on GitHub
A production-ready fullstack boilerplate for building SaaS applications β Java 21 + Spring Boot 3.4.1 backend, Angular 21 frontend, MSSQL database, fully containerized with Docker Compose. Clone, configure, and ship.
π Full Features & Live Demo: zukovlabs.com
β Found this useful? Drop a star β it helps other Java developers find this project.
See the PRO Version in Action (2-minute Demo)
βΆ Click to watch the full walkthrough on YouTube
Table of Contents
- Upgrade to PRO
- Free vs. PRO Comparison
- Overview
- Tech Stack
- Prerequisites
- Getting Started
- Environment Variables
- Database & Migrations
- API Reference
- Project Structure
- License
β‘ Upgrade to PRO
Skip 200+ hours of engineering work.
The Community Edition gives you a solid foundation. The PRO version ships everything you need to launch a real, monetized SaaS product β without building it from scratch.
What you get with PRO that you cannot build in a weekend:
| Area | What PRO Delivers |
|---|---|
| Payments | Full Stripe integration: Checkout Sessions, Webhook handling with signature verification, Billing Portal, and automatic post-payment login via Magic Link |
| Passwordless Auth | Magic Link (one-time email links, 15-min TTL) β a proven conversion booster for SaaS onboarding |
| Email Service | Thymeleaf HTML email templates: welcome, magic link, payment success β production-ready and styled |
| Security | IP-based sliding-window rate limiter on all auth endpoints β brute-force and flood protection |
| Data Layer | Server-side pagination (Spring Pageable + MatPaginator) β Community Edition loads all rows client-side; PRO paginates at the database level for scale |
| Access Control | Strict RBAC with three roles (ADMIN / MANAGER / USER) enforced via @PreAuthorize at the method level |
| Multi-Tenancy | Entity ownership enforcement β users can only see and delete their own records. 403 FORBIDDEN if violated |
| Signal Caching | Angular signal<T> cache in services β two components, one HTTP request |
| Test Suite | 13 test files, 88 cases: Mockito strict stubs, ArgumentCaptor assertions, Vitest frontend tests, real ObjectMapper for Stripe JSON fallback path |
The math is simple:
- Payments: Stripe integration (webhooks, billing portal, edge cases): ~40 hours
- Auth & Comms: Magic Link logic, Email Service, Thymeleaf templates: ~40 hours
- Security & Core: Rate limiting, strict RBAC, data ownership (403): ~40 hours
- Frontend UX: Dashboard charts, Server-side pagination, Signal Cache: ~40 hours
- Quality Assurance: 88 strict test cases, Mockito, Vitest: ~40 hours
- Total: 200+ hours of deep engineering β or one license purchase.
π Get PRO Version β β¬149 one-time β
Free vs. PRO Comparison
| Feature | Community (Free) | PRO |
|---|---|---|
| Java 21 + Spring Boot 3.4.1 | β | β |
| Angular 21 Standalone Components | β | β |
| MSSQL 2022 + Flyway Migrations | β | β |
| Multi-stage Docker Builds | β | β |
| Nginx SPA Hosting + Security Headers | β | β |
| MSSQL Healthcheck (no startup race) | β | β |
| JWT Auth (Access + Refresh Tokens) | β Basic | β Enhanced |
| Refresh Token Rotation | β | β |
| BCrypt Password Hashing | β | β |
| User Profile Management | β | β |
| Basic Customer CRUD | β | β |
| Dashboard Stats API | β | β |
| Angular Material UI | β | β |
| 401 Race Condition Protection (Interceptor) | β | β |
Auth Guard (JWT exp validation + redirect) | β | β |
| β | β | β |
| Stripe Checkout + Webhook Handling | β | β |
| Stripe Billing Portal (self-service) | β | β |
| Magic Link (Passwordless Auth) | β | β |
| Post-Payment Auto-Login via Magic Link | β | β |
| Email Service (Thymeleaf HTML templates) | β | β |
| IP Rate Limiting (brute-force protection) | β | β |
Server-Side Pagination (Spring Pageable backend + MatPaginator) | β | β |
| Strict RBAC (ADMIN / MANAGER / USER) | β | β |
| Entity Ownership Enforcement (403) | β | β |
| Signal Cache (no duplicate HTTP calls) | β | β |
| Dashboard Charts (Chart.js) | β | β |
| 13 Test Files / 88 Test Cases | β | β |
| Mockito Strict Stubs + ArgumentCaptor | β | β |
| Vitest Frontend Test Suite | β | β |
| Fail-Fast JWT Secret Validation | β | β |
| Commercial Use License | β MIT | β Commercial |
π Upgrade to PRO β
Overview
The Community Edition is a clean, runnable fullstack starting point β no toy demo, no half-implemented code. It ships with:
- Stateless JWT authentication with access and refresh token rotation
- Basic Customer CRM β create, list, and delete customer records
- User profile management β update name and change password
- Dashboard stats endpoint β aggregate data from the backend
- One-command Docker deploy β
docker compose up -d --buildstarts the entire stack - Nginx-served Angular SPA with
/api/*proxy to the Spring Boot backend, gzip compression, and security headers - It compiles successfully, passes standard health checks, and provides a secure starting point.
Architecture
ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Docker Compose β
β β
β ββββββββββββ βββββββββββββββββ βββββββββββ β
β β MSSQL βββββΆβ Spring Boot ββββββ Nginx β β
β β :1433 β β :8080 β β :8081 β β
β ββββββββββββ βββββββββββββββββ ββββββ¬βββββ β
β healthcheck Flyway migrations β β
β passes first on startup Angular SPA β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β²
Browser Client
Request flow:
Request β JwtAuthenticationFilter β SecurityConfig rules β Controller β Service β Repository
Tech Stack
| Component | Technology | Version |
|---|---|---|
| Language | Java | 21 LTS |
| Framework | Spring Boot | 3.4.1 |
| Security | Spring Security | 6.x |
| ORM | Hibernate / JPA | β |
| JWT | JJWT | 0.12.3 (HS512) |
| Migrations | Flyway | β |
| Build Tool | Maven | 3.9.6 |
| Frontend | Angular | 21 (Standalone) |
| UI Library | Angular Material | 21 |
| Reactive | RxJS | 7.8 |
| Database | MSSQL Server | 2022 |
| Containerization | Docker + Compose | β |
| Web Server | Nginx | Alpine |
Prerequisites
Install these before you start:
| Tool | Purpose | Min Version |
|---|---|---|
| Docker Desktop | Run the full stack | Latest |
| Java 21 JDK | Local backend development | 21 LTS |
| Node.js | Local frontend development | 20+ |
Getting Started
1. Clone the Repository
git clone https://github.com/zukovlabs/enterprise-java-saas-starter-kit.git
cd enterprise-java-saas-starter-kit
2. Configure Environment Variables
Copy the example file and set your values:
copy .env.example .env
Open .env and set at minimum:
JWT_SECRET=your-256-bit-hex-secret-here
DB_PASSWORD=YourStrongPassword1!
CORS_ALLOWED_ORIGINS=http://localhost:8081
Generate a strong JWT secret:
openssl rand -hex 32
3. Start the Stack
docker compose up -d --build
Docker Compose will:
- Start the MSSQL container and wait for the healthcheck to pass
- Start the Spring Boot backend β Flyway migrations run automatically on startup
- Start the Angular frontend served via Nginx
4. Open the Application
| Service | URL |
|---|---|
| Frontend | http://localhost:8081 |
| Backend API | http://localhost:8080 |
| Database | localhost:1433 |
5. Log In with the Demo Accounts
Flyway seeds two accounts on first startup:
| Password | Role | |
|---|---|---|
admin@saaskit.com | Admin1234! | ADMIN |
user@saaskit.com | User1234! | USER |
6. Useful Commands
# Watch backend logs
docker compose logs -f backend
# Stop the stack
docker compose down
# Stop and remove volumes (fresh DB)
docker compose down -v
# Rebuild a single service
docker compose up -d --build backend
7. Local Development (Optional)
If you want to edit the code with full IDE support (IntelliSense, types), you should install the dependencies locally on your host machine:
Frontend:
cd frontend
npm install
npm start # runs Angular dev server on http://localhost:4200
Environment Variables
All variables are sourced from the .env file (see .env.example for a full template with comments).
| Variable | Required | Default | Description |
|---|---|---|---|
APP_URL | β | http://localhost:8081 | Base URL of the application |
JWT_SECRET | β | β | 256-bit hex string for HS512 signing |
JWT_EXPIRATION_MS | β | 86400000 (24h) | Access token TTL in milliseconds |
JWT_REFRESH_EXPIRATION_MS | β | 604800000 (7d) | Refresh token TTL in milliseconds |
DB_PASSWORD | β | StrongP@ssw0rd! | MSSQL SA account password |
CORS_ALLOWED_ORIGINS | β | http://localhost:4200,http://localhost:8081,http://localhost | Comma-separated allowed CORS origins |
Database & Migrations
Schema is managed by Flyway β migrations run automatically on every backend startup.
Migration files: src/main/resources/db/migration/
| File | Description |
|---|---|
V1__init_schema.sql | Creates users and customers tables. Seeds two demo accounts and sample customers. Refresh tokens are stateless JWTs β no database table required. |
Default development credentials:
| Field | Value |
|---|---|
| Host | localhost:1433 |
| User | sa |
| Password | StrongP@ssw0rd! (override via DB_PASSWORD) |
| Database | master |
Note: Demo accounts seeded by Flyway use
{noop}plain-text passwords for developer convenience. All passwords created via/api/auth/registerare BCrypt-encoded automatically.
API Reference
Authentication β /api/auth
| Method | Endpoint | Auth | Description |
|---|---|---|---|
POST | /api/auth/register | β | Register a new user |
POST | /api/auth/login | β | Login, returns accessToken + refreshToken |
POST | /api/auth/refresh | β | Rotate tokens using a valid refresh token |
Login response:
{
"token": "eyJ...",
"refreshToken": "eyJ..."
}
All subsequent requests must include:
Authorization: Bearer <token>
Users β /api/user
| Method | Endpoint | Auth | Description |
|---|---|---|---|
GET | /api/user/profile | β | Get the authenticated user's profile |
PUT | /api/user/profile | β | Update first name and last name |
PUT | /api/user/password | β | Change password (requires current password) |
Customers β /api/customers
| Method | Endpoint | Auth | Description |
|---|---|---|---|
GET | /api/customers | β | List all customers |
POST | /api/customers | β | Create a new customer |
DELETE | /api/customers/{id} | β | Delete a customer by ID |
Dashboard β /api/dashboard
| Method | Endpoint | Auth | Description |
|---|---|---|---|
GET | /api/dashboard/stats | β | Get aggregate stats (total and active customer counts) |
Project Structure
enterprise-saas-starter-core/
β
βββ src/main/java/com/saaskit/starter/
β βββ SaasApplication.java # Spring Boot entry point (@SpringBootApplication)
β βββ config/
β β βββ ApplicationConfig.java # Auth provider, password encoder, UserDetailsService
β β βββ SecurityConfig.java # Filter chain, CORS, public vs. protected endpoints
β β
β βββ controller/
β β βββ AuthController.java # /api/auth/** (register, login, refresh)
β β βββ CustomerController.java # /api/customers (list, create, delete β calls repository directly)
β β βββ DashboardController.java # /api/dashboard/stats (calls repository directly)
β β βββ UserController.java # /api/user/** (profile, password)
β β
β βββ service/
β β βββ AuthService.java # Registration, login, JWT refresh logic
β β βββ UserService.java # Profile & password management
β β
β βββ repository/
β β βββ UserRepository.java
β β βββ CustomerRepository.java
β β
β βββ model/
β β βββ User.java # User entity (email, password, role)
β β βββ Customer.java # Customer entity
β β
β βββ dto/ # Java Records β validated request/response DTOs
β β βββ LoginRequest.java
β β βββ RegisterRequest.java
β β βββ AuthResponse.java
β β βββ DashboardStats.java
β β βββ UpdateProfileRequest.java
β β βββ ChangePasswordRequest.java
β β
β βββ security/
β βββ JwtUtils.java # HS512 token generation, parsing, expiry check
β βββ JwtAuthenticationFilter.java# Extracts + validates JWT, sets SecurityContext
β
βββ src/main/resources/
β βββ application.yml # Full configuration (environment-variable driven)
β βββ db/migration/
β βββ V1__init_schema.sql # Schema creation + demo data seed
β
βββ src/test/java/ # Backend unit tests (JUnit 5 + Mockito)
β
βββ frontend/
β βββ src/app/
β β βββ pages/
β β β βββ landing/ # Public marketing / home page
β β β βββ login/ # Email + password login form
β β β βββ register/ # Registration form
β β β βββ dashboard/ # Stats overview page
β β β βββ customers/ # Customer list + create/delete
β β β β βββ customer-dialog/ # Add-customer dialog component
β β β βββ settings/ # Profile & password management
β β β
β β βββ services/
β β β βββ auth.service.ts # Login, register, refresh, logout
β β β βββ user.service.ts # Profile CRUD
β β β βββ customer.service.ts # Customer API calls
β β β βββ dashboard.service.ts # Stats API call
β β β
β β βββ components/
β β β βββ confirm-dialog/ # Reusable confirmation dialog
β β β
β β βββ layout/main-layout/ # App shell: sidebar + header
β β βββ models/ # TypeScript interfaces (customer, dashboard-stats)
β β βββ auth.guard.ts # Checks token presence in localStorage before route activation
β β βββ auth.interceptor.ts # Injects Bearer token + handles 401 with token refresh
β β
β βββ nginx.conf # SPA routing, /api reverse proxy, gzip, security headers
β βββ Dockerfile # Multi-stage: Node 20 β Nginx Alpine
β
βββ Dockerfile # Multi-stage: Maven 3.9.6 + JDK 21 β JRE 21 Alpine
βββ compose.yaml # DB (healthcheck) β Backend β Frontend
βββ .env.example # All variables with descriptions
βββ pom.xml # Maven dependencies
Want More? Upgrade to PRO
The Community Edition is intentionally minimal. The PRO version is what you actually ship to customers.
PRO adds:
- Stripe payments (Checkout, Webhooks, Billing Portal)
- Magic Link passwordless authentication
- HTML email service with Thymeleaf templates
- IP rate limiting on auth endpoints
- Server-side pagination (no full-table loads)
- Strict three-tier RBAC (
ADMIN/MANAGER/USER) - Entity ownership enforcement with
403responses - Angular Signal cache (zero duplicate HTTP calls)
- Dashboard charts with Chart.js
- 13 test files, 88 cases β Mockito strict stubs, Vitest frontend,
ArgumentCaptorassertions
π See full details at zukovlabs.com β
Contributing
Contributions, bug reports, and feature requests are welcome. Open an issue or submit a pull request.
Support & Questions
Have a question, found a bug, or need help?
- Technical issues: Please open a GitHub Issue
- Business or private inquiries: Drop me an email at support@zukovlabs.com
License
This project is licensed under the MIT License β free to use, modify, and distribute. See LICENSE for details.
Enterprise SaaS Starter PRO is a separate commercial product with its own license terms.
Built by ZukovLabs