feat(backend): persist tasks and generated message history
- add EntityTask domain and CRUD API backed by PostgreSQL - relate generated messages directly to tasks and delete on task removal - move preview generation to backend Llama endpoint - migrate frontend task APIs from localStorage to backend endpoints - update tests and CLAUDE rules for backend-owned LLM/persistence
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
package com.condado.newsletter.model
|
||||
|
||||
import jakarta.persistence.CascadeType
|
||||
import jakarta.persistence.Column
|
||||
import jakarta.persistence.Entity
|
||||
import jakarta.persistence.FetchType
|
||||
import jakarta.persistence.GeneratedValue
|
||||
import jakarta.persistence.GenerationType
|
||||
import jakarta.persistence.Id
|
||||
import jakarta.persistence.JoinColumn
|
||||
import jakarta.persistence.ManyToOne
|
||||
import jakarta.persistence.OneToMany
|
||||
import jakarta.persistence.Table
|
||||
import org.hibernate.annotations.CreationTimestamp
|
||||
import java.time.LocalDateTime
|
||||
import java.util.UUID
|
||||
|
||||
/**
|
||||
* Represents a configurable task belonging to a virtual entity.
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "entity_tasks")
|
||||
class EntityTask(
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "entity_id", nullable = false)
|
||||
val virtualEntity: VirtualEntity,
|
||||
|
||||
@Column(nullable = false)
|
||||
val name: String,
|
||||
|
||||
@Column(columnDefinition = "TEXT", nullable = false)
|
||||
val prompt: String,
|
||||
|
||||
@Column(name = "schedule_cron", nullable = false)
|
||||
val scheduleCron: String,
|
||||
|
||||
@Column(name = "email_lookback", nullable = false)
|
||||
val emailLookback: String,
|
||||
|
||||
@Column(nullable = false)
|
||||
val active: Boolean = true,
|
||||
|
||||
@CreationTimestamp
|
||||
@Column(name = "created_at", updatable = false, nullable = false)
|
||||
val createdAt: LocalDateTime? = null
|
||||
) {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.UUID)
|
||||
var id: UUID? = null
|
||||
|
||||
@OneToMany(mappedBy = "task", cascade = [CascadeType.ALL], orphanRemoval = true)
|
||||
val generatedMessages: MutableList<GeneratedMessageHistory> = mutableListOf()
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.condado.newsletter.model
|
||||
|
||||
import jakarta.persistence.Column
|
||||
import jakarta.persistence.Entity
|
||||
import jakarta.persistence.GeneratedValue
|
||||
import jakarta.persistence.GenerationType
|
||||
import jakarta.persistence.Id
|
||||
import jakarta.persistence.FetchType
|
||||
import jakarta.persistence.JoinColumn
|
||||
import jakarta.persistence.ManyToOne
|
||||
import jakarta.persistence.Table
|
||||
import java.time.LocalDateTime
|
||||
import java.util.UUID
|
||||
|
||||
/**
|
||||
* Stores generated test messages for a task, so the history survives page reloads and restarts.
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "generated_message_history")
|
||||
class GeneratedMessageHistory(
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "task_id", nullable = false)
|
||||
val task: EntityTask,
|
||||
|
||||
@Column(nullable = false)
|
||||
val label: String,
|
||||
|
||||
@Column(columnDefinition = "TEXT", nullable = false)
|
||||
val content: String,
|
||||
|
||||
@Column(name = "created_at", nullable = false)
|
||||
val createdAt: LocalDateTime = LocalDateTime.now()
|
||||
) {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.UUID)
|
||||
var id: UUID? = null
|
||||
}
|
||||
Reference in New Issue
Block a user