A comprehensive architectural overview of the Bidancer Core Backend system, showcasing microservices design, domain-driven architecture, event-driven communication, and modern development practices.
ποΈ High-Level Architecture#
The Bidancer platform follows a microservices architecture pattern with clear separation of concerns and domain-driven design (DDD) principles. Our architecture is designed for scalability, maintainability, and independent service deployment.π Architecture Layers#
Our system is organized into five distinct layers, each with specific responsibilities:1οΈβ£ Client Layer#
π Web and mobile applications
π Consumes APIs through the gateway layer
π¨ Handles user interactions and presentation logic
2οΈβ£ Gateway Layer#
Nginx: HTTPS reverse proxy for local development with wildcard SSL
API Gateway/Proxy: Intelligent request routing to appropriate microservices
π Handles SSL termination, load balancing, and centralized request routing
3οΈβ£ Microservices Layer#
Independent, deployable services with specific business responsibilities:| Service | Responsibility |
|---|
| π Auth Service | User authentication, authorization, session management |
| π€ User Service | User profile management and user-related operations |
| π’ Business Service | Business entity creation, management, and validation |
| π Tender Service | Tender lifecycle management, bidding processes |
| π¬ Enquiry Service | Customer and business enquiry handling |
| π¦ Catalog Service | Product and service catalog management |
| π° Wallet Service | Digital wallet operations, balance management |
| π³ Billing Service | Payment processing, invoice generation |
| π Master Service | Master data and configuration management |
| π Activity Service | User activity tracking and analytics |
| β‘ Handler Service | Centralized event processing and workflow orchestration |
| π« NotFound Service | Handles 404 errors and routing fallbacks |
4οΈβ£ Data Layer#
Domain-driven database separation using Prisma ORM:| Database | Purpose | Services |
|---|
| π Authentication DB | User credentials, sessions, tokens | Auth, User |
| ποΈ Platform DB | Core business data | Business, Tender, Enquiry, Catalog, Activity |
| π Master DB | Configuration and master data | Master |
| π΅ Wallet DB | Financial transactions and balances | Wallet, Billing |
5οΈβ£ Shared Libraries Layer#
Reusable components across microservices:βοΈ Config: Centralized configuration management
π‘οΈ Middleware: Common middleware (auth, logging, error handling)
π¨ Events: Event definitions and pub/sub utilities
π§ Email: Email sending and templating
π KYC Kit: KYC verification utilities
π³ Payment Gateway: Payment provider integrations
π Telemetry: Observability, metrics, and tracing
π§ Utils: Common utility functions
ποΈ Database Architecture#
Domain-Driven Database Design#
Domain-Driven Database Design#
The system uses a domain-driven database design approach, with separate databases for each major domain to ensure:β
Data isolation: Reduces coupling between services
β
Independent scaling: Each domain can be scaled independently
β
Focused schema management: Easier to maintain and evolve schemas
β
Security boundaries: Better access control and data protection
π Database Domains#
π Authentication Domain#
Schema: prisma-authenticationπ₯ User accounts and credentials
π« Authentication tokens (JWT, refresh tokens)
π‘οΈ Two-factor authentication data
Services: Auth Service, User Service
ποΈ Platform Domain#
π’ Business entities and profiles
π Tender listings and bids
π¦ Product/service catalog
Services: Business, Tender, Enquiry, Catalog, Activity
π Master Data Domain#
βοΈ System configurations
π·οΈ Categories and taxonomies
π Geographic data (countries, states, cities)
π Industry classifications
π Static reference data
π΅ Wallet Domain#
π° Wallet accounts and balances
Services: Wallet Service, Billing Service
π‘ Event-Driven Communication#
The system implements an event-driven architecture using Google Cloud Pub/Sub for asynchronous communication between microservices, enabling loose coupling and better scalability.π¨ Event Types#
π€ User Events#
βοΈ User profile updated
π’ Business Events#
π Business profile updated
π Business subscription changed
π Tender Events#
β
/β Bid accepted/rejected
π¬ Enquiry Events#
π° Wallet Events#
π³ Payment Events#
β¨ Benefits of Event-Driven Architecture with GCP Pub/Sub#
1.
π Loose Coupling: Services don't need to know about each other directly
2.
π Scalability: Event consumers can be scaled independently; Pub/Sub auto-scales
3.
π Reliability: Messages are persisted and delivered with at-least-once guarantee
4.
π Auditability: Complete event history for compliance and debugging
5.
π― Flexibility: Easy to add new event consumers without modifying publishers
6.
β‘ Performance: Low-latency message delivery with global infrastructure
7.
π Security: Built-in encryption, IAM integration, and access controls
8.
π Dead Letter Queue: Automatic handling of failed message processing
β‘ Event Processing Flow#
The Handler Service acts as a workflow orchestrator using GCP Pub/Sub. For detailed information on how the Handler Service orchestrates HTTP API calls across microservices, see the Handler Service Orchestration section below.1.
π¨ Services publish events to Pub/Sub topics using @libs/events wrapper
2.
π‘ GCP Pub/Sub receives and stores messages in topics
3.
π Pub/Sub pushes messages to subscriptions (push) or consumers pull messages
4.
π Event consumers (Handler Service, Activity Service, etc.) receive messages
5.
β‘ Handler Service processes events and orchestrates workflows via HTTP API calls
6.
β
Consumers acknowledge messages after successful processing
7.
π Failed messages are retried or sent to dead letter queue
π‘ Note: This pattern enables complex business workflows while maintaining loose coupling between services. GCP Pub/Sub ensures reliable message delivery with automatic retries and dead letter handling.
π Handler Service Orchestration#
The Handler Service acts as the central orchestrator, processing events and coordinating actions across multiple microservices through HTTP API calls.π Orchestration Workflow#
Handler Service listens to all events from the Event Bus
Events are queued and processed asynchronously
Each event contains metadata and instructions for processing
Step 2: Workflow ExecutionWorkflow Engine analyzes the event type and data
Determines which services need to be called
Sequences API calls based on dependencies and business rules
Makes RESTful API calls to target microservices
Passes relevant data and context from the event
Handles authentication and authorization tokens
Step 4: Response HandlingCollects responses from all API calls
Handles errors and retries failed calls
Logs results for audit and debugging
Triggers follow-up events if needed
Notifies monitoring systems
π Example Orchestration Scenarios#
Scenario 1: New User Registration
1.
POST /api/users/profile β Create user profile
2.
POST /api/wallet/create β Create user wallet
3.
POST /api/activity/log β Log registration activity
4.
POST /api/email/send β Send welcome email
Scenario 2: Tender Published
1.
POST /api/business/notify β Notify business owner
2.
POST /api/users/notify-matching β Notify users with matching interests
3.
POST /api/activity/log β Log tender publication
4.
POST /api/email/send-batch β Send email notifications
5.
POST /api/catalog/update-stats β Update catalog statistics
Scenario 3: Payment Successful
Event: payment.successful1.
POST /api/wallet/credit β Credit wallet balance
2.
POST /api/billing/update-invoice β Mark invoice as paid
3.
POST /api/tender/unlock β Unlock tender access if applicable
4.
POST /api/activity/log β Log payment activity
5.
POST /api/email/send-receipt β Send payment receipt
π» Local Development Setup#
The local development environment is designed for easy setup and realistic HTTPS testing with trusted certificates.π οΈ Local Setup Components#
1οΈβ£ mkcert#
π Generates locally-trusted TLS certificates
ποΈ Creates a local Certificate Authority (CA)
β
Installs CA in system trust store
π Supports wildcard certificates for *.local.bidancer.com
2οΈβ£ dnsmasq#
π Provides wildcard DNS resolution
π― Routes all *.local.bidancer.com to 127.0.0.1
π« Eliminates need for manual /etc/hosts entries
βΎοΈ Supports unlimited subdomains
3οΈβ£ Nginx#
π Acts as HTTPS reverse proxy
π― Routes based on subdomain
π Proxies to backend services on various ports
4οΈβ£ Port Forwarding (macOS)#
π§ Uses pf (packet filter) to forward ports
π 443 β 8443 (HTTPS)
π€ Allows Nginx to run without root privileges
π Local Development Flow#
| Step | Action |
|---|
| 1 | Developer runs bun setup:local init --map app:3000 --map api:5100 |
| 2 | Script installs and configures mkcert, dnsmasq, and Nginx |
| 3 | Developer starts services: bun run dev:all |
| 4 | Services run on their assigned ports (e.g., Auth on 8001, User on 8002) |
| 5 | Nginx proxies HTTPS requests to appropriate services |
| 6 | Browser trusts certificates without warnings β
|
π§ Microservices Overview#
π― Service Responsibilities#
π― Service Responsibilities#
| Service | Port | Database | Primary Responsibilities |
|---|
| π Auth | 8001 | Authentication | Login, registration, JWT tokens, sessions |
| π€ User | 8002 | Authentication | User profiles, preferences, settings |
| π’ Business | 8003 | Platform | Business entity CRUD, verification |
| π Tender | 8004 | Platform | Tender management, bidding logic |
| π¬ Enquiry | 8005 | Platform | Enquiry handling, assignment, responses |
| π¦ Catalog | 8006 | Platform | Product/service catalog, categories |
| π° Wallet | 8007 | Wallet | Digital wallet, balance management |
| π³ Billing | 8008 | Wallet | Payment processing, invoicing |
| π Master | 8009 | Master | Master data, configurations |
| π Activity | 8010 | Platform | Activity tracking, analytics |
| β‘ Handler | 8011 | β | Event processing, workflow orchestration |
| π« NotFound | 9999 | β | 404 error handling |
βοΈ Technology Stack#
π Runtime & Framework#
Bun: High-performance JavaScript runtime
TypeScript: Type-safe development
ποΈ Database & ORM#
PostgreSQL: Primary database
Prisma: ORM for all domainsπ Authentication domain
π API & Communication#
REST APIs: HTTP/JSON for synchronous communication
Google Cloud Pub/Sub: Asynchronous event-driven messaging via @libs/events wrapper
WebSockets: Real-time updates (where applicable)
Biome: Fast linter and formatter
Prettier: Code formatting
mkcert: Local TLS certificates
βοΈ Infrastructure#
Google Cloud Build: CI/CD
Nginx: Production reverse proxy and load balancing
π Observability#
Telemetry Library: Custom observability
Logging: Structured logging across services
Metrics: Performance and health metrics
Tracing: Distributed request tracing
π Design Principles#
1οΈβ£ Domain-Driven Design (DDD)#
π― Services organized around business domains
ποΈ Clear bounded contexts
π¬ Ubiquitous language within each domain
2οΈβ£ Microservices Best Practices#
π― Single Responsibility: Each service has one clear purpose
π Independent Deployment: Services can be deployed independently
π Data Isolation: Each service owns its data
π‘ API-First: Well-defined contracts between services
3οΈβ£ Event-Driven Architecture#
β‘ Asynchronous communication for non-blocking operations
π Event sourcing for audit trails
π CQRS pattern where applicable
4οΈβ£ Security#
π JWT-based authentication
π₯ Role-based access control (RBAC)
π Encrypted communication (TLS/SSL)
π‘οΈ Secure credential storage
π KYC verification integration
5οΈβ£ Scalability#
βοΈ Horizontal scaling of services
π Database sharding capability
6οΈβ£ Resilience#
π Circuit breakers for external calls
π Retry mechanisms with exponential backoff
π‘οΈ Graceful degradation
π Health checks and monitoring
7οΈβ£ Developer Experience#
π¦ Monorepo for easier code sharing
π€ Automated local setup
π Comprehensive documentation
β¨ Consistent coding standards
π Future Considerations#
Planned Enhancements#
Planned Enhancements#
π Additional Resources#
README.md - Getting started guide and setup instructions
Built with β€οΈ by the Bidancer TeamFor questions or contributions, please contact the Bidancer core team.