001/*
002 * Copyright (c) 2026, Oracle and/or its affiliates.
003 *
004 * Licensed under the Universal Permissive License Version 1.0 as shown at
005 * https://oss.oracle.com/licenses/upl/
006 */
007package com.oracle.database.selectai.model;
008
009import java.sql.Timestamp;
010
011/**
012 * Read-only metadata row for a prompt stored in a Select AI conversation.
013 * <p>
014 * Instances are populated from {@code USER_CLOUD_AI_CONVERSATION_PROMPTS} and
015 * returned by {@link com.oracle.database.selectai.Conversation#listPrompts()}. Prompt
016 * metadata can contain caller-provided or generated content, including
017 * conversation titles, prompt text, prompt responses, client identifiers, and
018 * client IP addresses. Applications should avoid logging full prompt metadata
019 * unless application policy permits it.
020 *
021 * @see com.oracle.database.selectai.Conversation#listPrompts()
022 * @see com.oracle.database.selectai.Conversation#deletePrompt(String)
023 */
024public final class ConversationPrompt {
025    /** Conversation prompt identifier. */
026    private final String conversationPromptId;
027    /** Conversation identifier associated with the prompt. */
028    private final String conversationId;
029    /** Conversation title captured with the prompt row. */
030    private final String conversationTitle;
031    /** Select AI profile used for the prompt. */
032    private final String profileName;
033    /** Prompt action such as chat, narrate, or showsql. */
034    private final String promptAction;
035    /** Prompt text. */
036    private final String prompt;
037    /** Prompt response text. */
038    private final String promptResponse;
039    /** Row creation timestamp. */
040    private final Timestamp created;
041    /** Row modification timestamp. */
042    private final Timestamp modified;
043    /** Client identifier captured by the database. */
044    private final String clientIdentifier;
045    /** Client IP captured by the database. */
046    private final String clientIp;
047    /** Database session ID. */
048    private final Long sid;
049    /** Database session serial number. */
050    private final Long serialNumber;
051
052    private ConversationPrompt(Builder builder) {
053        this.conversationPromptId = builder.conversationPromptId;
054        this.conversationId = builder.conversationId;
055        this.conversationTitle = builder.conversationTitle;
056        this.profileName = builder.profileName;
057        this.promptAction = builder.promptAction;
058        this.prompt = builder.prompt;
059        this.promptResponse = builder.promptResponse;
060        this.created = copyTimestamp(builder.created);
061        this.modified = copyTimestamp(builder.modified);
062        this.clientIdentifier = builder.clientIdentifier;
063        this.clientIp = builder.clientIp;
064        this.sid = builder.sid;
065        this.serialNumber = builder.serialNumber;
066    }
067
068    /**
069     * Creates a builder for conversation prompt metadata.
070     *
071     * @return new builder
072     */
073    public static Builder builder() {
074        return new Builder();
075    }
076
077    /**
078     * Returns the conversation prompt identifier.
079     *
080     * @return conversation prompt identifier, or {@code null} when unavailable
081     */
082    public String getConversationPromptId() {
083        return conversationPromptId;
084    }
085
086    /**
087     * Returns the conversation identifier associated with this prompt.
088     *
089     * @return conversation identifier, or {@code null} when unavailable
090     */
091    public String getConversationId() {
092        return conversationId;
093    }
094
095    /**
096     * Returns the conversation title captured with this prompt row.
097     * <p>
098     * This value may contain caller-provided or customer content.
099     *
100     * @return conversation title, or {@code null} when unavailable
101     */
102    public String getConversationTitle() {
103        return conversationTitle;
104    }
105
106    /**
107     * Returns the Select AI profile used for this prompt.
108     *
109     * @return profile name, or {@code null} when unavailable
110     */
111    public String getProfileName() {
112        return profileName;
113    }
114
115    /**
116     * Returns the prompt action used for this prompt.
117     *
118     * @return prompt action such as {@code chat}, {@code narrate}, or {@code showsql}
119     */
120    public String getPromptAction() {
121        return promptAction;
122    }
123
124    /**
125     * Returns the prompt text.
126     * <p>
127     * This value may contain caller-provided or customer content.
128     *
129     * @return prompt text, or {@code null} when unavailable
130     */
131    public String getPrompt() {
132        return prompt;
133    }
134
135    /**
136     * Returns the prompt response text.
137     * <p>
138     * This value may contain generated response text or customer content.
139     *
140     * @return prompt response text, or {@code null} when unavailable
141     */
142    public String getPromptResponse() {
143        return promptResponse;
144    }
145
146    /**
147     * Returns the prompt row creation timestamp.
148     *
149     * @return defensive copy of creation timestamp, or {@code null} when unavailable
150     */
151    public Timestamp getCreated() {
152        return copyTimestamp(created);
153    }
154
155    /**
156     * Returns the prompt row modification timestamp.
157     *
158     * @return defensive copy of modification timestamp, or {@code null} when unavailable
159     */
160    public Timestamp getModified() {
161        return copyTimestamp(modified);
162    }
163
164    /**
165     * Returns the database client identifier captured with this prompt.
166     *
167     * @return client identifier, or {@code null} when unavailable
168     */
169    public String getClientIdentifier() {
170        return clientIdentifier;
171    }
172
173    /**
174     * Returns the client IP address captured by the database.
175     * <p>
176     * This value may be customer or client network metadata.
177     *
178     * @return client IP address, or {@code null} when unavailable
179     */
180    public String getClientIp() {
181        return clientIp;
182    }
183
184    /**
185     * Returns the database session identifier captured with this prompt.
186     *
187     * @return database session identifier, or {@code null} when unavailable
188     */
189    public Long getSid() {
190        return sid;
191    }
192
193    /**
194     * Returns the database session serial number captured with this prompt.
195     *
196     * @return database session serial number, or {@code null} when unavailable
197     */
198    public Long getSerialNumber() {
199        return serialNumber;
200    }
201
202    /**
203     * Returns a non-sensitive summary of this prompt metadata.
204     *
205     * @return summary string that omits prompt text, prompt response, and title
206     */
207    @Override
208    public String toString() {
209        return "ConversationPrompt{"
210                + "conversationPromptId='" + conversationPromptId + '\''
211                + ", conversationId='" + conversationId + '\''
212                + ", profileName='" + profileName + '\''
213                + ", promptAction='" + promptAction + '\''
214                + ", created=" + created
215                + ", modified=" + modified
216                + ", hasConversationTitle=" + (conversationTitle != null)
217                + ", hasPrompt=" + (prompt != null)
218                + ", hasPromptResponse=" + (promptResponse != null)
219                + ", hasClientIdentifier=" + (clientIdentifier != null)
220                + ", hasClientIp=" + (clientIp != null)
221                + ", sid=" + sid
222                + ", serialNumber=" + serialNumber
223                + '}';
224    }
225
226    /**
227     * Builder for {@link ConversationPrompt}.
228     */
229    public static final class Builder {
230        /** Conversation prompt identifier being assembled. */
231        private String conversationPromptId;
232        /** Conversation identifier being assembled. */
233        private String conversationId;
234        /** Conversation title being assembled. */
235        private String conversationTitle;
236        /** Profile name being assembled. */
237        private String profileName;
238        /** Prompt action being assembled. */
239        private String promptAction;
240        /** Prompt text being assembled. */
241        private String prompt;
242        /** Prompt response text being assembled. */
243        private String promptResponse;
244        /** Creation timestamp being assembled. */
245        private Timestamp created;
246        /** Modification timestamp being assembled. */
247        private Timestamp modified;
248        /** Client identifier being assembled. */
249        private String clientIdentifier;
250        /** Client IP address being assembled. */
251        private String clientIp;
252        /** Database session identifier being assembled. */
253        private Long sid;
254        /** Database session serial number being assembled. */
255        private Long serialNumber;
256
257        private Builder() {
258        }
259
260        /**
261         * Sets the conversation prompt identifier.
262         *
263         * @param conversationPromptId conversation prompt identifier
264         * @return this builder instance
265         */
266        public Builder conversationPromptId(String conversationPromptId) {
267            this.conversationPromptId = conversationPromptId;
268            return this;
269        }
270
271        /**
272         * Sets the conversation identifier associated with the prompt.
273         *
274         * @param conversationId conversation identifier
275         * @return this builder instance
276         */
277        public Builder conversationId(String conversationId) {
278            this.conversationId = conversationId;
279            return this;
280        }
281
282        /**
283         * Sets the conversation title captured with the prompt row.
284         *
285         * @param conversationTitle conversation title
286         * @return this builder instance
287         */
288        public Builder conversationTitle(String conversationTitle) {
289            this.conversationTitle = conversationTitle;
290            return this;
291        }
292
293        /**
294         * Sets the Select AI profile used for the prompt.
295         *
296         * @param profileName profile name
297         * @return this builder instance
298         */
299        public Builder profileName(String profileName) {
300            this.profileName = profileName;
301            return this;
302        }
303
304        /**
305         * Sets the prompt action.
306         *
307         * @param promptAction prompt action such as {@code chat}, {@code narrate}, or {@code showsql}
308         * @return this builder instance
309         */
310        public Builder promptAction(String promptAction) {
311            this.promptAction = promptAction;
312            return this;
313        }
314
315        /**
316         * Sets the prompt text.
317         *
318         * @param prompt prompt text
319         * @return this builder instance
320         */
321        public Builder prompt(String prompt) {
322            this.prompt = prompt;
323            return this;
324        }
325
326        /**
327         * Sets the prompt response text.
328         *
329         * @param promptResponse prompt response text
330         * @return this builder instance
331         */
332        public Builder promptResponse(String promptResponse) {
333            this.promptResponse = promptResponse;
334            return this;
335        }
336
337        /**
338         * Sets the prompt row creation timestamp.
339         *
340         * @param created creation timestamp
341         * @return this builder instance
342         */
343        public Builder created(Timestamp created) {
344            this.created = created;
345            return this;
346        }
347
348        /**
349         * Sets the prompt row modification timestamp.
350         *
351         * @param modified modification timestamp
352         * @return this builder instance
353         */
354        public Builder modified(Timestamp modified) {
355            this.modified = modified;
356            return this;
357        }
358
359        /**
360         * Sets the database client identifier captured with the prompt.
361         *
362         * @param clientIdentifier client identifier
363         * @return this builder instance
364         */
365        public Builder clientIdentifier(String clientIdentifier) {
366            this.clientIdentifier = clientIdentifier;
367            return this;
368        }
369
370        /**
371         * Sets the client IP address captured by the database.
372         *
373         * @param clientIp client IP address
374         * @return this builder instance
375         */
376        public Builder clientIp(String clientIp) {
377            this.clientIp = clientIp;
378            return this;
379        }
380
381        /**
382         * Sets the database session identifier.
383         *
384         * @param sid database session identifier
385         * @return this builder instance
386         */
387        public Builder sid(Long sid) {
388            this.sid = sid;
389            return this;
390        }
391
392        /**
393         * Sets the database session serial number.
394         *
395         * @param serialNumber database session serial number
396         * @return this builder instance
397         */
398        public Builder serialNumber(Long serialNumber) {
399            this.serialNumber = serialNumber;
400            return this;
401        }
402
403        /**
404         * Builds immutable conversation prompt metadata.
405         *
406         * @return immutable conversation prompt metadata
407         */
408        public ConversationPrompt build() {
409            return new ConversationPrompt(this);
410        }
411    }
412
413    private static Timestamp copyTimestamp(Timestamp value) {
414        return value == null ? null : new Timestamp(value.getTime());
415    }
416}