https://www.youtube.com/watch?v=AHSHjCVUsu8
위의 밋업 동영상의 내용을 요약한 글이다.
세번째 발표를 두 번째에 작성
팀 스파르타 이동현 주관 발표
아키텍쳐는 견고해야 한다. ( 수정 과 삽입이 용이해야함 )
고수준의 의존성 방향을 지양해야함.

기존 Layered Architecture
각 단계가 서로에게 의존 함.
=> 기존 Layered Architecture 에서 의존성을 역전시킴!
=> 외부에 의존하지 않는 도메인 로직을 가질 수 있음!

핵사고날 아키텍쳐는 기본적으로 외부 & 내부 존재
내부는 도메인 계층으로 , 순수 비즈니스 로직 캡슐화 한 영역
외부는 기존 아키텍쳐 에서 , 도메인 영역 분리한 영역

Port / Adapter Pattern
Infrastructure 나 Interface 에 영향 받지않는 비즈니스 도메인 코드 작성 할 수 있음.
export type Applicants = any;
export class Recruiter {
    constructor(
        public userId : string,
        public name : string,
        public email : string,
        public availableApplicants : Applicants[],
        )
  		{}
  	viewResume(applicant:Applicant){
      	applicant.clickNumbers +=1;
    }
  	saveResume(applicant:Applicant){
      applicant.isSaved = true;
    }
  sendInterviewRequest(applicant:Applicant){
    applicant.status = 'interview';
  }
}import { viewResumseRespDto } from '../../adapter/in/web/dto/response/viewResume-response-dto';
import { saveResumeRespDto } from '../../adapter/in/web/dto/response/saveResume-response-dto';
import { sendInterviewRequestRespDto } from '../../adapter/in/web/dto/response/sendInterviewRequest-response-dto';
export interface ApplicantLoadInPort {
  viewResume() : Promise<viewResumeRespDto>;
  saveResume() : Promise<saveResumeRespDto>;
  sendInterviewRequest() : Promise<sendInterviewRequestRespDto>;
}export interface IRecruiterRepository {
  	findRecruiterById(_id : ObjectId) : Promise<Recruiter>;
  	findApplicantById(_id : ObjectId) : Promise<Applicant>;
  	updateRecruiter(recruiter : Recruiter);
}export class ApplicantService implements ApplicantLoadInPort {
  	constructor(
  		@Inject(Logger) private readonly logger : LoggerService ,
        @Inject(ApplicantPersistenceAdapter) private readonly applicantLoadPort : ApplicantLoadPort ,
       	@Inject(ApplicantStatusPersistenceAdapter) private readonly applicantStatusLoader : ApplicantStatusLoader,
        @Inject(InterviewPersistenceAdapter) private readonly interviewPersistenceAdapter : InterviewPersistencePort)
  		{}
 	async findApplicant(resumeId) : Promise<Applicant> {
      	return await this.applicantLoadPort.loadApplicant(resumeId);
    }
}@Controller('resume')
export clas ApplicantController {
  	constructor(
      @Inject(ApplicantService) private readonly applicantService : ApplicantLoadInPort,
      @Inject(Logger) private readonly logger : LoggerService,){}
=> 결론적으론 , 외부로 나가는 의존성 없는 도메인을 가짐.

export class newInterviewRequestedEvent {
  	constructor(){
      	public readonly name : string,
        public readonly recruiterName : string,
    }
}this.eventBus.publish( 
  new newInterviewRequestedEvent(applicant.name,recruiter.name),
);