Skip to content
34 changes: 34 additions & 0 deletions src/domain/shared/affiliation/Affiliation.ts

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Info: ValueObject.equals() uses JSON.stringify which is key-order-dependent for these complex objects

The base ValueObject.equals() at src/domain/base/ValueObject.ts:16 compares values via JSON.stringify(this.value) === JSON.stringify(vo.value). For the new Affiliation value types — which are plain objects with multiple keys — this comparison is sensitive to property insertion order. Two semantically identical affiliation objects constructed with properties in different orders would be considered unequal. This is a pre-existing design characteristic of ValueObject, not introduced by this PR, but it becomes more relevant now that ValueObject is being used with multi-field objects rather than primitives or simple types.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { ValueObject } from "#domain/base/ValueObject";
import type {
DoctoralAffiliationValue,
MasterAffiliationValue,
ProfessionalAffiliationValue,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

これは何を想定されている

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://www.shizuoka.ac.jp/subject/

を見ると博士課程以外に専門職学位課程というのがあるらしいのでそれ。ただ英訳については疑義あり

UndergraduateAffiliationValue,
} from "./universityStructure";

/** 学部所属 */
export class UndergraduateAffiliation extends ValueObject<UndergraduateAffiliationValue> {
protected validate(): void {}
Comment thread
KinjiKawaguchi marked this conversation as resolved.
}

/** 修士課程所属 */
export class MasterAffiliation extends ValueObject<MasterAffiliationValue> {
protected validate(): void {}
}

/** 博士課程所属 */
export class DoctoralAffiliation extends ValueObject<DoctoralAffiliationValue> {
protected validate(): void {}
}

/** 専門職学位課程所属 */
export class ProfessionalAffiliation extends ValueObject<ProfessionalAffiliationValue> {
protected validate(): void {}
}
Comment thread
KinjiKawaguchi marked this conversation as resolved.
Comment thread
KinjiKawaguchi marked this conversation as resolved.

/** 所属 — 学生が大学組織のどこに在籍しているかを表す */
export type Affiliation =
| UndergraduateAffiliation // 学部
| MasterAffiliation // 修士
| DoctoralAffiliation // 博士
| ProfessionalAffiliation; // 専門職
2 changes: 2 additions & 0 deletions src/domain/shared/affiliation/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from "./Affiliation";
export * from "./universityStructure";
326 changes: 326 additions & 0 deletions src/domain/shared/affiliation/universityStructure.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,326 @@
/**
* 静岡大学の組織構造定義
*
* 各学部・研究科の階層を型レベルで表現する。
*
* フィールドとユビキタス言語の対応:
* - `faculty` — 学部(学部課程の組織単位)
* - `school` — 研究科・大学院(大学院課程の組織単位)
* - `department` — 学科
* - `program` — 課程(例: 学校教育教員養成課程)
* - `major` — 専攻
* - `course` — コース(専門分野の細分化)
* - `subspecialty` — 専修(コースよりさらに細分化された専門領域)
* - `enrollmentType` — 入学区分(昼間コース / 夜間主コース)
* - `year` — 在学年次
*
* @see https://www.shizuoka.ac.jp/subject/
*/

// ── 年次 ──

export type UndergraduateYear = 1 | 2 | 3 | 4;
export type MasterYear = 1 | 2;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

M2+みたいな例外はどう扱う予定

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

それはM2何じゃないか、進級という概念があるんだろうか?...

export type DoctoralYear = 1 | 2 | 3;
export type ProfessionalYear = 1 | 2;

// ── 学部(Undergraduate) ──

/** 人文社会科学部 @see https://www.hss.shizuoka.ac.jp/ */
export type HumanitiesFacultyValue =
| {
/** 学部 */
faculty: "人文社会科学部";
/** 入学区分 */
enrollmentType: "昼間コース";
/** 学科 */
department: "社会学科" | "言語文化学科" | "法学科" | "経済学科";
/** 在学年次 */
year: UndergraduateYear;
}
| {
/** 学部 */
faculty: "人文社会科学部";
/** 入学区分 */
enrollmentType: "夜間主コース";
/** 学科 */
department: "法学科" | "経済学科";
/** 在学年次 */
year: UndergraduateYear;
};

/** 教育学部 @see https://www.ed.shizuoka.ac.jp/applicants/about/organization/ */
export type EducationFacultyValue =
| {
/** 学部 */
faculty: "教育学部";
/** 課程 */
program: "学校教育教員養成課程";
/** 専攻 */
major: "発達教育学専攻";
/** 専修 */
subspecialty: "教育実践学専修" | "教育心理学専修" | "幼児教育専修";
/** 在学年次 */
year: UndergraduateYear;
}
| {
faculty: "教育学部";
program: "学校教育教員養成課程";
major: "初等学習開発学専攻";
year: UndergraduateYear;
}
| {
faculty: "教育学部";
program: "学校教育教員養成課程";
major: "養護教育専攻";
year: UndergraduateYear;
}
| {
faculty: "教育学部";
program: "学校教育教員養成課程";
major: "特別支援教育専攻";
year: UndergraduateYear;
}
| {
faculty: "教育学部";
program: "学校教育教員養成課程";
major: "教科教育学専攻";
subspecialty:
| "国語教育専修"
| "社会科教育専修"
| "数学教育専修"
| "理科教育専修"
| "音楽教育専修"
| "美術教育専修"
| "保健体育教育専修"
| "技術教育専修"
| "家庭科教育専修"
| "英語教育専修";
year: UndergraduateYear;
};

/** 情報学部 @see https://www.inf.shizuoka.ac.jp/ */
export type InformaticsFacultyValue = {
/** 学部 */
faculty: "情報学部";
/** 学科 */
department: "情報科学科" | "行動情報学科" | "情報社会学科";
/** 在学年次 */
year: UndergraduateYear;
};

/** 理学部 @see https://www.sci.shizuoka.ac.jp/dep_study */
export type ScienceFacultyValue =
| {
faculty: "理学部";
department:
| "数学科"
| "物理学科"
| "化学科"
| "生物科学科"
| "地球科学科";
year: UndergraduateYear;
}
| {
faculty: "理学部";
/** コース */
course: "創造理学コース";
year: UndergraduateYear;
};

/** 工学部 @see https://www.eng.shizuoka.ac.jp/department/ */
export type EngineeringFacultyValue =
| {
faculty: "工学部";
department: "機械工学科";
course:
| "宇宙・環境コース"
| "知能・材料コース"
| "電気機械システムコース";
year: UndergraduateYear;
}
| {
faculty: "工学部";
department: "電気電子工学科";
course: "情報エレクトロニクスコース" | "エネルギー・電子制御コース";
year: UndergraduateYear;
}
| {
faculty: "工学部";
department: "電子物質科学科";
course: "電子物理デバイスコース" | "材料エネルギー化学コース";
year: UndergraduateYear;
}
| {
faculty: "工学部";
department: "化学バイオ工学科";
course: "環境応用化学コース" | "バイオ応用工学コース";
year: UndergraduateYear;
}
| {
faculty: "工学部";
department: "数理システム工学科";
year: UndergraduateYear;
};

/** 農学部 @see https://www.agr.shizuoka.ac.jp/ */
export type AgricultureFacultyValue =
| {
faculty: "農学部";
department: "生物資源科学科";
course: "バイオサイエンスコース" | "環境サイエンスコース";
year: UndergraduateYear;
}
| {
faculty: "農学部";
department: "応用生命科学科";
year: UndergraduateYear;
};

/** グローバル共創科学部 @see https://www.gkk.shizuoka.ac.jp/outline/courses/ */
export type GlobalCoCreationFacultyValue = {
faculty: "グローバル共創科学部";
department: "グローバル共創科学科";
course:
| "国際地域共生学コース"
| "生命圏循環共生学コース"
| "総合人間科学コース";
year: UndergraduateYear;
};

/** 地域創造学環 @see https://www.srd.shizuoka.ac.jp/ */
export type RegionalDevelopmentValue = {
faculty: "地域創造学環";
year: UndergraduateYear;
};

export type UndergraduateAffiliationValue =
| HumanitiesFacultyValue // 人文社会科学部
| EducationFacultyValue // 教育学部
| InformaticsFacultyValue // 情報学部
| ScienceFacultyValue // 理学部
| EngineeringFacultyValue // 工学部
| AgricultureFacultyValue // 農学部
| GlobalCoCreationFacultyValue // グローバル共創科学部
| RegionalDevelopmentValue; // 地域創造学環

// ── 修士課程(Master) ──

/** 人文社会科学研究科 @see https://www.hss.shizuoka.ac.jp/ghss/ */
export type HumanitiesMasterValue =
| {
/** 研究科・大学院 */
school: "人文社会科学研究科";
/** 専攻 */
major: "臨床人間科学専攻";
/** コース */
course: "臨床心理学コース" | "臨床人間科学コース";
/** 在学年次 */
year: MasterYear;
}
| {
school: "人文社会科学研究科";
major: "比較地域文化専攻";
course: "歴史・文化論コース" | "言語文化論コース";
year: MasterYear;
}
| {
school: "人文社会科学研究科";
major: "経済専攻";
course: "国際経営コース" | "地域公共政策コース";
year: MasterYear;
};

/** 総合科学技術研究科 @see https://www.shizuoka.ac.jp/subject/graduate/stg/ */
export type IntegratedSciTechMasterValue =
| {
school: "総合科学技術研究科";
major: "情報学専攻";
course: "基盤情報学コース" | "領域情報学コース";
year: MasterYear;
}
| {
school: "総合科学技術研究科";
major: "理学専攻";
course:
| "数学コース"
| "物理学コース"
| "化学コース"
| "生物科学コース"
| "地球科学コース";
year: MasterYear;
}
| {
school: "総合科学技術研究科";
major: "工学専攻";
course:
| "機械工学コース"
| "電気電子工学コース"
| "電子物質科学コース"
| "化学バイオ工学コース"
| "数理システム工学コース"
| "事業開発マネジメントコース";
year: MasterYear;
}
| {
school: "総合科学技術研究科";
major: "農学専攻";
course:
| "生物資源科学コース"
| "応用生命科学コース"
| "環境森林科学コース";
year: MasterYear;
};

/** 山岳流域研究院 @see https://www.igsmw.shizuoka.ac.jp/ */
export type MountainWatershedValue = {
school: "山岳流域研究院";
year: MasterYear;
};

export type MasterAffiliationValue =
| HumanitiesMasterValue // 人文社会科学研究科
| IntegratedSciTechMasterValue // 総合科学技術研究科
| MountainWatershedValue; // 山岳流域研究院

// ── 博士課程(Doctoral) ──

/** 創造科学技術大学院 @see https://gsst.shizuoka.ac.jp/ */
export type CreativeSciTechDoctoralValue = {
school: "創造科学技術大学院";
major:
| "ナノビジョン工学専攻"
| "光・ナノ物質機能専攻"
| "情報科学専攻"
| "環境・エネルギーシステム専攻"
| "バイオサイエンス専攻";
year: DoctoralYear;
};

/** 教育学研究科(博士) @see https://subdev.ed.shizuoka.ac.jp/ */
export type EducationDoctoralValue = {
school: "教育学研究科";
major: "共同教科開発学専攻";
year: DoctoralYear;
};

/** 光医工学研究科 @see https://www.cmmp.shizuoka.ac.jp/ */
export type OptoBiomedicalDoctoralValue = {
school: "光医工学研究科";
major: "光医工学共同専攻";
year: DoctoralYear;
};

export type DoctoralAffiliationValue =
| CreativeSciTechDoctoralValue // 創造科学技術大学院
| EducationDoctoralValue // 教育学研究科
| OptoBiomedicalDoctoralValue; // 光医工学研究科

// ── 専門職学位課程(Professional) ──

/** 教育学研究科(専門職) @see https://dapse2.ed.shizuoka.ac.jp/ */
export type ProfessionalAffiliationValue = {
school: "教育学研究科";
major: "教育実践高度化専攻";
year: ProfessionalYear;
};
Comment thread
KinjiKawaguchi marked this conversation as resolved.
1 change: 1 addition & 0 deletions src/domain/shared/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from "./affiliation";
export * from "./StudentId";
Comment thread
KinjiKawaguchi marked this conversation as resolved.