File size: 3,518 Bytes
4977db2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import Foundation
import GRDB

public struct PromptRecord: Codable, FetchableRecord, Identifiable, Hashable, Sendable {
    public static let databaseTableName = "prompts"

    public let id: Int64
    public var title: String
    public var content: String
    public var source: String?
    public var isStarred: Bool
    public var tags: String?
    public var model: String?
    public var rating: Int?
    public var useCount: Int
    public var createdAt: String
    public var updatedAt: String
    public var promptedAt: String?

    public init(
        id: Int64,
        title: String,
        content: String,
        source: String?,
        isStarred: Bool,
        tags: String?,
        model: String?,
        rating: Int?,
        useCount: Int,
        createdAt: String,
        updatedAt: String,
        promptedAt: String? = nil
    ) {
        self.id = id
        self.title = title
        self.content = content
        self.source = source
        self.isStarred = isStarred
        self.tags = tags
        self.model = model
        self.rating = rating
        self.useCount = useCount
        self.createdAt = createdAt
        self.updatedAt = updatedAt
        self.promptedAt = promptedAt
    }

    public var tagList: [String] {
        guard let tags else { return [] }
        return tags
            .split(separator: ",")
            .map { $0.trimmingCharacters(in: .whitespacesAndNewlines) }
            .filter { !$0.isEmpty }
    }

    public var sourceFamily: String {
        guard let source, !source.isEmpty else { return "unknown" }
        return source.split(separator: ":", maxSplits: 1).first.map(String.init) ?? source
    }

    enum CodingKeys: String, CodingKey {
        case id
        case title
        case content
        case source
        case isStarred = "is_starred"
        case tags
        case model
        case rating
        case useCount = "use_count"
        case createdAt = "created_at"
        case updatedAt = "updated_at"
        case promptedAt = "prompted_at"
    }
}

public struct PromptDraft: Hashable, Sendable {
    public var title: String
    public var content: String
    public var source: String
    public var tags: String?
    public var model: String?
    public var rating: Int?
    public var isStarred: Bool

    public init(
        title: String = "",
        content: String = "",
        source: String = "manual",
        tags: String? = nil,
        model: String? = nil,
        rating: Int? = nil,
        isStarred: Bool = false
    ) {
        self.title = title
        self.content = content
        self.source = source
        self.tags = tags
        self.model = model
        self.rating = rating
        self.isStarred = isStarred
    }

    public init(prompt: PromptRecord) {
        title = prompt.title
        content = prompt.content
        source = prompt.source ?? "manual"
        tags = prompt.tags
        model = prompt.model
        rating = prompt.rating
        isStarred = prompt.isStarred
    }

    public var validationMessage: String? {
        if title.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
            return "Der Titel darf nicht leer sein."
        }
        if content.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
            return "Der Prompt-Inhalt darf nicht leer sein."
        }
        if let rating, !(1...5).contains(rating) {
            return "Die Bewertung muss zwischen 1 und 5 liegen."
        }
        return nil
    }
}