@mongoosejs/studio 0.0.74 → 0.0.75
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/backend/actions/ChatMessage/executeScript.js +74 -0
- package/backend/actions/ChatMessage/index.js +3 -0
- package/backend/actions/ChatThread/createChatMessage.js +253 -0
- package/backend/actions/ChatThread/createChatThread.js +19 -0
- package/backend/actions/ChatThread/getChatThread.js +36 -0
- package/backend/actions/ChatThread/index.js +6 -0
- package/backend/actions/ChatThread/listChatThreads.js +24 -0
- package/backend/actions/index.js +2 -0
- package/backend/db/chatMessageSchema.js +30 -0
- package/backend/db/chatThreadSchema.js +15 -0
- package/backend/index.js +6 -2
- package/express.js +1 -0
- package/frontend/public/app.js +2902 -196
- package/frontend/public/tw.css +146 -0
- package/frontend/src/api.js +38 -3
- package/frontend/src/async-button/async-button.html +12 -2
- package/frontend/src/chat/chat-message/chat-message.html +16 -0
- package/frontend/src/chat/chat-message/chat-message.js +66 -0
- package/frontend/src/chat/chat-message-script/chat-message-script.html +52 -0
- package/frontend/src/chat/chat-message-script/chat-message-script.js +35 -0
- package/frontend/src/chat/chat.html +69 -0
- package/frontend/src/chat/chat.js +89 -0
- package/frontend/src/index.js +22 -37
- package/frontend/src/modal/modal.html +2 -2
- package/frontend/src/modal/modal.js +3 -2
- package/frontend/src/navbar/navbar.html +4 -0
- package/frontend/src/navbar/navbar.js +3 -0
- package/frontend/src/routes.js +19 -3
- package/package.json +2 -1
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const Archetype = require('archetype');
|
|
4
|
+
const mongoose = require('mongoose');
|
|
5
|
+
const vm = require('vm');
|
|
6
|
+
|
|
7
|
+
const ExecuteScriptParams = new Archetype({
|
|
8
|
+
userId: {
|
|
9
|
+
$type: mongoose.Types.ObjectId
|
|
10
|
+
},
|
|
11
|
+
chatMessageId: {
|
|
12
|
+
$type: mongoose.Types.ObjectId
|
|
13
|
+
},
|
|
14
|
+
script: {
|
|
15
|
+
$type: String
|
|
16
|
+
}
|
|
17
|
+
}).compile('ExecuteScriptParams');
|
|
18
|
+
|
|
19
|
+
module.exports = ({ db }) => async function executeScript(params) {
|
|
20
|
+
const { userId, chatMessageId, script } = new ExecuteScriptParams(params);
|
|
21
|
+
const ChatMessage = db.model('__Studio_ChatMessage');
|
|
22
|
+
|
|
23
|
+
const chatMessage = await ChatMessage.findById(chatMessageId);
|
|
24
|
+
if (!chatMessage) {
|
|
25
|
+
throw new Error('Chat message not found');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Create a sandbox with the db object
|
|
29
|
+
const logs = [];
|
|
30
|
+
const sandbox = { db, console: {} };
|
|
31
|
+
|
|
32
|
+
// Capture console logs
|
|
33
|
+
sandbox.console.log = function() {
|
|
34
|
+
const args = Array.from(arguments);
|
|
35
|
+
logs.push(args.map(arg => typeof arg === 'object' ? JSON.stringify(arg) : arg).join(' '));
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const context = vm.createContext(sandbox);
|
|
39
|
+
|
|
40
|
+
let output;
|
|
41
|
+
let error;
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
// Execute the script in the sandbox
|
|
45
|
+
output = await vm.runInContext(wrappedScript(script), context);
|
|
46
|
+
|
|
47
|
+
chatMessage.script = script;
|
|
48
|
+
chatMessage.executionResult = { output, logs: logs.join('\n'), error: null };
|
|
49
|
+
await chatMessage.save();
|
|
50
|
+
|
|
51
|
+
return { chatMessage };
|
|
52
|
+
} catch (err) {
|
|
53
|
+
error = err.message;
|
|
54
|
+
|
|
55
|
+
// Update the chat message with the error
|
|
56
|
+
await ChatMessage.updateOne(
|
|
57
|
+
{ _id: chatMessageId },
|
|
58
|
+
{
|
|
59
|
+
script,
|
|
60
|
+
executionResult: {
|
|
61
|
+
output: null,
|
|
62
|
+
logs: logs.join('\n'),
|
|
63
|
+
error
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
throw new Error(`Script execution failed: ${error}`);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const wrappedScript = script => `(async () => {
|
|
73
|
+
${script}
|
|
74
|
+
})()`;
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const Archetype = require('archetype');
|
|
4
|
+
const mongoose = require('mongoose');
|
|
5
|
+
|
|
6
|
+
const CreateChatMessageParams = new Archetype({
|
|
7
|
+
chatThreadId: {
|
|
8
|
+
$type: mongoose.Types.ObjectId
|
|
9
|
+
},
|
|
10
|
+
userId: {
|
|
11
|
+
$type: mongoose.Types.ObjectId
|
|
12
|
+
},
|
|
13
|
+
content: {
|
|
14
|
+
$type: String
|
|
15
|
+
}
|
|
16
|
+
}).compile('CreateChatMessageParams');
|
|
17
|
+
|
|
18
|
+
const systemPrompt = `
|
|
19
|
+
You are a data querying assistant who writes scripts for users accessing MongoDB data using Node.js and Mongoose.
|
|
20
|
+
|
|
21
|
+
Keep scripts concise. Avoid unnecessary comments and error handling, unless explicitly asked for by the user.
|
|
22
|
+
|
|
23
|
+
Assume the user has pre-defined schemas and models. Do not define any new schemas or models for the user.
|
|
24
|
+
|
|
25
|
+
Use async/await where possible. Assume top-level await is allowed.
|
|
26
|
+
|
|
27
|
+
Format output as Markdown, including code fences for any scripts the user requested.
|
|
28
|
+
|
|
29
|
+
Add a brief text description of what the script does.
|
|
30
|
+
|
|
31
|
+
If the user's query is best answered with a chart, return a Chart.js 4 configuration as \`return { $chart: chartJSConfig };\`
|
|
32
|
+
|
|
33
|
+
Example output:
|
|
34
|
+
|
|
35
|
+
The following script counts the number of users which are not deleted.
|
|
36
|
+
|
|
37
|
+
\`\`\`javascript
|
|
38
|
+
const users = await db.model('User').find({ isDeleted: false });
|
|
39
|
+
return { numUsers: users.length };
|
|
40
|
+
\`\`\`
|
|
41
|
+
|
|
42
|
+
-----------
|
|
43
|
+
|
|
44
|
+
Here is a description of the user's models. Assume these are the only models available in the system unless explicitly instructed otherwise by the user.
|
|
45
|
+
|
|
46
|
+
Vehicle (collection name: Vehicle)
|
|
47
|
+
- _id: ObjectId
|
|
48
|
+
- userId: ObjectId (ref User)
|
|
49
|
+
- authorizedUsers: Array
|
|
50
|
+
- status: String
|
|
51
|
+
- _previousStatus: String
|
|
52
|
+
- make: String
|
|
53
|
+
- model: String
|
|
54
|
+
- year: Number
|
|
55
|
+
- color: String
|
|
56
|
+
- nickName: String
|
|
57
|
+
- tollTagId: String
|
|
58
|
+
- availabilityDate: String
|
|
59
|
+
- vehicleFeatures: Array
|
|
60
|
+
- vehicleIdentityId: ObjectId (ref VehicleIdentity)
|
|
61
|
+
- images: Object
|
|
62
|
+
- thumbnail: String
|
|
63
|
+
- photos: Array
|
|
64
|
+
- registrationPhoto: String
|
|
65
|
+
- smartcarId: String
|
|
66
|
+
- smartcarPermissions: Array
|
|
67
|
+
- percentRemaining: Number
|
|
68
|
+
- range: Number
|
|
69
|
+
- location: Object
|
|
70
|
+
- locationTimestamp: Date
|
|
71
|
+
- pricePerMonth: Number
|
|
72
|
+
- pricePerWeek: Number
|
|
73
|
+
- returnAddress: String
|
|
74
|
+
- returnLocation: Object
|
|
75
|
+
- description: String
|
|
76
|
+
- maxUnlockRadiusMiles: Number
|
|
77
|
+
- returnRadiusKM: Number
|
|
78
|
+
- numReviews: Number
|
|
79
|
+
- numCompletedTrips: Number
|
|
80
|
+
- totalReviewScore: Number
|
|
81
|
+
- totalRevenueGenerated: Number
|
|
82
|
+
- bookingsCount: Number
|
|
83
|
+
- odometer: Number
|
|
84
|
+
- pickupInstructions: String
|
|
85
|
+
- returnInstructions: String
|
|
86
|
+
- unlockInstructions: String
|
|
87
|
+
- chargingState: String
|
|
88
|
+
- isPluggedIn: Boolean
|
|
89
|
+
- currentBookingId: ObjectId (ref Booking)
|
|
90
|
+
- maxTripLengthDays: Number
|
|
91
|
+
- smartcarWebhookIds: Array
|
|
92
|
+
- lastErrorMessage: String
|
|
93
|
+
- vinNumber: String
|
|
94
|
+
- licensePlate: String
|
|
95
|
+
- licensePlateState: String
|
|
96
|
+
- registrationExpirationDate: String
|
|
97
|
+
- style: Object
|
|
98
|
+
- driveUnit: Object
|
|
99
|
+
- efficiencyPackage: String
|
|
100
|
+
- performancePackage: String
|
|
101
|
+
- connectivityProvider: String
|
|
102
|
+
- abiId: String
|
|
103
|
+
- platformFeePercentage: Number
|
|
104
|
+
- promotionsEnabled: Boolean
|
|
105
|
+
- modelDescription: String
|
|
106
|
+
- isConcierge: Boolean
|
|
107
|
+
- lastLoadedSuperchargerInvoicesAt: Date
|
|
108
|
+
- privateBookingNotes: String
|
|
109
|
+
- publicMarketingNotes: String
|
|
110
|
+
- fleetKeyState: Object
|
|
111
|
+
- weakBattery: Boolean
|
|
112
|
+
- fleetITconnectionStartDate: Date
|
|
113
|
+
- fleetITId: Number
|
|
114
|
+
- interiorTrim: String
|
|
115
|
+
- skipLoadingSuperchargerInvoices: Boolean
|
|
116
|
+
- chargeKey: Object
|
|
117
|
+
- securityDepositPerUser: Array
|
|
118
|
+
|
|
119
|
+
User (collection name User)
|
|
120
|
+
- _id: ObjectId
|
|
121
|
+
- firstName: String
|
|
122
|
+
- lastName: String
|
|
123
|
+
- email: String (required, lowercase)
|
|
124
|
+
- picture: String
|
|
125
|
+
- zipCode: String
|
|
126
|
+
- telephone: String
|
|
127
|
+
- verifiedTelephone: Boolean
|
|
128
|
+
- verifiedEmail: Boolean
|
|
129
|
+
- googleUserId: String
|
|
130
|
+
- appleUserId: String
|
|
131
|
+
- smartcarUserId: String
|
|
132
|
+
- stripeCustomerId: String
|
|
133
|
+
- roles: Array of String (enum: 'root', 'admin', 'manager', 'host', 'verified-driver', 'internal-tester', 'authorized-payer')
|
|
134
|
+
- accountPreference: String (enum: 'host', 'guest', 'both')
|
|
135
|
+
- defaultPaymentMethodId: ObjectId (ref PaymentMethod)
|
|
136
|
+
- personaInquiryId: String
|
|
137
|
+
- personaAccountId: String
|
|
138
|
+
- personaInquiryStatus: String (enum: 'created', 'approved', 'declined')
|
|
139
|
+
- personaHasDriverLicense: Boolean
|
|
140
|
+
- driverLicenseState: String
|
|
141
|
+
- numReviews: Number
|
|
142
|
+
- totalReviewScore: Number
|
|
143
|
+
- needsSmartcarReconnect: Boolean
|
|
144
|
+
- isFrozen: Boolean
|
|
145
|
+
- instantTransactions: Boolean
|
|
146
|
+
- publicNotes: String
|
|
147
|
+
- bookingNotes: String
|
|
148
|
+
- hostOnboarding: Object
|
|
149
|
+
- guestOnboarding: Object
|
|
150
|
+
- canUseApp: Boolean
|
|
151
|
+
- useWalletForChargeReceipt: Boolean
|
|
152
|
+
- appOnboardingToken: Object
|
|
153
|
+
- addedToLaunchlist: Boolean
|
|
154
|
+
- stripeAccountId: String
|
|
155
|
+
- isStripeConnectedAccountConfirmed: Boolean
|
|
156
|
+
- requestedAccountDeletion: Boolean
|
|
157
|
+
- qrcodeUrl: String
|
|
158
|
+
- checkrCandidateId: String
|
|
159
|
+
- checkrInvitationId: String
|
|
160
|
+
- checkrInvitationUrl: String
|
|
161
|
+
- checkrInvitationStatus: String
|
|
162
|
+
- referralCode: String
|
|
163
|
+
- referralUrl: String
|
|
164
|
+
- referralConversionId: ObjectId (ref ReferralConversion)
|
|
165
|
+
- abiOwnerId: String
|
|
166
|
+
- abiRenterId: String
|
|
167
|
+
- driverLicense: Object
|
|
168
|
+
- securityDeposit: Number
|
|
169
|
+
- tripcityOwnerId: String
|
|
170
|
+
- bannedUserId: ObjectId (ref BannedUser)
|
|
171
|
+
- isConcierge: Boolean
|
|
172
|
+
- lastHostDashboardLoginAt: Date
|
|
173
|
+
- internalSlackChannel: String
|
|
174
|
+
- skipLoadingSuperchargerInvoices: Boolean
|
|
175
|
+
`.trim();
|
|
176
|
+
|
|
177
|
+
module.exports = ({ db }) => async function createChatMessage(params) {
|
|
178
|
+
const { chatThreadId, userId, content, script } = new CreateChatMessageParams(params);
|
|
179
|
+
const ChatThread = db.model('__Studio_ChatThread');
|
|
180
|
+
const ChatMessage = db.model('__Studio_ChatMessage');
|
|
181
|
+
|
|
182
|
+
// Check that the user owns the thread
|
|
183
|
+
const chatThread = await ChatThread.findOne({ _id: chatThreadId });
|
|
184
|
+
if (!chatThread) {
|
|
185
|
+
throw new Error('Chat thread not found');
|
|
186
|
+
}
|
|
187
|
+
if (userId != null && chatThread.userId.toString() !== userId.toString()) {
|
|
188
|
+
throw new Error('Not authorized');
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const messages = await ChatMessage.find({ chatThreadId }).sort({ createdAt: 1 });
|
|
192
|
+
const llmMessages = messages.map(m => ({
|
|
193
|
+
role: m.role,
|
|
194
|
+
content: m.content
|
|
195
|
+
}));
|
|
196
|
+
llmMessages.push({ role: 'user', content });
|
|
197
|
+
|
|
198
|
+
if (chatThread.title == null) {
|
|
199
|
+
getChatCompletion([
|
|
200
|
+
{ role: 'system', content: 'Summarize the following chat thread in 6 words or less, as a helpful thread title' },
|
|
201
|
+
...llmMessages
|
|
202
|
+
]).then(res => {
|
|
203
|
+
const title = res.choices?.[0]?.message?.content;
|
|
204
|
+
chatThread.title = title;
|
|
205
|
+
return chatThread.save();
|
|
206
|
+
}).catch(() => {});
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
llmMessages.unshift({
|
|
210
|
+
role: 'system',
|
|
211
|
+
content: systemPrompt
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
// Create the chat message and get OpenAI response in parallel
|
|
215
|
+
const chatMessages = await Promise.all([
|
|
216
|
+
ChatMessage.create({
|
|
217
|
+
chatThreadId,
|
|
218
|
+
role: 'user',
|
|
219
|
+
content,
|
|
220
|
+
script,
|
|
221
|
+
executionResult: null
|
|
222
|
+
}),
|
|
223
|
+
getChatCompletion(llmMessages).then(res => {
|
|
224
|
+
const content = res.choices?.[0]?.message?.content || '';
|
|
225
|
+
console.log('Content', content, res);
|
|
226
|
+
return ChatMessage.create({
|
|
227
|
+
chatThreadId,
|
|
228
|
+
role: 'assistant',
|
|
229
|
+
content
|
|
230
|
+
});
|
|
231
|
+
})
|
|
232
|
+
]);
|
|
233
|
+
|
|
234
|
+
return { chatMessages };
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
async function getChatCompletion(messages, options = {}) {
|
|
238
|
+
const response = await fetch('https://api.openai.com/v1/chat/completions', {
|
|
239
|
+
method: 'POST',
|
|
240
|
+
headers: {
|
|
241
|
+
Authorization: `Bearer ${process.env.OPENAI_API_KEY}`,
|
|
242
|
+
'Content-Type': 'application/json'
|
|
243
|
+
},
|
|
244
|
+
body: JSON.stringify({
|
|
245
|
+
model: 'gpt-4o',
|
|
246
|
+
max_tokens: 2500,
|
|
247
|
+
...options,
|
|
248
|
+
messages
|
|
249
|
+
})
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
return await response.json();
|
|
253
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const Archetype = require('archetype');
|
|
4
|
+
const mongoose = require('mongoose');
|
|
5
|
+
|
|
6
|
+
const CreateChatThreadParams = new Archetype({
|
|
7
|
+
userId: {
|
|
8
|
+
$type: mongoose.Types.ObjectId
|
|
9
|
+
}
|
|
10
|
+
}).compile('CreateChatThreadParams');
|
|
11
|
+
|
|
12
|
+
module.exports = ({ db }) => async function createChatThread(params) {
|
|
13
|
+
const { userId } = new CreateChatThreadParams(params);
|
|
14
|
+
const ChatThread = db.model('__Studio_ChatThread');
|
|
15
|
+
|
|
16
|
+
const chatThread = await ChatThread.create({ userId });
|
|
17
|
+
|
|
18
|
+
return { chatThread };
|
|
19
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const Archetype = require('archetype');
|
|
4
|
+
const mongoose = require('mongoose');
|
|
5
|
+
|
|
6
|
+
const GetChatThreadParams = new Archetype({
|
|
7
|
+
chatThreadId: {
|
|
8
|
+
$type: mongoose.Types.ObjectId
|
|
9
|
+
},
|
|
10
|
+
userId: {
|
|
11
|
+
$type: mongoose.Types.ObjectId
|
|
12
|
+
}
|
|
13
|
+
}).compile('GetChatThreadParams');
|
|
14
|
+
|
|
15
|
+
module.exports = ({ db }) => async function getChatThread(params) {
|
|
16
|
+
const { chatThreadId, userId } = new GetChatThreadParams(params);
|
|
17
|
+
const ChatThread = db.model('__Studio_ChatThread');
|
|
18
|
+
const ChatMessage = db.model('__Studio_ChatMessage');
|
|
19
|
+
|
|
20
|
+
const chatThread = await ChatThread.findById(chatThreadId);
|
|
21
|
+
|
|
22
|
+
if (!chatThread) {
|
|
23
|
+
throw new Error('Chat thread not found');
|
|
24
|
+
}
|
|
25
|
+
if (userId && chatThread.userId.toString() !== userId.toString()) {
|
|
26
|
+
throw new Error('Not authorized');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const chatMessages = await ChatMessage.find({ chatThreadId })
|
|
30
|
+
.sort({ createdAt: -1 });
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
chatThread,
|
|
34
|
+
chatMessages: chatMessages.reverse() // Return in chronological order
|
|
35
|
+
};
|
|
36
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const Archetype = require('archetype');
|
|
4
|
+
const mongoose = require('mongoose');
|
|
5
|
+
|
|
6
|
+
const ListChatThreadsParams = new Archetype({
|
|
7
|
+
userId: {
|
|
8
|
+
$type: mongoose.Types.ObjectId
|
|
9
|
+
}
|
|
10
|
+
}).compile('ListChatThreadsParams');
|
|
11
|
+
|
|
12
|
+
module.exports = ({ db }) => async function listChatThreads(params) {
|
|
13
|
+
// Just validate the params object, but no actual parameters needed
|
|
14
|
+
const { userId } = new ListChatThreadsParams(params);
|
|
15
|
+
const ChatThread = db.model('__Studio_ChatThread');
|
|
16
|
+
|
|
17
|
+
// Get all chat threads
|
|
18
|
+
const chatThreads = await ChatThread.find(userId ? { userId } : {})
|
|
19
|
+
.sort({ updatedAt: -1 }); // Sort by most recently updated
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
chatThreads
|
|
23
|
+
};
|
|
24
|
+
};
|
package/backend/actions/index.js
CHANGED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const mongoose = require('mongoose');
|
|
4
|
+
|
|
5
|
+
const chatMessageSchema = new mongoose.Schema({
|
|
6
|
+
chatThreadId: {
|
|
7
|
+
type: 'ObjectId',
|
|
8
|
+
required: true
|
|
9
|
+
},
|
|
10
|
+
role: {
|
|
11
|
+
type: String,
|
|
12
|
+
enum: ['user', 'assistant'],
|
|
13
|
+
required: true
|
|
14
|
+
},
|
|
15
|
+
content: {
|
|
16
|
+
type: String,
|
|
17
|
+
required: true
|
|
18
|
+
},
|
|
19
|
+
script: {
|
|
20
|
+
type: String,
|
|
21
|
+
required: false
|
|
22
|
+
},
|
|
23
|
+
executionResult: {
|
|
24
|
+
output: mongoose.Schema.Types.Mixed,
|
|
25
|
+
logs: String,
|
|
26
|
+
error: String
|
|
27
|
+
}
|
|
28
|
+
}, { timestamps: true });
|
|
29
|
+
|
|
30
|
+
module.exports = chatMessageSchema;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const mongoose = require('mongoose');
|
|
4
|
+
|
|
5
|
+
const chatThreadSchema = new mongoose.Schema({
|
|
6
|
+
title: {
|
|
7
|
+
type: String
|
|
8
|
+
},
|
|
9
|
+
userId: {
|
|
10
|
+
type: mongoose.ObjectId,
|
|
11
|
+
ref: 'User'
|
|
12
|
+
}
|
|
13
|
+
}, { timestamps: true });
|
|
14
|
+
|
|
15
|
+
module.exports = chatThreadSchema;
|
package/backend/index.js
CHANGED
|
@@ -4,12 +4,16 @@ const Actions = require('./actions');
|
|
|
4
4
|
const { applySpec } = require('extrovert');
|
|
5
5
|
const mongoose = require('mongoose');
|
|
6
6
|
|
|
7
|
+
const chatMessageSchema = require('./db/chatMessageSchema');
|
|
8
|
+
const chatThreadSchema = require('./db/chatThreadSchema');
|
|
7
9
|
const dashboardSchema = require('./db/dashboardSchema');
|
|
8
10
|
|
|
9
11
|
module.exports = function backend(db) {
|
|
10
12
|
db = db || mongoose.connection;
|
|
11
|
-
|
|
13
|
+
|
|
12
14
|
const Dashboard = db.model('__Studio_Dashboard', dashboardSchema, 'studio__dashboards');
|
|
15
|
+
const ChatMessage = db.model('__Studio_ChatMessage', chatMessageSchema, 'studio__chatMessages');
|
|
16
|
+
const ChatThread = db.model('__Studio_ChatThread', chatThreadSchema, 'studio__chatThreads');
|
|
13
17
|
const actions = applySpec(Actions, { db });
|
|
14
18
|
return actions;
|
|
15
|
-
};
|
|
19
|
+
};
|