v1.2.2: Add Healthcare specialization, mark cancelled courses, rename Digital Marketing
Apply the J27 (5/6/2026) Stern specialization sheet: - Add Healthcare (HCR) as the 15th specialization, with HCR cross-listings on spr2-health-medical, spr3-analytics-ml, sum2-social-media (renamed), and fall1-managing-change. 10 credits available, no required-course gate. - Rename sum2-social-media to "Digital Marketing Strategy in Practice"; replace its description with new MSKCC-anchored content; clear instructor pending confirmation of new lead. - Switch from delete-and-replace to the previously-unused cancelled flag (Approach B): mark spr5-customer-insights cancelled, add Managing Growing Companies back to Summer Set 2 as a cancelled placeholder per the printed sheet. - Update data integrity tests: course count 46 -> 47, spec count 14 -> 15; per-spec "across sets" helper now filters cancelled courses so future cancellations trigger an obvious assertion failure (BRM 6 -> 5, MKT 7 -> 6, HCR 4 new). - Replace hardcoded 14 in optimizer.test.ts with SPECIALIZATIONS.length.
This commit is contained in:
@@ -5,16 +5,16 @@ import { SPECIALIZATIONS } from '../specializations';
|
||||
import { coursesBySet, coursesBySpec } from '../lookups';
|
||||
|
||||
describe('Data integrity', () => {
|
||||
it('has exactly 46 courses', () => {
|
||||
expect(COURSES.length).toBe(46);
|
||||
it('has exactly 47 courses', () => {
|
||||
expect(COURSES.length).toBe(47);
|
||||
});
|
||||
|
||||
it('has exactly 12 elective sets', () => {
|
||||
expect(ELECTIVE_SETS.length).toBe(12);
|
||||
});
|
||||
|
||||
it('has exactly 14 specializations', () => {
|
||||
expect(SPECIALIZATIONS.length).toBe(14);
|
||||
it('has exactly 15 specializations', () => {
|
||||
expect(SPECIALIZATIONS.length).toBe(15);
|
||||
});
|
||||
|
||||
it('every course belongs to a valid set and that set references the course', () => {
|
||||
@@ -78,30 +78,33 @@ describe('Data integrity', () => {
|
||||
});
|
||||
|
||||
describe('per-specialization "across sets" counts match reachability table', () => {
|
||||
// Expected counts: number of distinct sets that have at least one qualifying course
|
||||
// Expected counts: number of distinct sets that have at least one non-cancelled qualifying course
|
||||
const expectedAcrossSets: Record<string, number> = {
|
||||
MGT: 11,
|
||||
STR: 9,
|
||||
LCM: 9,
|
||||
FIN: 9,
|
||||
CRF: 8,
|
||||
MKT: 7,
|
||||
MKT: 6,
|
||||
BNK: 6,
|
||||
BRM: 6,
|
||||
FIM: 6,
|
||||
MTO: 6,
|
||||
BRM: 5,
|
||||
GLB: 5,
|
||||
EMT: 4,
|
||||
ENT: 4,
|
||||
HCR: 4,
|
||||
SBI: 4,
|
||||
};
|
||||
|
||||
for (const [specId, expected] of Object.entries(expectedAcrossSets)) {
|
||||
it(`${specId} qualifies across ${expected} sets`, () => {
|
||||
const entries = coursesBySpec[specId] || [];
|
||||
const courseIds = entries.map((e) => e.courseId);
|
||||
const setIds = new Set(
|
||||
courseIds.map((cid) => COURSES.find((c) => c.id === cid)!.setId)
|
||||
entries
|
||||
.map((e) => COURSES.find((c) => c.id === e.courseId)!)
|
||||
.filter((c) => !c.cancelled)
|
||||
.map((c) => c.setId)
|
||||
);
|
||||
expect(setIds.size).toBe(expected);
|
||||
});
|
||||
|
||||
@@ -114,8 +114,8 @@ export const COURSE_DESCRIPTIONS: Record<string, CourseInfo> = {
|
||||
instructors: ['Luke Williams'],
|
||||
},
|
||||
'sum2-social-media': {
|
||||
description: 'This course is designed to provide business leaders with a framework for a company to evaluate social media and enhance their integrated marketing campaigns. You will be provided with the tools to understand the current mobile technology landscape. This course covers important issues that leaders must have a POV on, including: data privacy, marketing technology, mobile video, and top mobile advertising companies. This course strikes a balanced approach of covering the pressing issues of today and timeless foundational marketing principles.\n\nThis is a fast-paced course that is designed for you to learn the basic concepts, terms, and principles that apply to the social media industry. To become familiar with key strategic issues across the sector, you will analyze the activities of the leading social media companies and applications through articles, case studies, and lectures. By the conclusion of the course, as a senior executive you will have gained an understanding of the opportunities and challenges your organization must consider as it manages its social media and mobile technology platforms.',
|
||||
instructors: ['Stewart Krentzman'],
|
||||
description: 'Digital strategy drives business performance. It shapes how companies capture demand and design customer experiences. At senior management levels today, digital fluency is expected. Business leaders know where to focus their teams, what to prioritize, and where customer understanding driven by agentic AI can create competitive advantage.\n\nThe course centers on live engagement with the senior digital strategy team at Memorial Sloan Kettering Cancer Center - one of the top two cancer centers in the country. Teams will develop and present a digital strategy that encourages patients under the age of 40 to seek their care at MSKCC.\n\nYou\'ll build a practical framework connecting segmentation, positioning, content, channels, platforms, AI, and performance measurement. Increasingly, this includes agentic AI - systems that don\'t just generate outputs, but act: orchestrating journeys, adapting content in real time. The challenge is not access to these capabilities but knowing where and how to deploy them for impact.\n\nTara Liggins, VP of Engagement at L\'Oréal, will join several sessions to show how digital strategy translates into digital tactical engagement. Dr. Nnamdi Ezeanochie, a thought leader at Google Gemini will lead a session on how all aspects of AI is reshaping strategy - from passive tools to systems that act, decide, and optimize.\n\nBy the end of this course, students will not just understand digital strategy. Importantly, they will leave with the confidence and judgment to LEAD cross-functional teams, influence executive stakeholders, and drive digital strategies that don\'t sit on slides - but get funded, implemented, and deliver results.',
|
||||
instructors: [],
|
||||
},
|
||||
'sum2-leading-ai': {
|
||||
description: 'We\'re at a new age, an age where artificial intelligence is becoming the most influential General Purpose Technology, a technology that once arrived, is poised to morph all aspects of our lives, irreversibly. Artificial Intelligence (AI) rapidly moves into the mainstream, supported by emerging capabilities in cloud and quantum computing, big data, open source software, and ML algorithms to name a few key forces. AI is already demonstrating capabilities that generate greater efficiencies, precision, and personalization, and at times, greater creative output than humans. And with this growing capacity, there grow questions regarding the business value of AI, the societal implications of deploying this technology, and of course, new and intriguing ethical considerations. This course will introduce you to some of the major disruptive Artificial Intelligence developments, concepts, and considerations, and will address the future of work questions as we lead and evolve/sustain AI-enabled businesses.',
|
||||
|
||||
+11
-5
@@ -22,7 +22,7 @@ export const COURSES: Course[] = [
|
||||
},
|
||||
{
|
||||
id: 'spr2-health-medical', name: 'The Business of Health & Medical Care', setId: 'spr2',
|
||||
qualifications: [{ specId: 'STR', marker: 'S2' }],
|
||||
qualifications: [{ specId: 'HCR', marker: 'standard' }, { specId: 'STR', marker: 'S2' }],
|
||||
},
|
||||
{
|
||||
id: 'spr2-human-rights', name: 'Human Rights and Business', setId: 'spr2',
|
||||
@@ -54,7 +54,7 @@ export const COURSES: Course[] = [
|
||||
},
|
||||
{
|
||||
id: 'spr3-analytics-ml', name: 'Analytics & Machine Learning for Managers', setId: 'spr3',
|
||||
qualifications: [{ specId: 'MTO', marker: 'standard' }],
|
||||
qualifications: [{ specId: 'HCR', marker: 'standard' }, { specId: 'MTO', marker: 'standard' }],
|
||||
},
|
||||
|
||||
// === Spring Elective Set 4 ===
|
||||
@@ -91,6 +91,7 @@ export const COURSES: Course[] = [
|
||||
{
|
||||
id: 'spr5-customer-insights', name: 'Customer Insights', setId: 'spr5',
|
||||
qualifications: [{ specId: 'BRM', marker: 'standard' }, { specId: 'MKT', marker: 'standard' }],
|
||||
cancelled: true,
|
||||
},
|
||||
|
||||
// === Summer Elective Set 1 ===
|
||||
@@ -108,6 +109,11 @@ export const COURSES: Course[] = [
|
||||
},
|
||||
|
||||
// === Summer Elective Set 2 ===
|
||||
{
|
||||
id: 'sum2-managing-growing-companies', name: 'Managing Growing Companies', setId: 'sum2',
|
||||
qualifications: [],
|
||||
cancelled: true,
|
||||
},
|
||||
{
|
||||
id: 'sum2-innovation-design', name: 'Innovation and Design', setId: 'sum2',
|
||||
qualifications: [
|
||||
@@ -116,8 +122,8 @@ export const COURSES: Course[] = [
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'sum2-social-media', name: 'Social Media and Mobile Technology', setId: 'sum2',
|
||||
qualifications: [{ specId: 'BRM', marker: 'standard' }, { specId: 'EMT', marker: 'standard' }, { specId: 'MKT', marker: 'standard' }],
|
||||
id: 'sum2-social-media', name: 'Digital Marketing Strategy in Practice', setId: 'sum2',
|
||||
qualifications: [{ specId: 'BRM', marker: 'standard' }, { specId: 'EMT', marker: 'standard' }, { specId: 'HCR', marker: 'standard' }, { specId: 'MKT', marker: 'standard' }],
|
||||
},
|
||||
{
|
||||
id: 'sum2-leading-ai', name: 'Leading in the Age of AI', setId: 'sum2',
|
||||
@@ -164,7 +170,7 @@ export const COURSES: Course[] = [
|
||||
},
|
||||
{
|
||||
id: 'fall1-managing-change', name: 'Managing Change', setId: 'fall1',
|
||||
qualifications: [{ specId: 'LCM', marker: 'standard' }, { specId: 'MGT', marker: 'standard' }, { specId: 'STR', marker: 'S2' }],
|
||||
qualifications: [{ specId: 'HCR', marker: 'standard' }, { specId: 'LCM', marker: 'standard' }, { specId: 'MGT', marker: 'standard' }, { specId: 'STR', marker: 'S2' }],
|
||||
},
|
||||
{
|
||||
id: 'fall1-social-entrepreneurship', name: 'Social Entrepreneurship', setId: 'fall1',
|
||||
|
||||
@@ -27,7 +27,7 @@ export const ELECTIVE_SETS: ElectiveSet[] = [
|
||||
},
|
||||
{
|
||||
id: 'sum2', name: 'Summer Elective Set 2', term: 'Summer',
|
||||
courseIds: ['sum2-innovation-design', 'sum2-social-media', 'sum2-leading-ai', 'sum2-business-drivers'],
|
||||
courseIds: ['sum2-managing-growing-companies', 'sum2-innovation-design', 'sum2-social-media', 'sum2-leading-ai', 'sum2-business-drivers'],
|
||||
},
|
||||
{
|
||||
id: 'sum3', name: 'Summer Elective Set 3', term: 'Summer',
|
||||
|
||||
@@ -9,6 +9,7 @@ export const SPECIALIZATIONS: Specialization[] = [
|
||||
{ id: 'FIN', name: 'Finance', abbreviation: 'FIN' },
|
||||
{ id: 'FIM', name: 'Financial Instruments and Markets', abbreviation: 'FIM' },
|
||||
{ id: 'GLB', name: 'Global Business', abbreviation: 'GLB' },
|
||||
{ id: 'HCR', name: 'Healthcare', abbreviation: 'HCR' },
|
||||
{ id: 'LCM', name: 'Leadership and Change Management', abbreviation: 'LCM' },
|
||||
{ id: 'MGT', name: 'Management', abbreviation: 'MGT' },
|
||||
{ id: 'MKT', name: 'Marketing', abbreviation: 'MKT' },
|
||||
|
||||
@@ -149,7 +149,7 @@ describe('optimize (integration)', () => {
|
||||
expect(result.allocations).toBeDefined();
|
||||
expect(result.statuses).toBeDefined();
|
||||
expect(result.upperBounds).toBeDefined();
|
||||
expect(Object.keys(result.statuses).length).toBe(14);
|
||||
expect(Object.keys(result.statuses).length).toBe(SPECIALIZATIONS.length);
|
||||
});
|
||||
|
||||
it('modes can produce different results', () => {
|
||||
|
||||
Reference in New Issue
Block a user