diff --git a/.gitignore b/.gitignore
index d15fe9b..14d9b1b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -37,4 +37,6 @@ build/
*.gguf
-*.log
\ No newline at end of file
+*.log
+
+*.db
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 70f4b02..d641665 100644
--- a/pom.xml
+++ b/pom.xml
@@ -42,6 +42,23 @@
4.2.0
+
+
+ org.xerial
+ sqlite-jdbc
+ 3.45.1.0
+
+
+
+ org.hibernate.orm
+ hibernate-community-dialects
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
org.springframework.boot
diff --git a/src/main/java/com/pablotj/ia/chat/boot/adapter/controller/ChatPageController.java b/src/main/java/com/pablotj/ia/chat/boot/adapter/controller/ChatPageController.java
index 76bead0..bb488b9 100644
--- a/src/main/java/com/pablotj/ia/chat/boot/adapter/controller/ChatPageController.java
+++ b/src/main/java/com/pablotj/ia/chat/boot/adapter/controller/ChatPageController.java
@@ -1,10 +1,9 @@
package com.pablotj.ia.chat.boot.adapter.controller;
+import com.pablotj.ia.chat.boot.application.session.ChatSessionManager;
import com.pablotj.ia.chat.boot.application.usecase.ChatUseCase;
import com.pablotj.ia.chat.boot.domain.model.ChatMessage;
-import com.pablotj.ia.chat.boot.web.session.ChatSessionManager;
import jakarta.servlet.http.HttpSession;
-import java.util.Date;
import java.util.List;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -32,7 +31,7 @@ public class ChatPageController {
List messages = chatSessionManager.getMessages(session);
if (messages != null && messages.isEmpty()) {
try {
- chatUseCase.processUserPrompt("", session);
+ messages.add(chatUseCase.processUserPrompt("", session));
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
}
diff --git a/src/main/java/com/pablotj/ia/chat/boot/application/session/ChatSessionManager.java b/src/main/java/com/pablotj/ia/chat/boot/application/session/ChatSessionManager.java
new file mode 100644
index 0000000..2940748
--- /dev/null
+++ b/src/main/java/com/pablotj/ia/chat/boot/application/session/ChatSessionManager.java
@@ -0,0 +1,38 @@
+package com.pablotj.ia.chat.boot.application.session;
+
+import com.pablotj.ia.chat.boot.domain.model.ChatMessage;
+import com.pablotj.ia.chat.boot.domain.port.ChatMessageStore;
+import jakarta.servlet.http.HttpSession;
+import java.util.ArrayList;
+import org.springframework.stereotype.Component;
+import org.springframework.util.ObjectUtils;
+
+import java.util.List;
+
+@Component
+public class ChatSessionManager {
+
+ private final ChatMessageStore chatMessageStore;
+
+ public ChatSessionManager(ChatMessageStore chatMessageStore) {
+ this.chatMessageStore = chatMessageStore;
+ }
+
+ public List getMessages(HttpSession session) {
+ String sessionId = session.getId();
+ List messages = chatMessageStore.getMessages(sessionId);
+ List filteredMessages = new ArrayList<>(messages);
+
+ if (ObjectUtils.isEmpty(filteredMessages)) {
+ return new ArrayList<>();
+ } else {
+ filteredMessages.removeIf(m -> ObjectUtils.isEmpty(m.text()));
+ }
+ return filteredMessages;
+ }
+
+ public void setMessages(HttpSession session, List messages) {
+ messages.removeIf(m -> ObjectUtils.isEmpty(m.text()));
+ chatMessageStore.saveMessages(session.getId(), messages);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/pablotj/ia/chat/boot/application/usecase/ChatUseCase.java b/src/main/java/com/pablotj/ia/chat/boot/application/usecase/ChatUseCase.java
index 0844620..bb33b62 100644
--- a/src/main/java/com/pablotj/ia/chat/boot/application/usecase/ChatUseCase.java
+++ b/src/main/java/com/pablotj/ia/chat/boot/application/usecase/ChatUseCase.java
@@ -2,10 +2,9 @@ package com.pablotj.ia.chat.boot.application.usecase;
import com.pablotj.ia.chat.boot.application.prompt.PromptBuilder;
import com.pablotj.ia.chat.boot.application.prompt.PromptTemplates;
+import com.pablotj.ia.chat.boot.application.session.ChatSessionManager;
import com.pablotj.ia.chat.boot.domain.model.ChatMessage;
-import com.pablotj.ia.chat.boot.domain.service.ChatService;
import com.pablotj.ia.chat.boot.infraestructure.llm.LlmModelClient;
-import com.pablotj.ia.chat.boot.web.session.ChatSessionManager;
import jakarta.servlet.http.HttpSession;
import java.util.Date;
import java.util.List;
diff --git a/src/main/java/com/pablotj/ia/chat/boot/domain/port/ChatMessageStore.java b/src/main/java/com/pablotj/ia/chat/boot/domain/port/ChatMessageStore.java
new file mode 100644
index 0000000..8b95e28
--- /dev/null
+++ b/src/main/java/com/pablotj/ia/chat/boot/domain/port/ChatMessageStore.java
@@ -0,0 +1,9 @@
+package com.pablotj.ia.chat.boot.domain.port;
+
+import com.pablotj.ia.chat.boot.domain.model.ChatMessage;
+import java.util.List;
+
+public interface ChatMessageStore {
+ List getMessages(String sessionId);
+ void saveMessages(String sessionId, List messages);
+}
diff --git a/src/main/java/com/pablotj/ia/chat/boot/persistence/ChatMessageEntity.java b/src/main/java/com/pablotj/ia/chat/boot/persistence/ChatMessageEntity.java
new file mode 100644
index 0000000..846d206
--- /dev/null
+++ b/src/main/java/com/pablotj/ia/chat/boot/persistence/ChatMessageEntity.java
@@ -0,0 +1,44 @@
+package com.pablotj.ia.chat.boot.persistence;
+
+import jakarta.persistence.*;
+import java.util.Date;
+
+@Entity
+@Table(name = "chat_messages")
+public class ChatMessageEntity {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ private String sessionId;
+
+ @Column(length = 4000)
+ private String text;
+
+ private String role;
+
+ private Date date;
+
+ // Getters y Setters
+
+ public Long getId() { return id; }
+ public void setId(Long id) { this.id = id; }
+
+ public String getSessionId() { return sessionId; }
+ public void setSessionId(String sessionId) { this.sessionId = sessionId; }
+
+ public String getText() { return text; }
+ public void setText(String text) { this.text = text; }
+
+ public String getRole() { return role; }
+ public void setRole(String role) { this.role = role; }
+
+ public Date getDate() {
+ return date;
+ }
+
+ public void setDate(Date date) {
+ this.date = date;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/pablotj/ia/chat/boot/persistence/ChatMessageJpaRepository.java b/src/main/java/com/pablotj/ia/chat/boot/persistence/ChatMessageJpaRepository.java
new file mode 100644
index 0000000..39d86af
--- /dev/null
+++ b/src/main/java/com/pablotj/ia/chat/boot/persistence/ChatMessageJpaRepository.java
@@ -0,0 +1,10 @@
+package com.pablotj.ia.chat.boot.persistence;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import java.util.List;
+
+
+public interface ChatMessageJpaRepository extends JpaRepository {
+ List findBySessionIdOrderByIdAsc(String sessionId);
+ void deleteBySessionId(String sessionId);
+}
\ No newline at end of file
diff --git a/src/main/java/com/pablotj/ia/chat/boot/persistence/ChatMessageMapper.java b/src/main/java/com/pablotj/ia/chat/boot/persistence/ChatMessageMapper.java
new file mode 100644
index 0000000..3300a18
--- /dev/null
+++ b/src/main/java/com/pablotj/ia/chat/boot/persistence/ChatMessageMapper.java
@@ -0,0 +1,19 @@
+package com.pablotj.ia.chat.boot.persistence;
+
+import com.pablotj.ia.chat.boot.domain.model.ChatMessage;
+
+public class ChatMessageMapper {
+
+ public static ChatMessageEntity toEntity(String sessionId, ChatMessage message) {
+ ChatMessageEntity entity = new ChatMessageEntity();
+ entity.setSessionId(sessionId);
+ entity.setRole(message.role());
+ entity.setText(message.text());
+ entity.setDate(message.date());
+ return entity;
+ }
+
+ public static ChatMessage toDomain(ChatMessageEntity entity) {
+ return new ChatMessage(entity.getRole(), entity.getText(), entity.getDate());
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/pablotj/ia/chat/boot/persistence/SqliteChatMessageStore.java b/src/main/java/com/pablotj/ia/chat/boot/persistence/SqliteChatMessageStore.java
new file mode 100644
index 0000000..36a4cbc
--- /dev/null
+++ b/src/main/java/com/pablotj/ia/chat/boot/persistence/SqliteChatMessageStore.java
@@ -0,0 +1,35 @@
+package com.pablotj.ia.chat.boot.persistence;
+
+import com.pablotj.ia.chat.boot.domain.model.ChatMessage;
+import com.pablotj.ia.chat.boot.domain.port.ChatMessageStore;
+import org.springframework.stereotype.Repository;
+import java.util.List;
+import org.springframework.transaction.annotation.Transactional;
+
+@Repository
+public class SqliteChatMessageStore implements ChatMessageStore {
+
+ private final ChatMessageJpaRepository repository;
+
+ public SqliteChatMessageStore(ChatMessageJpaRepository repository) {
+ this.repository = repository;
+ }
+
+ @Override
+ public List getMessages(String sessionId) {
+ return repository.findBySessionIdOrderByIdAsc(sessionId)
+ .stream()
+ .map(ChatMessageMapper::toDomain)
+ .toList();
+ }
+
+ @Override
+ @Transactional
+ public void saveMessages(String sessionId, List messages) {
+ repository.deleteBySessionId(sessionId);
+ List entities = messages.stream()
+ .map(m -> ChatMessageMapper.toEntity(sessionId, m))
+ .toList();
+ repository.saveAll(entities);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/pablotj/ia/chat/boot/web/session/ChatSessionManager.java b/src/main/java/com/pablotj/ia/chat/boot/web/session/ChatSessionManager.java
deleted file mode 100644
index c853a5d..0000000
--- a/src/main/java/com/pablotj/ia/chat/boot/web/session/ChatSessionManager.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package com.pablotj.ia.chat.boot.web.session;
-
-import com.pablotj.ia.chat.boot.domain.model.ChatMessage;
-import jakarta.servlet.http.HttpSession;
-import java.util.ArrayList;
-import java.util.List;
-import org.springframework.stereotype.Component;
-import org.springframework.util.ObjectUtils;
-
-@Component
-public class ChatSessionManager {
-
- private static final String ATTR_MESSAGES = "messages";
-
- @SuppressWarnings("unchecked")
- public List getMessages(HttpSession session) {
- List messages = (List) session.getAttribute(ATTR_MESSAGES);
- if (messages == null) {
- messages = new ArrayList<>();
- session.setAttribute(ATTR_MESSAGES, messages);
- }
- messages.removeIf(m -> ObjectUtils.isEmpty(m.text()));
- return messages;
- }
-
- public void setMessages(HttpSession session, List messages) {
- session.setAttribute(ATTR_MESSAGES, messages);
- }
-}
-
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
deleted file mode 100644
index f794079..0000000
--- a/src/main/resources/application.properties
+++ /dev/null
@@ -1,9 +0,0 @@
-spring.application.name = ia-chat-boot
-server.port = 8080
-
-! Model
-llama.model.name = openchat-3.5-0106.Q4_K_M
-llama.model.gpu.enabled = true
-llama.model.gpu.layers = 35
-llama.model.tokens = 1024
-
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
new file mode 100644
index 0000000..5affd85
--- /dev/null
+++ b/src/main/resources/application.yml
@@ -0,0 +1,19 @@
+server:
+ port: 8080
+spring:
+ application:
+ name: ia-chat-boot
+ datasource:
+ url: jdbc:sqlite:file:chat.db
+ jpa:
+ database-platform: org.hibernate.community.dialect.SQLiteDialect
+ hibernate:
+ ddl-auto: update
+llama:
+ model:
+ name: openchat-3.5-0106.Q4_K_M
+ gpu:
+ enabled: true
+ layers: 35
+ tokens: 1024
+