mirror of
https://github.com/Dvorinka/Trackeep.git
synced 2026-06-03 20:12:58 +00:00
feat: major feature updates and cleanup
- Add Redis architecture implementation - Update browser extension functionality - Clean up deprecated files and documentation - Enhance backend handlers for auth, messages, search - Add new configuration options and settings - Update Docker and deployment configurations
This commit is contained in:
@@ -49,10 +49,17 @@ type AttachmentInput struct {
|
||||
Title string `json:"title"`
|
||||
}
|
||||
|
||||
type ReferenceInput struct {
|
||||
EntityType string `json:"entity_type"`
|
||||
EntityID uint `json:"entity_id"`
|
||||
DeepLink string `json:"deep_link"`
|
||||
}
|
||||
|
||||
type CreateMessageRequest struct {
|
||||
Body string `json:"body"`
|
||||
Attachments []AttachmentInput `json:"attachments"`
|
||||
Metadata map[string]interface{} `json:"metadata"`
|
||||
References []ReferenceInput `json:"references"`
|
||||
}
|
||||
|
||||
type UpdateMessageRequest struct {
|
||||
@@ -641,8 +648,8 @@ func CreateConversationMessage(c *gin.Context) {
|
||||
}
|
||||
|
||||
trimmedBody := strings.TrimSpace(req.Body)
|
||||
if trimmedBody == "" && len(req.Attachments) == 0 {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Message body or attachments are required"})
|
||||
if trimmedBody == "" && len(req.Attachments) == 0 && len(req.References) == 0 {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Message body, attachments, or references are required"})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -656,6 +663,37 @@ func CreateConversationMessage(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
referenceRows := make([]models.MessageReference, 0, len(req.References))
|
||||
for _, ref := range req.References {
|
||||
entityType := normalizeReferenceType(ref.EntityType)
|
||||
if entityType == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid reference entity_type"})
|
||||
return
|
||||
}
|
||||
if ref.EntityID == 0 {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid reference entity_id"})
|
||||
return
|
||||
}
|
||||
deepLink := strings.TrimSpace(ref.DeepLink)
|
||||
if deepLink == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid reference deep_link"})
|
||||
return
|
||||
}
|
||||
if !isReferenceDeepLinkAllowed(deepLink) {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Unsupported reference deep_link"})
|
||||
return
|
||||
}
|
||||
if !canReferenceEntity(models.DB, userID, entityType, ref.EntityID) {
|
||||
c.JSON(http.StatusForbidden, gin.H{"error": "Reference target is not accessible"})
|
||||
return
|
||||
}
|
||||
referenceRows = append(referenceRows, models.MessageReference{
|
||||
EntityType: entityType,
|
||||
EntityID: ref.EntityID,
|
||||
DeepLink: deepLink,
|
||||
})
|
||||
}
|
||||
|
||||
suggestions, inferredAttachments, isSensitive := services.DetectMessageContent(trimmedBody)
|
||||
for _, inferred := range inferredAttachments {
|
||||
if hasAttachment(attachmentRows, inferred.Kind, inferred.URL) {
|
||||
@@ -719,6 +757,13 @@ func CreateConversationMessage(c *gin.Context) {
|
||||
models.DB.Create(&attachmentRows)
|
||||
}
|
||||
|
||||
for i := range referenceRows {
|
||||
referenceRows[i].MessageID = message.ID
|
||||
}
|
||||
if len(referenceRows) > 0 {
|
||||
models.DB.Create(&referenceRows)
|
||||
}
|
||||
|
||||
if len(suggestions) > 0 {
|
||||
suggestionRows := make([]models.MessageSuggestion, 0, len(suggestions))
|
||||
for _, s := range suggestions {
|
||||
@@ -2159,6 +2204,33 @@ func normalizeAttachmentKind(kind string) string {
|
||||
}
|
||||
}
|
||||
|
||||
func normalizeReferenceType(entityType string) string {
|
||||
t := strings.ToLower(strings.TrimSpace(entityType))
|
||||
switch t {
|
||||
case "task", "bookmark", "calendar_event", "youtube_video", "learning_path", "saved_search", "github", "password_vault_item", "ai_chat_session", "ai_chat_message":
|
||||
return t
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func isReferenceDeepLinkAllowed(deepLink string) bool {
|
||||
return strings.HasPrefix(deepLink, "/") || strings.HasPrefix(deepLink, "http://") || strings.HasPrefix(deepLink, "https://")
|
||||
}
|
||||
|
||||
func canReferenceEntity(db *gorm.DB, userID uint, entityType string, entityID uint) bool {
|
||||
switch entityType {
|
||||
case "ai_chat_session":
|
||||
var session models.ChatSession
|
||||
return db.Where("id = ? AND user_id = ?", entityID, userID).First(&session).Error == nil
|
||||
case "ai_chat_message":
|
||||
var message models.ChatMessage
|
||||
return db.Where("id = ? AND user_id = ?", entityID, userID).First(&message).Error == nil
|
||||
default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
func compactMessageTitle(text string, limit int) string {
|
||||
trimmed := strings.TrimSpace(text)
|
||||
if len(trimmed) <= limit {
|
||||
|
||||
Reference in New Issue
Block a user