Backend REST API service for the Dallas Makerspace member portal, built with Kotlin and Ktor.
The Member Profile Service provides RESTful APIs for member data management, integrations with external systems (Active Directory, Discourse, WHMCS), and automated synchronization workflows.
Port: 8081 (default)
Tech Stack:
- Ktor 3.0.1
- Kotlin 2.0.21
- Exposed ORM (database access)
- Dagger (dependency injection)
- MariaDB
src/main/kotlin/org/dallasmakerspace/Application.kt
di/- Dagger dependency injection setup with@SingletonscopedAppComponentplugins/- Ktor plugin configuration (Routing, Database, HTTP, Serialization)routing/- REST API routes using Ktor Resourcesmembers/- Business logic with Observer pattern for member changesrepositories/- Data access layer using Exposed ORMactivedirectory/- LDAP/AD integration for user synchronizationdiscourse/- Discourse API client for forum integrationcore/- Database connections (MariaDB), AppConfig, loggingcron/- Scheduled jobs (member refresh, sync tasks)webhook/- Webhook routing and handlersdataviz/- Data visualization reports
-
Dependency Injection (Dagger)
@Singletonscoped components- Lazy initialization in routing to avoid circular dependencies
-
Observer Pattern
IMemberPropChangeObserverfor tracking member property changes- Enables decoupled event handling across the system
-
Repository + Service Pattern
- Clear separation between data access and business logic
- Exposed ORM with suspend transactions for async operations
-
Conditional Mocking
app.use-mock-servicesconfiguration flag- Enables testing without external dependencies
-
Router Pattern
- Name-based handler registration for webhooks and data visualization
- Extensible plugin architecture
Requests to the API must include:
X-Api-Key- API key for authenticationX-Api-Client- Client identifier
Configuration file: src/main/resources/application.conf
Key configuration sections:
- Database connection (MariaDB)
- LDAP/Active Directory settings
- Discourse API credentials
- API keys and client identifiers
- Mock services toggle (
app.use-mock-services)
./gradlew :service:runThe service will start on port 8081 by default.
# All tests
./gradlew :service:test
# Specific test class
./gradlew :service:test --tests "org.dallasmakerspace.YourTestClass"./gradlew :service:build# Run static analysis
./gradlew :service:detekt
# Generate code coverage report
./gradlew :service:koverHtmlReportCoverage reports are generated in build/reports/kover/html/index.html
- Open the root
member-portalproject in IntelliJ IDEA - The service module will be automatically recognized
- Run configurations can be created for
Application.kt
The service requires a MariaDB instance. Configure connection details in application.conf:
database {
host = "localhost"
port = 3306
name = "member_portal"
user = "your_user"
password = "your_password"
}
- User authentication and synchronization
- Group membership management
- Configuration in
application.confunderactivedirectory
- Forum SSO integration
- User profile synchronization
- API client in
discourse/package
- External member data sources
- Webhook handlers for data updates
The service includes cron jobs for:
- Member data refresh
- Active Directory synchronization
- Discourse user sync
Jobs are configured in the cron/ package.
API routes are defined using Ktor Resources in the routing/ package. Key endpoints include:
- Member CRUD operations
- Group management
- Data visualization reports
- Webhook handlers
See the routing configuration in plugins/Routing.kt for the complete API surface.
Database connection errors:
- Verify MariaDB is running
- Check credentials in
application.conf - Ensure database exists and migrations are applied
LDAP/AD connection issues:
- Verify network connectivity to AD server
- Check credentials and LDAP DN configuration
- Review SSL/TLS settings if applicable
Mock services not working:
- Set
app.use-mock-services = trueinapplication.conf - Restart the service after configuration changes