Skip to content
CAI
Software that uses CAICheck a score

anton-liauchuk/educational-platform

66.7

Adequate · 22 September 2026

3.5k

lines of production code

Java

primary language

7

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

This system is an educational platform that manages the full lifecycle of courses, including creation, approval, and publishing workflows. It supports student enrollment, course reviews, and user authentication with role-based access control for teachers, students, and administrators. The architecture is modular, utilizing event-driven communication between components to handle cross-module interactions like user creation and course rating updates.

Features

Add ability to list course proposals

Users with the ADMIN role can now retrieve a list of all course proposals. This is enabled by new query and handler classes (ListCourseProposalsQuery and ListCourseProposalsQueryHandler) that expose the existing CourseProposalRepository to the application layer, allowing administrators to view all pending proposals.

administration/application/src/main/java/com/educational/platform/administration/course/query · high confidence

Add command handler for approving course proposals

A new command handler for approving course proposals has been introduced. This handler enforces ADMIN role authorization, performs the approval within a transaction, and publishes a corresponding integration event upon successful approval.

administration/application/src/main/java/com/educational/platform/administration/course/approve · medium confidence

Add command handler for creating courses

A new command handler, CreateEnrollmentCourseCommandHandler, has been introduced to process CreateCourseCommand requests. This handler, annotated with Spring's @Component and @Transactional, instantiates an EnrollCourse entity and persists it via the EnrollCourseRepository, effectively enabling the creation of new courses through the application layer.

course-enrollments/application/src/main/java/com/educational/platform/course/enrollments/course/create · high confidence

Add command handler for declining course proposals

Administrators can now decline a course proposal through a new command handler that validates the request, updates the proposal status, and publishes an integration event upon successful decline.

administration/application/src/main/java/com/educational/platform/administration/course/decline · high confidence

Add course approval workflow via new command handlers

Users can now submit courses for approval and have them approved by administrators. This change introduces new command handlers for sending a course to the approval state and for the subsequent approval action, along with an integration event listener to bridge the administrative approval process.

courses/application/src/main/java/com/educational/platform/courses/course/approve · high confidence

Add course publishing capability with teacher access control

Users can now publish a course through a new command handler that enforces teacher role and ownership checks before allowing the course to be published.

courses/application/src/main/java/com/educational/platform/courses/course/publish · high confidence

Add query handlers for retrieving a single course and listing courses

New query handlers have been introduced to support fetching a single course by its unique identifier and retrieving a list of courses. The \CourseByUUIDQueryHandler\ now resolves a course by UUID, while the \ListCourseQueryHandler\ provides access to a list of course data transfer objects. These changes enable the application to query course data through dedicated command/query objects and handlers.

courses/application/src/main/java/com/educational/platform/courses/course/query · high confidence

Add sign-in command and handler for user authentication

Introduced a new sign-in capability for the user login flow. A SignInCommand record, validated with Jakarta annotations, is handled by SignInCommandHandler, which validates input, authenticates the user via Spring Security's AuthenticationManager, and returns a JWT token. This adds the core authentication logic for the login feature.

users/application/src/main/java/com/educational/platform/users/login · high confidence

Add student course registration capability

Users can now register for a course through a new command handler that creates a course enrollment, saves it to the repository, and publishes an integration event. Access to this operation is restricted to users with the 'STUDENT' role.

course-enrollments/application/src/main/java/com/educational/platform/course/enrollments/register · high confidence

Add user registration command and handler

Introduced a new user registration flow via a \UserRegistrationCommand\ and its corresponding \UserRegistrationCommandHandler\. The handler validates the registration data, ensures the username is unique, persists the new user, publishes a \UserCreatedIntegrationEvent\, and returns a JWT token.

users/application/src/main/java/com/educational/platform/users/registration · high confidence

Added command handler for creating students

The course enrollments module now includes a new command handler that processes student creation requests. This handler, located in the \create\ package, receives a \CreateStudentCommand\ and persists the new student record via the \StudentRepository\. This change introduces the application-layer logic for student creation within the course enrollments module.

course-enrollments/application/src/main/java/com/educational/platform/course/enrollments/student/create · high confidence

Added domain markers and common exceptions

The common module now includes marker interfaces for Domain-Driven Design patterns, specifically AggregateRoot and ValueObject, which allow domain classes to be identified by type. Additionally, new exception classes have been introduced to handle specific error scenarios: ResourceNotFoundException for missing resources, UnprocessableEntityException for validation failures, and RelatedResourceIsNotResolvedException for unresolved dependencies.

common · high confidence

Added query handlers for retrieving course enrollments

Users can now retrieve their course enrollments via two new query handlers: one that fetches a single enrollment by its UUID, and another that lists all enrollments for the authenticated student. Both handlers enforce role-based access control, requiring the 'STUDENT' role to execute these read-only operations.

course-enrollments/application/src/main/java/com/educational/platform/course/enrollments/query · high confidence

Added security configuration and exception handling

The security module now includes a new SecurityConfiguration class that enables method-level security and registers a BCryptPasswordEncoder bean, controlled by the com.educational.platform.security.enabled property. Additionally, a JwtTokenValidationException class has been added to handle JWT validation errors, and the application-security.properties file is introduced to enable security by default.

security/config · high confidence

Configure H2 in-memory database and Liquibase for local development

Added application.properties to configure an H2 in-memory database for testing and local development, enabling the H2 console and setting up Liquibase for schema management. The db.changelog-master.yml file was introduced to orchestrate database migrations for users, courses, course reviews, and course enrollments, establishing the initial database structure.

configuration/src/main/resources · high confidence

Course management domain model and data transfer objects

The courses module now includes a comprehensive set of domain models and DTOs to support course creation, approval workflows, and curriculum management. This includes the core Course entity with approval and publish statuses, along with related models for curriculum items (Lectures and Quizzes) and their corresponding DTOs for data retrieval. The update also introduces repository interfaces and custom implementations to fetch course details and verify teacher permissions, enabling the backend to handle course lifecycle states and structured content.

courses/application/src/main/java/com/educational/platform/courses/course · high confidence

Course proposal management endpoints

A new REST API is introduced for managing course proposals, allowing administrators to approve or decline proposals and list all pending proposals. The controller exposes endpoints at /administration/course-proposals, supporting PUT and DELETE requests for approval status changes and a GET request to retrieve the list of proposals.

administration/web/src/main/java · high confidence

Introduce command objects and handler for creating courses and curriculum items

The application layer now includes new command objects for creating a course and its curriculum items (lectures, quizzes, and questions). Specifically, \CreateCourseCommand\ and \CreateCourseCommandHandler\ enable course creation, while \CreateCurriculumItemCommand\ serves as the base for \CreateLectureCommand\, \CreateQuizCommand\, and \CreateQuestionCommand\. The handler enforces that only users with the 'TEACHER' role can create courses, returning the new course's UUID upon success.

courses/application/src/main/java/com/educational/platform/courses/course/create · high confidence

Introduce course and student domain models and repositories

Added new domain entities for the course enrollments module: EnrollCourse and Student, each with their respective Spring Data JPA repositories (EnrollCourseRepository and StudentRepository). This establishes the persistence layer for managing course and student records within the application.

course-enrollments/application/src/main/java/com/educational/platform/course/enrollments/course, course-enrollments/application/src/main/java/com/educational/platform/course/enrollments/student · high confidence

Introduce course proposal management domain and repository

Added the core domain model for course proposals, including the \CourseProposal\ entity with approval and decline workflows, along with associated exceptions, DTOs, and a JPA repository for listing and retrieving proposals by UUID.

administration/application/src/main/java/com/educational/platform/administration/course · high confidence

Introduce course review endpoints

The course-reviews module now exposes REST endpoints for creating, retrieving, and updating course reviews. Users can submit a new review via a POST to /courses/{uuid}/reviews, fetch all reviews for a course via GET /courses/{uuid}/reviews, and modify an existing review via PUT /courses/{courseUuid}/reviews/{reviewUuid}. The controller delegates to specific command and query handlers, indicating a shift toward a command/query architecture for these operations.

course-reviews/web/src/main/java · high confidence

Introduce course review functionality

Users can now submit, update, and list reviews for courses. This change adds the domain models (CourseReview, Comment, CourseRating), repositories, and command/query handlers that allow users to create and modify their own reviews, while also enabling the retrieval of all reviews for a specific course.

course-reviews/application/src/main/java · high confidence

Introduced Teacher aggregate root and repository

Added the Teacher entity class and its corresponding Spring Data JPA repository interface. The Teacher class implements AggregateRoot and includes a username field, while the repository provides a method to find teachers by username.

courses/application/src/main/java/com/educational/platform/courses/teacher · medium confidence

Introduces user domain model and password validation

The users module now includes core domain classes to support user management and authentication. A new User entity and associated DTOs (UserDTO, RoleDTO) define the data structure for storing and transferring user information, including username, email, and role. A Role enum with values for students and teachers is introduced, alongside a custom password validation constraint (ValidPassword) that enforces length and whitespace rules via a new PasswordConstraintValidator. These changes provide the foundational data models and validation logic required for user registration and security.

users/application/src/main/java/com/educational/platform/users · high confidence

JWT-based authentication and user registration endpoints

The users service now supports user sign-up and sign-in via REST endpoints (/users/sign-up and /users/sign-in). A new security layer has been introduced, featuring a JwtTokenFilter that validates JWTs on each request and configures Spring Security to enforce authentication for all endpoints except public ones (sign-in, sign-up, API docs, H2 console, and public resources). The controller delegates to command handlers for registration and login, returning JWTs upon successful authentication.

users/web/src/main/java · high confidence

Launch the Educational Platform application entry point

The application's main entry point is now defined in EducationalPlatformApplication.java, enabling the Spring Boot application to start. The configuration enables asynchronous processing and loads properties from application-security.properties.

configuration/src/main/java · high confidence

New course enrollment endpoints for registration and listing

A new CourseEnrollmentController has been added to expose REST endpoints for course enrollments. Users can now register a student for a course via a POST to /courses/{uuid}/course-enrollments and retrieve a list of all course enrollments via a GET to /course-enrollments. The controller integrates with the Axon framework's command and query handlers to process these requests.

course-enrollments/web/src/main/java · high confidence

New integration events for cross-module communication

Added new integration event records to each module's \integration-events\ package, enabling cross-module communication. Specifically, the system now publishes events for user creation, course approval/declination, student enrollment, course rating recalculation, and course submission for approval.

(repo-wide) · high confidence

Project initialization and documentation scaffolding

The repository was initialized with essential project governance and setup files, including a MIT License, Code of Conduct, and Contributing guidelines. The README was expanded to document the educational platform's modular monolith architecture, domain-driven design patterns, and module structure. Additionally, the Gradle wrapper scripts and .gitignore were added to standardize the build environment.

(repo-wide) · high confidence

Behavioural changes

Added event-driven handlers for student enrollment and rating updates

The application now automatically updates course student counts and ratings in response to integration events. Specifically, a new event listener triggers an increase in the student count when a student enrolls in a course, and another listener updates the course rating when recalculated. These changes implement the core logic for these updates using Spring's event handling, replacing the previous Axon-based approach.

courses/application/src/main/java/com/educational/platform/courses/course/numberofsudents, courses/application/src/main/java/com/educational/platform/courses/course/rating · medium confidence

Asynchronous teacher creation via event-driven integration

The system now creates teacher records asynchronously in response to user creation events. A new event listener listens for \UserCreatedIntegrationEvent\ and triggers the \CreateTeacherCommand\ via a dedicated command handler, enabling decoupled, non-blocking processing of new teacher accounts.

courses/application/src/main/java/com/educational/platform/courses/teacher/create · high confidence

Course creation now supports asynchronous integration events

The administration module now handles course creation via a new command handler and an integration event listener. A new CreateCourseProposalCommand and its handler allow direct creation of course proposals, while a new SendCourseToApproveIntegrationEventHandler listens for integration events to trigger the same creation logic asynchronously.

administration/application/src/main/java/com/educational/platform/administration/course/create · high confidence

Introduce JWT-based authentication for user security

Added new security components to the users module: a JwtTokenProvider for generating, validating, and resolving JWT tokens, and a MyUserDetails service implementing Spring's UserDetailsService to load user details from the database. These changes enable token-based authentication for user login and registration flows.

users/application/src/main/java/com/educational/platform/users/security · medium confidence

Introduce course enrollment domain model and query support

The course enrollments module now includes a new domain model for tracking course enrollments, including a CompletionStatus enum to represent enrollment states (IN\_PROGRESS, COMPLETED) and a CourseEnrollment entity with a UUID identifier. A factory component handles enrollment creation with validation, and a repository provides new query capabilities to retrieve enrollments by UUID and to fetch enrollment details for a specific student, exposing DTOs for external consumption.

course-enrollments/application/src/main/java/com/educational/platform/course/enrollments · medium confidence

New Course API endpoints for creation and publishing

The platform now exposes a RESTful API for managing courses. Users can create a new course via a POST to /courses, which returns the course's UUID, and publish an existing course via a PUT to /courses/{uuid}/publish-status. The controller delegates to Axon command handlers, and error handling returns a 409 Conflict when a course cannot be published.

courses/web/src/main/java · high confidence

Standardized error response format for API exceptions

The application now returns a consistent JSON structure for error responses. A new \ErrorResponse\ record and a \GlobalExceptionHandler\ have been introduced to catch various exceptions (such as validation errors, resource not found, and unprocessable entity) and return them with appropriate HTTP status codes and a standardized body format.

web · high confidence

Updated Gradle wrapper to version 9.2.1

The Gradle wrapper has been updated to use Gradle 9.2.1, ensuring the project uses a specific, consistent build tool version for all developers and CI environments.

gradle · high confidence

Test coverage

Added API tests for course proposal approval workflow; Added API tests for user sign-up and sign-in; Added SQL test data for course enrollment tests; Added SignUpHelper test utility for API testing; Added architecture tests for event immutability, command handler nullability, and layering rules; Added integration tests for the course API; Added integration tests for the course enrollment API; Added integration tests for the course review API; Added test application class for the users module; Added tests for course enrollment functionality; Added tests for course lifecycle and security; Added tests for course proposal approval, decline, and listing; Added tests for course review creation, updates, and security; Added unit tests for the sign-in command handler; Added unit tests for user registration command handling.

Dependencies

Migrate build configuration to Kotlin DSL and centralize dependency versions

The project's build system has been converted from Groovy to Kotlin DSL, with all \build.gradle\ files replaced by \build.gradle.kts\ files. A new \gradle/libs.versions.toml\ file centralizes version management for libraries such as Spring Boot, JUnit, Mockito, and Rest Assured. The root \build.gradle.kts\ configures Java 25 compatibility and imports the Spring Boot dependency management BOM, ensuring consistent dependency versions across all subprojects.

(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

Score

  • CAI 63 → 67 (+3.7)
  • Rubric changed (rubric-2026.08.19 → rubric-2026.09.15) — scores are not directly comparable.

Lenses

  • Code Health 100 → 98 (-1.7)
  • Architecture 99 → 92 (-7.2)
  • Maturity 86 → 86 (+0.0)
  • Readiness 36 → 43 (+6.6)
  • Security 100 → 100 (+0.0)
  • Domain Modelling 79 → 84 (+5.0)

Resolved (18)

  • Change coupling: ApproveCourseProposalCommandHandler.java ↔ DeclineCourseProposalCommandHandler.java (administration/application/src/main/java/com/educational/platform/administration/course/approve/ApproveCourseProposalCommandHandler.java)
  • Change coupling: SignInCommandHandler.java ↔ UserRegistrationCommandHandler.java (users/application/src/main/java/com/educational/platform/users/login/SignInCommandHandler.java)
  • Context and decision are both present but the body is clipped mid-sentence ('We can add custom features to Spring functionality when it's needed.') before any consequences/trade-offs or a review link appear (docs/architecture-decisions/0002-integration-events-implementation.md)
  • Context lists only the two alternatives (same model vs separate models) and a decision that is restated as 'it will be used' without explaining why CQRS was chosen over those options (docs/architecture-decisions/0003-cqrs.md)
  • Context lists three solutions but never states the problem being solved (e.g. data inconsistency across requests) and the decision is restated verbatim without consequences (docs/architecture-decisions/0004-validation.md)
  • Context lists two alternatives but the decision is restated as a tautology ('rich domain model solution will be used') with no rationale or trade-offs (docs/architecture-decisions/0006-rich-domain-model.md)
  • Coverage not included — suite not readable by the collector
  • Decision is a boilerplate list with links citing design sources but no context/problem and consequences are couched in the decision's own wording ('it's forbidden to create a transaction which spans more than one bounded context') (docs/architecture-decisions/0001-bounded-contexts-communication.md)
  • Decision is narrow and consequences/trade-offs are absent: only that primary keys must not be used for cross-module/external identifier exchange; no mention of why uuids/good natural keys are preferred over each (docs/architecture-decisions/0005-identifier-between-modules.md)
  • Dependency hygiene not measured — dependency manifest found but not parsed for hygiene
  • Duplicated block (7 lines × 2) (administration/application/src/main/java/com/educational/platform/administration/course/approve/ApproveCourseProposalCommandHandler.java)
  • LLM evaluation failed
  • No consequences/trade-offs are stated (e.g., loss of Spring-specific features like data persistence or security) (docs/architecture-decisions/0012-make-application-framework-independent.md)
  • No consequences/trade-offs section describing the cost of adopting Axon (e.g. learning curve, configuration complexity) and benefits such as event sourcing (docs/architecture-decisions/0011-use-axon-event-publishing-mechanism.md)
  • No exposed public API
  • Test reliability not included
  • Uninformative title and the decision is restated verbatim as Context (docs/architecture-decisions/0008-result-from-comand-handlers.md)
  • single-maintainer — knowledge-concentration (bus factor) risk

New (33)

  • Context is a bare 'The idea from CQRS - do not return anything from command processing. But in some cases...' with no problem statement and decision body identical (returns generated identifiers after processing) then clipped (docs/architecture-decisions/0008-result-from-comand-handlers.md)
  • Context lists only the two alternatives (same model vs separate models) and no problem; decision is restated as principle plus a one-line implementation description without any trade-offs (docs/architecture-decisions/0003-cqrs.md)
  • Context lists three solutions but never states which one is chosen and the trade-offs of each; Decision only names the always-valid approach with no consequences (docs/architecture-decisions/0004-validation.md)
  • Context lists two alternatives but the decision is restated verbatim ('rich domain model solution will be used...') with no trade-offs; the title is uninformative (docs/architecture-decisions/0006-rich-domain-model.md)
  • Decision is a boilerplate list of references without any rationale or trade-offs (docs/architecture-decisions/0001-bounded-contexts-communication.md)
  • Decision is narrow and consequences are absent: it only states which keys should be used (natural keys or uuids) without banning primary keys for cross-module/external communications and with no trade-offs (docs/architecture-decisions/0005-identifier-between-modules.md)
  • Dependency hygiene PARTLY measured — Maven/Gradle declarations read, no dependency graph resolved
  • Documentation: no installation or build instructions (README.md)
  • Documentation: no usage examples (README.md)
  • Duplicated block (6 lines × 2) (administration/application/src/main/java/com/educational/platform/administration/course/approve/ApproveCourseProposalCommandHandler.java)
  • Informative title ('7. API First.') duplicates the heading rather than conveying value; could be replaced by something like 'API documentation must precede implementation' (docs/architecture-decisions/0007-api-first.md)
  • No consequences/trade-offs are stated (e.g., loss of Spring-specific features like data repositories or security) (docs/architecture-decisions/0012-make-application-framework-independent.md)
  • No consequences/trade-offs section (e.g. learning curve, tooling cost, operational complexity of the Axon event-store layer) (docs/architecture-decisions/0011-use-axon-event-publishing-mechanism.md)
  • No direct assertions: approve_existingCourseProposal_noContent (administration/web/src/test/java/com/educational/platform/administration/course/api/CourseProposalApiTest.java)
  • No direct assertions: create_validRequest_created (courses/web/src/test/java/com/educational/platform/courses/api/CourseApiTest.java)
  • No direct assertions: decline_existingCourseProposal_noContent (administration/web/src/test/java/com/educational/platform/administration/course/api/CourseProposalApiTest.java)
  • No direct assertions: publish_alreadyApprovedCourse_noContent (courses/web/src/test/java/com/educational/platform/courses/api/CourseApiTest.java)
  • No direct assertions: register_validCourse_createdWithUUID (course-enrollments/web/src/test/java/com/educational/platform/course/enrollments/api/CourseEnrollmentApiTest.java)
  • No direct assertions: review_validRequest_created (course-reviews/web/src/test/java/com/educational/platform/course/reviews/api/CourseReviewApiTest.java)
  • No direct assertions: reviews_validRequest_reviews (course-reviews/web/src/test/java/com/educational/platform/course/reviews/api/CourseReviewApiTest.java)
  • …and 13 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

anton-liauchuk/educational-platform 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 22 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 a6f575c3df95acd0e2891f23f8cab229cbb89c87 — 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-90d5d2fe38ee.