Skip to content

Conversation

@catturtle123
Copy link
Contributor

@catturtle123 catturtle123 commented Aug 23, 2025

📌 Overview

create prompt

🔍 Related Issues

✨ Changes

📸 Screenshots / Test Results (Optional)

Attach images or videos if necessary.

✅ Checklist

  • I have followed the code style guidelines.
  • I have removed unnecessary comments or console logs.
  • I have written/updated related tests.
  • I have verified that all features work correctly in my local environment.

🗒️ Additional Notes

Add any other context or information here.

Summary by CodeRabbit

  • New Features
    • Added an API endpoint to create prompts and return the new prompt’s ID.
    • Supports multiple built-in presets (Custom, RAG QA, RAG Summarizer, Code Review Backend/General, EN–KO Translation, Multi-language Translation, Korean Proofreading, Text Summarizer, Data Cleaner, Email Writer, Safety Filtered) with default system prompts.
    • Input validation added for prompt name and system prompt length; created prompts are persisted for later use.

@catturtle123 catturtle123 self-assigned this Aug 23, 2025
@catturtle123 catturtle123 added the feature New feature or request label Aug 23, 2025
@catturtle123 catturtle123 linked an issue Aug 23, 2025 that may be closed by this pull request
2 tasks
@coderabbitai
Copy link

coderabbitai bot commented Aug 23, 2025

Walkthrough

Adds prompt creation functionality: new POST /api/v1/prompts controller, request/response DTOs, service with transactional create/save flow, JPA repository, Prompt factory method from request, and an expanded PreSet enum with multiple presets and default system prompts.

Changes

Cohort / File(s) Summary
API Layer: Controller
src/main/kotlin/simplerag/ragback/domain/prompt/controller/PromptController.kt
New REST controller at /api/v1/prompts with POST endpoint accepting PromptCreateRequest and returning ApiResponse<PromptPreviewResponse> by delegating to PromptService.
Service & Repository
src/main/kotlin/simplerag/ragback/domain/prompt/service/PromptService.kt, src/main/kotlin/simplerag/ragback/domain/prompt/repository/PromptRepository.kt
PromptService added with createPrompt (transactional) that maps request to entity, saves via PromptRepository : JpaRepository<Prompt, Long>, and returns preview DTO.
DTOs
src/main/kotlin/simplerag/ragback/domain/prompt/dto/PromptRequestDTO.kt, src/main/kotlin/simplerag/ragback/domain/prompt/dto/PromptResponseDTO.kt
Added PromptCreateRequest(name, preSet, systemPrompt) with validation and PromptPreviewResponse(id) plus from(prompt) factory.
Domain Model & Enums
src/main/kotlin/simplerag/ragback/domain/prompt/entity/Prompt.kt, src/main/kotlin/simplerag/ragback/domain/prompt/entity/enums/PreSet.kt
Prompt companion factory from(PromptCreateRequest) selects system prompt based on PreSet; PreSet refactored to include description and defaultSystemPrompt with multiple preset constants (e.g., CUSTOM, RAG_QA, ...).

Sequence Diagram(s)

sequenceDiagram
    autonumber
    actor Client
    participant Controller as PromptController
    participant Service as PromptService
    participant Repo as PromptRepository
    participant Entity as Prompt

    Client->>Controller: POST /api/v1/prompts (PromptCreateRequest)
    Controller->>Service: createPrompt(request)
    Service->>Entity: Prompt.from(request)
    Service->>Repo: save(prompt)
    Repo-->>Service: savedPrompt
    Service-->>Controller: PromptPreviewResponse.from(savedPrompt)
    Controller-->>Client: ApiResponse<PromptPreviewResponse> (201)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Assessment against linked issues

Objective Addressed Explanation
Add OpenSource Prompt Set (#21)
Create Prompt API (#21)

I nibble lines and hop with glee,
New presets sprout for all to see.
A POST, a save, an ID that beams,
Carrots of code and rabbit dreams. 🥕🐇

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/#21-create-prompt

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@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: 11

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/main/kotlin/simplerag/ragback/domain/prompt/entity/Prompt.kt (1)

19-21: Consider setting an explicit TEXT type for portability

@Lob without columnDefinition can become a BLOB on some dialects. If you target PostgreSQL/MySQL and intend a large text column, prefer an explicit type (e.g., TEXT).

Add (outside this hunk):

@Column(name = "system_prompt", nullable = false, columnDefinition = "TEXT")
@Lob
val systemPrompt: String,
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 0b38578 and 5575d84.

📒 Files selected for processing (7)
  • src/main/kotlin/simplerag/ragback/domain/prompt/controller/PromptController.kt (1 hunks)
  • src/main/kotlin/simplerag/ragback/domain/prompt/dto/PromptRequestDTO.kt (1 hunks)
  • src/main/kotlin/simplerag/ragback/domain/prompt/dto/PromptResponseDTO.kt (1 hunks)
  • src/main/kotlin/simplerag/ragback/domain/prompt/entity/Prompt.kt (2 hunks)
  • src/main/kotlin/simplerag/ragback/domain/prompt/entity/enums/PreSet.kt (1 hunks)
  • src/main/kotlin/simplerag/ragback/domain/prompt/repository/PromptRepository.kt (1 hunks)
  • src/main/kotlin/simplerag/ragback/domain/prompt/service/PromptService.kt (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
src/main/kotlin/simplerag/ragback/domain/prompt/controller/PromptController.kt (2)
src/main/kotlin/simplerag/ragback/domain/index/controller/IndexController.kt (2)
  • indexService (11-59)
  • HttpStatus (18-25)
src/main/kotlin/simplerag/ragback/domain/document/controller/DataFileController.kt (1)
  • dataFileService (20-64)
src/main/kotlin/simplerag/ragback/domain/prompt/repository/PromptRepository.kt (2)
src/main/kotlin/simplerag/ragback/domain/prompt/entity/FewShot.kt (1)
  • name (6-29)
src/main/kotlin/simplerag/ragback/domain/chat/entity/Model.kt (1)
  • name (8-29)
src/main/kotlin/simplerag/ragback/domain/prompt/dto/PromptResponseDTO.kt (2)
src/main/kotlin/simplerag/ragback/domain/document/dto/DataFileResponseDTO.kt (4)
  • id (14-25)
  • id (44-65)
  • from (19-23)
  • id (68-78)
src/main/kotlin/simplerag/ragback/domain/index/dto/IndexResponseDTO.kt (2)
  • indexId (20-32)
  • toIndexPreviewResponse (25-30)
🔇 Additional comments (2)
src/main/kotlin/simplerag/ragback/domain/prompt/controller/PromptController.kt (1)

3-11: I’ve added scripts to print the first 200 lines of both PromptController.kt and IndexController.kt so we can verify if the suggested annotations and imports are used or missing. Once we have the outputs, we can confirm whether to add @ResponseStatus, HttpStatus, @Validated, and @Valid (or javax.validation.Valid) imports.

src/main/kotlin/simplerag/ragback/domain/prompt/service/PromptService.kt (1)

10-12: Transactional boundaries and mapping look solid

Service is correctly read-only by default with a write method for creation. Mapping via the entity factory and returning a preview DTO is clean.

Also applies to: 16-23

Comment on lines +12 to +16
@RestController
@RequestMapping("/api/v1/prompts")
class PromptController(
private val promptService: PromptService
) {
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Return HTTP 201 for creation and enable bean validation on the request

Consistent with your Index/DataFile controllers, mark the POST as 201 Created and enable validation.

 @RestController
 @RequestMapping("/api/v1/prompts")
-class PromptController(
+@Validated
+class PromptController(
     private val promptService: PromptService
 ) {

     @PostMapping
+    @ResponseStatus(HttpStatus.CREATED)
     fun createPrompt(
-        @RequestBody promptCreateRequest: PromptCreateRequest
+        @RequestBody @Valid promptCreateRequest: PromptCreateRequest
     ): ApiResponse<PromptPreviewResponse> {
         val savedPrompt = promptService.createPrompt(promptCreateRequest)
         return ApiResponse.ok(savedPrompt)
     }

To confirm consistency across controllers, you can run:

Also applies to: 18-23


🏁 Script executed:

#!/bin/bash
# Show POST endpoints and whether they declare 201
rg -nP --type=kt -C2 '@PostMapping' src/main/kotlin/simplerag/ragback/domain/.+?/controller/.+?Controller\.kt \
  | sed -n '1,200p'

Length of output: 153


To ensure we correctly mirror the behavior of your existing controllers, let’s re-scan all controller classes for @PostMapping and check whether they already declare @ResponseStatus(HttpStatus.CREATED) and @Valid. Please run:


🏁 Script executed:

#!/bin/bash
# Find all @PostMapping in controller classes and show surrounding lines
rg -n '@PostMapping' -C2 src/main/kotlin/simplerag/ragback/domain/*/controller/*Controller.kt

Length of output: 1791


To confirm the exact annotations on your existing POST endpoints, let’s extract the relevant snippets from both controllers:


🏁 Script executed:

#!/bin/bash
echo "=== IndexController.createIndex ==="
rg -nP -C3 'fun createIndex' src/main/kotlin/simplerag/ragback/domain/index/controller/IndexController.kt || true
rg -nP '@RequestBody' -C3 src/main/kotlin/simplerag/ragback/domain/index/controller/IndexController.kt || true
rg -nP '@Valid' -C3 src/main/kotlin/simplerag/ragback/domain/index/controller/IndexController.kt || true
rg -nP '@ResponseStatus' -C3 src/main/kotlin/simplerag/ragback/domain/index/controller/IndexController.kt || true

echo
echo "=== DataFileController POST ==="
rg -nP -C5 '@PostMapping' src/main/kotlin/simplerag/ragback/domain/document/controller/DataFileController.kt || true
rg -nP '@ResponseStatus' -C3 src/main/kotlin/simplerag/ragback/domain/document/controller/DataFileController.kt || true
rg -nP '@Validated' -C3 src/main/kotlin/simplerag/ragback/domain/document/controller/DataFileController.kt || true

Length of output: 3599


PromptController: mark POST create as 201 Created and enable bean validation

To stay consistent with your other controllers, please update PromptController as follows:

• File: src/main/kotlin/simplerag/ragback/domain/prompt/controller/PromptController.kt
• Add @Validated at the class level
• Annotate the createPrompt method with @ResponseStatus(HttpStatus.CREATED)
• Add @Valid to the @RequestBody parameter

 @RestController
 @RequestMapping("/api/v1/prompts")
-@Validated
-class PromptController(
+@Validated
+class PromptController(
     private val promptService: PromptService
 ) {

     @PostMapping
+    @ResponseStatus(HttpStatus.CREATED)
     fun createPrompt(
-        @RequestBody promptCreateRequest: PromptCreateRequest
+        @RequestBody @Valid promptCreateRequest: PromptCreateRequest
     ): ApiResponse<PromptPreviewResponse> {
         val savedPrompt = promptService.createPrompt(promptCreateRequest)
         return ApiResponse.ok(savedPrompt)
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@RestController
@RequestMapping("/api/v1/prompts")
class PromptController(
private val promptService: PromptService
) {
@RestController
@RequestMapping("/api/v1/prompts")
@Validated
class PromptController(
private val promptService: PromptService
) {
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
fun createPrompt(
@RequestBody @Valid promptCreateRequest: PromptCreateRequest
): ApiResponse<PromptPreviewResponse> {
val savedPrompt = promptService.createPrompt(promptCreateRequest)
return ApiResponse.ok(savedPrompt)
}
}
🤖 Prompt for AI Agents
In
src/main/kotlin/simplerag/ragback/domain/prompt/controller/PromptController.kt
around lines 12–16, the controller should enable bean validation and return the
correct status for POST: add the @Validated annotation at the class level,
annotate the createPrompt handler with @ResponseStatus(HttpStatus.CREATED), and
add @Valid to the @RequestBody parameter; also add the necessary imports
(org.springframework.validation.annotation.Validated,
org.springframework.web.bind.annotation.ResponseStatus,
org.springframework.http.HttpStatus and javax/ jakarta.validation.Valid
depending on your setup).

Comment on lines 6 to 10
data class PromptCreateRequest(
val name: String,
val preSet: PreSet,
val systemPrompt: String,
) No newline at end of file
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add bean validation and make systemPrompt optional for non-CUSTOM presets

Right now any request must provide a systemPrompt even when a preset will override it, and there’s no validation aligned with your DB constraints (name length = 100). Enforce invariants at the edge and improve DX by making systemPrompt optional unless preSet == CUSTOM.

Apply this diff to the DTO:

 data class PromptCreateRequest(
-    val name: String,
-    val preSet: PreSet,
-    val systemPrompt: String,
+    @field:jakarta.validation.constraints.NotBlank
+    @field:jakarta.validation.constraints.Size(max = 100)
+    val name: String,
+    val preSet: PreSet,
+    @field:jakarta.validation.constraints.Size(max = 20000)
+    val systemPrompt: String? = null,
 )

And ensure the controller method is annotated with @Validated so these constraints are enforced.

Additionally add the missing imports (outside the changed hunk):

import jakarta.validation.constraints.NotBlank
import jakarta.validation.constraints.Size
🤖 Prompt for AI Agents
In src/main/kotlin/simplerag/ragback/domain/prompt/dto/PromptRequestDTO.kt
around lines 6 to 10, add bean validation to align with DB constraints and make
systemPrompt optional unless preSet == CUSTOM: annotate the name field with
@field:NotBlank and @field:Size(max = 100) to enforce non-empty and max length
100; keep preSet required; change systemPrompt to nullable (String?) and remove
unconditional @NotBlank, then implement conditional validation by adding a
custom validator or a @AssertTrue boolean function on the DTO that returns true
when preSet != PreSet.CUSTOM or (preSet == PreSet.CUSTOM &&
!systemPrompt.isNullOrBlank()), and annotate that method with
@AssertTrue(message = "systemPrompt is required for CUSTOM preset"); add the
missing imports (jakarta.validation.constraints.NotBlank,
jakarta.validation.constraints.Size and
jakarta.validation.constraints.AssertTrue) and ensure the controller handling
this DTO is annotated with @Validated so the constraints are enforced.


data class PromptCreateRequest(
val name: String,
val preSet: PreSet,
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Consider renaming preSet → preset for consistent, idiomatic naming

The mixed-case “PreSet” leaks into the API as preSet. Kotlin/Java community typically uses “preset”. Renaming early avoids long-term churn across DB column names, JSON, and code.

🤖 Prompt for AI Agents
In src/main/kotlin/simplerag/ragback/domain/prompt/dto/PromptRequestDTO.kt
around line 8, the property name `preSet: PreSet` leaks non-idiomatic
mixed-casing into the API; rename the property to `preset: PreSet` and update
all references accordingly (constructor usages, JSON serialization names, DTO
mapping, database/ORM column mappings, tests and any callers) ensuring
serialization annotations (e.g., @JsonProperty) or column mappings are adjusted
if you must preserve an external contract during rollout; run and update
unit/integration tests and compile-time references to finish the rename.

@@ -0,0 +1,15 @@
package simplerag.ragback.domain.prompt.dto

import simplerag.ragback.domain.prompt.entity.Prompt
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Import PreSet if exposing it in the response

If you include preset in the preview, add the missing import.

Apply this diff if you adopt the response changes below:

-import simplerag.ragback.domain.prompt.entity.Prompt
+import simplerag.ragback.domain.prompt.entity.Prompt
+import simplerag.ragback.domain.prompt.entity.enums.PreSet
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import simplerag.ragback.domain.prompt.entity.Prompt
// src/main/kotlin/simplerag/ragback/domain/prompt/dto/PromptResponseDTO.kt
import simplerag.ragback.domain.prompt.entity.Prompt
import simplerag.ragback.domain.prompt.entity.enums.PreSet
// …rest of file…
🤖 Prompt for AI Agents
In src/main/kotlin/simplerag/ragback/domain/prompt/dto/PromptResponseDTO.kt
around line 3, the DTO now exposes the PreSet type but the corresponding import
is missing; add an import for simplerag.ragback.domain.prompt.entity.PreSet
(i.e. import simplerag.ragback.domain.prompt.entity.PreSet) alongside the
existing Prompt import so the file compiles and the response can reference
PreSet.

Comment on lines +5 to +14
data class PromptPreviewResponse(
val id: Long,
) {
companion object {
fun from(
prompt: Prompt
): PromptPreviewResponse {
return PromptPreviewResponse(prompt.id)
}
}
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Return minimally useful metadata in the preview (id, name, preset)

Returning only id creates an immediate follow-up GET to show what was created. Mirror the pattern from other “PreviewResponse” types and include name and preSet.

Apply this diff:

-data class PromptPreviewResponse(
-    val id: Long,
-) {
-    companion object {
-        fun from(
-            prompt: Prompt
-        ): PromptPreviewResponse {
-            return PromptPreviewResponse(prompt.id)
-        }
-    }
-}
+data class PromptPreviewResponse(
+    val id: Long,
+    val name: String,
+    val preSet: PreSet,
+) {
+    companion object {
+        fun from(prompt: Prompt): PromptPreviewResponse =
+            PromptPreviewResponse(
+                id = prompt.id,
+                name = prompt.name,
+                preSet = prompt.preSet,
+            )
+    }
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
data class PromptPreviewResponse(
val id: Long,
) {
companion object {
fun from(
prompt: Prompt
): PromptPreviewResponse {
return PromptPreviewResponse(prompt.id)
}
}
data class PromptPreviewResponse(
val id: Long,
val name: String,
val preSet: PreSet,
) {
companion object {
fun from(prompt: Prompt): PromptPreviewResponse =
PromptPreviewResponse(
id = prompt.id,
name = prompt.name,
preSet = prompt.preSet,
)
}
}
🤖 Prompt for AI Agents
In src/main/kotlin/simplerag/ragback/domain/prompt/dto/PromptResponseDTO.kt
around lines 5 to 14, the PromptPreviewResponse currently only returns id;
update the data class to include val name: String and val preSet: Boolean (or
the actual type used on Prompt) and modify the companion from(prompt: Prompt) to
populate those fields from prompt.name and prompt.preSet so the preview contains
id, name and preSet to avoid an extra GET.

Comment on lines +7 to +64
CUSTOM(
"User-defined custom prompt",
"TODO: custom system prompt here"
),

// Retrieval / Q&A
RAG_QA(
"Question Answering with retrieved context",
"TODO: system prompt for RAG_QA"
),
RAG_SUMMARIZER(
"Summarize documents retrieved via RAG",
"TODO: system prompt for RAG_SUMMARIZER"
),

// Code related
CODE_REVIEW_BACKEND(
"Backend code review (Java/Kotlin/Spring)",
"TODO: system prompt for CODE_REVIEW_BACKEND"
),
CODE_REVIEW_GENERAL(
"General code review and best practices",
"TODO: system prompt for CODE_REVIEW_GENERAL"
),

// Language tasks
TRANSLATION_EN_KO(
"English ↔ Korean translation",
"TODO: system prompt for TRANSLATION_EN_KO"
),
TRANSLATION_MULTI(
"Multi-language translation",
"TODO: system prompt for TRANSLATION_MULTI"
),
PROOFREAD_KR(
"Korean proofreading / grammar correction",
"TODO: system prompt for PROOFREAD_KR"
),

// Content tasks
TEXT_SUMMARIZER(
"General text summarization",
"TODO: system prompt for TEXT_SUMMARIZER"
),
DATA_CLEANER(
"Text cleaning and preprocessing",
"TODO: system prompt for DATA_CLEANER"
),
EMAIL_WRITER(
"Email / message generation",
"TODO: system prompt for EMAIL_WRITER"
),

// Safety / Guardrails
SAFETY_FILTERED(
"Safe response (avoid harmful or unsafe outputs)",
"TODO: system prompt for SAFETY_FILTERED"
)
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

⚠️ Potential issue

Do not ship with “TODO” default prompts — this violates requirements and will persist placeholders

Per PR objectives (“Add OpenSource Prompt Set”), every non-CUSTOM preset currently writes “TODO …” into the database via defaultSystemPrompt. That’s a correctness and product issue.

Pick one of the following immediately:

  • Minimal fix now: replace TODOs with sane, short defaults.
  • Safer guard: block non-CUSTOM creation until defaults exist.
  • Better architecture: store template keys here and load full prompt text from external resources (files/DB), enabling iteration without redeploys.

Minimal, immediate fix (replace only the string literals below):

@@
     CUSTOM(
         "User-defined custom prompt",
-        "TODO: custom system prompt here"
+        ""  // Not used — CUSTOM comes from request
     ),
@@
     RAG_QA(
         "Question Answering with retrieved context",
-        "TODO: system prompt for RAG_QA"
+        "You are a grounded QA assistant. Use ONLY the provided CONTEXT to answer. If the answer is not in CONTEXT, say \"I don't know\". Cite sources by title or id."
     ),
     RAG_SUMMARIZER(
         "Summarize documents retrieved via RAG",
-        "TODO: system prompt for RAG_SUMMARIZER"
+        "Summarize the provided CONTEXT for a busy reader. Use bullet points, keep facts verifiable, avoid speculation, and include key entities, dates, and numbers."
     ),
@@
     CODE_REVIEW_BACKEND(
         "Backend code review (Java/Kotlin/Spring)",
-        "TODO: system prompt for CODE_REVIEW_BACKEND"
+        "Review backend code (Kotlin/Java/Spring). Focus on correctness, concurrency, security, input validation, performance, error handling, transactions, and testability. Output concise action items with code snippets."
     ),
     CODE_REVIEW_GENERAL(
         "General code review and best practices",
-        "TODO: system prompt for CODE_REVIEW_GENERAL"
+        "Perform a pragmatic code review. Identify bugs, edge cases, readability issues, dead code, and missing tests. Propose minimal diffs to fix critical issues."
     ),
@@
     TRANSLATION_EN_KO(
         "English ↔ Korean translation",
-        "TODO: system prompt for TRANSLATION_EN_KO"
+        "Translate between English and Korean. Preserve meaning, tone, and formatting. Provide only the translation without additional commentary."
     ),
     TRANSLATION_MULTI(
         "Multi-language translation",
-        "TODO: system prompt for TRANSLATION_MULTI"
+        "Translate between the user’s source and target languages. Maintain tone and formatting. Do not add explanations unless asked."
     ),
     PROOFREAD_KR(
         "Korean proofreading / grammar correction",
-        "TODO: system prompt for PROOFREAD_KR"
+        "Proofread Korean text. Fix grammar, spacing, and style while preserving meaning. Output only the corrected text."
     ),
@@
     TEXT_SUMMARIZER(
         "General text summarization",
-        "TODO: system prompt for TEXT_SUMMARIZER"
+        "Summarize the text in 5–7 bullet points. Be faithful, concise, and include critical facts (who/what/when/where/why)."
     ),
     DATA_CLEANER(
         "Text cleaning and preprocessing",
-        "TODO: system prompt for DATA_CLEANER"
+        "Normalize whitespace, remove boilerplate, fix common encoding issues, and standardize quotes and dashes. Preserve semantic content."
     ),
     EMAIL_WRITER(
         "Email / message generation",
-        "TODO: system prompt for EMAIL_WRITER"
+        "Draft a clear, polite email given purpose, audience, and key points. Include subject and body. Keep it concise and actionable."
     ),
@@
     SAFETY_FILTERED(
         "Safe response (avoid harmful or unsafe outputs)",
-        "TODO: system prompt for SAFETY_FILTERED"
+        "Follow safety best practices. Refuse requests involving illegal, harmful, or sensitive content. Offer safe alternatives when declining."
     )

Longer-term architecture (recommended):

  • Replace defaultSystemPrompt: String with templateKey: String and look up prompt text from a registry (JSON/YAML in resources or DB), enabling A/B tests and localization without code changes.

Comment on lines 24 to 26
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "prompts_id")
val id: Long = 0
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify your Kotlin JPA configuration if keeping val id: Long = 0

Hibernate must set this generated id on a val field via reflection/bytecode enhancement. Ensure the Kotlin JPA/all-open plugins are applied. Alternatively, prefer val id: Long? = null to reduce surprises (will require adapting DTO mapping).

Run this quick check:


🏁 Script executed:

#!/bin/bash
# Verify Kotlin JPA/all-open is enabled
rg -nP 'kotlin\("plugin\.jpa"\)|allOpen|kotlin-jpa' -g 'build.gradle*' -C2 || true

Length of output: 267


🏁 Script executed:

#!/bin/bash
# Display the first 50 lines of build.gradle* to inspect plugin declarations
head -n 50 build.gradle build.gradle.kts || true

Length of output: 1683


Verify Kotlin JPA compiler plugin setup – confirms ID handling

Your Gradle configuration already applies the necessary Kotlin compiler plugins to support JPA entities:

  • The org.jetbrains.kotlin.plugin.jpa compiler plugin is declared in the plugins block, which wraps both the no-arg and all-open plugins for JPA support, automatically generating a no-argument constructor and opening classes annotated with @Entity, @Embeddable, and @MappedSuperclass (kotlinlang.org).
  • An explicit allOpen block lists jakarta.persistence.Entity and jakarta.persistence.MappedSuperclass, ensuring these classes aren’t final so Hibernate can proxy them (kotlinlang.org).

Given this setup, Hibernate will correctly set the generated id on your val id: Long = 0 field via reflection/bytecode enhancement.
As an optional refactoring for clearer “unsaved” semantics, you may choose to change the declaration to:

val id: Long? = null

and update any DTO mappings accordingly to use null as the sentinel for new entities.

🤖 Prompt for AI Agents
In src/main/kotlin/simplerag/ragback/domain/prompt/entity/Prompt.kt around lines
24-26, confirm the Kotlin JPA compiler plugins are enabled in Gradle
(org.jetbrains.kotlin.plugin.jpa / no-arg and all-open configured for
jakarta.persistence annotations) so Hibernate can set the @Id @GeneratedValue
val id: Long = 0 via reflection; optionally refactor the entity id to a nullable
sentinel by changing it to val id: Long? = null and update any DTO/mapping code
that assumes 0 to use null for unsaved entities.

Comment on lines +28 to +49
companion object {
fun from(
promptCreateRequest: PromptCreateRequest
): Prompt {

val prompt = if (promptCreateRequest.preSet == PreSet.CUSTOM) {
Prompt(
promptCreateRequest.name,
promptCreateRequest.preSet,
promptCreateRequest.systemPrompt
)
} else {
Prompt(
promptCreateRequest.name,
promptCreateRequest.preSet,
promptCreateRequest.preSet.defaultSystemPrompt
)
}

return prompt
}
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Normalize inputs, enforce invariants, and fail fast if presets are not configured

  • Trim and validate name against blank input.
  • Make systemPrompt resolution explicit with a when and validate non-blank.
  • Guard against accidentally persisting TODO defaults.
  • Reduce duplication in the factory.

Apply this diff within the factory:

     companion object {
         fun from(
             promptCreateRequest: PromptCreateRequest
         ): Prompt {
-
-            val prompt = if (promptCreateRequest.preSet == PreSet.CUSTOM) {
-                Prompt(
-                    promptCreateRequest.name,
-                    promptCreateRequest.preSet,
-                    promptCreateRequest.systemPrompt
-                )
-            } else {
-                Prompt(
-                    promptCreateRequest.name,
-                    promptCreateRequest.preSet,
-                    promptCreateRequest.preSet.defaultSystemPrompt
-                )
-            }
-
-            return prompt
+            val name = promptCreateRequest.name.trim()
+            require(name.isNotBlank()) { "Prompt name must not be blank." }
+
+            val resolvedSystemPrompt = when (promptCreateRequest.preSet) {
+                PreSet.CUSTOM -> (promptCreateRequest.systemPrompt ?: "").trim()
+                else -> promptCreateRequest.preSet.defaultSystemPrompt.trim()
+            }
+
+            require(resolvedSystemPrompt.isNotBlank()) {
+                "systemPrompt must not be blank. For non-CUSTOM presets, defaultSystemPrompt must be configured."
+            }
+            if (promptCreateRequest.preSet != PreSet.CUSTOM &&
+                resolvedSystemPrompt.startsWith("TODO", ignoreCase = true)
+            ) {
+                throw IllegalStateException("Preset ${promptCreateRequest.preSet} defaultSystemPrompt is not configured.")
+            }
+
+            return Prompt(
+                name = name,
+                preSet = promptCreateRequest.preSet,
+                systemPrompt = resolvedSystemPrompt,
+            )
         }
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
companion object {
fun from(
promptCreateRequest: PromptCreateRequest
): Prompt {
val prompt = if (promptCreateRequest.preSet == PreSet.CUSTOM) {
Prompt(
promptCreateRequest.name,
promptCreateRequest.preSet,
promptCreateRequest.systemPrompt
)
} else {
Prompt(
promptCreateRequest.name,
promptCreateRequest.preSet,
promptCreateRequest.preSet.defaultSystemPrompt
)
}
return prompt
}
}
companion object {
fun from(
promptCreateRequest: PromptCreateRequest
): Prompt {
val name = promptCreateRequest.name.trim()
require(name.isNotBlank()) { "Prompt name must not be blank." }
val resolvedSystemPrompt = when (promptCreateRequest.preSet) {
PreSet.CUSTOM -> (promptCreateRequest.systemPrompt ?: "").trim()
else -> promptCreateRequest.preSet.defaultSystemPrompt.trim()
}
require(resolvedSystemPrompt.isNotBlank()) {
"systemPrompt must not be blank. For non-CUSTOM presets, defaultSystemPrompt must be configured."
}
if (promptCreateRequest.preSet != PreSet.CUSTOM &&
resolvedSystemPrompt.startsWith("TODO", ignoreCase = true)
) {
throw IllegalStateException("Preset ${promptCreateRequest.preSet} defaultSystemPrompt is not configured.")
}
return Prompt(
name = name,
preSet = promptCreateRequest.preSet,
systemPrompt = resolvedSystemPrompt,
)
}
}
🤖 Prompt for AI Agents
In src/main/kotlin/simplerag/ragback/domain/prompt/entity/Prompt.kt around lines
28 to 49, the factory does not normalize or validate inputs and duplicates
construction logic; change it to trim and validate the incoming name (reject
blank after trim), resolve the systemPrompt with an explicit when on preSet (use
promptCreateRequest.systemPrompt for PreSet.CUSTOM, otherwise use
preSet.defaultSystemPrompt), validate the resolved systemPrompt is non-blank and
fail fast if it is blank or matches any TODO/default sentinel, and then
construct and return a single Prompt instance (reduce duplication by building
the resolvedName and resolvedSystemPrompt first and reuse them for
construction).

import org.springframework.data.jpa.repository.JpaRepository
import simplerag.ragback.domain.prompt.entity.Prompt

interface PromptRepository: JpaRepository<Prompt, Long> No newline at end of file
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Style nit + add helper to prevent duplicate names

  • Kotlin style: add a space before the colon.
  • Expose existsByName to preempt duplicates at the service layer (pair with a DB unique constraint).

Apply this diff:

-interface PromptRepository: JpaRepository<Prompt, Long>
+interface PromptRepository : JpaRepository<Prompt, Long> {
+    fun existsByName(name: String): Boolean
+}

And add a unique constraint on prompts.name (outside this hunk):

@Table(
    name = "prompts",
    uniqueConstraints = [UniqueConstraint(name = "uk_prompts_name", columnNames = ["name"])]
)
🤖 Prompt for AI Agents
In
src/main/kotlin/simplerag/ragback/domain/prompt/repository/PromptRepository.kt
around line 6, the interface declaration needs Kotlin style spacing and an
existence helper: change "interface PromptRepository: JpaRepository<Prompt,
Long>" to use a space before the colon and add a method signature fun
existsByName(name: String): Boolean so services can check duplicates; also add a
unique constraint on the prompts table in the Prompt entity with @Table(name =
"prompts", uniqueConstraints = [UniqueConstraint(name = "uk_prompts_name",
columnNames = ["name"])]) to enforce uniqueness at the DB level.

Comment on lines +16 to +23
@Transactional
fun createPrompt(
promptCreateRequest: PromptCreateRequest
): PromptPreviewResponse {
val prompt = Prompt.from(promptCreateRequest)
val savedPrompt = promptRepository.save(prompt)
return PromptPreviewResponse.from(savedPrompt)
}
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Consider guarding against duplicate names and clarifying default system prompt behavior

  • If prompt names must be unique, add a repository existence check (or handle unique index violations) to return a domain-friendly error rather than surfacing a DB exception.
  • Ensure Prompt.from applies a sensible default: when preSet != CUSTOM and systemPrompt is null/blank, use the preset’s defaultSystemPrompt. If that logic isn’t in the factory yet, move it there to centralize invariants.

Example (outside this file):

// PromptRepository.kt
interface PromptRepository : JpaRepository<Prompt, Long> {
    fun existsByName(name: String): Boolean
}
// PromptService.kt (inside createPrompt)
if (promptRepository.existsByName(promptCreateRequest.name)) {
    // throw your domain exception, e.g., DuplicateResourceException("Prompt name already exists")
}

If a DB-level guarantee is desired, also add a unique constraint on the name column and translate DataIntegrityViolationException.

🤖 Prompt for AI Agents
In src/main/kotlin/simplerag/ragback/domain/prompt/service/PromptService.kt
around lines 16-23, guard against duplicate prompt names and centralize default
system-prompt logic: before saving, call
promptRepository.existsByName(promptCreateRequest.name) and throw a
domain-friendly DuplicateResourceException (or similar) if true; also
catch/translate DataIntegrityViolationException from the repository save to the
same domain exception if you prefer DB-level uniqueness. Move or augment
Prompt.from to ensure that when promptCreateRequest.preSet != PreSet.CUSTOM and
systemPrompt is null/blank it sets systemPrompt to the preset’s
defaultSystemPrompt so the factory enforces that invariant rather than relying
on service code.

Copy link

@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

♻️ Duplicate comments (3)
src/main/kotlin/simplerag/ragback/domain/prompt/dto/PromptRequestDTO.kt (2)

10-10: Rename preSet → preset for idiomatic, stable API naming (keep backward compatibility with aliases)

Adopt “preset” consistently; accept legacy “preSet” via @JsonAlias to avoid breaking clients.

The diff above includes this rename plus @JsonAlias("preSet") to keep old payloads working. I can sweep usages across the codebase if you’d like.


8-12: Harden validation at the edge; make systemPrompt optional and conditionally required (CUSTOM only)

Enforce invariants consistent with DB constraints and UX. Name should be non-blank and ≤100. systemPrompt shouldn’t be mandatory when a preset supplies the default; require it only for user-defined/custom presets.

Apply this diff:

 package simplerag.ragback.domain.prompt.dto

-import jakarta.validation.constraints.Size
+import com.fasterxml.jackson.annotation.JsonAlias
+import com.fasterxml.jackson.annotation.JsonProperty
+import jakarta.validation.constraints.AssertTrue
+import jakarta.validation.constraints.NotBlank
+import jakarta.validation.constraints.Size
 import simplerag.ragback.domain.prompt.entity.enums.PreSet
 
 
 data class PromptCreateRequest(
-    @field:Size(max = 100)
-    val name: String,
-    val preSet: PreSet,
-    @field:Size(max = 20000)
-    val systemPrompt: String,
+    @field:NotBlank
+    @field:Size(max = 100)
+    val name: String,
+    @JsonProperty("preset")
+    @JsonAlias("preSet")
+    val preset: PreSet,
+    @field:Size(max = 20000)
+    val systemPrompt: String? = null,
 ) 
+{
+    @AssertTrue(message = "systemPrompt is required when preset is CUSTOM")
+    fun isSystemPromptValid(): Boolean =
+        preset != PreSet.CUSTOM || !systemPrompt.isNullOrBlank()
+}

Follow-ups:

  • Update mapping code (e.g., Prompt.from(request)) to use request.preset instead of request.preSet.
  • Ensure controller is annotated with @Validated so these constraints are enforced (see controller comment).

I can push a follow-up patch touching the mapper/service and add tests for both CUSTOM and non-CUSTOM paths.

src/main/kotlin/simplerag/ragback/domain/prompt/controller/PromptController.kt (1)

11-15: Enable bean validation at the controller level

Add @Validated to ensure the DTO constraints trigger on this endpoint, consistent with IndexController.

 @RestController
 @RequestMapping("/api/v1/prompts")
-class PromptController(
+@org.springframework.validation.annotation.Validated
+class PromptController(
     private val promptService: PromptService
 ) {

Alternatively, add the import and short annotation:

+import org.springframework.validation.annotation.Validated
@@
-@RequestMapping("/api/v1/prompts")
-class PromptController(
+@RequestMapping("/api/v1/prompts")
+@Validated
+class PromptController(
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 5575d84 and abdde09.

📒 Files selected for processing (2)
  • src/main/kotlin/simplerag/ragback/domain/prompt/controller/PromptController.kt (1 hunks)
  • src/main/kotlin/simplerag/ragback/domain/prompt/dto/PromptRequestDTO.kt (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
src/main/kotlin/simplerag/ragback/domain/prompt/dto/PromptRequestDTO.kt (2)
src/main/kotlin/simplerag/ragback/domain/prompt/entity/Prompt.kt (1)
  • name (7-26)
src/main/kotlin/simplerag/ragback/domain/prompt/entity/enums/PreSet.kt (1)
  • NONE (3-5)
src/main/kotlin/simplerag/ragback/domain/prompt/controller/PromptController.kt (1)
src/main/kotlin/simplerag/ragback/domain/index/controller/IndexController.kt (2)
  • indexService (11-59)
  • HttpStatus (18-25)
🔇 Additional comments (2)
src/main/kotlin/simplerag/ragback/domain/prompt/dto/PromptRequestDTO.kt (1)

1-13: Confirm PreSet enum includes CUSTOM and verify DTO-to-entity mapping

I’ve checked the PreSet enum in src/main/kotlin/simplerag/ragback/domain/prompt/entity/enums/PreSet.kt and it does define a CUSTOM constant, so the conditional validation predicate can safely refer to it. However, I didn’t find any factory or conversion function that maps PromptCreateRequest (in src/main/kotlin/simplerag/ragback/domain/prompt/dto/PromptCreateRequest.kt) into your domain Prompt entity. Please verify:

  • That a mapping (e.g. from(request: PromptCreateRequest)) exists and is actually invoked when creating a Prompt.
  • That your mapping logic applies defaultSystemPrompt for all presets except CUSTOM, and enforces systemPrompt when preSet == CUSTOM.
  • If no such factory exists yet, either implement it or adjust your validation logic to ensure systemPrompt remains required for non-CUSTOM presets (or update the predicate to match your desired behavior).
src/main/kotlin/simplerag/ragback/domain/prompt/controller/PromptController.kt (1)

17-24: POST semantics and validation look good

Using @ResponseStatus(HttpStatus.CREATED) and @Valid on the request aligns with your other controllers.

Comment on lines +17 to +24
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
fun createPrompt(
@RequestBody @Valid promptCreateRequest: PromptCreateRequest
): ApiResponse<PromptPreviewResponse> {
val savedPrompt = promptService.createPrompt(promptCreateRequest)
return ApiResponse.ok(savedPrompt)
}
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Optional: set Location header for the created resource

If PromptPreviewResponse exposes the new prompt’s ID, consider returning ResponseEntity with a Location header for better REST semantics.

Example (illustrative):

-import org.springframework.http.HttpStatus
+import org.springframework.http.HttpStatus
+import org.springframework.http.ResponseEntity
+import org.springframework.http.HttpHeaders
+import org.springframework.web.util.UriComponentsBuilder
@@
-    @ResponseStatus(HttpStatus.CREATED)
-    fun createPrompt(
+    fun createPrompt(
         @RequestBody @Valid promptCreateRequest: PromptCreateRequest
-    ): ApiResponse<PromptPreviewResponse> {
-        val savedPrompt = promptService.createPrompt(promptCreateRequest)
-        return ApiResponse.ok(savedPrompt)
+    ): ResponseEntity<ApiResponse<PromptPreviewResponse>> {
+        val savedPrompt = promptService.createPrompt(promptCreateRequest)
+        val location = UriComponentsBuilder.fromPath("/api/v1/prompts/{id}")
+            .buildAndExpand(savedPrompt.id)
+            .toUri()
+        return ResponseEntity
+            .status(HttpStatus.CREATED)
+            .header(HttpHeaders.LOCATION, location.toString())
+            .body(ApiResponse.ok(savedPrompt))
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
fun createPrompt(
@RequestBody @Valid promptCreateRequest: PromptCreateRequest
): ApiResponse<PromptPreviewResponse> {
val savedPrompt = promptService.createPrompt(promptCreateRequest)
return ApiResponse.ok(savedPrompt)
}
// Add these imports (in addition to the existing HttpStatus import)
import org.springframework.http.ResponseEntity
import org.springframework.http.HttpHeaders
import org.springframework.web.util.UriComponentsBuilder
@PostMapping
fun createPrompt(
@RequestBody @Valid promptCreateRequest: PromptCreateRequest
): ResponseEntity<ApiResponse<PromptPreviewResponse>> {
val savedPrompt = promptService.createPrompt(promptCreateRequest)
val location = UriComponentsBuilder
.fromPath("/api/v1/prompts/{id}")
.buildAndExpand(savedPrompt.id)
.toUri()
return ResponseEntity
.status(HttpStatus.CREATED)
.header(HttpHeaders.LOCATION, location.toString())
.body(ApiResponse.ok(savedPrompt))
}
🤖 Prompt for AI Agents
In
src/main/kotlin/simplerag/ragback/domain/prompt/controller/PromptController.kt
around lines 17 to 24, update the createPrompt method to return a ResponseEntity
and set a Location header pointing to the newly created prompt resource: after
saving, extract the new prompt ID from PromptPreviewResponse (if it does not
contain an ID, add it to the DTO or return an object that includes the ID),
build the resource URI (e.g. using
ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}").buildAndExpand(id).toUri()),
and return ResponseEntity.created(location).body(savedPrompt) so the response
status is 201 and the Location header is set.

Comment on lines +8 to +9
@field:Size(max = 100)
val name: String,
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Align DTO with DB non-null constraint for name; add @notblank

The DB declares name NOT NULL with length 100. Add @notblank in addition to @SiZe to block all-whitespace names.

Apply the @NotBlank addition from the main diff above.

🤖 Prompt for AI Agents
In src/main/kotlin/simplerag/ragback/domain/prompt/dto/PromptRequestDTO.kt
around lines 8 to 9, the DTO field 'name' only has @Size(max = 100) but the DB
column is NOT NULL and should reject blank/whitespace-only values; add the
@NotBlank annotation alongside @Size to enforce non-blank input and update
imports to include javax.validation.constraints.NotBlank (or the project's
validation package) so the validator will reject empty/whitespace names to match
the DB constraint.

@catturtle123 catturtle123 merged commit a20c782 into develop Aug 23, 2025
1 check passed
@catturtle123 catturtle123 deleted the feature/#21-create-prompt branch August 23, 2025 09:45
@coderabbitai coderabbitai bot mentioned this pull request Aug 23, 2025
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

✨ [Feature] Create Prompt

2 participants