⚠️ Note on Environment Variables: All API keys, secrets, and environment variables (e.g., Cloudflare R2, Sandbox, Razorpay) visible indocker-compose.ymlor elsewhere have been permanently revoked and deleted from their providers. They are included in the repository safely and purely for demonstration, structural context, and local testing purposes.
This repository serves as a portfolio piece demonstrating production-grade, scalable Go microservices. It contains the backend API, protobuf contracts, and frontend integration docs for a comprehensive Loan Management System (LMS).
This project utilizes several advanced backend engineering patterns:
- Contract-First Design: Using gRPC and Protobufs creates a strict, language-agnostic API contract. This prevents breaking changes, enables auto-generated client stubs, and makes frontend integration predictable.
- High Performance & Efficiency: Go paired with gRPC (HTTP/2 + binary serialization) provides significantly lower latency and higher throughput compared to traditional REST/JSON APIs.
- Type-Safe Persistence: Using
sqlceliminates the overhead and "magic" of heavy ORMs. It guarantees type safety at compile-time and prevents SQL injections while maintaining the speed of raw SQL. Database schema and migrations are fully managed viagolang-migrate. - Robust Security Model: The implementation includes Role-Based Access Control (RBAC) via gRPC interceptors, Argon2 password hashing, JWT refresh rotation, and Time-based One-Time Password (TOTP) MFA, adhering to modern security standards.
- Scalability: The separation of state—using PostgreSQL for persistent relational data and Redis for ephemeral state (OTPs/sessions)—ensures the Go API layer remains completely stateless and horizontally scalable.
- Maintainability: The Clean Architecture approach ensures that business logic is decoupled from transport and database concerns, making the codebase highly testable and easy to navigate.
The backend is designed to provide a robust, scalable, and secure API for the LMS platform. It handles all core business logic including user authentication and session management, borrower onboarding, KYC processing, direct sales team (DST) management, loan product configurations, and media uploads. It serves as the single source of truth for the platform, ensuring data integrity across PostgreSQL and Redis.
The main runnable service is core-api (Go + gRPC).
lms-monorepo/
├── proto/ # Protobuf definitions for all gRPC APIs (See proto/README.md)
│ ├── admin/v1/admin.proto # Admin and employee management contract
│ ├── auth/v1/auth.proto # Auth and session contract
│ ├── branch/v1/branch.proto # Bank branch management contract
│ ├── chat/v1/chat.proto # Chat and messaging contract
│ ├── dst/v1/dst.proto # DST account retrieval contract
│ ├── kyc/v1/kyc.proto # Borrower KYC contract
│ ├── loan/v1/loan.proto # Loan service contract
│ ├── media/v1/media.proto # Media upload/list contract
│ ├── onboarding/v1/onboarding.proto # Borrower onboarding contract
│ ├── query/v1/query.proto # System queries and reporting
│ └── remark/v1/remark.proto # Remarks and notes contract
├── services/
│ └── core-api/ # Go backend main service (See services/core-api/README.md)
├── docker-compose.yml # Local infra + core-api
├── docs/ # Frontend integration docs
├── Makefile # Helper commands (proto, sqlc, docker)
└── go.work # Go workspace (currently includes core-api)
Frontend API docs are available in docs/README.md.
- Transport: gRPC using protobuf definitions from
proto/ - Services:
AuthService,AdminService,BranchService,ChatService,DstService,KycService,LoanService,MediaService,OnboardingService,QueryService,RemarkService - Backend: Go service in
services/core-api - Data layer:
- Postgres for users, profiles, refresh tokens, webauthn credentials, KYC history, media metadata
- Redis for OTP/MFA/session state
- Auth model:
- Password (Argon2)
- OTP verification for signup
- TOTP for MFA
- JWT access token + refresh token rotation
- WebAuthn scaffolding (partially implemented)
- Docker Desktop / Docker Engine with Compose v2
From repo root:
docker compose up --buildor:
make docker-upWhat starts:
postgresonlocalhost:15432redisonlocalhost:16379core-apigRPC server onlocalhost:18080
On first startup of the Postgres volume, schema is auto-loaded from:
services/core-api/internal/repository/schema/001_auth.sql
If you already have an existing Postgres Docker volume and need a clean re-init:
docker compose down -v
docker compose up --buildIf you want to run API directly on your host and keep infra in Docker:
- Start infra only (Postgres + Redis):
docker compose up -d postgres redis- Run backend:
cd services/core-api
POSTGRES_DSN="postgres://lms:lms@localhost:15432/lms?sslmode=disable" REDIS_ADDR="localhost:16379" go run .Default config (if env vars are not set) is defined in services/core-api/internal/config/config.go.
Useful env vars:
GRPC_PORT(default:8080)POSTGRES_DSN(default points to local postgres)REDIS_ADDR(default:localhost:6379)REDIS_PASSWORD(optional)JWT_SIGNING_KEY(default dev key; change for non-local use)
Generates gRPC/Go types into services/core-api/internal/transport/grpc/generated/*.
make protoGenerates typed query code into services/core-api/internal/repository/generated/.
make sqlcInputs:
- Schema:
services/core-api/internal/repository/schema/ - Queries:
services/core-api/internal/repository/queries/
Config file:
services/core-api/sqlc.yaml
cd services/core-api
go test ./...
go build ./...If you are new to this repo, read in this order:
- Contracts first (
proto/) - Server entrypoint + wiring
services/core-api/main.goservices/core-api/cmd/server/run.go
- Transport layer
services/core-api/internal/transport/grpc/auth_handler.goservices/core-api/internal/transport/grpc/interceptors/auth.go
- Business logic
services/core-api/internal/service/auth/service.go
- Persistence
services/core-api/internal/repository/queries/*.sqlservices/core-api/internal/repository/generated/*.go
- Infra/config utilities
services/core-api/internal/db/*.goservices/core-api/internal/config/config.go
Typical call path:
- gRPC method defined in proto
- Handler receives request (
auth_handler.go) - JWT/RBAC interceptors run (for protected methods)
- Auth service executes business logic (
service.go) - SQLC-generated repository methods read/write Postgres
- Redis stores short-lived auth state (OTP/MFA/active token)
auth.v1.AuthService- Signup:
InitiateSignup,VerifySignupOTPs - Login/MFA:
LoginPrimary,InitiateReopen,SelectLoginMFAFactor,VerifyLoginMFA - Account security:
SetupTOTP,VerifyTOTPSetup,GetMyProfile,ChangePassword, forgot-password flow, WebAuthn begin/finish methods - Session:
RefreshToken(returns precondition to use reopen flow),Logout
- Signup:
admin.v1.AdminService- Admin bootstrap, employee creation/update, branch management, DST creation/commission updates
branch.v1.BranchService- Bank branch management operations
chat.v1.ChatService- Messaging and chat operations
dst.v1.DstService- DST account retrieval for admin/manager views:
GetDstAccount,ListDstAccounts
- DST account retrieval for admin/manager views:
kyc.v1.KycService- Consent recording, Aadhaar OTP verify flow, PAN verification, borrower KYC status/history
loan.v1.LoanService- Loan product setup, application lifecycle, collateral/documents, bureau snapshots, loans, EMI schedule, and payments
media.v1.MediaService- Presigned upload init/complete and user media listing
onboarding.v1.OnboardingService- Borrower onboarding:
CompleteBorrowerOnboarding
- Borrower onboarding:
query.v1.QueryService- Reporting and read-only query operations
remark.v1.RemarkService- Comments and remarks management
failed to connect to postgres: verify Postgres is running and DSN is correct.failed to connect to redis: Redis is required at startup; checkREDIS_ADDRand container health.- Auth tables missing: if schema did not initialize, recreate Postgres volume (
docker compose down -v). - Generated code out of sync: rerun
make protoand/ormake sqlc.
From repo root:
make docker-up
make docker-down
make proto
make sqlc