musora-content-services 2.122.0 → 2.122.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.coderabbit.yaml +0 -0
- package/.editorconfig +0 -0
- package/.github/pull_request_template.md +0 -0
- package/.github/workflows/conventional-commits.yaml +0 -0
- package/.github/workflows/docs.js.yml +0 -0
- package/.github/workflows/node.js.yml +0 -0
- package/.prettierignore +0 -0
- package/.prettierrc +0 -0
- package/CHANGELOG.md +19 -0
- package/CLAUDE.md +0 -0
- package/README.md +0 -0
- package/babel.config.cjs +0 -0
- package/jest.config.js +0 -0
- package/jsdoc.json +0 -0
- package/package.json +1 -1
- package/src/constants/award-assets.js +0 -0
- package/src/constants/membership-permissions.ts +0 -0
- package/src/contentTypeConfig.js +4 -3
- package/src/filterBuilder.js +0 -0
- package/src/index.d.ts +0 -0
- package/src/index.js +0 -0
- package/src/infrastructure/http/HttpClient.ts +0 -0
- package/src/infrastructure/http/executors/FetchRequestExecutor.ts +0 -0
- package/src/infrastructure/http/index.ts +0 -0
- package/src/infrastructure/http/interfaces/HeaderProvider.ts +0 -0
- package/src/infrastructure/http/interfaces/HttpError.ts +0 -0
- package/src/infrastructure/http/interfaces/NetworkError.ts +0 -0
- package/src/infrastructure/http/interfaces/RequestExecutor.ts +0 -0
- package/src/infrastructure/http/interfaces/RequestOptions.ts +0 -0
- package/src/infrastructure/http/providers/DefaultHeaderProvider.ts +0 -0
- package/src/lib/ads/monoid.ts +0 -0
- package/src/lib/ads/semigroup.ts +0 -0
- package/src/lib/brands.ts +0 -0
- package/src/lib/lastUpdated.js +0 -0
- package/src/lib/sanity/filter.ts +0 -0
- package/src/lib/sanity/query.ts +0 -0
- package/src/services/api/types.js +0 -0
- package/src/services/api/types.ts +0 -0
- package/src/services/awards/award-callbacks.js +0 -0
- package/src/services/awards/award-query.js +0 -0
- package/src/services/awards/internal/.indexignore +0 -0
- package/src/services/awards/internal/award-definitions.js +0 -0
- package/src/services/awards/internal/award-events.js +0 -0
- package/src/services/awards/internal/award-manager.js +0 -0
- package/src/services/awards/internal/certificate-builder.js +0 -0
- package/src/services/awards/internal/completion-data-generator.js +0 -0
- package/src/services/awards/internal/content-progress-observer.js +0 -0
- package/src/services/awards/internal/image-utils.js +0 -0
- package/src/services/awards/internal/message-generator.js +0 -0
- package/src/services/awards/internal/types.js +0 -0
- package/src/services/awards/types.d.ts +0 -0
- package/src/services/awards/types.js +0 -0
- package/src/services/config.js +0 -0
- package/src/services/content/artist.ts +0 -0
- package/src/services/content/content.ts +0 -0
- package/src/services/content/genre.ts +0 -0
- package/src/services/content/instructor.ts +0 -0
- package/src/services/content-org/content-org.js +0 -0
- package/src/services/content-org/guided-courses.ts +0 -0
- package/src/services/content-org/learning-paths.ts +64 -48
- package/src/services/content-org/playlists-types.js +0 -0
- package/src/services/content-org/playlists.js +0 -0
- package/src/services/content.js +0 -0
- package/src/services/contentAggregator.js +0 -0
- package/src/services/contentLikes.js +0 -0
- package/src/services/contentProgress.js +20 -10
- package/src/services/dataContext.js +0 -0
- package/src/services/dateUtils.js +0 -0
- package/src/services/eventsAPI.js +0 -0
- package/src/services/forums/categories.ts +0 -0
- package/src/services/forums/forums.ts +0 -0
- package/src/services/forums/posts.ts +0 -0
- package/src/services/forums/threads.ts +0 -0
- package/src/services/forums/types.ts +0 -0
- package/src/services/gamification/awards.ts +0 -0
- package/src/services/gamification/gamification.js +0 -0
- package/src/services/imageSRCBuilder.js +0 -0
- package/src/services/imageSRCVerify.js +0 -0
- package/src/services/liveTesting.ts +0 -0
- package/src/services/permissions/PermissionsAdapter.ts +0 -0
- package/src/services/permissions/PermissionsAdapterFactory.ts +0 -0
- package/src/services/permissions/PermissionsV1Adapter.ts +0 -0
- package/src/services/permissions/PermissionsV2Adapter.ts +0 -0
- package/src/services/permissions/README.md +0 -0
- package/src/services/permissions/index.ts +0 -0
- package/src/services/progress-events.js +0 -0
- package/src/services/progress-row/base.js +7 -3
- package/src/services/progress-row/rows/.indexignore +0 -0
- package/src/services/progress-row/rows/content-card.js +0 -0
- package/src/services/progress-row/rows/method-card.js +1 -1
- package/src/services/progress-row/rows/playlist-card.js +0 -0
- package/src/services/railcontent.js +0 -0
- package/src/services/recommendations.js +0 -0
- package/src/services/reporting/README.md +0 -0
- package/src/services/reporting/reporting.ts +0 -0
- package/src/services/reporting/types.ts +0 -0
- package/src/services/sanity.js +1 -1
- package/src/services/sentry/.indexignore +0 -0
- package/src/services/sentry/index.ts +0 -0
- package/src/services/sync/.indexignore +0 -0
- package/src/services/sync/adapters/factory.ts +0 -0
- package/src/services/sync/adapters/lokijs.ts +0 -0
- package/src/services/sync/adapters/sqlite.ts +0 -0
- package/src/services/sync/context/index.ts +0 -0
- package/src/services/sync/context/providers/base.ts +0 -0
- package/src/services/sync/context/providers/connectivity.ts +0 -0
- package/src/services/sync/context/providers/durability.ts +0 -0
- package/src/services/sync/context/providers/index.ts +0 -0
- package/src/services/sync/context/providers/session.ts +0 -0
- package/src/services/sync/context/providers/tabs.ts +0 -0
- package/src/services/sync/context/providers/visibility.ts +0 -0
- package/src/services/sync/database/factory.ts +0 -0
- package/src/services/sync/effects/index.ts +0 -0
- package/src/services/sync/effects/logout-warning.ts +0 -0
- package/src/services/sync/errors/boundary.ts +0 -0
- package/src/services/sync/errors/index.ts +0 -0
- package/src/services/sync/errors/validators.ts +0 -0
- package/src/services/sync/fetch.ts +0 -0
- package/src/services/sync/index.ts +0 -0
- package/src/services/sync/manager.ts +0 -0
- package/src/services/sync/models/Base.ts +0 -0
- package/src/services/sync/models/ContentLike.ts +0 -0
- package/src/services/sync/models/ContentProgress.ts +0 -0
- package/src/services/sync/models/Practice.ts +0 -0
- package/src/services/sync/models/PracticeDayNote.ts +0 -0
- package/src/services/sync/models/UserAwardProgress.ts +0 -0
- package/src/services/sync/models/index.ts +0 -0
- package/src/services/sync/repositories/base.ts +2 -16
- package/src/services/sync/repositories/content-likes.ts +0 -0
- package/src/services/sync/repositories/content-progress.ts +7 -4
- package/src/services/sync/repositories/index.ts +0 -0
- package/src/services/sync/repositories/practice-day-notes.ts +0 -0
- package/src/services/sync/repositories/practices.ts +0 -0
- package/src/services/sync/repositories/user-award-progress.ts +0 -0
- package/src/services/sync/repository-proxy.ts +0 -0
- package/src/services/sync/resolver.ts +0 -0
- package/src/services/sync/retry.ts +0 -0
- package/src/services/sync/run-scope.ts +0 -0
- package/src/services/sync/schema/index.ts +0 -0
- package/src/services/sync/serializers/index.ts +0 -0
- package/src/services/sync/serializers/model.ts +0 -0
- package/src/services/sync/serializers/raw.ts +0 -0
- package/src/services/sync/store/index.ts +4 -2
- package/src/services/sync/store/push-coalescer.ts +0 -0
- package/src/services/sync/store-configs.ts +0 -0
- package/src/services/sync/strategies/base.ts +0 -0
- package/src/services/sync/strategies/index.ts +0 -0
- package/src/services/sync/strategies/initial.ts +0 -0
- package/src/services/sync/strategies/polling.ts +0 -0
- package/src/services/sync/telemetry/flood-prevention.ts +0 -0
- package/src/services/sync/telemetry/index.ts +0 -0
- package/src/services/sync/telemetry/sampling.ts +0 -0
- package/src/services/sync/utils/event-emitter.ts +0 -0
- package/src/services/sync/utils/index.ts +0 -0
- package/src/services/sync/utils/throttle.ts +0 -0
- package/src/services/sync/utils/timers.ts +0 -0
- package/src/services/types.js +0 -0
- package/src/services/urlBuilder.ts +0 -0
- package/src/services/user/chat.js +0 -0
- package/src/services/user/interests.js +0 -0
- package/src/services/user/management.js +0 -0
- package/src/services/user/memberships.ts +0 -0
- package/src/services/user/notifications.js +0 -0
- package/src/services/user/onboarding.ts +0 -0
- package/src/services/user/payments.ts +0 -0
- package/src/services/user/permissions.js +0 -0
- package/src/services/user/profile.js +0 -0
- package/src/services/user/sessions.js +0 -0
- package/src/services/user/types.d.ts +0 -0
- package/src/services/user/types.js +0 -0
- package/src/services/user/user-management-system.js +0 -0
- package/src/services/userActivity.js +0 -0
- package/test/HttpClient.test.js +0 -0
- package/test/awards/award-alacarte-observer.test.js +0 -0
- package/test/awards/award-auto-refresh.test.js +0 -0
- package/test/awards/award-calculations.test.js +0 -0
- package/test/awards/award-certificate-display.test.js +0 -0
- package/test/awards/award-collection-edge-cases.test.js +0 -0
- package/test/awards/award-collection-filtering.test.js +0 -0
- package/test/awards/award-completion-flow.test.js +0 -0
- package/test/awards/award-exclusion-handling.test.js +0 -0
- package/test/awards/award-multi-lesson.test.js +0 -0
- package/test/awards/award-observer-integration.test.js +0 -0
- package/test/awards/award-query-messages.test.js +0 -0
- package/test/awards/award-user-collection.test.js +0 -0
- package/test/awards/duplicate-prevention.test.js +0 -0
- package/test/awards/helpers/completion-mock.js +0 -0
- package/test/awards/helpers/index.js +0 -0
- package/test/awards/helpers/mock-setup.js +0 -0
- package/test/awards/helpers/progress-emitter.js +0 -0
- package/test/awards/message-generator.test.js +0 -0
- package/test/content.test.js +0 -0
- package/test/contentLikes.test.js +0 -0
- package/test/contentProgress.test.js +0 -0
- package/test/dataContext.test.js +0 -0
- package/test/forum.test.js +0 -0
- package/test/imageSRCBuilder.test.js +0 -0
- package/test/imageSRCVerify.test.js +0 -0
- package/test/initializeTests.js +0 -0
- package/test/learningPaths.test.js +0 -0
- package/test/lib/__snapshots__/filter.test.ts.snap +0 -0
- package/test/lib/filter.test.ts +0 -0
- package/test/lib/lastUpdated.test.js +0 -0
- package/test/lib/query.test.ts +0 -0
- package/test/live/contentProgressLive.test.js +0 -0
- package/test/live/railcontentLive.test.js +0 -0
- package/test/localStorageMock.js +0 -0
- package/test/log.js +0 -0
- package/test/mockData/award-definitions.js +0 -0
- package/test/mockData/mockData_fetchByRailContentIds_one_content.json +0 -0
- package/test/mockData/mockData_progress_content.json +0 -0
- package/test/mockData/mockData_sanity_progress_content.json +0 -0
- package/test/mockData/mockData_user_practices.json +0 -0
- package/test/notifications.test.js +0 -0
- package/test/progressRows.test.js +0 -0
- package/test/sanityQueryService.test.js +0 -0
- package/test/streakMessage.test.js +0 -0
- package/test/sync/adapter.ts +0 -0
- package/test/sync/initialize-sync-manager.js +0 -0
- package/test/sync/models/award-database-integration.test.js +0 -0
- package/test/user/permissions.test.js +0 -0
- package/test/userActivity.test.js +0 -0
- package/tools/generate-index.cjs +0 -0
- package/.claude/settings.local.json +0 -16
- package/.yarnrc.yml +0 -1
- package/check_content.js +0 -30
- package/check_content.mjs +0 -32
- package/test/logout.test.js +0 -199
- package/test/reporting.test.js +0 -132
- package/test_owned_navigate.js +0 -74
- package/tsconfig.json +0 -17
package/.coderabbit.yaml
CHANGED
|
File without changes
|
package/.editorconfig
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/.prettierignore
CHANGED
|
File without changes
|
package/.prettierrc
CHANGED
|
File without changes
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
### [2.122.3](https://github.com/railroadmedia/musora-content-services/compare/v2.122.2...v2.122.3) (2026-01-23)
|
|
6
|
+
|
|
7
|
+
### [2.122.2](https://github.com/railroadmedia/musora-content-services/compare/v2.122.1...v2.122.2) (2026-01-23)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
### Bug Fixes
|
|
11
|
+
|
|
12
|
+
* broken method index ([#735](https://github.com/railroadmedia/musora-content-services/issues/735)) ([126f985](https://github.com/railroadmedia/musora-content-services/commit/126f985866f60bcca1d1ddb2dd97ba8847ff4219))
|
|
13
|
+
|
|
14
|
+
### [2.122.1](https://github.com/railroadmedia/musora-content-services/compare/v2.122.0...v2.122.1) (2026-01-23)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Bug Fixes
|
|
18
|
+
|
|
19
|
+
* handle global live streams ([#727](https://github.com/railroadmedia/musora-content-services/issues/727)) ([e0ed5f3](https://github.com/railroadmedia/musora-content-services/commit/e0ed5f398f61a2188beae56a05547494862a16b7))
|
|
20
|
+
* removes tentative progress call functionality ([#716](https://github.com/railroadmedia/musora-content-services/issues/716)) ([a167d3b](https://github.com/railroadmedia/musora-content-services/commit/a167d3b94c1d2ef6df9a7f76e4c4ea4c71f9bfb5))
|
|
21
|
+
* **T3PS-1562:** hide nonpinned method card ([#721](https://github.com/railroadmedia/musora-content-services/issues/721)) ([cc250ee](https://github.com/railroadmedia/musora-content-services/commit/cc250ee072cac976fc7389eb86e77eff1230b73a))
|
|
22
|
+
* **T3PS-1579:** fix reset bubbling ([#718](https://github.com/railroadmedia/musora-content-services/issues/718)) ([a9490a8](https://github.com/railroadmedia/musora-content-services/commit/a9490a85aeb4df947770a265543fa6782e30b436))
|
|
23
|
+
|
|
5
24
|
## [2.122.0](https://github.com/railroadmedia/musora-content-services/compare/v2.118.1...v2.122.0) (2026-01-22)
|
|
6
25
|
|
|
7
26
|
|
package/CLAUDE.md
CHANGED
|
File without changes
|
package/README.md
CHANGED
|
File without changes
|
package/babel.config.cjs
CHANGED
|
File without changes
|
package/jest.config.js
CHANGED
|
File without changes
|
package/jsdoc.json
CHANGED
|
File without changes
|
package/package.json
CHANGED
|
File without changes
|
|
File without changes
|
package/src/contentTypeConfig.js
CHANGED
|
@@ -145,6 +145,7 @@ export const liveFields = `
|
|
|
145
145
|
"thumbnail": thumbnail.asset->url,
|
|
146
146
|
${artistOrInstructorName()},
|
|
147
147
|
difficulty_string,
|
|
148
|
+
railcontent_id,
|
|
148
149
|
"instructors": ${instructorField},
|
|
149
150
|
'videoId': coalesce(live_event_stream_id, video.external_id)
|
|
150
151
|
`
|
|
@@ -647,9 +648,9 @@ export function getIntroVideoFields(type) {
|
|
|
647
648
|
`"id": railcontent_id`,
|
|
648
649
|
'title',
|
|
649
650
|
'brand',
|
|
650
|
-
`"instructor":
|
|
651
|
-
`
|
|
652
|
-
`
|
|
651
|
+
`"instructor": ${instructorField}`,
|
|
652
|
+
`difficulty`,
|
|
653
|
+
`difficulty_string`,
|
|
653
654
|
`"type": _type`,
|
|
654
655
|
'brand',
|
|
655
656
|
`"description": ${descriptionField}`,
|
package/src/filterBuilder.js
CHANGED
|
File without changes
|
package/src/index.d.ts
CHANGED
|
File without changes
|
package/src/index.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/src/lib/ads/monoid.ts
CHANGED
|
File without changes
|
package/src/lib/ads/semigroup.ts
CHANGED
|
File without changes
|
package/src/lib/brands.ts
CHANGED
|
File without changes
|
package/src/lib/lastUpdated.js
CHANGED
|
File without changes
|
package/src/lib/sanity/filter.ts
CHANGED
|
File without changes
|
package/src/lib/sanity/query.ts
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/src/services/config.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -56,17 +56,20 @@ interface CollectionObject {
|
|
|
56
56
|
* @param userDate - local datetime. must have date and time - format 2025-10-31T13:45:00
|
|
57
57
|
* @param forceRefresh - force cache refresh
|
|
58
58
|
*/
|
|
59
|
-
export async function getDailySession(
|
|
59
|
+
export async function getDailySession(
|
|
60
|
+
brand: string,
|
|
61
|
+
userDate: Date,
|
|
62
|
+
forceRefresh: boolean = false
|
|
63
|
+
) {
|
|
60
64
|
const dateWithTimezone = formatLocalDateTime(userDate)
|
|
61
65
|
const url: string = `${LEARNING_PATHS_PATH}/daily-session/get?brand=${brand}&userDate=${encodeURIComponent(dateWithTimezone)}`
|
|
62
66
|
try {
|
|
63
|
-
const response = await dataPromiseGET(url, forceRefresh) as DailySessionResponse
|
|
67
|
+
const response = (await dataPromiseGET(url, forceRefresh)) as DailySessionResponse
|
|
64
68
|
if (!response) {
|
|
65
69
|
return await updateDailySession(brand, userDate, false)
|
|
66
70
|
}
|
|
67
71
|
dailySessionPromise = null // reset promise after successful fetch
|
|
68
72
|
return response as DailySessionResponse
|
|
69
|
-
|
|
70
73
|
} catch (error: any) {
|
|
71
74
|
if (error.status === 204) {
|
|
72
75
|
return await updateDailySession(brand, userDate, false)
|
|
@@ -88,16 +91,23 @@ export async function updateDailySession(
|
|
|
88
91
|
) {
|
|
89
92
|
const dateWithTimezone = formatLocalDateTime(userDate)
|
|
90
93
|
const url: string = `${LEARNING_PATHS_PATH}/daily-session/create`
|
|
91
|
-
const body = {
|
|
94
|
+
const body = {
|
|
95
|
+
brand: brand,
|
|
96
|
+
userDate: dateWithTimezone,
|
|
97
|
+
keepFirstLearningPath: keepFirstLearningPath,
|
|
98
|
+
}
|
|
99
|
+
try {
|
|
100
|
+
const response = (await POST(url, body)) as DailySessionResponse
|
|
92
101
|
|
|
93
|
-
|
|
102
|
+
if (response) {
|
|
103
|
+
const urlGet: string = `${LEARNING_PATHS_PATH}/daily-session/get?brand=${brand}&userDate=${encodeURIComponent(dateWithTimezone)}`
|
|
104
|
+
dataPromiseGET(urlGet, true) // refresh cache
|
|
105
|
+
}
|
|
94
106
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
107
|
+
return response
|
|
108
|
+
} catch (error: any) {
|
|
109
|
+
return null
|
|
98
110
|
}
|
|
99
|
-
|
|
100
|
-
return response
|
|
101
111
|
}
|
|
102
112
|
|
|
103
113
|
function formatLocalDateTime(date: Date): string {
|
|
@@ -112,7 +122,7 @@ function formatLocalDateTime(date: Date): string {
|
|
|
112
122
|
export async function getActivePath(brand: string, forceRefresh: boolean = false) {
|
|
113
123
|
const url: string = `${LEARNING_PATHS_PATH}/active-path/get?brand=${brand}`
|
|
114
124
|
|
|
115
|
-
const response = await dataPromiseGET(url, forceRefresh) as ActiveLearningPathResponse
|
|
125
|
+
const response = (await dataPromiseGET(url, forceRefresh)) as ActiveLearningPathResponse
|
|
116
126
|
activePathPromise = null // reset promise after successful fetch
|
|
117
127
|
|
|
118
128
|
return response
|
|
@@ -127,7 +137,7 @@ export async function startLearningPath(brand: string, learningPathId: number) {
|
|
|
127
137
|
const url: string = `${LEARNING_PATHS_PATH}/active-path/set`
|
|
128
138
|
const body = { brand: brand, learning_path_id: learningPathId }
|
|
129
139
|
|
|
130
|
-
const response = await POST(url, body) as ActiveLearningPathResponse
|
|
140
|
+
const response = (await POST(url, body)) as ActiveLearningPathResponse
|
|
131
141
|
|
|
132
142
|
// manual BE call to avoid recursive POST<->GET calls
|
|
133
143
|
if (response) {
|
|
@@ -138,16 +148,22 @@ export async function startLearningPath(brand: string, learningPathId: number) {
|
|
|
138
148
|
return response
|
|
139
149
|
}
|
|
140
150
|
|
|
141
|
-
async function dataPromiseGET(
|
|
151
|
+
async function dataPromiseGET(
|
|
152
|
+
url: string,
|
|
153
|
+
forceRefresh: boolean
|
|
154
|
+
): Promise<DailySessionResponse | ActiveLearningPathResponse> {
|
|
142
155
|
if (url.includes('daily-session')) {
|
|
143
156
|
if (!dailySessionPromise || forceRefresh) {
|
|
144
|
-
dailySessionPromise = GET(url, {
|
|
157
|
+
dailySessionPromise = GET(url, {
|
|
158
|
+
cache: forceRefresh ? 'reload' : 'default',
|
|
159
|
+
}) as Promise<DailySessionResponse>
|
|
145
160
|
}
|
|
146
161
|
return dailySessionPromise
|
|
147
|
-
|
|
148
162
|
} else if (url.includes('active-path')) {
|
|
149
163
|
if (!activePathPromise || forceRefresh) {
|
|
150
|
-
activePathPromise = GET(url, {
|
|
164
|
+
activePathPromise = GET(url, {
|
|
165
|
+
cache: forceRefresh ? 'reload' : 'default',
|
|
166
|
+
}) as Promise<ActiveLearningPathResponse>
|
|
151
167
|
}
|
|
152
168
|
return activePathPromise
|
|
153
169
|
}
|
|
@@ -183,14 +199,10 @@ export async function getEnrichedLearningPath(learningPathId) {
|
|
|
183
199
|
}
|
|
184
200
|
)) as any
|
|
185
201
|
// add awards to LP parents only
|
|
186
|
-
response = await addContextToLearningPaths(() => response, {addAwards:true})
|
|
202
|
+
response = await addContextToLearningPaths(() => response, { addAwards: true })
|
|
187
203
|
if (!response) return response
|
|
188
204
|
|
|
189
|
-
response.children = mapContentToParent(
|
|
190
|
-
response.children,
|
|
191
|
-
LEARNING_PATH_LESSON,
|
|
192
|
-
learningPathId
|
|
193
|
-
)
|
|
205
|
+
response.children = mapContentToParent(response.children, LEARNING_PATH_LESSON, learningPathId)
|
|
194
206
|
return response
|
|
195
207
|
}
|
|
196
208
|
|
|
@@ -216,7 +228,7 @@ export async function getEnrichedLearningPaths(learningPathIds: number[]) {
|
|
|
216
228
|
}
|
|
217
229
|
)) as any
|
|
218
230
|
// add awards to LP parents only
|
|
219
|
-
response = await addContextToLearningPaths(() => response, {addAwards:true})
|
|
231
|
+
response = await addContextToLearningPaths(() => response, { addAwards: true })
|
|
220
232
|
|
|
221
233
|
if (!response) return response
|
|
222
234
|
|
|
@@ -300,9 +312,9 @@ export async function fetchLearningPathLessons(
|
|
|
300
312
|
userDate: Date
|
|
301
313
|
) {
|
|
302
314
|
const learningPath = await getEnrichedLearningPath(learningPathId)
|
|
303
|
-
let dailySession = await getDailySession(brand, userDate) as DailySessionResponse // what if the call just fails, and a DS does exist?
|
|
315
|
+
let dailySession = (await getDailySession(brand, userDate)) as DailySessionResponse // what if the call just fails, and a DS does exist?
|
|
304
316
|
if (!dailySession) {
|
|
305
|
-
dailySession = await updateDailySession(brand, userDate, false) as DailySessionResponse
|
|
317
|
+
dailySession = (await updateDailySession(brand, userDate, false)) as DailySessionResponse
|
|
306
318
|
}
|
|
307
319
|
|
|
308
320
|
const isActiveLearningPath = (dailySession?.active_learning_path_id || 0) == learningPathId
|
|
@@ -320,8 +332,6 @@ export async function fetchLearningPathLessons(
|
|
|
320
332
|
let previousContentIds = []
|
|
321
333
|
let previousLearningPathId = null
|
|
322
334
|
|
|
323
|
-
|
|
324
|
-
|
|
325
335
|
for (const session of dailySession.daily_session) {
|
|
326
336
|
if (session.learning_path_id === learningPathId) {
|
|
327
337
|
todayContentIds = session.content_ids || []
|
|
@@ -361,13 +371,13 @@ export async function fetchLearningPathLessons(
|
|
|
361
371
|
)
|
|
362
372
|
}
|
|
363
373
|
if (nextContentIds.length !== 0) {
|
|
364
|
-
nextLPDailies = await getLearningPathLessonsByIds(
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
374
|
+
nextLPDailies = await getLearningPathLessonsByIds(nextContentIds, nextLearningPathId).then(
|
|
375
|
+
(lessons) =>
|
|
376
|
+
lessons.map((lesson) => ({
|
|
377
|
+
...lesson,
|
|
378
|
+
in_next_learning_path: learningPath.progressStatus === STATE.COMPLETED,
|
|
379
|
+
}))
|
|
380
|
+
)
|
|
371
381
|
}
|
|
372
382
|
|
|
373
383
|
return {
|
|
@@ -421,22 +431,28 @@ export async function completeMethodIntroVideo(
|
|
|
421
431
|
const methodStructure = await fetchMethodV2Structure(brand)
|
|
422
432
|
|
|
423
433
|
const firstLearningPathId = methodStructure.learning_paths[0].id
|
|
424
|
-
response.active_path_response = await methodIntroVideoCompleteActions(
|
|
434
|
+
response.active_path_response = await methodIntroVideoCompleteActions(
|
|
435
|
+
brand,
|
|
436
|
+
firstLearningPathId,
|
|
437
|
+
new Date()
|
|
438
|
+
)
|
|
425
439
|
|
|
426
440
|
response.intro_video_response = await completeIfNotCompleted(introVideoId)
|
|
427
441
|
|
|
428
442
|
return response
|
|
429
443
|
}
|
|
430
444
|
|
|
431
|
-
async function methodIntroVideoCompleteActions(
|
|
445
|
+
async function methodIntroVideoCompleteActions(
|
|
446
|
+
brand: string,
|
|
447
|
+
learningPathId: number,
|
|
448
|
+
userDate: Date
|
|
449
|
+
) {
|
|
432
450
|
const stringDate = userDate.toISOString().split('T')[0]
|
|
433
451
|
const url: string = `${LEARNING_PATHS_PATH}/method-intro-video-complete-actions`
|
|
434
452
|
const body = { brand: brand, learningPathId: learningPathId, userDate: stringDate }
|
|
435
453
|
return (await POST(url, body)) as DailySessionResponse
|
|
436
454
|
}
|
|
437
455
|
|
|
438
|
-
|
|
439
|
-
|
|
440
456
|
interface completeLearningPathIntroVideo {
|
|
441
457
|
intro_video_response: SyncWriteDTO<ContentProgress, any> | null
|
|
442
458
|
learning_path_reset_response: SyncWriteDTO<ContentProgress, any> | null
|
|
@@ -465,19 +481,13 @@ export async function completeLearningPathIntroVideo(
|
|
|
465
481
|
const collection: CollectionObject = { id: learningPathId, type: COLLECTION_TYPE.LEARNING_PATH }
|
|
466
482
|
|
|
467
483
|
if (!lessonsToImport) {
|
|
468
|
-
|
|
469
484
|
response.learning_path_reset_response = await resetIfPossible(learningPathId, collection)
|
|
470
485
|
} else {
|
|
471
|
-
|
|
472
486
|
response.lesson_import_response = await contentStatusCompletedMany(lessonsToImport, collection)
|
|
473
487
|
const activePath = await getActivePath(brand)
|
|
474
488
|
|
|
475
489
|
if (activePath.active_learning_path_id === learningPathId) {
|
|
476
|
-
response.update_dailies_response = await updateDailySession(
|
|
477
|
-
brand,
|
|
478
|
-
new Date(),
|
|
479
|
-
true
|
|
480
|
-
)
|
|
490
|
+
response.update_dailies_response = await updateDailySession(brand, new Date(), true)
|
|
481
491
|
}
|
|
482
492
|
}
|
|
483
493
|
|
|
@@ -494,13 +504,19 @@ async function completeIfNotCompleted(
|
|
|
494
504
|
return introVideoStatus !== 'completed' ? await contentStatusCompleted(contentId) : null
|
|
495
505
|
}
|
|
496
506
|
|
|
497
|
-
async function resetIfPossible(
|
|
507
|
+
async function resetIfPossible(
|
|
508
|
+
contentId: number,
|
|
509
|
+
collection: CollectionParameter = null
|
|
510
|
+
): Promise<SyncWriteDTO<ContentProgress, any> | null> {
|
|
498
511
|
const status = await getProgressState(contentId, collection)
|
|
499
512
|
|
|
500
513
|
return status !== '' ? await contentStatusReset(contentId, collection) : null
|
|
501
514
|
}
|
|
502
515
|
|
|
503
|
-
export async function onContentCompletedLearningPathActions(
|
|
516
|
+
export async function onContentCompletedLearningPathActions(
|
|
517
|
+
contentId: number,
|
|
518
|
+
collection: CollectionObject | null
|
|
519
|
+
) {
|
|
504
520
|
if (collection?.type !== COLLECTION_TYPE.LEARNING_PATH) return
|
|
505
521
|
if (contentId !== collection?.id) return
|
|
506
522
|
|
|
@@ -525,5 +541,5 @@ export async function onContentCompletedLearningPathActions(contentId: number, c
|
|
|
525
541
|
await startLearningPath(brand, nextLearningPath.id)
|
|
526
542
|
const nextLearningPathData = await getEnrichedLearningPath(nextLearningPath.id)
|
|
527
543
|
|
|
528
|
-
await contentStatusReset(nextLearningPathData.intro_video.id, {skipPush: true})
|
|
544
|
+
await contentStatusReset(nextLearningPathData.intro_video.id, { skipPush: true })
|
|
529
545
|
}
|
|
File without changes
|
|
File without changes
|
package/src/services/content.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -531,9 +531,8 @@ async function saveContentProgress(contentId, collection, progress, currentSecon
|
|
|
531
531
|
}
|
|
532
532
|
}
|
|
533
533
|
|
|
534
|
-
if (Object.keys(bubbledProgresses).length
|
|
535
|
-
|
|
536
|
-
await db.contentProgress.recordProgressMany(bubbledProgresses, collection, {tentative: !isLP, skipPush: true, fromLearningPath})
|
|
534
|
+
if (Object.keys(bubbledProgresses).length > 0) {
|
|
535
|
+
await db.contentProgress.recordProgressMany(bubbledProgresses, collection, {skipPush: true, fromLearningPath})
|
|
537
536
|
}
|
|
538
537
|
|
|
539
538
|
if (isLP) {
|
|
@@ -567,8 +566,7 @@ async function setStartedOrCompletedStatus(contentId, collection, isCompleted, {
|
|
|
567
566
|
...trickleProgress(hierarchy, contentId, collection, progress),
|
|
568
567
|
...await bubbleProgress(hierarchy, contentId, collection)
|
|
569
568
|
}
|
|
570
|
-
|
|
571
|
-
await db.contentProgress.recordProgressMany(progresses, collection, {tentative: !isLP, skipPush: true})
|
|
569
|
+
await db.contentProgress.recordProgressMany(progresses, collection, {skipPush: true})
|
|
572
570
|
|
|
573
571
|
if (isLP) {
|
|
574
572
|
let exportProgresses = progresses
|
|
@@ -600,7 +598,7 @@ async function setStartedOrCompletedStatusMany(contentIds, collection, isComplet
|
|
|
600
598
|
}
|
|
601
599
|
|
|
602
600
|
const contents = Object.fromEntries(contentIds.map((id) => [id, progress]))
|
|
603
|
-
const response = await db.contentProgress.recordProgressMany(contents, collection, {
|
|
601
|
+
const response = await db.contentProgress.recordProgressMany(contents, collection, {skipPush: true})
|
|
604
602
|
|
|
605
603
|
// we assume this is used only for contents within the same hierarchy
|
|
606
604
|
const hierarchy = await getHierarchy(collection.id, collection)
|
|
@@ -613,8 +611,7 @@ async function setStartedOrCompletedStatusMany(contentIds, collection, isComplet
|
|
|
613
611
|
...(await bubbleProgress(hierarchy, contentId, collection)),
|
|
614
612
|
}
|
|
615
613
|
}
|
|
616
|
-
|
|
617
|
-
await db.contentProgress.recordProgressMany(progresses, collection, {tentative: !isLP, skipPush: true})
|
|
614
|
+
await db.contentProgress.recordProgressMany(progresses, collection, {skipPush: true})
|
|
618
615
|
|
|
619
616
|
if (isLP) {
|
|
620
617
|
let exportProgresses = progresses
|
|
@@ -647,8 +644,21 @@ async function resetStatus(contentId, collection = null, {skipPush = false} = {}
|
|
|
647
644
|
...trickleProgress(hierarchy, contentId, collection, progress),
|
|
648
645
|
...await bubbleProgress(hierarchy, contentId, collection)
|
|
649
646
|
}
|
|
650
|
-
//
|
|
651
|
-
|
|
647
|
+
// have to use different endpoints for erase vs record
|
|
648
|
+
const eraseProgresses = Object.fromEntries(
|
|
649
|
+
Object.entries(progresses).filter(([_, pct]) => pct === 0)
|
|
650
|
+
)
|
|
651
|
+
progresses = Object.fromEntries(
|
|
652
|
+
Object.entries(progresses).filter(([_, pct]) => pct > 0)
|
|
653
|
+
)
|
|
654
|
+
|
|
655
|
+
if (Object.keys(progresses).length > 0) {
|
|
656
|
+
await db.contentProgress.recordProgressMany(progresses, collection, {skipPush: true, fromLearningPath: isLP})
|
|
657
|
+
}
|
|
658
|
+
if (Object.keys(eraseProgresses).length > 0) {
|
|
659
|
+
const eraseIds = Object.keys(eraseProgresses).map(Number)
|
|
660
|
+
await db.contentProgress.eraseProgressMany(eraseIds, collection, {skipPush: true})
|
|
661
|
+
}
|
|
652
662
|
|
|
653
663
|
if (isLP) {
|
|
654
664
|
progresses[contentId] = progress
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -178,12 +178,16 @@ function sortCards(pinnedCard, contentCardMap, playlistCards, methodCard, limit)
|
|
|
178
178
|
combined.push(pinnedCard)
|
|
179
179
|
}
|
|
180
180
|
|
|
181
|
-
|
|
181
|
+
const progressList = Array.from(contentCardMap.values())
|
|
182
|
+
|
|
183
|
+
combined = [...combined, ...progressList, ...playlistCards]
|
|
184
|
+
|
|
185
|
+
// welcome card state will only show if pinned
|
|
186
|
+
if (methodCard.type !== 'method') {
|
|
182
187
|
combined.push(methodCard)
|
|
183
188
|
}
|
|
184
189
|
|
|
185
|
-
|
|
186
|
-
return mergeAndSortItems([...combined, ...progressList, ...playlistCards], limit)
|
|
190
|
+
return mergeAndSortItems(combined, limit)
|
|
187
191
|
}
|
|
188
192
|
|
|
189
193
|
function mergeAndSortItems(items, limit) {
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|