Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • add_route_assignments
  • ask-user-to-delete-exercises-on-duplicates
  • bedran_exercise-list
  • jw_sonar
  • jw_sonar_backup
  • main
  • update-dependencies
  • v6.0.0
  • 2.0.0
  • 2.1.0
  • 2.2.0
  • 3.0.0
  • 3.0.1
  • 3.1.0
  • 3.1.1
  • 3.1.2
  • 3.1.3
  • 3.2.0
  • 3.3.0
  • 3.4.0
  • 3.4.1
  • 3.4.2
  • 3.5.0
  • 3.5.1
  • 3.5.2
  • 3.5.3
  • 4.0.0
  • 4.1.0
  • 5.0.0
  • 5.0.1
  • 6.0.0-dev
  • v1.0.1
32 results

Target

Select target project
  • Dojo_Project_Nguyen/backend/dojobackendapi
  • dojo_project/projects/backend/dojobackendapi
2 results
Select Git revision
  • add_route_assignments
  • ask-user-to-delete-exercises-on-duplicates
  • bedran_exercise-list
  • jw_sonar
  • jw_sonar_backup
  • main
  • update-dependencies
  • v6.0.0
  • 2.0.0
  • 2.1.0
  • 2.2.0
  • 3.0.0
  • 3.0.1
  • 3.1.0
  • 3.1.1
  • 3.1.2
  • 3.1.3
  • 3.2.0
  • 3.3.0
  • 3.4.0
  • 3.4.1
  • 3.4.2
  • 3.5.0
  • 3.5.1
  • 3.5.2
  • 3.5.3
  • 4.0.0
  • 4.1.0
  • 5.0.0
  • 5.0.1
  • 6.0.0-dev
  • v1.0.1
32 results
Show changes
Commits on Source (11)
......@@ -17,7 +17,16 @@
- No modifications / Keep major and minors versions in sync with all parts of the project
-->
## 5.0.0 (Upcoming)
## 5.0.1 (2025-02-25)
### 🐛 Bugfix
- Fix some bugs related to assignments / exercises deletion
### 🔨 Internal / Developers
- Adminer: Style migration to dracula theme
## 5.0.0 (2024-10-21)
### ✨ Feature
- Add possibility of self-host the solution
......
openapi: 3.1.0
info:
title: Dojo API
version: 5.0.0
version: 5.0.1
description: |
**Backend API of the Dojo project.**
......
This diff is collapsed.
{
"name" : "dojo_backend_api",
"description" : "Backend API of the Dojo project",
"version" : "5.0.0",
"version" : "5.0.1",
"license" : "AGPLv3",
"author" : "Michaël Minelli <dojo@minelli.me>",
"main" : "dist/src/app.js",
......
/*
Warnings:
- Added the required column `gitlabCreationDate` to the `Assignment` table without a default value. This is not possible if the table is not empty.
- Added the required column `gitlabCreationDate` to the `Exercise` table without a default value. This is not possible if the table is not empty.
*/
-- AlterTable
ALTER TABLE `Assignment` ADD COLUMN `gitlabCreationDate` DATETIME(3) NULL AFTER `gitlabCreationInfo`;
UPDATE `Assignment` SET `gitlabCreationDate` = `gitlabLastInfoDate`;
ALTER TABLE `Assignment` MODIFY COLUMN `gitlabCreationDate` DATETIME(3) NOT NULL AFTER `gitlabCreationInfo`;
-- AlterTable
ALTER TABLE `Exercise` ADD COLUMN `gitlabCreationDate` DATETIME(3) NULL DEFAULT NULL AFTER `gitlabCreationInfo`;
UPDATE `Exercise` SET `gitlabCreationDate` = `gitlabLastInfoDate`;
ALTER TABLE `Exercise` MODIFY COLUMN `gitlabCreationDate` DATETIME(3) NOT NULL AFTER `gitlabCreationInfo`;
......@@ -38,6 +38,7 @@ model Assignment {
gitlabId Int
gitlabLink String
gitlabCreationInfo Json @db.Json
gitlabCreationDate DateTime
gitlabLastInfo Json @db.Json
gitlabLastInfoDate DateTime
published Boolean @default(false)
......@@ -55,6 +56,7 @@ model Exercise {
gitlabId Int
gitlabLink String
gitlabCreationInfo Json @db.Json
gitlabCreationDate DateTime
gitlabLastInfo Json @db.Json
gitlabLastInfoDate DateTime
deleted Boolean @default(false)
......
This diff is collapsed.
......@@ -15,11 +15,10 @@ class ExerciseManager {
}) as unknown as Exercise ?? undefined;
}
getFromAssignment(assignmentName: string, include: Prisma.ExerciseInclude | undefined = undefined): Promise<Array<Exercise>> {
// deleteFilter is a boolean that is true to get only deleted exercises, false to get only non-deleted exercises, and undefined to get all exercises
getFromAssignment(assignmentName: string, deleteFilter: boolean | undefined = undefined, include: Prisma.ExerciseInclude | undefined = undefined): Promise<Array<Exercise>> {
return db.exercise.findMany({
where : {
assignmentName: assignmentName
},
where : { assignmentName: assignmentName, ...(deleteFilter !== undefined ? { deleted: deleteFilter } : {}) },
include: include
}) as Promise<Array<Exercise>>;
}
......
......@@ -133,6 +133,17 @@ class GitlabManager extends SharedGitlabManager {
}
}
async renameRepository(repoId: number, newName: string): Promise<ProjectSchema> {
try {
return await this.api.Projects.edit(repoId, {
name: newName
});
} catch ( e ) {
logger.error(JSON.stringify(e));
return Promise.reject(e);
}
}
async moveRepository(repoId: number, newRepoId: number): Promise<ProjectSchema> {
try {
return await this.api.Projects.transfer(repoId, newRepoId);
......
......@@ -107,7 +107,8 @@ class AssignmentRoutes implements RoutesManager {
some: {
id: req.session.profile.id
}
}
},
deleted : false
},
include: {
assignment: false,
......@@ -174,6 +175,7 @@ class AssignmentRoutes implements RoutesManager {
gitlabId : repository.id,
gitlabLink : repository.web_url,
gitlabCreationInfo: repository as unknown as Prisma.JsonObject,
gitlabCreationDate: new Date(),
gitlabLastInfo : repository as unknown as Prisma.JsonObject,
gitlabLastInfoDate: new Date(),
staff : {
......
......@@ -24,6 +24,7 @@ import GlobalHelper from '../helpers/GlobalHelper.js';
import { IFileDirStat } from '../shared/helpers/recursiveFilesStats/RecursiveFilesStats.js';
import ExerciseManager from '../managers/ExerciseManager.js';
import * as Gitlab from '@gitbeaker/rest';
import { ProjectSchema } from '@gitbeaker/rest';
import GitlabTreeFileType from '../shared/types/Gitlab/GitlabTreeFileType.js';
import { GitbeakerRequestError } from '@gitbeaker/requester-utils';
......@@ -110,11 +111,19 @@ class ExerciseRoutes implements RoutesManager {
}
}
await GitlabManager.moveRepository(repoId, Config.gitlab.group.deletedExercises);
// We rename (with unique str added) the repository before moving it because of potential name conflicts
const newName: string = `${ req.boundParams.exercise!.name }_${ uuidv4() }`;
await GitlabManager.renameRepository(repoId, newName);
const repository: ProjectSchema = await GitlabManager.moveRepository(repoId, Config.gitlab.group.deletedExercises);
await db.exercise.update({
where: { id: req.boundParams.exercise!.id },
data : { deleted: true }
data : {
name : newName,
gitlabLastInfo : repository as unknown as Prisma.JsonObject,
gitlabLastInfoDate: new Date(),
deleted : true
}
});
return req.session.sendResponse(res, StatusCodes.OK);
......@@ -133,7 +142,7 @@ class ExerciseRoutes implements RoutesManager {
private async checkExerciseLimit(assignment: Assignment, members: Array<Gitlab.UserSchema>): Promise<Array<Gitlab.UserSchema>> {
const exercises: Array<Exercise> | undefined = await ExerciseManager.getFromAssignment(assignment.name, { members: true });
const exercises: Array<Exercise> | undefined = await ExerciseManager.getFromAssignment(assignment.name, false, { members: true });
const reachedLimitUsers: Array<Gitlab.UserSchema> = [];
if ( exercises.length > 0 ) {
for ( const member of members ) {
......@@ -225,6 +234,7 @@ class ExerciseRoutes implements RoutesManager {
gitlabId : repository.id,
gitlabLink : repository.web_url,
gitlabCreationInfo: repository as unknown as Prisma.JsonObject,
gitlabCreationDate: new Date(),
gitlabLastInfo : repository as unknown as Prisma.JsonObject,
gitlabLastInfoDate: new Date(),
members : {
......
Subproject commit de8af98ab1085f83a5756e797812b400298689dd
Subproject commit 3605016ce0adf45698057bbe0a12bb658fe6bda0
......@@ -22,6 +22,7 @@ services:
- ADMINER_DEFAULT_SERVER=dojo-database
- TZ=Europe/Zurich
- ADMINER_PLUGINS=dump-alter dump-bz2 dump-date dump-json dump-xml dump-zip edit-foreign edit-textarea foreign-system json-column sql-log struct-comments tables-filter
- ADMINER_DESIGN=dracula
networks:
dojo-network:
aliases:
......