Codebase Overview¶
Where code lives and what each repo does. For team onboarding and quick navigation.
Repository Structure¶
All repos are on git.karmann.tech/vpn/:
| Repo | ID | Language | Purpose |
|---|---|---|---|
back |
33 | Java (Spring Boot) | Backend API |
desktop-alpha |
59 | Rust | Desktop client (our fork) |
android |
— | Kotlin | Android app |
ios |
— | Swift | iOS app |
vpn-config-service |
55 | Python | VPN worker service |
audit-bot |
56 | Python | Telegram audit bot |
telegram-user-bot |
58 | Python | Telegram user bot |
firebase-remote-config |
— | Rust | Firebase Remote Config updater |
documentation |
60 | MkDocs | This wiki |
Desktop — critical rule
Our repo: desktop-alpha (project 59) — push all changes here.
Original: desktop (project 38) — NEVER touch.
Frontend repos are separate git projects (not submodules):
- frontend/ — main landing pages
- lk_front/ — personal account (LK), deployed at shiva-app.io/account
- payment-widget/ — payment widget
Each has its own .git, CI/CD, and GitLab project.
Backend API (back)¶
Stack: Spring Boot 3.2.12, Java 21, Maven
Key numbers: - 37 controllers (~159 endpoints) - 567 Java files across 57 packages - 112 service classes (~29,670 LOC) - 16 JPA entities, 24 enums - 95 Flyway migrations
Main dependencies: - MySQL 8 (JPA/Hibernate) - Redis (Lettuce) + Caffeine cache - Keycloak (OAuth2 Resource Server) - Stripe 24.7.0, SBP, Cypix, Apple IAP, Google Play, YooKassa, NowPayments - Firebase Admin SDK 9.2.0 - Micrometer (Prometheus metrics) - Sentry 6.29.0
Package structure:
com.karmavpn/
├── config/ Spring configuration
├── controller/ REST endpoints
├── service/ Business logic
├── repository/ JPA repositories
├── model/ Entities
├── dto/ Data Transfer Objects
├── security/ JWT, auth filters, Keycloak
└── integration/ External APIs (payments, Firebase)
CI/CD: Blue-green deploy on push to main. Rotates between vpn-back-blue:8080 and vpn-back-green:8081 on 10.99.87.249.
Health check:
Desktop Client (desktop-alpha)¶
Stack: Rust (edition 2021), Cargo, Tauri
Workspace modules:
desktop-alpha/
├── shiva-app/ Main application (9MB)
├── shiva-daemon/ Background daemon
├── shiva-api/ API client (failover logic)
├── shiva-routing/ Routing logic
├── shiva-tun/ TUN interface
├── shiva-fw/ Firewall integration
└── shiva-dns/ DNS handling
API failover (shiva-api/src/request_sender.rs): - Hardcoded endpoints → Firebase Remote Config → DNS TXT (apis2.shiwa.se) - Triggers on: SSL errors, timeouts, HTTP 502 - No persistence: starts from first endpoint on restart
Platforms: Windows, macOS, Linux
Android App¶
Stack: Kotlin, Gradle (minSdk 24, targetSdk 36, Java 21)
Architecture:
- DI: Hilt (Dagger)
- Navigation: AndroidX Navigation Component
- Async: Kotlin Coroutines
- Multi-module: :feature:domain, :feature:data, :feature:coreui
API failover: Cycles through 20 hardcoded URLs. Saves the last successful URL to SharedPreferences.
Key file: feature/data/src/main/java/app/shiva/data/Utils.kt — endpoint list
iOS App¶
Stack: Swift, Xcode
Components:
- Shiva/ — Main app
- ShivaPacketTunnelProvider/ — VPN tunnel provider
- HevSocks5Tunnel.xcframework — SOCKS5 tunnel
- LibXray.xcframework — XRAY VPN protocol
VPN Config Service (vpn-config-service)¶
Stack: Python (FastAPI + asyncio), deployed on 10.99.87.249:8000
Role: Worker that syncs server state from MySQL/XUI panels, builds VLESS configs, fills XUI panels with clients.
See VPN Config Service for full details.
Infrastructure (Internal VMs)¶
| IP | Server | Stack | Criticality |
|---|---|---|---|
| 10.99.87.249 | Backend PROD (vpn-app02) | Spring Boot (blue/green), Redis, VCS, Remnawave | Critical |
| 10.99.87.62 | MySQL PROD | MySQL 8 | Critical |
| 10.99.87.63 | Frontend (vpn-app01) | vpn-front, vpn-lk, landing pages | High |
| 10.99.87.64 | Admin Panel | Next.js | Medium |
| 10.99.87.5 | Monitoring | Grafana, Prometheus, Loki, Audit Bot | Medium |
| 10.99.87.60 | Dev Backend | Spring Boot | Low |
| 10.99.87.61 | MySQL Dev | MySQL 8 | Low |
| 10.99.87.55 | Sentry | Error tracking | Medium |
External entry point: 212.70.189.60 (km-proxy01, Riga, Latvia) — nginx reverse proxy for all client traffic.
External Services¶
| Service | Purpose | Criticality |
|---|---|---|
| Firebase | Remote Config, Push Notifications | High |
| Stripe | Global payments | High |
| SBP / YooKassa | Russian payments | High |
| Sentry (self-hosted) | Error tracking | Medium |
| GitLab (self-hosted) | CI/CD, git repos | High |
| XRAY | VPN protocol on servers | Critical |
Build Commands¶
Backend:
mvn clean package -DskipTests
docker build -f docker/Dockerfile -t vpn-back:latest .
# Deploy: push to main → CI/CD (manual trigger for prod)
Desktop:
Android:
iOS:
Key Config Locations¶
| What | Where |
|---|---|
| Backend prod config | src/main/resources/application-prod.properties |
| Backend CI/CD | .gitlab-ci.yml |
| Desktop API endpoints | shiva-api/src/api_credentials.rs |
| Android API endpoints | feature/data/src/main/java/app/shiva/data/Utils.kt |
| VCS worker config | vpn-config-service/app/config.py |
| All passwords | Vaultwarden |
Known Issues / Tech Debt¶
| Issue | Severity | Status |
|---|---|---|
| No automated MySQL backups | P0 | Script exists, cron needed |
| Auth sessions in Redis (fail-open mode) | P0 | Keycloak migration deferred |
| Single backend instance | P1 | Blue-green helps, no multi-region |
| Desktop: no endpoint persistence | P1 | Restarts from first endpoint |
| Signing password in Android build.gradle | P1 | Hardcoded in source (see Vaultwarden) |