Skip to content

Commit 2c0c91d

Browse files
committed
refactors: more migration away from qualifiedIDstr
... and into a defined interface { cardID, courseID : string }
1 parent b83a019 commit 2c0c91d

File tree

8 files changed

+77
-58
lines changed

8 files changed

+77
-58
lines changed

packages/db/src/core/interfaces/courseDB.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { CourseConfig, CourseElo, DataShape, SkuilderCourseData } from '@vue-skuilder/common';
22
import { StudySessionNewItem, StudySessionItem } from './contentSource';
3-
import { TagStub, Tag } from '../types/types-legacy';
3+
import { TagStub, Tag, QualifiedCardID } from '../types/types-legacy';
44
import { DataLayerResult } from '../types/db';
55
import { NavigationStrategyManager } from './navigationStrategyManager';
66

@@ -84,7 +84,7 @@ export interface CourseDBInterface extends NavigationStrategyManager {
8484
*/
8585
getCardsCenteredAtELO(
8686
options: { limit: number; elo: 'user' | 'random' | number },
87-
filter?: (id: string) => boolean
87+
filter?: (card: QualifiedCardID) => boolean
8888
): Promise<StudySessionItem[]>;
8989

9090
/**

packages/db/src/core/interfaces/userDB.ts

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
} from '@db/core/types/user';
77
import { CourseElo, Status } from '@vue-skuilder/common';
88
import { Moment } from 'moment';
9-
import { CardHistory, CardRecord } from '../types/types-legacy';
9+
import { CardHistory, CardRecord, QualifiedCardID } from '../types/types-legacy';
1010
import { UserConfig } from '../types/user';
1111
import { DocumentUpdater } from '@db/study';
1212

@@ -17,55 +17,55 @@ export interface UserDBReader {
1717
get<T>(id: string): Promise<T & PouchDB.Core.RevisionIdMeta>;
1818
getUsername(): string;
1919
isLoggedIn(): boolean;
20-
20+
2121
/**
2222
* Get user configuration
2323
*/
2424
getConfig(): Promise<UserConfig>;
25-
25+
2626
/**
2727
* Get cards that the user has seen
2828
*/
2929
getSeenCards(courseId?: string): Promise<string[]>;
30-
30+
3131
/**
3232
* Get cards that are actively scheduled for review
3333
*/
34-
getActiveCards(): Promise<string[]>;
35-
34+
getActiveCards(): Promise<QualifiedCardID[]>;
35+
3636
/**
3737
* Get user's course registrations
3838
*/
3939
getCourseRegistrationsDoc(): Promise<CourseRegistrationDoc>;
40-
40+
4141
/**
4242
* Get the registration doc for a specific course.
4343
* @param courseId
4444
*/
4545
getCourseRegDoc(courseId: string): Promise<CourseRegistration>;
46-
46+
4747
/**
4848
* Get user's active courses
4949
*/
5050
getActiveCourses(): Promise<CourseRegistration[]>;
51-
51+
5252
/**
5353
* Get user's pending reviews
5454
*/
5555
getPendingReviews(courseId?: string): Promise<ScheduledCard[]>;
56-
56+
5757
getActivityRecords(): Promise<ActivityRecord[]>;
58-
58+
5959
/**
6060
* Get user's classroom registrations
6161
*/
6262
getUserClassrooms(): Promise<ClassroomRegistrationDoc>;
63-
63+
6464
/**
6565
* Get user's active classes
6666
*/
6767
getActiveClasses(): Promise<string[]>;
68-
68+
6969
getCourseInterface(courseId: string): Promise<UsrCrsDataInterface>;
7070
}
7171

@@ -77,22 +77,22 @@ export interface UserDBWriter extends DocumentUpdater {
7777
* Update user configuration
7878
*/
7979
setConfig(config: Partial<UserConfig>): Promise<void>;
80-
80+
8181
/**
8282
* Record a user's interaction with a card
8383
*/
8484
putCardRecord<T extends CardRecord>(record: T): Promise<CardHistory<CardRecord>>;
85-
85+
8686
/**
8787
* Register user for a course
8888
*/
8989
registerForCourse(courseId: string, previewMode?: boolean): Promise<PouchDB.Core.Response>;
90-
90+
9191
/**
9292
* Drop a course registration
9393
*/
9494
dropCourse(courseId: string, dropStatus?: string): Promise<PouchDB.Core.Response>;
95-
95+
9696
/**
9797
* Schedule a card for review
9898
*/
@@ -104,30 +104,30 @@ export interface UserDBWriter extends DocumentUpdater {
104104
scheduledFor: 'course' | 'classroom';
105105
schedulingAgentId: string;
106106
}): Promise<void>;
107-
107+
108108
/**
109109
* Remove a scheduled card review
110110
*/
111111
removeScheduledCardReview(reviewId: string): Promise<void>;
112-
112+
113113
/**
114114
* Register user for a classroom
115115
*/
116116
registerForClassroom(
117117
classId: string,
118118
registerAs: 'student' | 'teacher' | 'aide' | 'admin'
119119
): Promise<PouchDB.Core.Response>;
120-
120+
121121
/**
122122
* Drop user from classroom
123123
*/
124124
dropFromClassroom(classId: string): Promise<PouchDB.Core.Response>;
125-
125+
126126
/**
127127
* Update user's ELO rating for a course
128128
*/
129129
updateUserElo(courseId: string, elo: CourseElo): Promise<PouchDB.Core.Response>;
130-
130+
131131
/**
132132
* Reset all user data (progress, registrations, etc.) while preserving authentication
133133
*/
@@ -173,8 +173,7 @@ export interface UserDBAuthenticator {
173173
* Complete user database interface - combines all user operations
174174
* This maintains backward compatibility with existing code
175175
*/
176-
export interface UserDBInterface extends UserDBReader, UserDBWriter, UserDBAuthenticator {
177-
}
176+
export interface UserDBInterface extends UserDBReader, UserDBWriter, UserDBAuthenticator {}
178177

179178
export interface UserCourseSettings {
180179
[setting: string]: string | number | boolean;

packages/db/src/core/navigators/elo.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import { CourseDBInterface } from '../interfaces/courseDB';
33
import { UserDBInterface } from '../interfaces/userDB';
44
import { ContentNavigator } from './index';
55
import { CourseElo } from '@vue-skuilder/common';
6-
import { StudySessionReviewItem, StudySessionNewItem } from '..';
6+
import { StudySessionReviewItem, StudySessionNewItem, QualifiedCardID } from '..';
7+
import { StudySessionItem } from '../interfaces/contentSource';
78

89
export default class ELONavigator extends ContentNavigator {
910
user: UserDBInterface;
@@ -59,13 +60,16 @@ export default class ELONavigator extends ContentNavigator {
5960
async getNewCards(limit: number = 99): Promise<StudySessionNewItem[]> {
6061
const activeCards = await this.user.getActiveCards();
6162
return (
62-
await this.course.getCardsCenteredAtELO({ limit: limit, elo: 'user' }, (c: string) => {
63-
if (activeCards.some((ac) => c.includes(ac))) {
64-
return false;
65-
} else {
66-
return true;
63+
await this.course.getCardsCenteredAtELO(
64+
{ limit: limit, elo: 'user' },
65+
(c: QualifiedCardID) => {
66+
if (activeCards.some((ac) => c.cardID === ac.cardID)) {
67+
return false;
68+
} else {
69+
return true;
70+
}
6771
}
68-
})
72+
)
6973
).map((c) => {
7074
return {
7175
...c,

packages/db/src/core/types/types-legacy.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ export enum DocType {
2121
NAVIGATION_STRATEGY = 'NAVIGATION_STRATEGY',
2222
}
2323

24+
export interface QualifiedCardID {
25+
courseID: string;
26+
cardID: string;
27+
}
28+
2429
/**
2530
* Interface for all data on course content and pedagogy stored
2631
* in the c/pouch database.

packages/db/src/impl/common/BaseUserDB.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,12 @@ Currently logged-in as ${this._username}.`
277277
include_docs: true,
278278
});
279279

280-
return reviews.rows.map((r) => `${r.doc!.courseId}-${r.doc!.cardId}`);
280+
return reviews.rows.map((r) => {
281+
return {
282+
courseID: r.doc!.courseId,
283+
cardID: r.doc!.cardId,
284+
};
285+
});
281286
}
282287

283288
public async getActivityRecords(): Promise<ActivityRecord[]> {
@@ -657,7 +662,7 @@ Currently logged-in as ${this._username}.`
657662
private async applyDesignDocs() {
658663
log(`Starting applyDesignDocs for user: ${this._username}`);
659664
log(`Remote DB name: ${this.remoteDB.name || 'unknown'}`);
660-
665+
661666
if (this._username === 'admin') {
662667
// Skip admin user
663668
log('Skipping design docs for admin user');

packages/db/src/impl/couch/classroomDB.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ export class StudentClassroomDB
181181
);
182182

183183
return ret.filter((c) => {
184-
if (activeCards.some((ac) => c.cardID.includes(ac))) {
184+
if (activeCards.some((ac) => c.cardID === ac.cardID)) {
185185
// [ ] almost certainly broken after removing qualifiedID from StudySessionItem
186186
return false;
187187
} else {

packages/db/src/impl/couch/courseDB.ts

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,14 @@ import {
1818
StudySessionNewItem,
1919
StudySessionReviewItem,
2020
} from '../../core/interfaces/contentSource';
21-
import { CardData, DocType, SkuilderCourseData, Tag, TagStub } from '../../core/types/types-legacy';
21+
import {
22+
CardData,
23+
DocType,
24+
QualifiedCardID,
25+
SkuilderCourseData,
26+
Tag,
27+
TagStub,
28+
} from '../../core/types/types-legacy';
2229
import { logger } from '../../util/logger';
2330
import { GET_CACHED } from './clientCache';
2431
import { addNote55, addTagToCard, getCredentialledCourseConfig, getTagID } from './courseAPI';
@@ -547,7 +554,7 @@ above:\n${above.rows.map((r) => `\t${r.id}-${r.key}\n`)}`;
547554
limit: 99,
548555
elo: 'user',
549556
},
550-
filter?: (a: string) => boolean
557+
filter?: (a: QualifiedCardID) => boolean
551558
): Promise<StudySessionItem[]> {
552559
let targetElo: number;
553560

@@ -571,7 +578,7 @@ above:\n${above.rows.map((r) => `\t${r.id}-${r.key}\n`)}`;
571578
targetElo = options.elo;
572579
}
573580

574-
let cards: { courseID: string; cardID: string; elo?: number }[] = [];
581+
let cards: (QualifiedCardID & { elo?: number })[] = [];
575582
let mult: number = 4;
576583
let previousCount: number = -1;
577584
let newCount: number = 0;
@@ -584,20 +591,8 @@ above:\n${above.rows.map((r) => `\t${r.id}-${r.key}\n`)}`;
584591
logger.debug(`Found ${cards.length} elo neighbor cards...`);
585592

586593
if (filter) {
587-
const filtered = cards
588-
.map((card) => {
589-
if (card.elo) {
590-
return `${card.courseID}-${card.cardID}-${card.elo}`;
591-
} else {
592-
return `${card.courseID}-${card.cardID}`;
593-
}
594-
})
595-
.filter(filter);
594+
cards = cards.filter(filter);
596595
logger.debug(`Filtered to ${cards.length} cards...`);
597-
cards = filtered.map((card) => {
598-
const [courseID, cardID, elo] = card.split('-');
599-
return { courseID, cardID, elo: elo ? parseInt(elo) : undefined };
600-
});
601596
}
602597

603598
mult *= 2;

packages/db/src/impl/static/courseDB.ts

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,13 @@ import {
1010
import { StaticDataUnpacker } from './StaticDataUnpacker';
1111
import { StaticCourseManifest } from '../../util/packer/types';
1212
import { CourseConfig, CourseElo, DataShape, Status } from '@vue-skuilder/common';
13-
import { Tag, TagStub, DocType, SkuilderCourseData } from '../../core/types/types-legacy';
13+
import {
14+
Tag,
15+
TagStub,
16+
DocType,
17+
SkuilderCourseData,
18+
QualifiedCardID,
19+
} from '../../core/types/types-legacy';
1420
import { DataLayerResult } from '../../core/types/db';
1521
import { ContentNavigationStrategyData } from '../../core/types/contentNavigationStrategy';
1622
import { ScheduledCard } from '../../core/types/user';
@@ -141,7 +147,7 @@ export class StaticCourseDB implements CourseDBInterface {
141147

142148
async getCardsCenteredAtELO(
143149
options: { limit: number; elo: 'user' | 'random' | number },
144-
filter?: (id: string) => boolean
150+
filter?: (id: QualifiedCardID) => boolean
145151
): Promise<StudySessionNewItem[]> {
146152
let targetElo = typeof options.elo === 'number' ? options.elo : 1000;
147153

@@ -160,16 +166,21 @@ export class StaticCourseDB implements CourseDBInterface {
160166
targetElo = 800 + Math.random() * 400; // Random between 800-1200
161167
}
162168

163-
let cardIds = await this.unpacker.queryByElo(targetElo, options.limit * 2);
169+
let cardIds = (await this.unpacker.queryByElo(targetElo, options.limit * 2)).map((c) => {
170+
return {
171+
cardID: c,
172+
courseID: this.courseId,
173+
};
174+
});
164175

165176
if (filter) {
166177
cardIds = cardIds.filter(filter);
167178
}
168179

169-
return cardIds.slice(0, options.limit).map((cardId) => ({
180+
return cardIds.slice(0, options.limit).map((card) => ({
170181
status: 'new' as const,
171-
qualifiedID: `${this.courseId}-${cardId}`,
172-
cardID: cardId,
182+
// qualifiedID: `${this.courseId}-${cardId}`,
183+
cardID: card.cardID,
173184
contentSourceType: 'course' as const,
174185
contentSourceID: this.courseId,
175186
courseID: this.courseId,

0 commit comments

Comments
 (0)