musora-content-services 2.104.2 โ 2.104.4
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/.claude/settings.local.json +6 -8
- package/.yarnrc.yml +1 -0
- package/CHANGELOG.md +9 -0
- package/check_content.js +30 -0
- package/check_content.mjs +32 -0
- package/package.json +1 -1
- package/src/filterBuilder.js +0 -0
- package/src/lib/ads/monoid.ts +0 -0
- package/src/lib/ads/semigroup.ts +0 -0
- package/src/lib/httpHelper.js +0 -0
- package/src/lib/sanity/filter.ts +0 -0
- package/src/lib/sanity/query.ts +0 -0
- package/src/services/awards/award-callbacks.js +0 -0
- package/src/services/awards/types.d.ts +0 -0
- package/src/services/content/artist.ts +0 -0
- package/src/services/content/genre.ts +0 -0
- package/src/services/content/instructor.ts +0 -0
- package/src/services/content-org/learning-paths.ts +0 -0
- package/src/services/content-org/playlists.js +0 -0
- package/src/services/content.js +6 -1
- package/src/services/contentAggregator.js +0 -0
- package/src/services/contentProgress.js +0 -0
- package/src/services/forums/forums.ts +0 -0
- package/src/services/forums/threads.ts +0 -0
- package/src/services/permissions/PermissionsV2Adapter.ts +0 -0
- package/src/services/progress-events.js +0 -0
- package/src/services/reporting/reporting.ts +0 -0
- package/src/services/sanity.js +2 -1
- package/src/services/sync/fetch.ts +0 -0
- package/src/services/sync/manager.ts +0 -0
- package/src/services/sync/models/ContentProgress.ts +0 -0
- package/src/services/sync/repositories/content-progress.ts +0 -0
- package/src/services/sync/store/index.ts +0 -0
- package/src/services/user/memberships.ts +0 -0
- package/src/services/user/onboarding.ts +0 -0
- package/src/services/user/sessions.js +0 -0
- package/src/services/userActivity.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/query.test.ts +0 -0
- package/test/reporting.test.js +132 -0
- package/test/sanityQueryService.test.js +0 -0
- package/test/sync/adapter.ts +0 -0
- package/test/sync/initialize-sync-manager.js +0 -0
- package/test_owned_navigate.js +74 -0
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"permissions": {
|
|
3
3
|
"allow": [
|
|
4
|
+
"Read(//app/musora-platform-backend/**)",
|
|
5
|
+
"Read(//app/musora-platform-frontend/**)",
|
|
4
6
|
"Bash(find:*)",
|
|
5
|
-
"Bash(
|
|
6
|
-
"
|
|
7
|
-
"WebSearch",
|
|
8
|
-
"WebFetch(domain:watermelondb.dev)",
|
|
9
|
-
"WebFetch(domain:github.com)",
|
|
10
|
-
"Bash(git checkout:*)",
|
|
11
|
-
"Bash(npm run doc:*)",
|
|
7
|
+
"Bash(sed:*)",
|
|
8
|
+
"Read(//app/**)",
|
|
12
9
|
"Bash(cat:*)",
|
|
13
|
-
"Bash(
|
|
10
|
+
"Bash(docker exec:*)",
|
|
11
|
+
"Bash(npm config:*)"
|
|
14
12
|
],
|
|
15
13
|
"deny": [],
|
|
16
14
|
"ask": []
|
package/.yarnrc.yml
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
nodeLinker: node-modules
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,15 @@
|
|
|
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.104.4](https://github.com/railroadmedia/musora-content-services/compare/v2.104.3...v2.104.4) (2025-12-12)
|
|
6
|
+
|
|
7
|
+
### [2.104.3](https://github.com/railroadmedia/musora-content-services/compare/v2.104.0...v2.104.3) (2025-12-12)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
### Bug Fixes
|
|
11
|
+
|
|
12
|
+
* **MU2-1309:** navigateTo missing on owned contents ([9b12213](https://github.com/railroadmedia/musora-content-services/commit/9b12213ad8061d60eada1603c0384d36b7a955f3))
|
|
13
|
+
|
|
5
14
|
### [2.104.2](https://github.com/railroadmedia/musora-content-services/compare/v2.104.1...v2.104.2) (2025-12-12)
|
|
6
15
|
|
|
7
16
|
### [2.104.1](https://github.com/railroadmedia/musora-content-services/compare/v2.104.0...v2.104.1) (2025-12-12)
|
package/check_content.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
const { initializeService } = require('./src/services/config.js');
|
|
2
|
+
const { fetchByRailContentIds } = require('./src/services/sanity.js');
|
|
3
|
+
require('dotenv/config');
|
|
4
|
+
|
|
5
|
+
async function checkContent() {
|
|
6
|
+
initializeService({
|
|
7
|
+
sanityConfig: {
|
|
8
|
+
token: process.env.SANITY_TOKEN,
|
|
9
|
+
projectId: process.env.SANITY_PROJECT_ID,
|
|
10
|
+
dataset: process.env.SANITY_DATASET,
|
|
11
|
+
version: process.env.SANITY_VERSION || '2021-06-07',
|
|
12
|
+
},
|
|
13
|
+
railcontentConfig: {
|
|
14
|
+
token: process.env.RAILCONTENT_TOKEN,
|
|
15
|
+
userId: process.env.RAILCONTENT_USER_ID,
|
|
16
|
+
baseUrl: process.env.RAILCONTENT_BASE_URL,
|
|
17
|
+
authToken: process.env.RAILCONTENT_AUTH_TOKEN,
|
|
18
|
+
},
|
|
19
|
+
baseUrl: process.env.RAILCONTENT_BASE_URL,
|
|
20
|
+
localStorage: null,
|
|
21
|
+
isMA: false,
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
console.log('Checking railcontent_id: 421814');
|
|
25
|
+
const contents = await fetchByRailContentIds([421814]);
|
|
26
|
+
console.log('Results:', JSON.stringify(contents, null, 2));
|
|
27
|
+
console.log('Found:', contents.length, 'items');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
checkContent().catch(console.error);
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { initializeService } from './src/services/config.js';
|
|
2
|
+
import { fetchByRailContentIds } from './src/services/sanity.js';
|
|
3
|
+
import dotenv from 'dotenv';
|
|
4
|
+
|
|
5
|
+
dotenv.config();
|
|
6
|
+
|
|
7
|
+
async function checkContent() {
|
|
8
|
+
initializeService({
|
|
9
|
+
sanityConfig: {
|
|
10
|
+
token: process.env.SANITY_TOKEN,
|
|
11
|
+
projectId: process.env.SANITY_PROJECT_ID,
|
|
12
|
+
dataset: process.env.SANITY_DATASET,
|
|
13
|
+
version: process.env.SANITY_VERSION || '2021-06-07',
|
|
14
|
+
},
|
|
15
|
+
railcontentConfig: {
|
|
16
|
+
token: process.env.RAILCONTENT_TOKEN,
|
|
17
|
+
userId: process.env.RAILCONTENT_USER_ID,
|
|
18
|
+
baseUrl: process.env.RAILCONTENT_BASE_URL,
|
|
19
|
+
authToken: process.env.RAILCONTENT_AUTH_TOKEN,
|
|
20
|
+
},
|
|
21
|
+
baseUrl: process.env.RAILCONTENT_BASE_URL,
|
|
22
|
+
localStorage: null,
|
|
23
|
+
isMA: false,
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
console.log('Checking railcontent_id: 421814');
|
|
27
|
+
const contents = await fetchByRailContentIds([421814]);
|
|
28
|
+
console.log('Results:', JSON.stringify(contents, null, 2));
|
|
29
|
+
console.log('Found:', contents.length, 'items');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
checkContent().catch(console.error);
|
package/package.json
CHANGED
package/src/filterBuilder.js
CHANGED
|
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/httpHelper.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
|
package/src/services/content.js
CHANGED
|
@@ -527,5 +527,10 @@ export async function getOwnedContent(brand, {
|
|
|
527
527
|
};
|
|
528
528
|
}
|
|
529
529
|
|
|
530
|
-
return data
|
|
530
|
+
return await addContextToContent(() => data, {
|
|
531
|
+
dataField: 'entity',
|
|
532
|
+
addNavigateTo: true,
|
|
533
|
+
addProgressPercentage: true,
|
|
534
|
+
addProgressStatus: true,
|
|
535
|
+
});
|
|
531
536
|
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/src/services/sanity.js
CHANGED
|
@@ -2068,7 +2068,8 @@ export async function fetchOwnedContent(
|
|
|
2068
2068
|
showOnlyOwnedContent: true, // Key parameter: exclude membership content
|
|
2069
2069
|
}).buildFilter()
|
|
2070
2070
|
|
|
2071
|
-
|
|
2071
|
+
// Use 'tab-data' to include children field (needed for navigateTo calculation)
|
|
2072
|
+
const fieldsString = await getFieldsForContentTypeWithFilteredChildren('tab-data', true)
|
|
2072
2073
|
|
|
2073
2074
|
const query = buildEntityAndTotalQuery(filterWithRestrictions, fieldsString, {
|
|
2074
2075
|
sortOrder: sortOrder,
|
|
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/test/initializeTests.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/test/lib/filter.test.ts
CHANGED
|
File without changes
|
package/test/lib/query.test.ts
CHANGED
|
File without changes
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for Reporting Service
|
|
3
|
+
*
|
|
4
|
+
* Note: These tests use mocked HTTP calls. For integration tests,
|
|
5
|
+
* ensure the backend API is running at the configured baseUrl.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { initializeTestService } from './initializeTests.js'
|
|
9
|
+
import {
|
|
10
|
+
reportContent,
|
|
11
|
+
reportForumPost,
|
|
12
|
+
submitReport
|
|
13
|
+
} from '../src/services/reporting/reporting.ts'
|
|
14
|
+
|
|
15
|
+
// Mock HttpClient to avoid actual API calls in tests
|
|
16
|
+
jest.mock('../src/infrastructure/http/HttpClient', () => {
|
|
17
|
+
return {
|
|
18
|
+
HttpClient: jest.fn().mockImplementation(() => ({
|
|
19
|
+
post: jest.fn().mockResolvedValue({
|
|
20
|
+
report_id: 12345,
|
|
21
|
+
message: 'Report submitted successfully',
|
|
22
|
+
is_duplicate: false
|
|
23
|
+
})
|
|
24
|
+
}))
|
|
25
|
+
}
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
describe('Reporting Service', () => {
|
|
29
|
+
beforeEach(() => {
|
|
30
|
+
initializeTestService()
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
describe('reportContent', () => {
|
|
34
|
+
test('should submit a content report with video_not_working category', async () => {
|
|
35
|
+
const result = await reportContent({
|
|
36
|
+
contentId: 123,
|
|
37
|
+
category: 'video_not_working',
|
|
38
|
+
description: 'Video freezes at 2:30'
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
expect(result).toBeDefined()
|
|
42
|
+
expect(result.report_id).toBe(12345)
|
|
43
|
+
expect(result.message).toBe('Report submitted successfully')
|
|
44
|
+
expect(result.is_duplicate).toBe(false)
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
test('should submit a content report without description', async () => {
|
|
48
|
+
const result = await reportContent({
|
|
49
|
+
contentId: 456,
|
|
50
|
+
category: 'incorrect_content'
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
expect(result).toBeDefined()
|
|
54
|
+
expect(result.report_id).toBeDefined()
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
test('should submit a content report with other category and description', async () => {
|
|
58
|
+
const result = await reportContent({
|
|
59
|
+
contentId: 789,
|
|
60
|
+
category: 'other',
|
|
61
|
+
description: 'Audio quality is very poor'
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
expect(result).toBeDefined()
|
|
65
|
+
expect(result.report_id).toBeDefined()
|
|
66
|
+
expect(result.message).toBeDefined()
|
|
67
|
+
})
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
describe('reportForumPost', () => {
|
|
71
|
+
test('should submit a forum post report with required brand', async () => {
|
|
72
|
+
const result = await reportForumPost({
|
|
73
|
+
postId: 555,
|
|
74
|
+
brand: 'drumeo',
|
|
75
|
+
category: 'spam'
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
expect(result).toBeDefined()
|
|
79
|
+
expect(result.report_id).toBeDefined()
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
test('should submit a forum post report with description', async () => {
|
|
83
|
+
const result = await reportForumPost({
|
|
84
|
+
postId: 666,
|
|
85
|
+
brand: 'pianote',
|
|
86
|
+
category: 'harassment',
|
|
87
|
+
description: 'User is harassing other members'
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
expect(result).toBeDefined()
|
|
91
|
+
expect(result.report_id).toBeDefined()
|
|
92
|
+
expect(result.message).toBeDefined()
|
|
93
|
+
})
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
describe('submitReport', () => {
|
|
97
|
+
test('should submit a generic report for content', async () => {
|
|
98
|
+
const result = await submitReport({
|
|
99
|
+
reportableType: 'content',
|
|
100
|
+
reportableId: 999,
|
|
101
|
+
category: 'technical_issue',
|
|
102
|
+
description: 'Page not loading'
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
expect(result).toBeDefined()
|
|
106
|
+
expect(result.report_id).toBeDefined()
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
test('should submit a generic report for playlist', async () => {
|
|
110
|
+
const result = await submitReport({
|
|
111
|
+
reportableType: 'playlist',
|
|
112
|
+
reportableId: 777,
|
|
113
|
+
category: 'incorrect_content'
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
expect(result).toBeDefined()
|
|
117
|
+
expect(result.report_id).toBeDefined()
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
test('should submit a generic report for comment', async () => {
|
|
121
|
+
const result = await submitReport({
|
|
122
|
+
reportableType: 'comment',
|
|
123
|
+
reportableId: 888,
|
|
124
|
+
category: 'inappropriate',
|
|
125
|
+
description: 'Comment contains offensive language'
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
expect(result).toBeDefined()
|
|
129
|
+
expect(result.report_id).toBeDefined()
|
|
130
|
+
})
|
|
131
|
+
})
|
|
132
|
+
})
|
|
File without changes
|
package/test/sync/adapter.ts
CHANGED
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { initializeService } from './src/services/config.js'
|
|
2
|
+
import { getOwnedContent } from './src/services/content.js'
|
|
3
|
+
import dotenv from 'dotenv'
|
|
4
|
+
|
|
5
|
+
dotenv.config()
|
|
6
|
+
|
|
7
|
+
// Initialize service with credentials from .env
|
|
8
|
+
initializeService({
|
|
9
|
+
sanityConfig: {
|
|
10
|
+
token: process.env.SANITY_API_TOKEN,
|
|
11
|
+
projectId: process.env.SANITY_PROJECT_ID,
|
|
12
|
+
dataset: process.env.SANITY_DATASET,
|
|
13
|
+
version: '2023-01-01',
|
|
14
|
+
},
|
|
15
|
+
railcontentConfig: {
|
|
16
|
+
email: process.env.RAILCONTENT_EMAIL,
|
|
17
|
+
password: process.env.RAILCONTENT_PASSWORD,
|
|
18
|
+
userId: parseInt(process.env.RAILCONTENT_USER_ID),
|
|
19
|
+
baseUrl: process.env.RAILCONTENT_BASE_URL,
|
|
20
|
+
},
|
|
21
|
+
localStorage: null,
|
|
22
|
+
isMA: false,
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
async function testOwnedContentNavigateTo() {
|
|
26
|
+
console.log('\n๐งช Testing owned content with navigateTo...\n')
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
// Test for drumeo lessons
|
|
30
|
+
const result = await getOwnedContent('drumeo', {
|
|
31
|
+
type: ['course', 'guided-course', 'pack'],
|
|
32
|
+
limit: 5,
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
console.log('๐ Results:', {
|
|
36
|
+
total: result.total,
|
|
37
|
+
count: result.entity?.length || 0,
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
if (result.entity && result.entity.length > 0) {
|
|
41
|
+
result.entity.forEach((item, index) => {
|
|
42
|
+
console.log(`\n๐ฆ Item ${index + 1}:`)
|
|
43
|
+
console.log(` - ID: ${item.id}`)
|
|
44
|
+
console.log(` - Title: ${item.title}`)
|
|
45
|
+
console.log(` - Type: ${item.type}`)
|
|
46
|
+
console.log(` - Has children: ${item.children ? 'โ
YES' : 'โ NO'}`)
|
|
47
|
+
console.log(` - Children count: ${item.children?.length || 0}`)
|
|
48
|
+
console.log(` - Has navigateTo: ${item.navigateTo ? 'โ
YES' : 'โ NO'}`)
|
|
49
|
+
|
|
50
|
+
if (item.navigateTo) {
|
|
51
|
+
console.log(` - NavigateTo ID: ${item.navigateTo.id}`)
|
|
52
|
+
console.log(` - NavigateTo Type: ${item.navigateTo.type}`)
|
|
53
|
+
console.log(` - NavigateTo Title: ${item.children?.find(c => c.id === item.navigateTo.id)?.title || 'N/A'}`)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (item.progressPercentage !== undefined) {
|
|
57
|
+
console.log(` - Progress: ${item.progressPercentage}%`)
|
|
58
|
+
}
|
|
59
|
+
if (item.progressStatus) {
|
|
60
|
+
console.log(` - Status: ${item.progressStatus}`)
|
|
61
|
+
}
|
|
62
|
+
})
|
|
63
|
+
} else {
|
|
64
|
+
console.log('\nโ ๏ธ No owned content found for this user')
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
console.log('\nโ
Test completed successfully!')
|
|
68
|
+
} catch (error) {
|
|
69
|
+
console.error('\nโ Test failed:', error.message)
|
|
70
|
+
console.error(error.stack)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
testOwnedContentNavigateTo()
|