Skip to content
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

N21-1824 Course resync #5115

Merged
merged 34 commits into from
Jul 29, 2024
Merged
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
3e94225
- data model changes
IgorCapCoder Jul 17, 2024
9e5eb96
- update lastSyncedAt when provisioning group
IgorCapCoder Jul 17, 2024
e2ffd75
Merge branch 'main' into N21-1824-course-resync
IgorCapCoder Jul 17, 2024
be7e127
update group deletion + sync course logic
sdinkov Jul 19, 2024
d3e819b
Merge branch 'main' into N21-1824-course-resync
sdinkov Jul 19, 2024
fadd208
Merge branch 'main' into N21-1824-course-resync
sdinkov Jul 19, 2024
63e3c31
Merge branch 'main' into N21-1824-course-resync
IgorCapCoder Jul 19, 2024
f9f9c40
update group provisioning + tests
sdinkov Jul 19, 2024
a722a70
update course/group-provisioning tests
sdinkov Jul 19, 2024
6553f42
Merge branch 'main' into N21-1824-course-resync
sdinkov Jul 22, 2024
35ae019
N21-1824 migration script
mrikallab Jul 23, 2024
1383883
Merge remote-tracking branch 'origin/N21-1824-course-resync' into N21…
IgorCapCoder Jul 23, 2024
b21874a
Merge branch 'main' into N21-1824-course-resync
IgorCapCoder Jul 23, 2024
9874734
- group.repo.spec.ts still failing tests
IgorCapCoder Jul 23, 2024
29f3782
Merge branch 'main' into N21-1824-course-resync
IgorCapCoder Jul 24, 2024
9e31385
N21-2095 seed data
mrikallab Jul 24, 2024
aaf8e95
N21-2095 migr script fix
mrikallab Jul 24, 2024
7cdc559
N21-2095 fix seed data
mrikallab Jul 24, 2024
1318bbe
migration: Migration20240719115036
mrikallab Jul 24, 2024
f1a3c04
migration: Migration20240719115036
mrikallab Jul 24, 2024
32832fe
migration: Migration20240719115036
mrikallab Jul 24, 2024
a827406
Merge remote-tracking branch 'origin/N21-1824-course-resync' into N21…
IgorCapCoder Jul 25, 2024
54a706f
Merge branch 'main' into N21-1824-course-resync
IgorCapCoder Jul 25, 2024
1bb7ab9
fix group search
IgorCapCoder Jul 25, 2024
3d97634
fix empty group save
IgorCapCoder Jul 25, 2024
141272f
Merge branch 'main' into N21-1824-course-resync
IgorCapCoder Jul 25, 2024
c132a98
Merge branch 'main' into N21-1824-course-resync
sdinkov Jul 26, 2024
cfb9427
update migration script
sdinkov Jul 26, 2024
0f76770
update tests + import
sdinkov Jul 26, 2024
5348ae9
Merge branch 'main' into N21-1824-course-resync
sdinkov Jul 29, 2024
be9d53a
update group repo test
sdinkov Jul 29, 2024
a8aaa43
remove comment + update import
sdinkov Jul 29, 2024
fb20638
Merge branch 'main' into N21-1824-course-resync
sdinkov Jul 29, 2024
5f7522e
update group scope test
sdinkov Jul 29, 2024
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
69 changes: 69 additions & 0 deletions apps/server/src/migrations/mikro-orm/Migration20240719115036.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { Migration } from '@mikro-orm/migrations-mongodb';

export class Migration20240719115036 extends Migration {
async up(): Promise<void> {
await this.driver.aggregate('groups', [
{ $match: { externalSource_externalId: { $exists: true } } },
{
$set: {
externalSource: {
externalId: '$externalSource_externalId',
system: '$externalSource_system',
},
},
},
{ $merge: 'groups' },
]);
sdinkov marked this conversation as resolved.
Show resolved Hide resolved
console.info(
`Migrate fields externalSource_externalId and externalSource_system to nested document externalSource`
);

await this.driver.nativeUpdate(
'groups',
{},
{
$unset: { externalSource_externalId: '', externalSource_system: '' },
}
);
console.info(`Removed fields externalSource_externalId and externalSource_system`);

await this.driver.aggregate('groups', [
{ $match: { externalSource: { $exists: true } } },
{
$set: {
externalSource: {
lastSyncedAt: new Date(),
},
},
},
{ $merge: 'groups' },
]);

console.info(`Updated nested document externalSource. Added nested field lastSyncedAt`);
}

async down(): Promise<void> {
await this.driver.aggregate('groups', [
{ $match: { externalSource: { $exists: true } } },
{
$set: {
externalSource_externalId: '$externalSource.externalId',
externalSource_system: '$externalSource.system',
},
},
{ $merge: 'groups' },
]);
console.info(
`Rollback: Migrate fields externalSource_externalId and externalSource_system to nested document externalSource`
);

await this.driver.nativeUpdate(
'groups',
{ externalSource: { $exists: true } },
{
$unset: { externalSource: '' },
}
);
console.info(`Removed externalSource nested document`);
}
}
8 changes: 2 additions & 6 deletions apps/server/src/modules/group/entity/group.entity.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Collection, Embedded, Entity, Enum, ManyToOne, OneToMany, Property } from '@mikro-orm/core';
import { Course as CourseEntity } from '@shared/domain/entity';
import { Embedded, Entity, Enum, ManyToOne, Property } from '@mikro-orm/core';
import { BaseEntityWithTimestamps } from '@shared/domain/entity/base.entity';
import { ExternalSourceEmbeddable } from '@shared/domain/entity/external-source.embeddable';
import { SchoolEntity } from '@shared/domain/entity/school.entity';
Expand Down Expand Up @@ -37,7 +36,7 @@ export class GroupEntity extends BaseEntityWithTimestamps {
@Enum()
type: GroupEntityTypes;

@Embedded(() => ExternalSourceEmbeddable, { nullable: true })
@Embedded(() => ExternalSourceEmbeddable, { nullable: true, object: true })
externalSource?: ExternalSourceEmbeddable;

@Embedded(() => GroupValidPeriodEmbeddable, { nullable: true })
Expand All @@ -49,9 +48,6 @@ export class GroupEntity extends BaseEntityWithTimestamps {
@ManyToOne(() => SchoolEntity, { nullable: true })
organization?: SchoolEntity;

@OneToMany(() => CourseEntity, (course: CourseEntity) => course.syncedWithGroup)
syncedCourses: Collection<CourseEntity> = new Collection<CourseEntity>(this);

constructor(props: GroupEntityProps) {
super();
if (props.id) {
Expand Down
2 changes: 2 additions & 0 deletions apps/server/src/modules/group/repo/group-domain.mapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export class GroupDomainMapper {
const externalSourceEntity: ExternalSourceEmbeddable = new ExternalSourceEmbeddable({
externalId: externalSource.externalId,
system: em.getReference(SystemEntity, externalSource.systemId),
lastSyncedAt: externalSource.lastSyncedAt,
});

return externalSourceEntity;
Expand All @@ -79,6 +80,7 @@ export class GroupDomainMapper {
const externalSource: ExternalSource = new ExternalSource({
externalId: entity.externalId,
systemId: entity.system.id,
lastSyncedAt: entity.lastSyncedAt,
});

return externalSource;
Expand Down
2 changes: 2 additions & 0 deletions apps/server/src/modules/group/repo/group.repo.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ describe('GroupRepo', () => {
externalSource: new ExternalSource({
externalId: group.externalSource?.externalId ?? '',
systemId: group.externalSource?.system.id ?? '',
lastSyncedAt: group.externalSource?.lastSyncedAt ?? new Date(2024, 1, 1),
}),
users: [
new GroupUser({
Expand Down Expand Up @@ -676,6 +677,7 @@ describe('GroupRepo', () => {
externalSource: new ExternalSource({
externalId: groupEntity.externalSource?.externalId ?? '',
systemId: groupEntity.externalSource?.system.id ?? '',
lastSyncedAt: groupEntity.externalSource?.lastSyncedAt ?? new Date(2024, 1, 1),
}),
users: [
new GroupUser({
Expand Down
2 changes: 1 addition & 1 deletion apps/server/src/modules/group/repo/group.repo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export class GroupRepo extends BaseDomainObjectRepo<Group, GroupEntity> {
const entity: GroupEntity | null = await this.em.findOne(GroupEntity, {
externalSource: {
externalId,
system: systemId,
system: new ObjectId(systemId),
},
});

Expand Down
2 changes: 1 addition & 1 deletion apps/server/src/modules/group/repo/group.scope.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export class GroupScope extends Scope<GroupEntity> {

bySystemId(id: EntityId | undefined): this {
if (id) {
this.addQuery({ externalSource: { system: id } });
this.addQuery({ externalSource: { system: new ObjectId(id) } });
}
return this;
}
Expand Down
2 changes: 1 addition & 1 deletion apps/server/src/modules/group/uc/class-group.uc.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import { ClassService } from '@modules/class';
import { Class } from '@modules/class/domain';
import { classFactory } from '@modules/class/domain/testing/factory/class.factory';
import { ClassGroupUc } from '@modules/group/uc/class-group.uc';
import { CourseDoService } from '@modules/learnroom';
MarvinOehlerkingCap marked this conversation as resolved.
Show resolved Hide resolved
import { Course } from '@modules/learnroom/domain';
import { CourseDoService } from '@modules/learnroom/service/course-do.service';
import { courseFactory } from '@modules/learnroom/testing';
import { SchoolYearService } from '@modules/legacy-school';
import { ProvisioningConfig } from '@modules/provisioning';
Expand Down
2 changes: 1 addition & 1 deletion apps/server/src/modules/group/uc/class-group.uc.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { AuthorizationContextBuilder, AuthorizationService } from '@modules/authorization';
import { ClassService } from '@modules/class';
import { Class } from '@modules/class/domain';
import { CourseDoService } from '@modules/learnroom';
import { Course } from '@modules/learnroom/domain';
import { CourseDoService } from '@modules/learnroom/service/course-do.service';
import { SchoolYearService } from '@modules/legacy-school';
import { ProvisioningConfig } from '@modules/provisioning';
import { School, SchoolService, SchoolYear } from '@modules/school/domain';
Expand Down
1 change: 1 addition & 0 deletions apps/server/src/modules/learnroom/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export {
CourseCopyService,
CourseGroupService,
CourseService,
CourseDoService,
DashboardService,
RoomsService,
} from './service';
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { createMock, DeepMocked } from '@golevelup/ts-jest';
import { ObjectId } from '@mikro-orm/mongodb';
import { Group, GroupUser } from '@modules/group';
import { CourseDoService } from '@modules/learnroom';
import { Course } from '@modules/learnroom/domain';
import { CourseDoService } from '@modules/learnroom/service/course-do.service';
import { courseFactory } from '@modules/learnroom/testing';
import { RoleDto, RoleService } from '@modules/role';
import { Test, TestingModule } from '@nestjs/testing';
Expand Down Expand Up @@ -181,7 +181,11 @@ describe(SchulconnexCourseSyncService.name, () => {
const setup = () => {
const studentUserId = new ObjectId().toHexString();
const teacherUserId = new ObjectId().toHexString();
const course: Course = courseFactory.build({ teacherIds: [teacherUserId], studentIds: [studentUserId] });
const course: Course = courseFactory.build({
teacherIds: [teacherUserId],
IgorCapCoder marked this conversation as resolved.
Show resolved Hide resolved
studentIds: [studentUserId],
syncedWithGroup: new ObjectId().toHexString(),
});
const studentRoleId: string = new ObjectId().toHexString();
const studentRole: RoleDto = roleDtoFactory.build({ id: studentRoleId });
const teacherRole: RoleDto = roleDtoFactory.build();
Expand All @@ -205,7 +209,7 @@ describe(SchulconnexCourseSyncService.name, () => {
};
};

it('should keep the last teacher, remove all students and break the sync with the group', async () => {
it('should keep the last teacher, remove all students', async () => {
const { course, newGroup, teacherUserId } = setup();

await service.synchronizeCourseWithGroup(newGroup, newGroup);
Expand All @@ -218,7 +222,7 @@ describe(SchulconnexCourseSyncService.name, () => {
untilDate: newGroup.validUntil,
studentIds: [],
teacherIds: [teacherUserId],
syncedWithGroup: undefined,
syncedWithGroup: course.syncedWithGroup,
}),
]);
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Group, GroupUser } from '@modules/group';
import { CourseDoService } from '@modules/learnroom/service/course-do.service';
import { CourseDoService } from '@modules/learnroom';
import { RoleDto, RoleService } from '@modules/role';
import { Injectable } from '@nestjs/common';
import { RoleName } from '@shared/domain/interface';
Expand Down Expand Up @@ -38,7 +38,6 @@ export class SchulconnexCourseSyncService {
} else {
// Remove all remaining students and break the link, when the last teacher of the group should be removed
MarvinOehlerkingCap marked this conversation as resolved.
Show resolved Hide resolved
course.students = [];
course.syncedWithGroup = undefined;
}
});

Expand Down
Loading
Loading