-
Notifications
You must be signed in to change notification settings - Fork 23
[O2B-1620] Tags should associate user by id and not direct name #2234
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
de741a9
0abebc0
789c809
98641f9
4bd7b9b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,6 +21,7 @@ class TagAdapter { | |
| constructor() { | ||
| this.toEntity = this.toEntity.bind(this); | ||
| this.toDatabase = this.toDatabase.bind(this); | ||
| this.userAdapter = null; | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -29,12 +30,12 @@ class TagAdapter { | |
| * @param {SequelizeTag} databaseObject Object to convert. | ||
| * @returns {Tag} Converted entity object. | ||
| */ | ||
| toEntity({ id, text, description, email, mattermost, last_edited_name, archived, color, archivedAt, updatedAt }) { | ||
| toEntity({ id, text, description, email, mattermost, lastEditedBy, archived, color, archivedAt, updatedAt }) { | ||
| return { | ||
| id, | ||
| text, | ||
| description, | ||
| lastEditedName: last_edited_name, | ||
| lastEditedBy: lastEditedBy ? this.userAdapter.toNameOnly(lastEditedBy) : null, | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| email, | ||
| mattermost, | ||
| archived, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| /* | ||
| * @license | ||
| * Copyright CERN and copyright holders of ALICE O2. This software is | ||
| * distributed under the terms of the GNU General Public License v3 (GPL | ||
| * Version 3), copied verbatim in the file "COPYING". | ||
| * | ||
| * See http://alice-o2.web.cern.ch/license for full licensing information. | ||
| * | ||
| * In applying this license CERN does not waive the privileges and immunities | ||
| * granted to it by virtue of its status as an Intergovernmental Organization | ||
| * or submit itself to any jurisdiction. | ||
| */ | ||
|
|
||
| 'use strict'; | ||
|
|
||
| /** @type {import('sequelize-cli').Migration} */ | ||
| module.exports = { | ||
| up: async (queryInterface, Sequelize) => queryInterface.sequelize.transaction(async (transaction) => { | ||
| await queryInterface.addColumn('tags', 'last_edited_by_user_id', { | ||
| type: Sequelize.INTEGER, | ||
| allowNull: true, | ||
| references: { | ||
| model: 'users', | ||
| key: 'id', | ||
| }, | ||
| onUpdate: 'CASCADE', | ||
| onDelete: 'SET NULL', | ||
| }, { transaction }); | ||
|
|
||
| // Link existing tags to the user matching the stored name (ambiguous names resolve to the oldest user) | ||
| await queryInterface.sequelize.query( | ||
| `UPDATE tags t | ||
| SET t.last_edited_by_user_id = (SELECT MIN(u.id) FROM users u WHERE u.name = t.last_edited_name) | ||
| WHERE t.last_edited_name IS NOT NULL`, | ||
| { transaction }, | ||
| ); | ||
|
|
||
| await queryInterface.removeColumn('tags', 'last_edited_name', { transaction }); | ||
| }), | ||
|
|
||
| down: async (queryInterface, Sequelize) => queryInterface.sequelize.transaction(async (transaction) => { | ||
| await queryInterface.addColumn('tags', 'last_edited_name', { | ||
| type: Sequelize.STRING, | ||
| allowNull: true, | ||
| }, { transaction }); | ||
|
|
||
| await queryInterface.sequelize.query( | ||
| `UPDATE tags t | ||
| INNER JOIN users u ON u.id = t.last_edited_by_user_id | ||
| SET t.last_edited_name = u.name`, | ||
| { transaction }, | ||
| ); | ||
|
|
||
| await queryInterface.removeColumn('tags', 'last_edited_by_user_id', { transaction }); | ||
| }), | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,6 +21,9 @@ const { | |
| }, | ||
| } = require('../../database'); | ||
| const { tagAdapter } = require('../../database/adapters/index.js'); | ||
| const { BadParameterError } = require('../../server/errors/BadParameterError.js'); | ||
| const { ConflictError } = require('../../server/errors/ConflictError.js'); | ||
| const { getUserOrFail } = require('../../server/services/user/getUserOrFail.js'); | ||
|
|
||
| /** | ||
| * CreateTagUseCase | ||
|
|
@@ -30,23 +33,31 @@ class CreateTagUseCase { | |
| * Executes this use case. | ||
| * | ||
| * @param {Object} dto The CreateTagDto containing all data. | ||
| * @returns {Promise} Promise object represents the result of this use case. | ||
| * @returns {Promise<Tag>} resolves with the created tag | ||
| * @throws {BadParameterError} if no user is provided in the session | ||
| * @throws {NotFoundError} if the session user does not exist | ||
| * @throws {ConflictError} if a tag with the same text already exists | ||
| */ | ||
| async execute(dto) { | ||
| const { body } = dto; | ||
| body.last_edited_name = dto?.session?.name; | ||
| const userId = dto?.session?.id; | ||
| if (userId === undefined || userId === null) { | ||
| throw new BadParameterError('A user is required to create a tag'); | ||
| } | ||
|
|
||
| const tag = await TransactionHelper.provide(async () => { | ||
| const queryBuilder = new QueryBuilder() | ||
| .where('text').is(body.text); | ||
| const tag = await TagRepository.findOne(queryBuilder); | ||
| if (tag) { | ||
| return null; | ||
| const user = await getUserOrFail({ userId }); | ||
| body.lastEditedByUserId = user.id; | ||
|
|
||
| const existingTag = await TagRepository.findOne(new QueryBuilder().where('text').is(body.text)); | ||
| if (existingTag) { | ||
| throw new ConflictError('The provided entity already exists'); | ||
| } | ||
|
|
||
| return TagRepository.insert(tagAdapter.toDatabase(body)); | ||
| }); | ||
|
|
||
| return tag ? tagAdapter.toEntity(tag) : null; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Could it be worth avoiding confusion/inconsistency to do the same? |
||
| return tagAdapter.toEntity(tag); | ||
| } | ||
| } | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'When the tag is edited' reads as if the field is only set when the tag is updated. After this change it's also set when the tag is created. Do you think it could be more specific, or is it clear enough?