>_EXECUTIVE SUMMARY
LearningCollectionAPI is a Kotlin / Spring Boot REST service that persists “learnings” — short notes / vocabulary cards — into MySQL, and serves them back for search and quiz. It is the HTTP backing store for the zsh-learn shell plugin. The data model is a single JPA entity (LearningCollection: id, learning, category, dateAdded). The interface is split across one hand-written controller (ten GET endpoints tuned for shell calls) and the Spring Data REST auto-generated CRUD surface under /learning.
The codebase is deliberately small — 6 main Kotlin files totalling 147 LOC — but carries a disproportionately large test suite: 23 test files, 6,155 LOC, 128 test methods (118 @Test + 10 @ParameterizedTest). The test-to-main LOC ratio is roughly 42:1, covering controller routes, the entity schema, repository contracts, CORS config, serialization, edge cases, idempotency, stress, and property-based fuzzing.
~REST SURFACE
Ten @GetMapping handlers on a single @RestController. Every operation is a GET — query param (/add, /filter) or path variable ({count}) — so the zsh-learn plugin can call them with a bare curl. “Text only” responses return just the learning strings; “full” responses return complete records.
| Method | Path | Handler | Behavior |
|---|---|---|---|
| GET | /add | add | Persists a new learning (category "programming", dateAdded now); returns the saved entity. |
| GET | /filter | filterLearn | Substring search (findAllByLearningContaining); returns matching text. |
| GET | /recents | learningItemRecentShortDefault | Last 20 (SHORT_CNT) learnings, text only. |
| GET | /recents/{count} | getLearningItemRecentShort | Last {count} learnings, text only. |
| GET | /recent/{count} | getLearningItemRecent | Last {count} learnings, full records. |
| GET | /random | learningItem | One random learning, full record. |
| GET | /randoms | learningItemCountShort | One random learning, text only. |
| GET | /randoms/{count} | getLearningItemCountShort | {count} random learnings, text only. |
| GET | /random/{count} | getLearningItemCount | {count} random learnings, full records. |
| GET | /dump | getDump | Streams mysqldump --extended-insert=FALSE root to the response writer. |
Recency = findAll().reversed() (newest-inserted first); randomness = findAll().shuffled(). Both load the full table into memory before slicing — acceptable at the personal-collection scale this serves.
$DATA MODEL
A single entity, LearningCollection (@Table(name = "LearningCollection")), implementing Serializable. Four columns, IDENTITY-generated primary key.
| Field | Kotlin type | JPA annotation | Purpose |
|---|---|---|---|
id | Long | @Id @GeneratedValue(strategy = IDENTITY) | Auto-increment PK. |
learning | String | @Column | The learning content. |
category | String | @Column | Defaults to "programming" on create. |
dateAdded | java.util.Date | @Column | Creation timestamp (Date()). |
LCRepo extends CrudRepository<LearningCollection, Long> and declares two derived query methods: findAllByLearningContaining (used by /filter) and findAllByCategoryContaining (exposed via Spring Data REST search, not wired to a controller route). The @RepositoryRestResource(path = "learning") annotation auto-publishes full CRUD under /learning.
%SOURCE INVENTORY
Six main Kotlin files under src/main/kotlin/com/menketechnologies/learningcollection/, totalling 147 LOC.
| File | Role |
|---|---|
LearningCollectionApplication.kt | @SpringBootApplication bootloader with main entrypoint. |
LearningController.kt | @RestController — the 10 @GetMapping endpoints; @Autowired LCRepo. |
LearningCollection.kt | @Entity — the 4-field schema, two constructors, serialVersionUID. |
LCRepo.kt | CrudRepository + @RepositoryRestResource; 2 derived query methods. |
Consts.kt | Top-level constants: SHORT_CNT, DB_NAME, DEFAULT_CAT, DUMP. |
WebConfig.kt | WebMvcConfigurer + RepositoryRestConfigurer — opens CORS on /** for both layers. |
!TEST COVERAGE
23 test files, 6,155 LOC, 128 test methods (118 @Test + 10 @ParameterizedTest), run on JUnit 5 (useJUnitPlatform) with kotlin-test-junit5, spring-boot-starter-test, and mockito-kotlin. The suite is far larger than the production code it exercises — controller, entity, repository, and config each carry multiple dedicated test classes.
| Area | Test files |
|---|---|
| Controller | LearningControllerTest, LearningControllerBoundaryTest, LearningControllerCombinationTest, LearningControllerDataFlowTest, LearningControllerEndpointMatrixTest, LearningControllerErrorPathTest, LearningControllerIdempotencyTest, LearningControllerRouteContractTest, LearningControllerStressTest |
| Entity | LearningCollectionTest, LearningCollectionContractTest, LearningCollectionEdgeCaseTest, LearningCollectionInvariantTest, LearningCollectionPropertyTest, LearningCollectionSchemaContractTest, LearningCollectionSerializationTest |
| Repository | LCRepoContractTest |
| Config / constants | ConstsTest, ConstsExtendedTest, WebConfigTest, WebConfigExtendedTest |
| Application | LearningCollectionApplicationTests, LearningCollectionApplicationEntryTest |
Per the README, the suite spans unit tests, integration tests, boundary analysis, stress tests, serialization checks, property-based fuzzing, repository contracts, idempotency checks, and application-entry tests. Run with ./gradlew test.
&DEPENDENCY MANIFEST
From build.gradle.kts. Spring Boot version is managed by the org.springframework.boot plugin (4.0.4) plus io.spring.dependency-management (1.1.7); unversioned starters inherit from the BOM.
| Dependency | Version | Scope |
|---|---|---|
spring-boot-starter-data-jpa | (BOM) 4.0.4 | implementation |
spring-boot-starter-data-rest | (BOM) 4.0.4 | implementation |
jackson-module-kotlin | (BOM) | implementation |
kotlin-reflect | 2.3.20 | implementation |
querydsl-jpa / querydsl-apt | 5.1.0 | implementation |
springdoc-openapi-ui / springdoc-openapi-data-rest | 1.8.0 | implementation |
lombok | (BOM) | compileOnly + annotationProcessor |
mysql-connector-j | (BOM) | runtimeOnly |
kotlin-test-junit5 | 2.3.20 | testImplementation |
spring-boot-starter-test | (BOM) | testImplementation |
mockito-kotlin | 6.3.0 | testImplementation |
junit-platform-launcher | (BOM) | testRuntimeOnly |
Kotlin plugins: jvm, plugin.spring, plugin.jpa (all 2.3.20). Compiler arg -Xjsr305=strict. allOpen opens @Entity / @MappedSuperclass / @Embeddable classes for JPA proxying. Java toolchain pinned to 17.
@RUNTIME & PERSISTENCE
From src/main/resources/application.properties.
| Setting | Value |
|---|---|
| Datasource URL | jdbc:mysql://localhost:3306/root?useUnicode=true&serverTimezone=UTC&… |
| Username | root |
| Password | (empty) |
| show-sql | false |
| Naming strategy | PhysicalNamingStrategyStandardImpl |
| HTTP port | 8080 (Spring Boot default) |
/PROJECT METADATA
| Item | Value |
|---|---|
| Group / version | com.menketechnologies / 0.0.1-SNAPSHOT |
| Root project | learningcollection |
| Language / runtime | Kotlin 2.3.20 on JVM (JDK 17 toolchain) |
| Framework | Spring Boot 4.0.4 (Data JPA + Data REST) |
| Build system | Gradle 9.4.1 (wrapper) |
| Author | MenkeTechnologies |
| Repository | github.com/MenkeTechnologies/LearningCollectionAPI |
| Issues | github.com/MenkeTechnologies/LearningCollectionAPI/issues |
| Umbrella | MenkeTechnologiesMeta |
| Docs home | menketechnologies.github.io/LearningCollectionAPI |