Skip to content
CAI
Software that uses CAICheck a score

dyrkin/luxmed-bot

46.7

Weak · 20 September 2026

7.5k

lines of production code

Scala

primary language

1

measurement over time

CAI band scale
CAI lens gauges

What this system is

This system is a Telegram bot service that facilitates appointment booking and health monitoring for the Luxmed medical portal. It manages user interactions through a state-machine architecture, handling authentication, multi-account support, and complex reservation workflows including rehabilitation services. The backend integrates with the Luxmed API to fetch and confirm appointments, while persisting user data and history in a PostgreSQL database.

Features

Initial Docker deployment configuration for Linux and ARM64

Users can now deploy the application using Docker with support for both standard (x86\_64) and ARM64 architectures. The setup includes a Dockerfile based on Eclipse Temurin 25 (JRE Noble) and specific docker-compose files for each architecture, utilizing PostgreSQL 10.6/10.7. The containerized service is configured with a fixed heap size of 128MB, sets the timezone to Europe/Warsaw, and includes a startup script that waits for the database to become available before launching the Java application.

docker · high confidence

Polish language support and manual date/time entry

Users can now select Polish (🇵🇱 Polski) as a language option in the bot. The interface has been updated to allow manual entry of dates (dd-MM format) and time ranges instead of relying solely on pickers, and the booking summary now displays specific time windows. Additionally, the help message has been updated to reflect current commands and the bot version.

server/src/main/scala/com/lbs/server/lang · high confidence

Support for multiple accounts and rehabilitation services

The service layer now supports multiple accounts per user, replacing the previous single-user ID model with an account-based identity system across API calls, data queries, and session management. Additionally, the service introduces dedicated endpoints and logic for rehabilitation services, including fetching rehab referrals, facilities, and available appointment terms, while also updating the underlying API client to use a new Luxmed API structure with improved error handling via Cats Monad.

server/src/main/scala/com/lbs/server/service · high confidence

Behavioural changes

Bot library upgraded to bot4s with file sending support

The bot module has migrated from the legacy info.mukel.telegrambot4s library to the modern com.bot4s.telegram (bot4s) framework. This upgrade brings improved async handling and structured logging via typesafe-scalalogging. As part of this migration, the bot now supports sending files (documents) to users, a capability previously unavailable. The change also updates internal model converters and removes legacy copyright headers.

bot · high confidence

Conversation logic refactored into a new state-machine architecture

The server-side conversation handling has been completely rewritten to use a new, explicit state-machine pattern based on Pekko Conversations, replacing the previous actor-based implementation. This change introduces dedicated conversation components for each user flow—such as Account management, Login, Booking, Rehab booking, and Monitoring—along with shared utilities like a Pager for paginated lists and a DatePicker for date selection. The new Router now manages user sessions and routes commands to these specific conversation instances, providing a more structured and maintainable foundation for the bot's interactive features.

server/src/main/scala/com/lbs/server/conversation · high confidence

Database model migration to Jakarta EE and multi-account support

The server's data models have been migrated from the legacy \javax.persistence\ API to \jakarta.persistence\, requiring a database schema update. The data model now supports multiple accounts per user by introducing an \accountId\ field across history and credential entities, replacing the previous single-user \userId\ linkage. Additionally, the \Monitoring\ entity has been expanded to support new booking features, including time-range selection (\timeFrom\/\timeTo\), rehab services, and referral tracking, while the legacy bug-reporting functionality has been removed.

server/src/main/scala/com/lbs/server/repository/model · high confidence

Enhanced booking data capture and reservation logic in server utilities

The server utility package has been refactored to support more detailed booking information and new reservation workflows. The monitoring converter now captures additional user context (username, account ID) and specific time ranges (timeFrom/timeTo) alongside a new offset field, while date fields are explicitly converted to the system zone. New converters have been introduced to handle reservation confirmation, term changes (allowing modification of existing bookings), and lock-term requests, replacing the previous simpler term presentation converters. These changes enable the backend to process more complex reservation scenarios and track finer-grained booking details.

server/src/main/scala/com/lbs/server/util · high confidence

JSON serialization switched from json4s to circe with automatic key normalization

The API's JSON handling has been replaced with the circe library, introducing automatic conversion of snake\_case and PascalCase JSON keys to camelCase during decoding. This change also removes the previous custom ZonedDateTime serializer, relying on circe's standard type classes, and adds explicit error logging for decode failures while maintaining the ability to serialize and deserialize objects via extension methods.

api/src/main/scala/com/lbs/api/json · high confidence

Luxmed API client migrated to new portal endpoints with improved reliability

The API client has been updated to support the new Luxmed portal endpoints (replacing the old PatientPortalMobileAPI base URL) and now uses JWT-based authorization for the new API paths. To prevent the application from hanging on unresponsive servers, explicit 30-second connection and read timeouts have been added to all HTTP requests. The underlying HTTP library has been switched from scalaj-http to sttp-client3, and the API implementation has been refactored to use a generic effect type (MonadError) instead of direct Future or Either returns, providing more robust error handling and flexibility for async operations.

api/src/main/scala/com/lbs/api · high confidence

Migrate CI to Drone and add ARM64 support

The project's continuous integration system has switched from Travis CI to Drone, introducing automated builds and Docker image publishing for both AMD64 and ARM64 architectures. The new pipeline handles testing, versioning, and deployment, including a specific step to restart the Luxmed service on the target server after publishing new ARM64 images. Additionally, the project now includes a \.scalafmt.conf\ for Scala code formatting and updated Gradle wrapper scripts.

(repo-wide) · high confidence

Migrated HTTP client to sttp and enhanced error handling

The HTTP layer has been refactored to use the sttp client library instead of scalaj-http, introducing a new \LuxmedResponse\ wrapper and a \Session\ case class that now includes JWT tokens alongside access tokens. Error handling has been significantly improved to provide specific exceptions for session expiration and invalid credentials, and sensitive data (such as passwords and tokens) is now automatically masked in debug logs to prevent accidental exposure.

api/src/main/scala/com/lbs/api/http · high confidence

Migration from single-user to multi-account data scoping

The repository layer has been updated to support multiple accounts per user. All history queries (city, clinic, service, doctor) and credential lookups now filter by \accountId\ instead of \userId\, and the history retention limit has been increased from 2 to 4 records. Additionally, monitoring counts and lists are now scoped to specific accounts, and a new method to retrieve all monitorings for an account has been added.

server/src/main/scala/com/lbs/server/repository · high confidence

Migration to Pekko, database connection flexibility, and Liquibase integration

The application now uses Pekko instead of Akka, featuring a dedicated thread pool with 64 threads to prevent blocking issues during external API calls. Database connectivity is now configurable via environment variables (DB\_HOST, DB\_PORT) rather than hardcoded localhost settings, and Hibernate DDL generation is disabled in favor of Liquibase for schema management. Additionally, logging output is redirected to a specific volume path (/lbs/log/app.log) and circular bean references are explicitly allowed.

server/src/main/resources · high confidence

Refactor chat actors to use a custom Finite State Machine

The chat actors in the server (including Auth, Book, Chat, Login, and others) have been refactored to use a custom \SafeFSM\ implementation instead of the previous Akka-based state handling. This change simplifies the conversation logic, making the code more readable and maintainable by explicitly defining state transitions for user interactions such as booking, login, and help requests.

server/src/main/scala/com/lbs/server/actor · high confidence

Refactored API exception hierarchy to support structured error handling

The API's exception handling has been restructured to provide more granular and structured error reporting. The previous generic \LuxmedException\ has been replaced by a new \ApiException\ base class and specific subclasses, including \GenericException\ (which carries a numeric error code), \InvalidLoginOrPasswordException\, and \SessionExpiredException\. This change allows consumers of the API to distinguish between authentication failures, session issues, and other errors more precisely.

api/src/main/scala/com/lbs/api/exception · high confidence

Refactored bot conversation flow from Akka actors to type-safe conversation classes

The server's internal architecture for handling user interactions has shifted from using Akka actors to a new 'conversation' model based on type-safe factory classes. This change, visible in the BootConfig and Boot files, replaces the previous actor-based routing (e.g., Auth, Login, Book) with explicit factories (e.g., authFactory, loginFactory, bookFactory) that instantiate conversation objects. This refactoring simplifies the underlying infrastructure by hiding the Akka actor system from the business logic layer, while also introducing Scala 3 features like \uninitialized\ for bean properties and \scala-logging\ for structured logging in the application entry point.

server/src/main/scala/com/lbs/server · medium confidence

Replaced legacy Luxmed API JSON models with new API-compatible structures

The JSON model layer for the Luxmed API integration has been completely rewritten to support the latest API version. The old model classes (such as \ReservationRequest\, \AvailableTermsResponse\, and \PayerDetails\) have been removed and replaced with a new set of case classes including \ReservationLocktermRequest\, \ReservationConfirmRequest\, \TermsIndexResponse\, and \DictionaryServiceVariants\. This change introduces support for new reservation workflows (locking and confirming terms), updated event structures, and more granular service variant dictionaries, while also adding robust JSON codecs via \io.circe\ to handle the new data formats.

api/src/main/scala/com/lbs/api/json/model · high confidence

Scheduler errors are now logged silently instead of failing loudly

The Scheduler in the common module now catches exceptions thrown by scheduled tasks and logs them via the standard logger, rather than letting them propagate and potentially crash the scheduling thread. This change, along with the removal of the custom Logger trait and migration to Scala 3 syntax (given/using) in model converters, represents a shift towards more robust error handling and modern Scala idioms in the shared utilities.

common · high confidence

Test coverage

Added integration tests for the Luxmed API client; Added test infrastructure and specs for server conversation and repository logic; Added tests for ExtendedHttpRequest error handling; Added tests for JSON model deserialization and removed legacy test files.

Dependencies

Gradle wrapper upgraded to version 9.5.0

The Gradle wrapper has been updated from version 4.6 to 9.5.0, which may affect build performance and compatibility. The configuration also introduces new network timeout and retry settings to handle distribution downloads more robustly.

gradle · high confidence

Upgrade to Scala 3 and modernize dependency stack

The project has migrated from Scala 2.12 to Scala 3 (version 3.8.3), requiring updates across all modules. This change replaces older libraries with their Scala 3-compatible counterparts, including switching from \scalaj-http\ and \json4s\ to \sttp\ and \circe\ in the API module, and from \telegrambot4s\ to \bot4s\ in the bot module. Logging dependencies were updated to use \scala-logging\ and newer \logback\ versions. Additionally, the server module upgraded the PostgreSQL driver to version 42.7.3, added Liquibase support, and updated Spring Boot test dependencies.

(dependencies) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

Baseline

  • First survey — no prior run to compare against. CAI 47.

Lenses

  • Code Health 98
  • Architecture 79
  • Maturity 59
  • Readiness 18
  • Security 88

Changes since last survey

  • 210 commits — 148 feature/other, 62 fixes

By area

  • server/src — 104 commits
  • (root) — 46 commits
  • api/src — 39 commits
  • bot/src — 5 commits
  • docker/Dockerfile — 5 commits
  • docker/run.sh — 3 commits
  • (repo) — 2 commits
  • common/src — 2 commits
  • bot/build.gradle — 1 commit
  • docker/docker-compose-arm64.yml — 1 commit
  • docker/docker-compose.yml — 1 commit
  • server/build.gradle — 1 commit

Notable commits

  • fix: #111 fixes null pointer exception when .termsForService.termsForDays[0].terms[0].doctor.firstName is null
  • fix: #15 Fixed the way how an offset should be applied to the date
  • fix: #18 fixed exception "Luxmed API exception: In order to use this app, please update it to the newest version available in the store"
  • fix: #23 Fixed "In order to use this app, please update it to the newest version available in the store" error
  • fix: #33 fixed akka testkit version
  • fix: #45 fixed bug when history doesn't work if a doctor is not specified in an event
  • fix: #45 fixed bug when searching with predefined clinic id didn't work.
  • fix: #50 fixed 409 Error: HTTP/1.1 409 Conflict
  • fix: #50 fixed internal server error caused by changing the list terms API
  • fix: #51 fixed the parsing error during the reservation of a paid service
  • fix: #77 fixed Luxmed API exception: Session expired
  • fix: #80 fixed bug when the bot books an appointment but doesn't send a notification to a user and doesn't cancel monitoring
  • fix: #89 fixed old app version exception
  • fix: Book: Fix getAllDoctors list
  • fix: Book: Fix getAllDoctors when clinicId is -1
  • fix: DataRepository: Fix forcing clinicId
  • fix: Fix bug: Caused by: java.io.FileNotFoundException: /usr/lib/libnss3.so (https://github.com/docker-library/openjdk/issues/289)
  • fix: Fixed arm64v8 build
  • fix: Fixed bug when app was unable to parse response from canTermBeChanged api call
  • fix: Fixed bug when monitoring is not deactivated as expected
  • …and 190 more

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

dyrkin/luxmed-bot was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 20 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit a5b7abc83389e718651ce8c6dbb005e72ae694b0 — the exact code this score is about.
  • Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-b51f968c9b10.