Skip to content

feat(kotlin): add Kotlin/Ktor/Exposed ecosystem#309

Open
cookiee339 wants to merge 10 commits intoaffaan-m:mainfrom
cookiee339:feat/kotlin-ecosystem
Open

feat(kotlin): add Kotlin/Ktor/Exposed ecosystem#309
cookiee339 wants to merge 10 commits intoaffaan-m:mainfrom
cookiee339:feat/kotlin-ecosystem

Conversation

@cookiee339
Copy link

@cookiee339 cookiee339 commented Feb 28, 2026

Summary

Add comprehensive Kotlin ecosystem support with 19 files covering idiomatic Kotlin, Ktor server framework, JetBrains Exposed ORM, Kotest/MockK testing, Koin DI, and Kover coverage.

Files Added

Skills (4)

  • skills/kotlin-patterns/SKILL.md — Idiomatic Kotlin: coroutines, null safety, sealed classes, extension functions, DSL builders
  • skills/kotlin-testing/SKILL.md — Kotest (FunSpec, BehaviorSpec), MockK, coroutine testing, property-based testing, Kover coverage
  • skills/kotlin-ktor-patterns/SKILL.md — Ktor server: routing DSL, plugins, authentication, Koin DI, kotlinx.serialization, WebSockets, testApplication
  • skills/kotlin-exposed-patterns/SKILL.md — JetBrains Exposed ORM: DSL queries, DAO pattern, transactions, HikariCP, Flyway migrations, repository pattern

Agents (2)

  • agents/kotlin-reviewer.md — Kotlin code reviewer for idiomatic patterns, null safety, coroutine safety, and security
  • agents/kotlin-build-resolver.md — Kotlin/Gradle build error resolver for compiler errors, dependency issues, and Gradle config

Commands (3)

  • commands/kotlin-review.md/kotlin-review slash command to invoke the kotlin-reviewer agent
  • commands/kotlin-build.md/kotlin-build slash command to invoke the kotlin-build-resolver agent
  • commands/kotlin-test.md/kotlin-test slash command to enforce TDD with Kotest/Kover

Rules — Claude Code (5)

  • rules/kotlin/coding-style.md — Kotlin coding conventions, naming, immutability, coroutine patterns
  • rules/kotlin/patterns.md — Architecture patterns: repository, service layer, Ktor routing, Exposed DAOs
  • rules/kotlin/testing.md — Testing standards: Kotest, MockK, coroutine test dispatchers, 80%+ coverage
  • rules/kotlin/security.md — Security: input validation, SQL injection prevention, coroutine cancellation safety
  • rules/kotlin/hooks.md — Hook configurations for Kotlin/Gradle projects (detekt, ktlint, build checks)

Rules — Cursor (5)

  • .cursor/rules/kotlin-coding-style.md
  • .cursor/rules/kotlin-patterns.md
  • .cursor/rules/kotlin-testing.md
  • .cursor/rules/kotlin-security.md
  • .cursor/rules/kotlin-hooks.md

Type

  • Skill
  • Agent
  • Hook
  • Command
  • Rules (Claude Code + Cursor)

Testing

  • All 19 files installed locally via the ECC plugin cache and tested with Claude Code
  • Skills load correctly when triggered by Kotlin file context
  • Agents invoked successfully via commands (/kotlin-review, /kotlin-build, /kotlin-test)
  • Rules auto-apply when working in Kotlin projects
  • Cursor rules load in Cursor IDE with Kotlin files open

Design Notes

  • Single PR: All 19 files form a cohesive Kotlin ecosystem (same pattern as the existing Go ecosystem which bundles skills + agents + commands + rules)
  • Skill line counts: Some skills are 665-790 lines, exceeding the 500-line guideline. This is intentional for comprehensive coverage matching the depth of existing Go skills (~675 lines)

Checklist

  • Follows format guidelines (SKILL.md frontmatter, agent YAML headers, command descriptions)
  • Tested with Claude Code
  • No sensitive info (API keys, paths)
  • Clear descriptions
  • Follows existing patterns (matches Go ecosystem structure)

Summary by cubic

Adds a full Kotlin ecosystem (Ktor, Exposed, Kotest) with skills, agents, commands, and rules. Hardens security, improves build/test tooling and docs, and adds JSONB null-safety plus a small query optimization.

  • New Features

    • Ecosystem: 4 skills (Kotlin, Ktor, Exposed, testing), 2 agents, 3 commands; rules for Claude Code and Cursor.
    • Coverage: Kover with 80%+ target.
    • Security/framework hardening: JWT audience/issuer/subject checks; Exposed LIKE escaping; Ktor DI via Route-scoped by inject; stricter email regex; Hikari READ_COMMITTED.
    • Tooling: local ./gradlew clean with build-cache, Codecov v5; refreshed Ktor patterns; testing skill adds “How It Works”.
  • Bug Fixes

    • Coroutines: replace runCatching+await with try/catch that rethrows CancellationException.
    • Timestamps: DAO updatedAt uses OffsetDateTime.now; keep CurrentTimestampWithTimeZone for DSL updates.
    • JWT: add missing issuer check in validate blocks.
    • WebSockets: restore 64 KiB frame limit and masking=false; safer iteration.
    • Versions: Kotlin 2.3.10, Kotest 6.1.4.
    • Database: JSONB null-safety (avoid !! on PGobject.value); map insert result directly to avoid extra findById.
    • Docs: align SKILL.md structures; Kover HTML viewing steps for macOS/Linux/Windows; deduplicate testing examples; refine kotlin-patterns; add missing imports and serialization prerequisites in test examples.

Written for commit 5cacc96. Summary will update on new commits.

Summary by CodeRabbit

  • Documentation
    • Added comprehensive Kotlin guidance: coding style, idioms/patterns, security, testing, and framework skill guides (Exposed, Ktor).
    • Added procedural docs and commands for Kotlin build, review, test, and TDD workflows.
    • Introduced a Kotlin reviewer and build-resolver guidance to standardize reviews and troubleshooting.
    • Added recommended tooling and post-edit hooks for formatting, linting, static analysis, and build verification.

Add comprehensive Kotlin ecosystem with 19 files:
- 4 skills: kotlin-patterns, kotlin-testing, kotlin-ktor-patterns, kotlin-exposed-patterns
- 2 agents: kotlin-reviewer, kotlin-build-resolver
- 3 commands: kotlin-review, kotlin-build, kotlin-test
- 5 rules (Claude Code): rules/kotlin/
- 5 rules (Cursor): .cursor/rules/kotlin-*

Covers idiomatic Kotlin, coroutines, null safety, Ktor server,
Exposed ORM, Kotest/MockK testing, Koin DI, and Kover coverage.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 28, 2026

📝 Walkthrough

Walkthrough

Adds a comprehensive set of new Kotlin-focused documentation: Cursor-scoped rules/hooks, repo-level Kotlin rules, agent/role profiles, command workflows, and multiple SKILL knowledge pages. All changes are new Markdown docs; no executable code or public API changes.

Changes

Cohort / File(s) Summary
Cursor rule docs
​.cursor/rules/kotlin-coding-style.md, ​.cursor/rules/kotlin-hooks.md, ​.cursor/rules/kotlin-patterns.md, ​.cursor/rules/kotlin-security.md, ​.cursor/rules/kotlin-testing.md
New Cursor-scoped Kotlin rule and hook docs: file globs, formatting/hooks (ktfmt/ktlint, detekt, Gradle build), style, patterns, security, and testing guidance.
Repository rule docs
rules/kotlin/coding-style.md, rules/kotlin/hooks.md, rules/kotlin/patterns.md, rules/kotlin/security.md, rules/kotlin/testing.md
New org-level Kotlin rule docs mirroring Cursor content: formatting rules, immutability/null-safety, expression bodies, scope/extension/DI patterns, security best practices, and testing recommendations.
Agent docs
agents/kotlin-reviewer.md, agents/kotlin-build-resolver.md
New agent role docs: Kotlin reviewer profile and Kotlin/Gradle build resolver with diagnostics, commands, workflows, and output formats.
Command guides
commands/kotlin-build.md, commands/kotlin-review.md, commands/kotlin-test.md
New command-oriented guides for build/fix, review, and TDD/test workflows with example sessions, common errors, and verification steps.
SKILL knowledge base
skills/kotlin-patterns/SKILL.md, skills/kotlin-testing/SKILL.md, skills/kotlin-exposed-patterns/SKILL.md, skills/kotlin-ktor-patterns/SKILL.md
Extensive SKILL documents covering idiomatic Kotlin patterns, testing (Kotest/MockK), Exposed ORM patterns, and Ktor server patterns with runnable examples, migrations, and testing guidance.
Large files to inspect
skills/..., agents/..., commands/...
Several very large SKILL and command/agent files (hundreds of lines each); review for example accuracy, consistency, and any unsafe or environment-specific CLI/Gradle examples.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • affaan-m

Poem

🐇 I hopped through markdown, quill in paw,
Lined rules and patterns without a flaw.
Hooks and skills, tests all in a row,
I nibbled bugs and helped things grow—
Happy hops until the builds all glow.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding a comprehensive Kotlin ecosystem with skills, agents, commands, and rules.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

11 issues found across 19 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name=".cursor/rules/kotlin-security.md">

<violation number="1" location=".cursor/rules/kotlin-security.md:37">
P1: JWT `validate` block unconditionally returns `JWTPrincipal` without checking any claims — this is an insecure pattern, especially problematic in a security guidance document. Per the Ktor docs, the `validate` function should verify claims (e.g., audience, issuer, or custom claims) and return `null` for invalid tokens. The `verifier` should also include `.withAudience()` and `.withIssuer()` checks.</violation>
</file>

<file name="skills/kotlin-patterns/SKILL.md">

<violation number="1" location="skills/kotlin-patterns/SKILL.md:282">
P2: Misleading `supervisorScope` example: `await().getOrDefault()` doesn't catch async failures. `Deferred.await()` re-throws the coroutine's exception directly — it does not return `kotlin.Result<T>` — so `.getOrDefault(emptyList())` is unreachable on failure. This defeats the purpose of demonstrating `supervisorScope` for independent failure handling.

Wrap each `await()` in `runCatching` to actually handle child failures gracefully.</violation>
</file>

<file name="agents/kotlin-build-resolver.md">

<violation number="1" location="agents/kotlin-build-resolver.md:66">
P2: Avoid `rm -rf` on home-directory paths in agent instructions. This agent has `Bash` tool access and could execute this command automatically, clearing global Gradle caches that affect all projects on the machine. Existing agents in this repo only use `rm -rf` on project-local directories. Consider replacing with the project-scoped `./gradlew clean` (already present) or at minimum scoping to the project's local `.gradle` directory.</violation>
</file>

<file name="skills/kotlin-ktor-patterns/SKILL.md">

<violation number="1" location="skills/kotlin-ktor-patterns/SKILL.md:93">
P1: `call.inject<UserService>()` is not a valid Koin API. According to the Koin-Ktor documentation, `inject()` is available on `Application`, `Route`, and `Routing` — not on `ApplicationCall`. This example won't compile. The correct pattern (already shown later in the file at line 366) is `val userService by inject<UserService>()` at the `Route` scope.</violation>

<violation number="2" location="skills/kotlin-ktor-patterns/SKILL.md:476">
P1: Setting `maxFrameSize = Long.MAX_VALUE` removes any limit on WebSocket frame sizes, which can lead to denial-of-service via memory exhaustion from malicious clients. Use a reasonable production limit instead.</violation>

<violation number="3" location="skills/kotlin-ktor-patterns/SKILL.md:496">
P1: Iterating over a `Collections.synchronizedSet` with `forEach` without wrapping in a `synchronized(connections)` block is not thread-safe and can throw `ConcurrentModificationException`. The Java docs state: "It is imperative that the user manually synchronize on the returned set when iterating over it." In a coroutine context, consider using `ConcurrentHashMap.newKeySet()` or a `Mutex` instead.</violation>
</file>

<file name="commands/kotlin-review.md">

<violation number="1" location="commands/kotlin-review.md:70">
P2: Nested code blocks will break markdown rendering. The outer ` ```text ` fence is closed prematurely by the first inner ` ```kotlin ` fence on line 90. Use a longer outer fence (` ```` `) so the inner triple-backtick blocks are treated as literal content.

(Based on your team's feedback about using longer fences for nested code blocks.) [FEEDBACK_USED]</violation>
</file>

<file name="skills/kotlin-exposed-patterns/SKILL.md">

<violation number="1" location="skills/kotlin-exposed-patterns/SKILL.md:244">
P1: LIKE wildcard injection: user input is interpolated directly into the LIKE pattern without escaping SQL wildcard characters (`%`, `_`). While Exposed parameterizes the value (safe from SQL injection), a malicious query string like `%` or `_` would match all records. In a skill file teaching patterns, this should demonstrate proper sanitization. The same unsafe pattern is duplicated in `ExposedUserRepository.search` below.

Escape LIKE-special characters before interpolation, e.g.:
```kotlin
private fun String.escapeLike(): String =
    this.replace("%", "\\%").replace("_", "\\_")
```</violation>

<violation number="2" location="skills/kotlin-exposed-patterns/SKILL.md:370">
P1: Type mismatch in DAO example: `CurrentTimestampWithTimeZone` is an `Expression<OffsetDateTime>`, but DAO entity properties expect concrete Kotlin values (e.g., `OffsetDateTime`). This compiles in DSL-style (`it[updatedAt] = expr`) but not in DAO-style property assignment. Use a concrete timestamp value instead.</violation>
</file>

<file name="skills/kotlin-testing/SKILL.md">

<violation number="1" location="skills/kotlin-testing/SKILL.md:785">
P2: The `codecov/codecov-action@v4` example is missing the required `token` input (a v4 breaking change — tokenless upload is no longer supported) and uses the deprecated `file` parameter (renamed to `files`). Users copying this CI snippet will get upload failures.</violation>
</file>

<file name="rules/kotlin/security.md">

<violation number="1" location="rules/kotlin/security.md:38">
P1: JWT `validate` block unconditionally accepts any token without checking claims. For a security guidance document, this sets a dangerous example. According to the Ktor documentation, the `validate` block should verify payload claims (e.g., audience, issuer) before returning a `JWTPrincipal`. Returning `null` rejects the token.</violation>
</file>

Since this is your first cubic review, here's how it works:

  • cubic automatically reviews your code and comments on bugs and improvements
  • Teach cubic by replying to its comments. cubic learns from your replies and gets better over time
  • Add one-off context when rerunning by tagging @cubic-dev-ai with guidance or docs links (including llms.txt)
  • Ask questions if you need clarification on any suggestion

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 12

🧹 Nitpick comments (6)
.cursor/rules/kotlin-testing.md (1)

8-8: Hyphenate compound adjective.

The phrase "Kotlin specific" should be hyphenated as "Kotlin-specific" when used as a compound adjective before a noun.

✏️ Proposed fix
-> This file extends the common testing rule with Kotlin specific content.
+> This file extends the common testing rule with Kotlin-specific content.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.cursor/rules/kotlin-testing.md at line 8, Change the phrase "Kotlin
specific" to the hyphenated compound adjective "Kotlin-specific" in the sentence
"This file extends the common testing rule with Kotlin specific content." so it
reads "This file extends the common testing rule with Kotlin-specific content.";
update that exact string occurrence in the document.
.cursor/rules/kotlin-patterns.md (1)

8-8: Hyphenate compound adjective.

The phrase "Kotlin specific" should be hyphenated as "Kotlin-specific" when used as a compound adjective before a noun.

✏️ Proposed fix
-> This file extends the common patterns rule with Kotlin specific content.
+> This file extends the common patterns rule with Kotlin-specific content.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.cursor/rules/kotlin-patterns.md at line 8, Replace the unhyphenated
compound adjective "Kotlin specific" with the hyphenated form "Kotlin-specific"
throughout this file (e.g., in the sentence "This file extends the common
patterns rule with Kotlin specific content.") so that compound adjectives before
nouns are correctly hyphenated; search for the exact phrase "Kotlin specific"
and update each occurrence to "Kotlin-specific".
rules/kotlin/testing.md (1)

9-9: Hyphenate compound adjective.

The phrase "Kotlin specific" should be hyphenated as "Kotlin-specific" when used as a compound adjective before a noun.

✏️ Proposed fix
-> This file extends [common/testing.md](../common/testing.md) with Kotlin specific content.
+> This file extends [common/testing.md](../common/testing.md) with Kotlin-specific content.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@rules/kotlin/testing.md` at line 9, Change the compound adjective "Kotlin
specific" to the hyphenated form "Kotlin-specific" in the sentence "This file
extends [common/testing.md] ...", i.e., update the phrase inside the line that
currently reads "This file extends [common/testing.md](../common/testing.md)
with Kotlin specific content." to "This file extends
[common/testing.md](../common/testing.md) with Kotlin-specific content."
rules/kotlin/coding-style.md (1)

9-9: Hyphenate compound adjective.

The phrase "Kotlin specific" should be hyphenated as "Kotlin-specific" when used as a compound adjective before a noun.

✏️ Proposed fix
-> This file extends [common/coding-style.md](../common/coding-style.md) with Kotlin specific content.
+> This file extends [common/coding-style.md](../common/coding-style.md) with Kotlin-specific content.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@rules/kotlin/coding-style.md` at line 9, Replace the unhyphenated phrase
"Kotlin specific" in the sentence "This file extends
[common/coding-style.md](../common/coding-style.md) with Kotlin specific
content." with the hyphenated compound adjective "Kotlin-specific" so the
sentence reads "This file extends
[common/coding-style.md](../common/coding-style.md) with Kotlin-specific
content."
skills/kotlin-ktor-patterns/SKILL.md (2)

156-166: Document security implications of ignoreUnknownKeys = true.

While ignoreUnknownKeys = true (line 161) is common for forward compatibility, it can mask security issues when deserializing untrusted input. Consider adding a note that additional validation should be performed on request data, especially for security-sensitive operations.

📝 Suggested documentation addition
 fun Application.configureSerialization() {
     install(ContentNegotiation) {
         json(Json {
             prettyPrint = true
             isLenient = false
             ignoreUnknownKeys = true
             encodeDefaults = true
             explicitNulls = false
         })
     }
 }
+
+// Note: ignoreUnknownKeys = true allows forward compatibility but silently
+// discards unknown fields. Always validate untrusted input explicitly in routes.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@skills/kotlin-ktor-patterns/SKILL.md` around lines 156 - 166, In
configureSerialization() the JSON configuration sets ignoreUnknownKeys = true
which can silently drop unexpected fields and mask malicious or malformed input;
update SKILL.md to document this security implication and instruct developers to
perform explicit validation and strict schema checks for security-sensitive
endpoints (e.g., validate DTOs after deserialization, use manual field
whitelisting or additional checks, or consider turning off ignoreUnknownKeys in
trusted contexts), and reference the configureSerialization() block and the
ignoreUnknownKeys setting so readers know where to look.

452-466: Inconsistent email validation pattern.

Line 454 uses overly simplistic validation ('@' in request.email), which accepts invalid emails like "@@" or "@Domain". This conflicts with the more robust EMAIL_REGEX pattern shown earlier in the document (line 162 in the other file context). Consider updating this example to use a proper regex or extracting validation to a reusable function.

♻️ Suggested improvement
+private val EMAIL_REGEX = Regex("^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$")
+
 fun CreateUserRequest.validate() {
     require(name.isNotBlank()) { "Name is required" }
     require(name.length <= 100) { "Name must be 100 characters or less" }
-    require('@' in email) { "Invalid email format" }
+    require(EMAIL_REGEX.matches(email)) { "Invalid email format" }
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@skills/kotlin-ktor-patterns/SKILL.md` around lines 452 - 466, The email
checks use a simplistic '@' presence check in the request handler and in
CreateUserRequest.validate() which allows invalid emails; replace these with the
shared EMAIL_REGEX (or a single reusable function like isValidEmail(email:
String): Boolean) and use that in both the handler (where request.email is
validated before calling userService.create) and in CreateUserRequest.validate()
so both validation sites reference the same robust regex/utility (update the
require(...) calls to use EMAIL_REGEX.matches(email) or isValidEmail(email)).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.cursor/rules/kotlin-coding-style.md:
- Line 8: Change the prose phrase "Kotlin specific" to the hyphenated form
"Kotlin-specific" in the sentence that reads "This file extends the common
coding style rule with Kotlin specific content." so the line becomes "This file
extends the common coding style rule with Kotlin-specific content."; locate and
update that exact phrase ("Kotlin specific") accordingly.

In @.cursor/rules/kotlin-hooks.md:
- Line 8: Update the sentence "This file extends the common hooks rule with
Kotlin specific content." to use the hyphenated form by changing "Kotlin
specific" to "Kotlin-specific" so the line reads: "This file extends the common
hooks rule with Kotlin-specific content."; locate and edit that exact text in
.cursor/rules/kotlin-hooks.md.

In @.cursor/rules/kotlin-security.md:
- Line 8: Replace the phrase in the sentence "This file extends the common
security rule with Kotlin specific content." by changing "Kotlin specific" to
the hyphenated form "Kotlin-specific" so the line reads "This file extends the
common security rule with Kotlin-specific content."; update that exact string in
the .cursor/rules/kotlin-security.md content.

In `@agents/kotlin-build-resolver.md`:
- Around line 65-67: Replace the destructive global cache deletion line (`rm -rf
~/.gradle/caches/transforms-*`) with safer, project-scoped steps: keep
`./gradlew clean` and add guidance to use `./gradlew build
--refresh-dependencies` (or `./gradlew --refresh-dependencies`) for forcing
dependency refresh; mention any home-directory cache purge as an explicit manual
last-resort step rather than part of the automated resolver.

In `@commands/kotlin-test.md`:
- Around line 89-140: The tests access result.errors after calling
validateRegistration but result is typed as ValidationResult so you must
smart-cast or cast to ValidationResult.Invalid before accessing errors; update
each failing test (the ones creating RegistrationRequest and calling
validateRegistration in tests named "blank name returns Invalid", "invalid email
returns Invalid", "short password returns Invalid", and "multiple errors returns
all errors") to either use a when expression to handle ValidationResult and pull
the Invalid case or explicitly cast result to ValidationResult.Invalid (e.g.,
val invalid = result as ValidationResult.Invalid) before asserting on
invalid.errors.

In `@rules/kotlin/hooks.md`:
- Line 9: Update the phrase in the file that currently reads "Kotlin specific
content" (the sentence starting "This file extends [common/hooks.md]...") to use
the hyphenated compound adjective "Kotlin-specific content" so it reads "This
file extends [common/hooks.md] with Kotlin-specific content."

In `@rules/kotlin/patterns.md`:
- Line 9: Replace the phrase "Kotlin specific content" in the sentence "This
file extends [common/patterns.md](../common/patterns.md) with Kotlin specific
content." with the hyphenated form "Kotlin-specific content" to hyphenate the
compound adjective.

In `@rules/kotlin/security.md`:
- Line 9: Update the sentence in rules/kotlin/security.md that currently reads
"This file extends [common/security.md](../common/security.md) with Kotlin
specific content." to use the hyphenated form "Kotlin-specific content" for
consistency; locate the line containing that exact sentence and replace "Kotlin
specific content" with "Kotlin-specific content".

In `@skills/kotlin-exposed-patterns/SKILL.md`:
- Around line 24-50: The HikariCP default in DatabaseFactory.create currently
sets transactionIsolation = "TRANSACTION_REPEATABLE_READ"; update the docs
and/or code so the isolation level choice is consistent and justified: either
change the default in DatabaseFactory.create/DatabaseConfig to
"TRANSACTION_READ_COMMITTED" to match PostgreSQL defaults and the Transaction
Isolation examples, or keep REPEATABLE_READ but add a concise explanation in
SKILL.md that REPEATABLE_READ provides snapshot isolation, can surface
serialization anomalies requiring application-level retries, and include an
example usage and guidance on adding retry logic; also add REPEATABLE_READ to
the Transaction Isolation examples so the documentation and
DatabaseFactory.create config align.

In `@skills/kotlin-ktor-patterns/SKILL.md`:
- Around line 472-479: In Application.configureWebSockets(), replace the unsafe
production settings by capping maxFrameSize to a reasonable value (e.g., a few
megabytes) instead of Long.MAX_VALUE and enable masking (set masking = true);
also add a short comment above the WebSockets install explaining these are
production-recommended values that can be adjusted per deployment and link to
rationale (DoS/memory and masking protection) so future developers know why the
limits exist.

In `@skills/kotlin-patterns/SKILL.md`:
- Around line 489-540: Update the Kotlin and Kotest versions in the build
script: change both kotlin("jvm") and kotlin("plugin.serialization") plugin
versions from "2.3.0" to "2.3.10" (the plugin version strings at the top of the
file) and update the Kotest testImplementation coordinates
("io.kotest:kotest-runner-junit5" and "io.kotest:kotest-assertions-core" and
"io.kotest:kotest-property") from "6.1.3" to "6.1.4"; leave other dependency
versions (Ktor, Exposed, kotlinx-coroutines, mockk) unchanged. Ensure the
version strings match exactly where they appear in the plugins block and the
dependencies block so the build picks up Kotlin 2.3.10 and Kotest 6.1.4.

In `@skills/kotlin-testing/SKILL.md`:
- Around line 11-31: Update the SKILL.md top-level headings to match the
required format by adding explicit top-level sections named "When to Use", "How
It Works", and "Examples" (you can move/rename the existing "When to Activate"
-> "When to Use", "TDD Workflow for Kotlin" and "The RED-GREEN-REFACTOR Cycle"
-> into "How It Works", and the step-by-step content into "Examples" or split as
appropriate); ensure the existing bullets about writing Kotlin tests, TDD steps,
and Kover configuration remain unchanged semantically but are placed under the
new headings so the file conforms to the skills/**/*.md guideline.

---

Nitpick comments:
In @.cursor/rules/kotlin-patterns.md:
- Line 8: Replace the unhyphenated compound adjective "Kotlin specific" with the
hyphenated form "Kotlin-specific" throughout this file (e.g., in the sentence
"This file extends the common patterns rule with Kotlin specific content.") so
that compound adjectives before nouns are correctly hyphenated; search for the
exact phrase "Kotlin specific" and update each occurrence to "Kotlin-specific".

In @.cursor/rules/kotlin-testing.md:
- Line 8: Change the phrase "Kotlin specific" to the hyphenated compound
adjective "Kotlin-specific" in the sentence "This file extends the common
testing rule with Kotlin specific content." so it reads "This file extends the
common testing rule with Kotlin-specific content."; update that exact string
occurrence in the document.

In `@rules/kotlin/coding-style.md`:
- Line 9: Replace the unhyphenated phrase "Kotlin specific" in the sentence
"This file extends [common/coding-style.md](../common/coding-style.md) with
Kotlin specific content." with the hyphenated compound adjective
"Kotlin-specific" so the sentence reads "This file extends
[common/coding-style.md](../common/coding-style.md) with Kotlin-specific
content."

In `@rules/kotlin/testing.md`:
- Line 9: Change the compound adjective "Kotlin specific" to the hyphenated form
"Kotlin-specific" in the sentence "This file extends [common/testing.md] ...",
i.e., update the phrase inside the line that currently reads "This file extends
[common/testing.md](../common/testing.md) with Kotlin specific content." to
"This file extends [common/testing.md](../common/testing.md) with
Kotlin-specific content."

In `@skills/kotlin-ktor-patterns/SKILL.md`:
- Around line 156-166: In configureSerialization() the JSON configuration sets
ignoreUnknownKeys = true which can silently drop unexpected fields and mask
malicious or malformed input; update SKILL.md to document this security
implication and instruct developers to perform explicit validation and strict
schema checks for security-sensitive endpoints (e.g., validate DTOs after
deserialization, use manual field whitelisting or additional checks, or consider
turning off ignoreUnknownKeys in trusted contexts), and reference the
configureSerialization() block and the ignoreUnknownKeys setting so readers know
where to look.
- Around line 452-466: The email checks use a simplistic '@' presence check in
the request handler and in CreateUserRequest.validate() which allows invalid
emails; replace these with the shared EMAIL_REGEX (or a single reusable function
like isValidEmail(email: String): Boolean) and use that in both the handler
(where request.email is validated before calling userService.create) and in
CreateUserRequest.validate() so both validation sites reference the same robust
regex/utility (update the require(...) calls to use EMAIL_REGEX.matches(email)
or isValidEmail(email)).

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2d3be88 and ee625f4.

📒 Files selected for processing (19)
  • .cursor/rules/kotlin-coding-style.md
  • .cursor/rules/kotlin-hooks.md
  • .cursor/rules/kotlin-patterns.md
  • .cursor/rules/kotlin-security.md
  • .cursor/rules/kotlin-testing.md
  • agents/kotlin-build-resolver.md
  • agents/kotlin-reviewer.md
  • commands/kotlin-build.md
  • commands/kotlin-review.md
  • commands/kotlin-test.md
  • rules/kotlin/coding-style.md
  • rules/kotlin/hooks.md
  • rules/kotlin/patterns.md
  • rules/kotlin/security.md
  • rules/kotlin/testing.md
  • skills/kotlin-exposed-patterns/SKILL.md
  • skills/kotlin-ktor-patterns/SKILL.md
  • skills/kotlin-patterns/SKILL.md
  • skills/kotlin-testing/SKILL.md

- JWT: add audience/issuer/subject claims validation
- Ktor: replace call.inject with Route-scoped by inject
- WebSocket: cap maxFrameSize at 64 KiB, add masking comment
- WebSocket: snapshot-under-lock for synchronizedSet iteration
- Exposed: escape %, _, \ in LIKE patterns to prevent wildcard injection
- Exposed: use Clock.System.now() instead of CurrentTimestampWithTimeZone in DAO
- Gradle: use project-local ./gradlew clean + .gradle/build-cache/
- Coroutines: wrap supervisorScope await in runCatching
- Tests: capture shouldBeInstanceOf return value before accessing .errors
- Markdown: use 4-backtick outer fence for nested code blocks
- CI: upgrade codecov-action to v5, add token, fix file→files key
- Testing skill: add How It Works section
- Ktor: use Regex(".+@.+\\..+") for email validation
- Gradle: add version-check comment to build.gradle.kts example
- HikariCP: use TRANSACTION_READ_COMMITTED instead of REPEATABLE_READ
- Style: hyphenate "Kotlin-specific" across all 11 rule files
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
skills/kotlin-exposed-patterns/SKILL.md (1)

11-18: Consider adding explicit top-level sections per skill guidelines.

The skill includes "When to Activate" but is missing explicit "How It Works" and "Examples" top-level sections. While the content is comprehensive and well-organized with Database Setup, Table Definitions, DSL Queries, etc., the coding guidelines specify: "Skills should be formatted as Markdown with clear sections for When to Use, How It Works, and Examples." Consider adding these as top-level sections (you can alias "When to Activate" → "When to Use" and organize the current subsections under "How It Works" and "Examples").

As per coding guidelines: Skills should be formatted as Markdown with clear sections for When to Use, How It Works, and Examples.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@skills/kotlin-exposed-patterns/SKILL.md` around lines 11 - 18, Rename the
current top-level header "When to Activate" to "When to Use", and add two
explicit top-level sections "How It Works" and "Examples"; move the existing
subsections (Database Setup, Table Definitions, DSL Queries, HikariCP, Flyway,
Repository pattern, JSON columns/complex queries) under "How It Works" as
explanatory subsections and create a short "Examples" section that includes
usage snippets or links to the DSL/DAO examples already present so the SKILL.md
follows the required When to Use / How It Works / Examples structure.
skills/kotlin-testing/SKILL.md (1)

11-28: Improved section structure, but still missing explicit "Examples" top-level section.

The file now includes an explicit "How It Works" section (lines 19-28), which is an improvement over the past review. However, it still lacks a dedicated top-level "Examples" section as specified in the coding guidelines. While code examples are embedded throughout (TDD workflow, Kotest specs, MockK, etc.), consider adding an explicit "Examples" top-level section that either consolidates key examples or clearly delineates the examples section. You could also rename "When to Activate" to "When to Use" for exact guideline compliance.

As per coding guidelines: Skills should be formatted as Markdown with clear sections for When to Use, How It Works, and Examples.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@skills/kotlin-testing/SKILL.md` around lines 11 - 28, Update the SKILL.md
headings to match guidelines: rename the top-level heading "When to Activate" to
"When to Use" and add a new top-level "Examples" section after "How It Works"
that consolidates representative code snippets (a short Kotest spec example, a
MockK mocking example, a small TDD RED/GREEN snippet, and the kover command
example). Ensure the new "Examples" section is clearly labeled and contains
concise, runnable snippets that reference the same concepts already in the doc
so reviewers can find examples for StringSpec/FunSpec/BehaviorSpec, MockK usage,
and the ./gradlew koverHtmlReport command.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@skills/kotlin-exposed-patterns/SKILL.md`:
- Around line 11-18: Rename the current top-level header "When to Activate" to
"When to Use", and add two explicit top-level sections "How It Works" and
"Examples"; move the existing subsections (Database Setup, Table Definitions,
DSL Queries, HikariCP, Flyway, Repository pattern, JSON columns/complex queries)
under "How It Works" as explanatory subsections and create a short "Examples"
section that includes usage snippets or links to the DSL/DAO examples already
present so the SKILL.md follows the required When to Use / How It Works /
Examples structure.

In `@skills/kotlin-testing/SKILL.md`:
- Around line 11-28: Update the SKILL.md headings to match guidelines: rename
the top-level heading "When to Activate" to "When to Use" and add a new
top-level "Examples" section after "How It Works" that consolidates
representative code snippets (a short Kotest spec example, a MockK mocking
example, a small TDD RED/GREEN snippet, and the kover command example). Ensure
the new "Examples" section is clearly labeled and contains concise, runnable
snippets that reference the same concepts already in the doc so reviewers can
find examples for StringSpec/FunSpec/BehaviorSpec, MockK usage, and the
./gradlew koverHtmlReport command.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ee625f4 and 8f7de59.

📒 Files selected for processing (17)
  • .cursor/rules/kotlin-coding-style.md
  • .cursor/rules/kotlin-hooks.md
  • .cursor/rules/kotlin-patterns.md
  • .cursor/rules/kotlin-security.md
  • .cursor/rules/kotlin-testing.md
  • agents/kotlin-build-resolver.md
  • commands/kotlin-review.md
  • commands/kotlin-test.md
  • rules/kotlin/coding-style.md
  • rules/kotlin/hooks.md
  • rules/kotlin/patterns.md
  • rules/kotlin/security.md
  • rules/kotlin/testing.md
  • skills/kotlin-exposed-patterns/SKILL.md
  • skills/kotlin-ktor-patterns/SKILL.md
  • skills/kotlin-patterns/SKILL.md
  • skills/kotlin-testing/SKILL.md
✅ Files skipped from review due to trivial changes (2)
  • .cursor/rules/kotlin-testing.md
  • skills/kotlin-ktor-patterns/SKILL.md
🚧 Files skipped from review as they are similar to previous changes (6)
  • .cursor/rules/kotlin-coding-style.md
  • .cursor/rules/kotlin-hooks.md
  • .cursor/rules/kotlin-patterns.md
  • skills/kotlin-patterns/SKILL.md
  • rules/kotlin/testing.md
  • commands/kotlin-test.md

Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 issues found across 17 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="skills/kotlin-exposed-patterns/SKILL.md">

<violation number="1" location="skills/kotlin-exposed-patterns/SKILL.md:374">
P2: Type mismatch and inconsistency: `Clock.System.now()` returns `kotlinx.datetime.Instant` but the column is defined with `timestampWithTimeZone` (expects `java.time.OffsetDateTime`). Every other `updatedAt` assignment in this file uses `CurrentTimestampWithTimeZone` (the DB-side timestamp expression). This should match for consistency and to avoid application-vs-database clock skew.</violation>
</file>

<file name="skills/kotlin-patterns/SKILL.md">

<violation number="1" location="skills/kotlin-patterns/SKILL.md:282">
P1: Using `runCatching` with `await()` (a suspend function) swallows `CancellationException`, breaking structured concurrency. This is a known anti-pattern ([KT-W1066](https://deepsource.com/directory/kotlin/issues/KT-W1066), [kotlinx.coroutines#1814](https://github.com/Kotlin/kotlinx.coroutines/issues/1814)). In a best-practices skill file, this will teach readers an unsafe pattern.

Use an explicit `try`/`catch` that rethrows `CancellationException`, or show a coroutine-safe `suspendRunCatching` helper.</violation>
</file>

<file name="rules/kotlin/security.md">

<violation number="1" location="rules/kotlin/security.md:45">
P2: JWT `validate` block checks audience but not issuer, despite both being configured in the verifier. Since this is a security best-practices example, the validation should be consistent — either re-check both claims for defense-in-depth or note that the verifier already handles them. Missing the issuer check here may mislead developers following this guide.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 1 file (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="skills/kotlin-ktor-patterns/SKILL.md">

<violation number="1" location="skills/kotlin-ktor-patterns/SKILL.md:478">
P1: This increases `maxFrameSize` from 64 KiB to 1 MB, contradicting the PR description which lists "WebSocket maxFrameSize 64 KiB" as a security hardening. A 1 MB frame limit makes the server more susceptible to memory-based denial-of-service. For a best-practices skill document, the previous conservative 64 KiB default with the cautionary comment was more appropriate.</violation>

<violation number="2" location="skills/kotlin-ktor-patterns/SKILL.md:479">
P2: Setting `masking = true` on the server side adds unnecessary XOR overhead on every outgoing frame. Per RFC 6455, masking is a client-to-server mechanism; server-to-client frames should not be masked. Ktor's own docs show `masking = false` as the default. The previous value (`false`) with the RFC explanation was correct.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

- Replace runCatching+await() anti-pattern with explicit try/catch that
  rethrows CancellationException to preserve structured concurrency
- Fix Clock.System.now() type mismatch by using CurrentTimestampWithTimeZone
  for consistency with other updatedAt assignments
- Add missing issuer check in JWT validate blocks for defense-in-depth
- Update Kotlin 2.3.0 -> 2.3.10 and Kotest 6.1.3 -> 6.1.4
- Restructure kotlin-testing SKILL.md with required When to Use, How It
  Works, and Examples top-level sections
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
skills/kotlin-testing/SKILL.md (1)

81-113: Consolidate duplicated examples to avoid drift.

The RED/GREEN email example and MockK basic mocking example are duplicated in multiple sections. Consider keeping one canonical example per topic and cross-linking to it.

Also applies to: 142-196, 49-79, 380-412

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@skills/kotlin-testing/SKILL.md` around lines 81 - 113, Consolidate duplicated
Kotlin examples by keeping one canonical implementation and test pair (the
validateEmail function and EmailValidatorTest) and replace other copies with
cross-references; specifically, retain the validateEmail(...) function and
EmailValidatorTest class as the single source of truth, remove duplicated blocks
elsewhere, and add internal links or references to that canonical section for
other mentions (e.g., where the RED/GREEN or MockK examples currently repeat) so
examples don't drift and maintenance stays centralized.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@skills/kotlin-exposed-patterns/SKILL.md`:
- Around line 11-19: Rename the top-level heading "When to Activate" to the
required "When to Use", and add the missing top-level headings "How It Works"
and "Examples" so the document follows the skills format; move the current
bullet list under the new "When to Use" heading, add a concise "How It Works"
section explaining Exposed + HikariCP/Flyway/DAO usage, and add at least one
small "Examples" snippet or referenced example note demonstrating Exposed
DSL/DAO usage and connection pooling; ensure headings are top-level (e.g., "#
When to Use", "# How It Works", "# Examples") and keep existing content but
reorganize under these headings.

In `@skills/kotlin-patterns/SKILL.md`:
- Around line 11-18: Rename the top-level "When to Activate" heading to "When to
Use" and reorganize the document to include top-level "How It Works" and
"Examples" headings; move or duplicate the existing bullets about
writing/reviewing/refactoring/configuring Kotlin under "When to Use", create a
"How It Works" section (can describe the skill's mechanics or triggers) and an
"Examples" section (add one or more usage examples or scenarios), ensuring the
SKILL.md follows the required top-level headings "When to Use", "How It Works",
and "Examples".

---

Nitpick comments:
In `@skills/kotlin-testing/SKILL.md`:
- Around line 81-113: Consolidate duplicated Kotlin examples by keeping one
canonical implementation and test pair (the validateEmail function and
EmailValidatorTest) and replace other copies with cross-references;
specifically, retain the validateEmail(...) function and EmailValidatorTest
class as the single source of truth, remove duplicated blocks elsewhere, and add
internal links or references to that canonical section for other mentions (e.g.,
where the RED/GREEN or MockK examples currently repeat) so examples don't drift
and maintenance stays centralized.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6fa82f3 and cc82320.

📒 Files selected for processing (5)
  • .cursor/rules/kotlin-security.md
  • rules/kotlin/security.md
  • skills/kotlin-exposed-patterns/SKILL.md
  • skills/kotlin-patterns/SKILL.md
  • skills/kotlin-testing/SKILL.md
✅ Files skipped from review due to trivial changes (1)
  • .cursor/rules/kotlin-security.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • rules/kotlin/security.md

Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 5 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="skills/kotlin-exposed-patterns/SKILL.md">

<violation number="1" location="skills/kotlin-exposed-patterns/SKILL.md:374">
P1: `CurrentTimestampWithTimeZone` is an SQL `Expression`/`Function` object, not an actual timestamp value. In the DAO pattern, entity property delegates expect the mapped Kotlin type (e.g., `Instant`), so this assignment won't compile. The original `Clock.System.now()` was correct for DAO usage. (`CurrentTimestampWithTimeZone` is valid in DSL-style updates like `it[updatedAt] = CurrentTimestampWithTimeZone`, which this file already uses correctly elsewhere.)</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Revert accidental regression from 6fa82f3 that increased maxFrameSize
from 64 KiB to 1 MB and set masking=true on the server side. The
original values from 8f7de59 were correct: 64 KiB frame limit for DoS
protection and masking=false per RFC 6455.
- Rename "When to Activate" to "When to Use" in kotlin-exposed-patterns
  and kotlin-patterns
- Add "How It Works" and "Examples" top-level sections to both files
- Deduplicate kotlin-testing examples by replacing full code blocks with
  cross-references to canonical sections
CurrentTimestampWithTimeZone is an SQL expression that works in DSL
updates but not in DAO property assignments where the delegated property
expects a concrete OffsetDateTime value.
Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 4 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="skills/kotlin-patterns/SKILL.md">

<violation number="1" location="skills/kotlin-patterns/SKILL.md:21">
P3: The description says "six key areas" but lists seven. Either update the count to "seven" or merge/remove one item to match.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
skills/kotlin-exposed-patterns/SKILL.md (1)

537-545: Avoid nested repository calls inside a transaction example.

At Line 544, findById(id.value) from inside newSuspendedTransaction is a misleading pattern for Exposed docs (extra transaction boundary and unnecessary second round-trip). Prefer mapping from the inserted row directly.

Suggested example refinement
 override suspend fun create(request: CreateUserRequest): User =
     newSuspendedTransaction(db = database) {
-        val id = UsersTable.insertAndGetId {
-            it[name] = request.name
-            it[email] = request.email
-            it[role] = request.role
-        }
-        findById(id.value)!!
+        val row = UsersTable.insert {
+            it[name] = request.name
+            it[email] = request.email
+            it[role] = request.role
+        }.resultedValues!!.single()
+        row.toUser()
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@skills/kotlin-exposed-patterns/SKILL.md` around lines 537 - 545, The create
suspend function currently performs an extra repository lookup by calling
findById(id.value) inside newSuspendedTransaction, causing an extra transaction
boundary and round-trip; instead, after inserting via UsersTable.insertAndGetId
(or use UsersTable.insert) map the inserted row/insert statement result directly
to a User and return it within the same newSuspendedTransaction block—replace
the findById call with direct mapping logic that builds the User from the
inserted columns (name, email, role, id) in the create(CreateUserRequest)
implementation.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@skills/kotlin-exposed-patterns/SKILL.md`:
- Around line 591-594: In valueFromDB (the JSONB decoding branch) avoid the
unsafe non-null assertion on PGobject.value; instead read PGobject.value into a
local nullable variable, explicitly check for null and throw an
IllegalArgumentException (or other clear error) with a descriptive message if it
is null, otherwise pass the non-null string to json.decodeFromString; update the
PGobject branch in valueFromDB to perform this null-check rather than using !!
so callers see a clear error instead of an NPE.

In `@skills/kotlin-testing/SKILL.md`:
- Around line 680-692: The README currently uses the macOS-only `open` command
to view the Kover HTML report; update SKILL.md so the instructions are
cross-platform by replacing or augmenting the `open
build/reports/kover/html/index.html` line with OS-specific alternatives (e.g.,
`xdg-open` for Linux, `start` for Windows) or a portable suggestion (e.g., "open
the generated file in your browser" or use a tiny Java/Gradle task to serve the
report). Reference the existing gradle task names (koverHtmlReport, koverVerify,
koverXmlReport) and ensure the doc block lists alternatives for macOS, Linux,
and Windows so users can open the HTML report regardless of OS.

---

Nitpick comments:
In `@skills/kotlin-exposed-patterns/SKILL.md`:
- Around line 537-545: The create suspend function currently performs an extra
repository lookup by calling findById(id.value) inside newSuspendedTransaction,
causing an extra transaction boundary and round-trip; instead, after inserting
via UsersTable.insertAndGetId (or use UsersTable.insert) map the inserted
row/insert statement result directly to a User and return it within the same
newSuspendedTransaction block—replace the findById call with direct mapping
logic that builds the User from the inserted columns (name, email, role, id) in
the create(CreateUserRequest) implementation.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cc82320 and 88a29f7.

📒 Files selected for processing (4)
  • skills/kotlin-exposed-patterns/SKILL.md
  • skills/kotlin-ktor-patterns/SKILL.md
  • skills/kotlin-patterns/SKILL.md
  • skills/kotlin-testing/SKILL.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • skills/kotlin-patterns/SKILL.md
  • skills/kotlin-ktor-patterns/SKILL.md

cookiee339 and others added 2 commits February 28, 2026 23:50
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
- Replace unsafe !! on PGobject.value with explicit null check and
  descriptive error message in JSONB column type
- Add Linux/Windows alternatives for viewing Kover HTML report
- Map insert result directly in create() instead of extra findById call
@cookiee339
Copy link
Author

@coderabbitai resume

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 28, 2026

✅ Actions performed

Reviews resumed.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
skills/kotlin-testing/SKILL.md (2)

437-455: Consider adding missing imports for completeness.

The debounce testing example uses MutableSharedFlow and launch without showing imports. While experienced developers will recognize these, adding the imports would make the example more self-contained for learners.

📚 Suggested addition
 import io.kotest.matchers.collections.shouldContainInOrder
 import kotlinx.coroutines.flow.toList
 import kotlinx.coroutines.test.runTest
+import kotlinx.coroutines.flow.MutableSharedFlow
+import kotlinx.coroutines.launch

 class FlowServiceTest : FunSpec({
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@skills/kotlin-testing/SKILL.md` around lines 437 - 455, The example is
missing imports for coroutine/test types used in the debounce test; add the
appropriate imports so the code is self-contained (e.g., imports for
MutableSharedFlow, launch, runTest, advanceTimeBy, and any test coroutine scope
utilities) and ensure SearchService and User types are resolved in the example's
context so the test compiles and runs as-is.

509-517: Consider adding a note about serialization requirements.

The property testing example for serialization roundtrip (line 513) uses Json.encodeToString without showing the required import or that the User class needs the @Serializable annotation. A brief note would help readers understand the prerequisites.

📝 Suggested addition

Add a comment before the test:

+    // Requires: import kotlinx.serialization.json.Json
+    //           and `@Serializable` annotation on User class
     test("serialization roundtrip preserves data") {
         checkAll(Arb.bind(Arb.string(1..50), Arb.string(5..100)) { name, email ->
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@skills/kotlin-testing/SKILL.md` around lines 509 - 517, Add a short
explanatory comment before the test("serialization roundtrip preserves data")
explaining that Json.encodeToString/Json.decodeFromString require
kotlinx.serialization and that the data class User must be annotated with
`@Serializable` (and appropriate imports for kotlinx.serialization.json.Json and
kotlinx.serialization.Serializable must be present), so readers know the
prerequisites for the example to compile and run.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@skills/kotlin-testing/SKILL.md`:
- Around line 437-455: The example is missing imports for coroutine/test types
used in the debounce test; add the appropriate imports so the code is
self-contained (e.g., imports for MutableSharedFlow, launch, runTest,
advanceTimeBy, and any test coroutine scope utilities) and ensure SearchService
and User types are resolved in the example's context so the test compiles and
runs as-is.
- Around line 509-517: Add a short explanatory comment before the
test("serialization roundtrip preserves data") explaining that
Json.encodeToString/Json.decodeFromString require kotlinx.serialization and that
the data class User must be annotated with `@Serializable` (and appropriate
imports for kotlinx.serialization.json.Json and
kotlinx.serialization.Serializable must be present), so readers know the
prerequisites for the example to compile and run.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 88a29f7 and eb1d023.

📒 Files selected for processing (3)
  • skills/kotlin-exposed-patterns/SKILL.md
  • skills/kotlin-patterns/SKILL.md
  • skills/kotlin-testing/SKILL.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • skills/kotlin-patterns/SKILL.md
  • skills/kotlin-exposed-patterns/SKILL.md

…ples

- Add MutableSharedFlow, launch, advanceTimeBy imports to Flow test
- Add kotlinx.serialization imports and @serializable prerequisite note
  to property-based testing example
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
skills/kotlin-testing/SKILL.md (1)

41-824: Consider nesting detailed content under Examples for clearer hierarchy.

From Line 41 onward, most sections are still top-level (##). Making them ### under ## Examples would improve scanability and keep the document structure tighter.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@skills/kotlin-testing/SKILL.md` around lines 41 - 824, The document uses many
top-level headings from "TDD Workflow for Kotlin" onward; group these under a
new "## Examples" section by converting those subsequent top-level headings
(e.g., "TDD Workflow for Kotlin", "Kotest Spec Styles", "Kotest Matchers",
"MockK", "Coroutine Testing", "Property-Based Testing", "Data-Driven Testing",
"Test Lifecycle and Fixtures", "Kotest Extensions", "Kover Coverage", "Ktor
testApplication Testing", etc.) into third-level headings (###) nested beneath a
newly inserted "## Examples" heading; update the heading levels consistently
throughout SKILL.md and adjust any internal anchors or TOC entries to match the
new hierarchy.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@skills/kotlin-testing/SKILL.md`:
- Around line 41-824: The document uses many top-level headings from "TDD
Workflow for Kotlin" onward; group these under a new "## Examples" section by
converting those subsequent top-level headings (e.g., "TDD Workflow for Kotlin",
"Kotest Spec Styles", "Kotest Matchers", "MockK", "Coroutine Testing",
"Property-Based Testing", "Data-Driven Testing", "Test Lifecycle and Fixtures",
"Kotest Extensions", "Kover Coverage", "Ktor testApplication Testing", etc.)
into third-level headings (###) nested beneath a newly inserted "## Examples"
heading; update the heading levels consistently throughout SKILL.md and adjust
any internal anchors or TOC entries to match the new hierarchy.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between eb1d023 and 5cacc96.

📒 Files selected for processing (1)
  • skills/kotlin-testing/SKILL.md

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant