Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,7 @@ docs

# exclude aux files
.git
.idea
.idea

# exclude database dumps
db_dumps
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ backend/sessions
backend/node_modules
backend/logs
backend/coverage

logs/
# ignore build files
dist/
frontend/node_modules
Expand Down
1 change: 1 addition & 0 deletions backend/db/.sequelizerc
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is that needed?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was added so that when we run npx sequelize-cli db:migrate, the CLI loads the .env file and has access to environment variables like POSTGRES_HOST, POSTGRES_CAREDB, etc. Without it, the config.js can't resolve process.env.POSTGRES_CAREDB and the migration fails.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dennis-zyska do we need that file though?

Copy link
Copy Markdown
Collaborator

@dennis-zyska dennis-zyska Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we usually don't use the command without the make file, so usually the envs are set. I wonder if it would always overwrite the current one with the .env (because we have multiple .env files), and the others would not work anymore

Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const path = require('path');
require('dotenv').config({ path: path.resolve(__dirname, '..', '..', '.env') });

module.exports = {
'config': path.resolve('./config', 'config.js'),
Expand Down
1 change: 1 addition & 0 deletions backend/db/config/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*
* @author Nils Dycke
*/

module.exports = {
development: {
username: 'postgres',
Expand Down
82 changes: 82 additions & 0 deletions backend/db/migrations/20260331100037-create-api_key.js
Comment thread
junaidferoz marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
'use strict';

module.exports = {
async up(queryInterface, Sequelize) {
await queryInterface.sequelize.query('CREATE EXTENSION IF NOT EXISTS pgcrypto;');

await queryInterface.createTable('ai_api_key', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
},
userId: {
type: Sequelize.INTEGER,
allowNull: false,
references: {
model: 'user',
key: 'id',
},
onDelete: 'CASCADE',
onUpdate: 'CASCADE',
},
provider: {
type: Sequelize.STRING,
allowNull: false,
},
name: {
type: Sequelize.STRING,
allowNull: false,
},
apiEndpoint: {
type: Sequelize.STRING,
allowNull: true,
defaultValue: null,
},
encryptedKey: {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this here? We should encrypted the columns from the postgres table itself

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. I forgot that we needed to do the encryption from Postgres itself. Please check this commit 1f5d580 where I have fixed this issue

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if is resolved, I can't see a change in the code, please reference to the commit if comments are resolved or explain why it is resolved

type: Sequelize.BLOB,
allowNull: false,
},
enabled: {
type: Sequelize.BOOLEAN,
allowNull: false,
defaultValue: true,
},
usageLimitMonthly: {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs to be discussed how to limit the API keys and models (please set it on the agenda of the team meetings)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I have set this point as one of the points to be discussed in our gradient meeting

type: Sequelize.INTEGER,
allowNull: true,
defaultValue: null,
},
lastUsedAt: {
type: Sequelize.DATE,
allowNull: true,
defaultValue: null,
},
deleted: {
type: Sequelize.BOOLEAN,
allowNull: false,
defaultValue: false,
},
deletedAt: {
type: Sequelize.DATE,
allowNull: true,
defaultValue: null,
},
createdAt: {
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.fn('NOW'),
},
updatedAt: {
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.fn('NOW'),
},
});
},

async down(queryInterface, Sequelize) {
await queryInterface.dropTable('ai_api_key');
},
};
55 changes: 55 additions & 0 deletions backend/db/migrations/20260331101522-create-llm_provider.js
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The sharing option should be represented in the model table. We should be able to share the model to a user or a group of users (we have the definition of roles in the database). You can ask @karimouf for some pointer on how to share it between different roles of users. This might need additional db tables, as we want to also define the limits for that sharing.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have discussed this with @karimouf He has sent me some files. going through with that

Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
'use strict';

module.exports = {
async up(queryInterface, Sequelize) {
await queryInterface.createTable('ai_model', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
},
name: {
type: Sequelize.STRING,
allowNull: false,
},
modelPath: {
type: Sequelize.STRING,
allowNull: false,
},
apiBaseUrl: {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please discuss with @akash9676 what parameters are needed for a model

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay @dennis-zyska. I have added this point in our internal meeting with @akash9676

type: Sequelize.STRING,
allowNull: false,
},
enabled: {
type: Sequelize.BOOLEAN,
allowNull: false,
defaultValue: true,
},
deleted: {
type: Sequelize.BOOLEAN,
allowNull: false,
defaultValue: false,
},
deletedAt: {
type: Sequelize.DATE,
allowNull: true,
defaultValue: null,
},
createdAt: {
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.fn('NOW'),
},
updatedAt: {
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.fn('NOW'),
},
});
},

async down(queryInterface, Sequelize) {
await queryInterface.dropTable('ai_model');
},
};
117 changes: 117 additions & 0 deletions backend/db/migrations/20260331103048-create-llm_log.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
'use strict';

module.exports = {
async up(queryInterface, Sequelize) {
await queryInterface.createTable('ai_log', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
},
userId: {
type: Sequelize.INTEGER,
allowNull: false,
references: {
model: 'user',
key: 'id',
},
onDelete: 'CASCADE',
onUpdate: 'CASCADE',
},
apiKeyId: {
type: Sequelize.INTEGER,
allowNull: true,
defaultValue: null,
references: {
model: 'ai_api_key',
key: 'id',
},
onDelete: 'SET NULL',
onUpdate: 'CASCADE',
},
modelId: {
type: Sequelize.INTEGER,
allowNull: false,
references: {
model: 'ai_model',
key: 'id',
},
onDelete: 'CASCADE',
onUpdate: 'CASCADE',
},
documentId: {
type: Sequelize.INTEGER,
allowNull: true,
defaultValue: null,
},
studySessionId: {
type: Sequelize.INTEGER,
allowNull: true,
defaultValue: null,
},
studyStepId: {
type: Sequelize.INTEGER,
allowNull: true,
defaultValue: null,
},
input: {
type: Sequelize.JSONB,
allowNull: true,
},
output: {
type: Sequelize.JSONB,
allowNull: true,
},
inputTokens: {
type: Sequelize.INTEGER,
allowNull: true,
defaultValue: null,
},
outputTokens: {
type: Sequelize.INTEGER,
allowNull: true,
defaultValue: null,
},
estimatedCost: {
type: Sequelize.FLOAT,
allowNull: true,
defaultValue: null,
},
latencyMs: {
type: Sequelize.INTEGER,
allowNull: true,
defaultValue: null,
},
status: {
type: Sequelize.STRING,
allowNull: false,
defaultValue: 'success',
},
deleted: {
type: Sequelize.BOOLEAN,
allowNull: false,
defaultValue: false,
},
deletedAt: {
type: Sequelize.DATE,
allowNull: true,
defaultValue: null,
},
createdAt: {
Comment thread
junaidferoz marked this conversation as resolved.
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.fn('NOW'),
},
updatedAt: {
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.fn('NOW'),
},
});
},

async down(queryInterface, Sequelize) {
await queryInterface.dropTable('ai_log');
},
};
96 changes: 96 additions & 0 deletions backend/db/migrations/20260331104511-create-prompt_template.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
'use strict';

module.exports = {
async up(queryInterface, Sequelize) {
await queryInterface.createTable('prompt_template', {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The prompt templates are handled by our template integration, please ask @mohammadsherif0 how to use it in detail (we need to add another type of template for it, two types, one usual Prompt template and one that can be used in studies). so this table is probably not needed

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have discussed this with mohammed. Expecting a response from him today, as he was busy with his tasks yesterday.

id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
},
userId: {
type: Sequelize.INTEGER,
allowNull: false,
references: {
model: 'user',
key: 'id',
},
onDelete: 'CASCADE',
onUpdate: 'CASCADE',
},
name: {
type: Sequelize.STRING,
allowNull: false,
},
description: {
type: Sequelize.TEXT,
allowNull: true,
defaultValue: null,
},
provider: {
type: Sequelize.STRING,
allowNull: true,
defaultValue: null,
},
model: {
type: Sequelize.STRING,
allowNull: true,
defaultValue: null,
},
promptText: {
type: Sequelize.TEXT,
allowNull: false,
},
inputMapping: {
type: Sequelize.JSONB,
allowNull: true,
defaultValue: {},
},
defaultOutputMapping: {
type: Sequelize.JSONB,
allowNull: true,
defaultValue: {},
},
shared: {
type: Sequelize.BOOLEAN,
allowNull: false,
defaultValue: false,
},
sharedScope: {
type: Sequelize.STRING,
allowNull: false,
defaultValue: 'none',
},
sharedTargetId: {
type: Sequelize.INTEGER,
allowNull: true,
defaultValue: null,
},
deleted: {
type: Sequelize.BOOLEAN,
allowNull: false,
defaultValue: false,
},
deletedAt: {
type: Sequelize.DATE,
allowNull: true,
defaultValue: null,
},
createdAt: {
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.fn('NOW'),
},
updatedAt: {
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.fn('NOW'),
},
});
},

async down(queryInterface, Sequelize) {
await queryInterface.dropTable('prompt_template');
},
};
Loading
Loading