Skip to content

Latest commit

 

History

History
1157 lines (881 loc) · 23.2 KB

File metadata and controls

1157 lines (881 loc) · 23.2 KB

MeetingRoomReservationSystem

Table of Contents

1. 背景

1.1. ドメイン

S社は、地方都市に本社を置くビル管理サービス事業会社である。市内に複数のビルを所有しており、主な事業は不動産賃貸事業及び設備総合管理事業である。

十数年前から所有物件の稼働率を向上するべく貸会議室運営事業に着手している。 当時としては先進的なオンライン予約システムを導入し、利用者からの評価も好評であった。 しかし、システムの老朽化が進んでおり、システムの刷新が求められている。

最近、システムの刷新プロジェクトが立ち上げられたが、担当者の急な退職により十分な引継ぎが行われなかったため全体を把握する人間が不在の状況となっておりプロジェクトは停滞している。

現在、貸会議室運事業の業務の大半は手作業で行われている。利用可能な会議室の登録は手作業でシステムに登録しているため、登録漏れや登録間違いにより予約した会議室が使えない、利用したい会議室がいつも使えないなど利用者からのクレームが発生しておりサービス品質向上が求めらている。 また、プロジェクタやホワイトボードなど付随する設備の要望が上がっているが十分に対応できていない状況である。

S社としては、システム刷新によるサービス品質向上を実現し、サブスクリプションサービスの導入による収益の多様化を実現することで貸会議室運営事業を新たな収益の柱に成長させたいと考えている。

2. 要件

2.1. 概要

要件定義にはリレーションシップ駆動要件分析(RDRA)を使用する。

RDRAとは短時間で要件を把握することを目的とした軽量の手法。 RDRAでは、決められたアイコンを使い、アイコンとアイコン、アイコンと図を関連づけ、アイコンで表現されたモデル要素と関連のつながりから要件を説明する。

rdra
rdra2

また、要件定義は開発と並行して都度反映され運用にも影響を与える。

life cycle.drawio

2.2. システム価値

2.2.1. システムコンテキスト

@startuml

title システムコンテキスト図

left to right direction

actor 利用者 as ac_01
actor スタッフ as ac_02
actor 会員 as ac_03
actor ゲスト as ac_04
ac_01 <|- ac_02
ac_01 <|-- ac_03

note top of ac_01
  利用者とはシステムを利用するアクター全般を指す。
  お金を払って会議室を利用する会員。
  窓口業務を担当するスタッフ。
end note

note bottom of ac_04
    ゲストとはシステムの公開サービスを利用するアクターを指す。
    会議室予約に興味を持っている潜在顧客。
end note

usecase 会議室予約システム as uc_01
note top of uc_01
  利用者がWebサイト上で会議室の予約をして、一覧で確認できるようにする。
  登録した利用者だけが利用できるようにする。
  スタッフは利用者の予約を取り消すことができるようにする。
end note

ac_02 -- (uc_01)
ac_03 -- (uc_01)
ac_04 -- (uc_01)

@enduml

2.2.2. 要求モデル

@startuml

title 要求モデル図

left to right direction

actor 会員 as ac_01
note "利用可能な会議室があるかを Web で検索したい" as k_r1
note "利用可能な会議室を Web で予約したい" as k_r2
note "予約を Web でキャンセルしたい" as k_r6
note "サービス内容の問い合わせをしたい" as k_r7
note as k_dr1 #Turquoise
  Web で会議室を検索でき、
  そのまま予約できること
end note
ac_01 -- k_r1
ac_01 -- k_r2
ac_01 -- k_r6
ac_01 -- k_r7
k_r1 -- k_dr1
k_r2 -- k_dr1
k_r6 -- k_dr1

actor スタッフ as ac_02
note "会員の予約を管理したい" as k_r3
note "利用者を管理したい" as k_r4
note "会議室を管理したい" as k_r5
ac_02 -- k_r3
ac_02 -- k_r4
ac_02 -- k_r5

actor ゲスト as ac_03
ac_03 -- k_r7

@enduml

2.3. システム外部環境

2.3.1. ビジネスコンテキスト

@startuml

title ビジネスコンテキスト図

left to right direction

actor 会員 as ac_01
actor ゲスト as ac_03

node 施設 {
  rectangle 窓口 {
    actor スタッフ as ac_02
  }
  usecase 予約管理 as uc_01
  usecase 会員管理 as uc_02
  artifact 会議室 as ar_01
}

ac_01 -- (uc_01)
ac_01 -- (uc_02)
ac_03 -- (uc_02)
(uc_01) -- (ar_01)
(uc_01) - ac_02
(uc_02) - ac_02

@enduml

2.3.2. ビジネスユースケース

会員管理
@startuml

title ビジネスユースケース図 - 会員管理

left to right direction

actor 会員 as ac_01
actor ゲスト as ac_02
agent 窓口 as ag_01

usecase 利用者の管理 as uc_01
usecase 利用者の認証 as uc_02
usecase 問い合わせ管理 as uc_03

ac_01 -- (uc_02)
ac_01 -- (uc_03)
ac_02 -- (uc_03)

(uc_01) -- ag_01
(uc_02) -- ag_01
(uc_03) -- ag_01

@enduml
予約管理
@startuml

title ビジネスユースケース図 - 予約管理

left to right direction

actor 会員 as ac_01

agent 窓口 as ag_01

usecase 会議室の検索 as uc_01
usecase 会議室の予約 as uc_02
usecase 会議室の登録 as uc_03

artifact 会議室 as af_01

ac_01 -- (uc_01)
ac_01 -- (uc_02)

(uc_01) --- af_01
(uc_01) -- ag_01
(uc_02) -- af_01
(uc_02) -- ag_01
(uc_03) -- ag_01

@enduml

2.3.3. 業務フロー

会員管理
問い合わせ管理
@startuml

title 業務フロー図 - 問い合わせ管理:BUC

|会員|
partition 問い合わせの実施 {
  :問い合わせをする;
}

|スタッフ|
partition 問い合わせの対応 {
  :問い合わせを確認する;
  :問い合わせに対応する;
}

|会員|
stop

@enduml
@startuml

title 業務フロー図 - 問い合わせ管理:BUC

|ゲスト|
partition 問い合わせの実施 {
  :問い合わせをする;
}

|スタッフ|
partition 問い合わせの対応 {
  :問い合わせを確認する;
  :問い合わせに対応する;
}

|ゲスト|
stop

@enduml
予約管理
会議室の予約
@startuml

title 業務フロー図 - 会議室の予約:BUC

|スタッフ|
partition 会議室の登録 {
  :会議室を登録する;
  :予約可能な会議室を登録する;
}

|会員|
partition 会議室の検索 {
  :予約可能な会議室を検索する;
}

partition 会議室の予約 {
  :会議室を予約する;
   if (キャンセル) then (必要)
    :取り消したい会議室の予約を選択する;
    :会議室の予約を取り消す;
   else (不要)
   endif
}

stop

@enduml

2.3.4. 利用シーン

会員管理
利用者の認証
@startuml

title 利用シーン図 - 利用者の認証:BUC

left to right direction

actor 会員 as ac_01
actor スタッフ as ac_02

frame 利用者の認証
note right of 利用者の認証
  申し込み済みの利用者を認証して会議室の予約・取り消しを実行できるようにする
end note

usecase 利用者を認証する

:ac_01: -- 利用者の認証
:ac_02: -- 利用者の認証
利用者の認証 -- (利用者を認証する)

@enduml
利用者の管理
@startuml

title 利用シーン図 - 利用者の管理:BUC

left to right direction

actor スタッフ as ac_02

frame 利用者の管理 as f_01
note right of f_01
 申し込みのあった利用者を窓口が手動でシステムに登録する
end note

usecase 利用申込みをする as uc_01
usecase 利用者を確認する as uc_02
usecase 利用者を登録をする as uc_03
usecase 利用者情報の更新をする as uc_04
usecase 利用者登録を抹消する as uc_05

:ac_02: -- f_01
f_01 -- (uc_01)
f_01 -- (uc_02)
f_01 -- (uc_03)
f_01 -- (uc_04)
f_01 -- (uc_05)

@enduml
予約管理
会議室の検索
@startuml

title 利用シーン図 - 会議室の検索:BUC

left to right direction

actor 会員 as ac_01
actor スタッフ as ac_02

frame 会議室の検索
note right of 会議室の検索
  利用者認証が完了している
  予約済みおよび予約可能な会議室を検索する
end note

usecase 予約可能な会議室を検索する

:ac_01: -- 会議室の検索
:ac_02: -- 会議室の検索
会議室の検索 -- (予約可能な会議室を検索する)


@enduml
会議室の登録
@startuml

title 利用シーン図 - 会議室の登録:BUC

left to right direction

actor スタッフ as ac_01

frame 会議室の登録
note right of 会議室の登録
   予約可能な会議室を登録する。
   利用者は予約可能な会議室に対して予約をすることができる。
end note

usecase 予約可能な会議室を登録する

:ac_01: -- 会議室の登録
会議室の登録 -- (会議室を登録する)
会議室の登録 -- (予約可能な会議室を登録する)


@enduml

2.3.5. バリエーション・条件

利用者区分

管理者

一般

ゲスト

2.4. システム境界

2.4.1. ユースケース複合図

会員管理
利用者の認証
@startuml
actor "会員" as user
actor "スタッフ" as admin
frame "利用者の認証" as f01
usecase "利用者を認証する" as UC1
boundary "ログイン画面" as b01
entity "利用者" as e01
user - f01
admin - f01
f01 - UC1
b01 -- UC1
UC1 - e01
@enduml
利用者の管理
@startuml
actor "スタッフ" as admin
frame "利用者の管理" as f01
usecase "利用者を確認する" as UC1
usecase "利用者を登録する" as UC2
usecase "利用者情報を更新する" as UC3
usecase "利用者登録を抹消する" as UC4
boundary "利用者一覧画面" as b01
boundary "利用者画面" as b02
entity "利用者" as e01
control "利用者バリエーション" as c01

admin - f01
f01 - UC1
f01 - UC2
f01 - UC3
f01 - UC4
b01 -- UC1
b02 -- UC2
b02 -- UC3
b02 -- UC4
UC2 -- c01
UC3 -- c01
UC4 -- c01
UC1 - e01
UC2 - e01
UC3 - e01
UC4 - e01
@enduml
問い合わせ管理
@startuml
actor "ゲスト" as gust
actor "会員" as user
actor "スタッフ" as admin
frame "問い合わせの実施" as f01
frame "問い合わせの対応" as f02
usecase "問い合わせをする" as UC1
usecase "問い合わせを確認する" as UC2
usecase "問い合わせに対応する" as UC3
boundary "問い合わせ画面" as b01
boundary "問い合わせ一覧画面" as b02
entity "問い合わせ" as e01

gust - f01
user - f01
f01 - UC1
b01 -- UC1
UC1 - e01

f01 --> f02

admin - f02
f02 - UC2
f02 - UC3
b02 -- UC2
b02 -- UC3
UC2 -- e01
予約管理
会議室の検索
@startuml
actor "会員" as user
actor "スタッフ" as admin
frame "会議室の検索" as f01
usecase "予約可能な会議室を検索する" as UC1
boundary "会議室予約一覧画面" as b01
entity "予約可能会議室" as e01

user - f01
admin - f01

f01 - UC1
b01 -- UC1
UC1 - e01

@enduml
会議室の予約
@startuml
actor "会員" as user
actor "スタッフ" as admin
frame "会議室の予約" as f01
usecase "予約可能な会議室を検索する" as UC1
usecase "会議室の予約一覧を取得する" as UC2
usecase "会議室を予約する" as UC3
usecase "会議室の予約を取り消す" as UC4
boundary "会議室予約一覧画面" as b01
boundary "会議室予約画面" as b02
control "予約条件" as c01
entity "予約可能会議室" as e01
entity "予約" as e02

user - f01
admin - f01

f01 - UC1
b01 -- UC1
UC1 -- e01

f01 - UC2
b02 -- UC2
UC2 -- e02

f01 - UC3
b02 -- UC3
UC3 -- e02
UC3 -- c01

f01 - UC4
b02 -- UC4
UC4 - e02

@enduml
会議室の登録
@startuml
actor "スタッフ" as admin
frame "会議室の登録" as f01
usecase "会議室を登録する" as UC1
usecase "予約可能な会議室を登録する" as UC2
boundary "会議室一覧画面" as b01
boundary "会議室登録画面" as b02
boundary "予約可能会議室一覧画面" as b03
boundary "予約可能会議室登録画面" as b04
control "予約可能条件" as c01
entity "予約可能会議室" as e01
entity "予約" as e02
entity "会議室" as e03

admin - f01
f01 - UC1
b01 -- UC1
b02 -- UC1
UC1 -- e03

f01 - UC2
b03 -- UC2
b04 -- UC2
UC2 -- e01
UC2 -- e02
UC2 -- e03
UC2 - c01

@enduml

2.5. システム

2.5.1. 情報モデル

@startuml

title 情報モデル図

left to right direction

entity 利用者
entity 予約
entity 会議室
entity 予約可能会議室

予約 -- 利用者
予約 -- 予約可能会議室
予約可能会議室 -- 会議室

@enduml

2.5.2. 状態モデル

3. 開発

3.1. 仕様

3.1.1. コンテキストマップ

skinparam componentStyle uml2

component [AuthContext] <<認証・認可>>
component [UserContext] <<利用者>>
component [ReservationContext] <<予約>>
component [FacilityContext] <<施設>>
component [ContactContext] <<問い合わせ>>

[AuthContext]<-->[UserContext] : Shared Kernel

[UserContext]<-->[ReservationContext] : Shared Kernel

[UserContext]<-->[ContactContext] : Shared Kernel

[ReservationContext]<-->[FacilityContext] : Shared Kernel

3.1.2. ユースケース

service method call hierarchy

認証・認可
@startuml
left to right direction
actor "会員" as member
actor "スタッフ" as admin
rectangle 認証・認可 {
  usecase "利用者の認証" as UC1
}
member --> UC1
admin --> UC1
@enduml
link:../cypress/integration/UserManagement/UserAuth.Basic.feature[role=include]

link:../cypress/integration/UserManagement/UserAuth.Extentions.feature[role=include]
利用者
@startuml
left to right direction
actor "スタッフ" as admin
rectangle 利用者 {
  usecase "利用者の管理" as UC1
}
admin --> UC1
@enduml
link:../cypress/integration/UserManagement/UserMnagement.Basic.feature[role=include]
予約
@startuml
left to right direction
actor "会員" as member
actor "スタッフ" as admin
rectangle 予約 {
  usecase "会議室の検索" as UC2
  usecase "会議室の予約" as UC3
}
member --> UC2
member --> UC3
admin --> UC2
admin --> UC3
@enduml
link:../cypress/integration/ReservationManagement/RoomSearch.Basic.feature[role=include]

link:../cypress/integration/ReservationManagement/RoomReserve.Basic.feature[role=include]

link:../cypress/integration/ReservationManagement/RoomReserve.Extentions.feature[role=include]
施設
@startuml
left to right direction
actor "スタッフ" as admin
rectangle 施設 {
  usecase "会議室の登録" as UC4
}
admin --> UC4
@enduml
link:../cypress/integration/ReservationManagement/RoomRegist.Basic.feature[role=include]

link:../cypress/integration/ReservationManagement/RoomRegist.Extentions.feature[role=include]
問い合わせ
@startuml
left to right direction
actor "会員" as member
actor "ゲスト" as gust
actor "スタッフ" as admin
rectangle 問い合わせ {
  usecase "問い合わせの実施" as UC1
  usecase "問い合わせの対応" as UC2
}
gust --> UC1
member --> UC1
admin --> UC2
@enduml
link:../cypress/integration/UserManagement/ContactMemberRegist.Basic.feature[role=include]

link:../cypress/integration/UserManagement/ContactGustRegist.Basic.feature[role=include]

link:../cypress/integration/UserManagement/ContactManagement.Basic.feature[role=include]

3.2. 設計

3.2.1. アプリケーションアーキテクチャ

architecture

3.2.2. ドメインモデル

package relation depth4
business rule relation
利用者
skinparam componentStyle uml2

package mrs.domain.model.auth.user {
	package "'User' Aggregate" <<Rectangle>> {
		class User <<(E,DarkSeaGreen) Entity>> {
		}
		class UserId <<(V,DarkSeaGreen) Value Object>> {
		}
		class UserName <<(V,DarkSeaGreen) Value Object>> {
		}
		class Password <<(V,DarkSeaGreen) Value Object>> {
		}
		enum RoleName {
			管理者
			一般
            ゲスト
		}
		class Staff <<(E,DarkSeaGreen) Entity>> {
		}
		class Member <<(E,DarkSeaGreen) Entity>> {
		}
		class MemberId <<(V,DarkSeaGreen) Value Object>> {
		}

        User <|-- Staff
        User <|-- Member
        UserId --* User
        Password --* User
        UserName -* User
        User *- RoleName
        Member *-- MemberId
	}
}
予約
skinparam componentStyle uml2

package mrs.domain.model.reservation.reservation {
	package "'Reservation' Aggregate" <<Rectangle>> {
		class Reservation <<(E,DarkSeaGreen) Entity>> {
		}
		class ReservationId <<(V,DarkSeaGreen) Value Object>> {
		}
		class ReservedTime <<(V,DarkSeaGreen) Value Object>> {
		}
		class ReservedDate <<(V,DarkSeaGreen) Value Object>> {
		}
		class MeetingRoom <<(E,DarkSeaGreen) Entity>> {
		}
		class RoomId <<(V,DarkSeaGreen) Value Object>> {
		}
		class ReservableRoom <<(E,DarkSeaGreen) Entity>> {
		}
		class ReservableRoomId <<(V,DarkSeaGreen) Value Object>> {
		}
		class ReservableRoomList <<(V,DarkSeaGreen) Value Object>> {
		}
	}
    ReservationId --* Reservation
    ReservedTime --* Reservation
    Reservation *-- ReservableRoom
    ReservableRoom *- ReservableRoomId
    ReservableRoomId *-- RoomId
    ReservableRoomId *-- ReservedDate
    MeetingRoom --* ReservableRoom
    MeetingRoom *-- RoomId
    ReservableRoomList *-- ReservableRoom
}
施設
skinparam componentStyle uml2

package mrs.domain.model.facility.facility {
	package "'MeetingRoom' Aggregate" <<Rectangle>> {
		class MeetingRoom <<(E,DarkSeaGreen) Entity>> {
		}
		class RoomId <<(V,DarkSeaGreen) Value Object>> {
		}
	}
    MeetingRoom *-- RoomId
}
問い合わせ
skinparam componentStyle uml2

package mrs.domain.model.contact.contact {
	package "'Contact' Aggregate" <<Rectangle>> {
		class Contact <<(E,DarkSeaGreen) Entity>> {
		}
        Interface ContactPerson {
        }
		class Member <<(E,DarkSeaGreen) Entity>> {
		}
		class Gust <<(E,DarkSeaGreen) Entity>> {
		}
        class ContactId <<(V,DarkSeaGreen) Value Object>> {
        }
        class MemberId <<(V,DarkSeaGreen) Value Object>> {
        }
        class ContactList <<(V,DarkSeaGreen) Value Object>> {
        }
	}
    Contact *- ContactPerson
    ContactId -* Contact
    ContactPerson <|.. Member
    MemberId -* Member
    ContactPerson <|.. Gust
    ContactList *-- Contact
}

3.2.3. データモデル

利用者
relationships.real.large
予約
relationships.real.large
施設
relationships.real.large
問い合わせ
relationships.real.large

4. 運用

4.1. 開発

npm start

4.2. テスト

npm test

4.3. ビルド

npm build

4.4. デプロイ

npm run deploy

5. 構築

ソフトウェア

バージョン

備考

Java

17

Node.js

16.3.0

5.1. アプリケーションコンポーネント

5.1.1. プロダクション・開発環境

package "UI" {
  [React]
}

package "API" {
  [SpringBoot]
}

database "DB" {
  frame "H2" {
    [mrs_test]
  }

  frame "PostgreSQL" {
    [mrs_development]
    [mrs_production]
  }
}

[React] -> [SpringBoot]
[SpringBoot] -- [mrs_test]
[SpringBoot] -- [mrs_development]
[SpringBoot] -- [mrs_production]

5.2. コンポーネントセットアップ

5.2.1. 開発関連

開発ツール
npm init -y
npm install --save-dev @babel/core @babel/cli @babel/preset-env @babel/register
npm install --save-dev npm-run-all watch foreman cpx rimraf marked@1.2.2
npm install --save-dev webpack webpack-cli html-webpack-plugin webpack-dev-server
touch Procfile.dev

5.2.2. ドキュメント関連

Asciidoctor
npm install --save-dev asciidoctor asciidoctor-kroki

5.2.3. フロントエンド関連

Cypress
npm install cypress
npmx cypress open
npm install --save-dev cypress-cucumber-preprocessor
npm install --save-dev cucumber-html-reporter
React
npm install --save-dev jest
npm install react react-dom
npm install --save-dev babel-loader @babel/preset-react
npm install --save-dev @testing-library/react @testing-library/jest-dom
npm install --save-dev sass-loader sass style-loader css-loader
npm install --save-dev identity-obj-proxy
npm install react-router-dom
npm install --save-dev typescript ts-loader
npm install --save @types/react @types/react-dom @types/react-router-dom
npm install --save-dev @types/jest@27.1.4 ts-jest@27.1.4
npx tsc --init
npm install -save @reduxjs/toolkit react-redux
npm install -save axios @types/axios
npm install --save-dev react-hook-form
npm install cross-env

6. 配置

6.1. システムアーキテクチャ

@startuml
actor 開発者
actor 利用者

cloud "Vercel" as vercel {
    package "Production Environment" as ui_prd_env {
      [UI] as ui_prd
    }
}

cloud "Heroku" as heroku {
    package "Production Environment" as api_prd_env {
      [API] as api_prd
      [DB] as db_prd
    }
}

cloud "GitHub" as github {
  [Git] as repository
}

開発者 --> repository
repository --> heroku
repository --> vercel
api_prd -> db_prd
api_prd <-- ui_prd
ui_prd <-- 利用者
@enduml
heroku create case-study-mrs
heroku open