diff --git a/.editorconfig b/.editorconfig index 991d43e2..f4296173 100644 --- a/.editorconfig +++ b/.editorconfig @@ -5,3 +5,6 @@ charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true end_of_line = lf + +[*.md] +trim_trailing_whitespace = false diff --git a/documents/forMarkdown/API_GET.md b/documents/forMarkdown/API_GET.md new file mode 100644 index 00000000..b490d1b3 --- /dev/null +++ b/documents/forMarkdown/API_GET.md @@ -0,0 +1,67 @@ +# [機能ID] 会員情報取得API GET /${パス} + +## 説明 + +- ユーザの会員情報を参照するAPI + +## 仕様 + +- ユーザの属性を参照する。 + - ユーザーマスタの全属性を返却する。 +- DBへのSELECT時に使用する当該ユーザのキーはアクセストークン.subとする + +## シーケンス図 + +```mermaid + + +sequenceDiagram +participant "Backend" as Backend +participant "DB" as db + +user ->> Backend: API Request + +note over Backend,db: 1. Retrieve user and physical subscription information + + Backend ->> db: 1.1 Select m_user, m_physical_sub_info + + alt no record + <- Backend: 1.1.1 Response status code: 400 + end + +note over Backend,db + 2. Retrieve required basic user attributes and + physical subscription information requirements for registered courses +end note + Backend -> db: 2.1 Select t_course_registration,\nm_course_basic_user_attribute, m_course + +<- Backend: Return response and status code: 200 + +@enduml + +``` + +## Request & Response + +### Request + +- なし + +### Response + +| Parameter | Description | Settings | Note | +| ------------------------------ | ------------------------------------------------------------------------------------------- | ---------------------------------- | ---- | +| last_name | 氏名 (姓) | m_user | | +| first_name | 氏名 (名) | m_user | | +| last_name_kana | 氏名カナ (姓) | m_user | | +| first_name_kana | 氏名カナ (名) | m_user | | +| date_of_birth | 生年月日 | m_user | | +| gender_type | 性別区分 | m_user | | +| tel | 電話番号 | m_user | | +| occupation_type | 職業区分 | m_user | | +| zipcode | 郵便番号 | m_user | | +| pref_code | 都道府県コード | m_user | | +| town | 市区町村大字 | m_user | | +| building | 番地・マンション名 | m_user | | +| address_kana | 住所カナ | m_user | | + diff --git "a/documents/forMarkdown/IF\345\256\232\347\276\251\346\233\270.md" "b/documents/forMarkdown/IF\345\256\232\347\276\251\346\233\270.md" new file mode 100644 index 00000000..3728756a --- /dev/null +++ "b/documents/forMarkdown/IF\345\256\232\347\276\251\346\233\270.md" @@ -0,0 +1,163 @@ +# IF01 設備有効開始受信 + +設備有効開始の取り込みを行う。 + +## 対向システム + +| 連携元 | 連携先 | +| ---------- | ------ | +| A システム | Future | + +## 環境情報 + +### Input + +| Item | Value | +| ---------------- | ------------------------------------------------ | +| 連携 S3 バケット | `${env}-example-import` | +| プレフィックス | `activate/year=${yyyy}/month=${MM}/day=${dd}/` | +| ファイル名 | `${yyyy}-${mm}-${dd}-${hh}-${MM}-${SS}.csv` | +| 保持期限 | 3 年 | + +### Output + +| Item | Value | +| ---------------- | ------------------------------------------------ | +| 連携 S3 バケット | `${env}-example-import` | +| プレフィックス | `activate/year=${yyyy}/month=${MM}/day=${dd}/` | +| ファイル名 | `${yyyy}-${mm}-${dd}-${hh}-${MM}-${SS}.csv` | +| 保持期限 | 3 年 | + +## 連携元定義 + +| Category | Item | Value | Memo | +| -------- | ----------------------------------- | --------- | -------------------- | +| Protocol | 連携方式(ファイル/API/ストリーム) | ファイル | | +| | 連携タイミング(随時/定時) | 定時 | | +| | 頻度 | 1 回/日 | | +| | 起動時間 | **16:00** | | +| | 処理完了期限 | **16:00** | | +| | 未着チェック(なし/WARN/ERROR) | WARN | | +| | 全件/差分 | 差分 | | +| | 0 件時連携 | あり | | +| Format | ファイル種別 | **CSV** | | +| | レイアウト | RFC 8259 | | +| | 文字コード | UTF-8 | | +| | 改行コード | LF | | +| | 圧縮 | - | | +| | 暗号化 | - | | +| | ヘッダ行 | あり | | +| | 項目順 | 固定 | 項目順は入れ替え不可 | +| | 機密情報 | - | | + +### 項目定義 + +| Name | Physical Name | Type | Length | Precision | Enum | Format | Sensitive | Example | Memo | +| ---------- | --------------- | ------ | ------ | --------- | ---- | ---------- | --------- | ---------- | ---- | +| 会社コード | company_cd | string | 5 | - | - | - | - | 00001 | | +| 設備コード | device_cd | string | 8 | - | - | - | - | 00000052 | | +| 有効開始日 | activation_date | string | 10 | - | - | YYYY-MM-DD | - | 2022-10-16 | [^1] | + +[^1]: 現在日以降である必要があるが、受信ではテスト観点で過去日も許容する + +#### サンプル + +```csv +company_cd,device_cd,activation_date +12121,00000052,2022-03-01 +12121,00000053,2022-03-30 +``` + +## 連携先定義 + +| Category | Item | Value | Memo | +| -------- | ----------------------------------- | --------- | -------------------- | +| Protocol | 連携方式(ファイル/API/ストリーム) | ファイル | | +| | 連携タイミング(随時/定時) | 定時 | | +| | 頻度 | 1 回/日 | | +| | 起動時間 | **16:00** | | +| | 処理完了期限 | **16:00** | | +| | 未着チェック(なし/WARN/ERROR) | WARN | | +| | 全件/差分 | 差分 | | +| | 0 件時連携 | あり | | +| Format | ファイル種別 | **CSV** | | +| | レイアウト | RFC 8259 | | +| | 文字コード | UTF-8 | | +| | 改行コード | LF | | +| | 圧縮 | - | | +| | 暗号化 | - | | +| | ヘッダ行 | あり | | +| | 項目順 | 固定 | 項目順は入れ替え不可 | +| | 機密情報 | - | | + + + +## 処理概要 + +- ファイル定義に則ったバリデーションを実施 +- 次の項目変換定義に従い加工し、出力先テーブルに Merge する +- 受信完了後、 Completed: YYYY-MM-DDTHH:MI:SS.SSS のタグを追加する + +## 処理シーケンス + +```plantuml +@startuml +!theme toy + +participant システム +participant S3 +database DB + +システム -> DB: 処理日付取得\n[日付管理] + +システム -> S3: 対象ファイルの存在チェック + +alt ファイルが存在しなかった場合 + システム -> システム: 処理終了して、次の処理を待機 +end + +システム -> DB: シーケンスの取得\n[シーケンスオブジェクト] + +システム -> DB: 1.実行開始レコード追加\n[IF受信管理] + +システム -> S3: 対象ファイルを取得 + +システム -> DB: 対象マスタのTruncate + +システム -> DB: ファイル連携処理 + +システム -> システム: 連携件数確認 + +システム -> S3: 処理済対象ファイルを格納 + +システム -> DB: 2.実行終了状態の更新\n[IF受信管理] +@enduml +``` + +## DB 項目 + +### 参照 + +なし + +### 登録 + +リストワークに以下のカラムでレコードを登録する + +- xxx ワーク.会社コード +- xxx ワーク.処理日付 +- xxx ワーク.yyy 区分 + +### 更新 + +なし + +## ビジネスロジック + +特記事項なし + +## エラー処理 +| Pattern | Description | recovery | +| -------- | ----------------------------------- | --------- | +| フォーマットエラー | 連携元から提供されているデータ形式が想定外 | 連携元またはIFの処理内容の修正と再実行(運用手順書のリンクでもいいかも) | + diff --git a/documents/forMarkdown/README.md b/documents/forMarkdown/README.md new file mode 100644 index 00000000..94bc02c9 --- /dev/null +++ b/documents/forMarkdown/README.md @@ -0,0 +1,123 @@ +--- +sidebarDepth: 4 +author: フューチャー株式会社 +home: true +heroText: Markdown設計ドキュメント規約 +tagline: Future Enterprise Markdown Design Document Standards +pageClass: lang-home +footer: ©2015 - 2024 Future Enterprise Coding Standards - Future Corporation +--- + +Markdown ベースの設計ドキュメントの規約をまとめる。 + +システム開発にて利用する設計ドキュメントを Markdown ベースにすることで、コーディングと同じ慣れたツールを用いて、Git によるバージョン管理、レビュープロセス、CI/CD などに自動化(静的解析、自動生成)を行いやすくし、ドキュメントを陳腐化させず、俊敏な設計開発を目指す。 + +Markdown に限った話では無いが、どういった内容を設計書に記載すべきかは悩むポイントは多い。 + +本規約では、アプリケーションの種別ごとに記載すべき内容と、それをどのような Markdown の構造で記載するかを規約化し、各チームで悩む余地を減らし、注力すべきことに集中できる環境を提供することを目的とする。 + +## 前提 + +本規約は以下の前提で作成されている + +- チーム/プロジェクトが 3 ~ 30 名程度規模程度 +- Git(GitHub, GitLab)で管理され、コードと設計書が同一リポジトリで管理される +- システム開発で必要なアプリケーション開発 + +## フォルダ階層 + +リポジトリ直下に `docs` フォルダを作成し、その配下に設計ドキュメントとなる Markdown ファイルを配備する。 + + + +次はバックエンド、フロントエンド、インフラのコードをモノリポで管理している例である。 + +```sh +. +├── backend # バックエンド系のコード +├── docs +├── frontend # フロントエンド系のコード +├── infrastructure # インフラ系のコード +``` + +`docs` 配下は以下のルールにしたがった構造を取る。 + +- `01_`、`02_` といったプレフィックスを持つ +- 番号には体系をもたせず、必要になったタイミングでインクリメントさせる +- オンボーディングコストを抑えるため、なるべく先頭に新規参画者が欲する情報を配備する + +構成例を次にあげる。 + + + +```sh +docs +├── 01_キャッチアップ # ドメイン知識など抑えておくべき前提知識 +├── 02_環境構築 # +├── 03_開発規約 # GitFlowなど、リリース方式、CI/CD周り +├── 04_ユーザーストーリー +├── 05_UI設計 # Figmaのパスなど +├── 06_画面設計書 +├── 07_API設計書 # OpenAPIのパス+各BL設計 +├── 08_データモデル # ERD, テーブル定義 +├── 09_IF設計書 # I/F定義+受信/送信BL設計 +├── 10_バッチ設計書 # タイマー、イベント起動の非同期処理のBL設計 +├── 11_インフラ設計 # 監視、キャパシティサイジング、コスト +├── ... +└── README.md +``` + +## システム構成図 + +TODO 論理, 物理, etc. + +## フロントエンド + +- UI設計(Figma) +- [](画面設計書.md) + +## バックエンド + +### テーブル定義書 + +A5ER + +以下の情報の管理 + +- 保持期限 +- 個人情報有無 + +パーティションなどはa5erで管理想定 + +### 区分値 + +TODO JSON/YAML で管理推奨など + +### Web API 設計書 + +API 定義書は OpenAPI.yaml で記載する + +TODO 各エンドポイント毎のプログラム設計 + +### プログラム設計書 + +TODO + +### I/F 定義書 + +I/F 定義書は、システム間の連携について定義と、その受信/配信処理の設計書です。 + +システム I/F は連携先の対向システムが存在するため、認識齟齬が無いように、どのようなプロトコル・項目であるかを定義する必要があります。 + +- [レイアウト](IF定義書.md) + +# Resources + +次のリンクから単一ファイルで作成されたコーディング規約を取得できます。 +(これらのファイルは[Pandoc]を利用して作成しています。) + +- [Markdown](https://github.com/future-architect/coding-standards/blob/master/documents/forMarkdown/xxx.md) +- [HTML](https://github.com/future-architect/coding-standards/blob/gh-pages/resources/xxx.html) +- [Word](https://github.com/future-architect/coding-standards/raw/gh-pages/resources/xxx.docx) + +[pandoc]: https://pandoc.org/ diff --git a/documents/forMarkdown/future_muscle_partner/README.md b/documents/forMarkdown/future_muscle_partner/README.md new file mode 100644 index 00000000..55050b68 --- /dev/null +++ b/documents/forMarkdown/future_muscle_partner/README.md @@ -0,0 +1,32 @@ +# Future Muscle Partner + +~いきつけのジムでパーソナルトレーニングを受けよう~ のFuture Muscle Partnerのリポジトリ。 + +## サービスコンセプト + +パーソナルトレーナーを身近なものにして、質が高く安全で楽しいフィットネス体験を提供する。 + +![アプリを通してトレーニがトレーナに予約し、トレーニングを実施するフロー](docs/future_muscle_partner_abstract.png) + +サービス概要: + +- アプリ上でジム公認のトレーナーを検索&予約し、いきつけのジムでトレーニングを受けることができる + +主なアクターとメリット: + +- トレーニー + - 自分が通っているジムでパーソナル受けられる + - トレーナーの得意分野ごとにトレーナーを使い分けられる +- パーソナルトレーニー + - 24H型ジムでサービスを提供できる + - いつ/誰に/どんなメニューでトレーニングしたかを管理できる + +## フォルダ階層 + +```sh +. +├── backend # バックエンド系のコード +├── docs # 設計書 +├── frontend # フロントエンド系のコード +├── infra # インフラ系のコード +``` diff --git "a/documents/forMarkdown/future_muscle_partner/docs/01_\347\222\260\345\242\203\346\247\213\347\257\211/README.md" "b/documents/forMarkdown/future_muscle_partner/docs/01_\347\222\260\345\242\203\346\247\213\347\257\211/README.md" new file mode 100644 index 00000000..e69de29b diff --git "a/documents/forMarkdown/future_muscle_partner/docs/02_\351\226\213\347\231\272\350\246\217\347\264\204/README.md" "b/documents/forMarkdown/future_muscle_partner/docs/02_\351\226\213\347\231\272\350\246\217\347\264\204/README.md" new file mode 100644 index 00000000..e69de29b diff --git "a/documents/forMarkdown/future_muscle_partner/docs/03_\347\224\273\351\235\242/README.md" "b/documents/forMarkdown/future_muscle_partner/docs/03_\347\224\273\351\235\242/README.md" new file mode 100644 index 00000000..e69de29b diff --git a/documents/forMarkdown/future_muscle_partner/docs/04_WebAPI/README.md b/documents/forMarkdown/future_muscle_partner/docs/04_WebAPI/README.md new file mode 100644 index 00000000..db55472e --- /dev/null +++ b/documents/forMarkdown/future_muscle_partner/docs/04_WebAPI/README.md @@ -0,0 +1,12 @@ +# Web API設計 + +## 一覧 + + + +| ID | 機能名 | メソッド | 詳細 | +| -- | --- | --| --| +| API01 | xxxx | GET | [API01設計書](API01)| +| API02 | xxxx | GET | [API02設計書](API02)| +| API03 | xxxx | GET | [API03設計書](API03)| + diff --git a/documents/forMarkdown/future_muscle_partner/docs/04_WebAPI/openapi.yaml b/documents/forMarkdown/future_muscle_partner/docs/04_WebAPI/openapi.yaml new file mode 100644 index 00000000..d3ba51da --- /dev/null +++ b/documents/forMarkdown/future_muscle_partner/docs/04_WebAPI/openapi.yaml @@ -0,0 +1,1262 @@ +openapi: 3.0.3 +info: + title: Future Muscle Partner API + description: パーソナルトレーナーのマッチングサービスAPI + version: 1.0.0 +tags: + - name: account + description: アカウント管理 + - name: profile + description: プロフィール + - name: trainer + description: パーソナルトレーナー + - name: booking + description: 予約 + - name: review + description: レビュー + - name: payment + description: 決済 + - name: provider + description: パーソナルトレーニング提供者 +security: + - Bearer: [] +paths: + /login: + post: + tags: + - account + summary: API-001 ログイン + operationId: login + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/LoginRequest' + responses: + '200': + description: ログインに成功しました。 + '400': + $ref: '#/components/responses/BadRequest' + '500': + $ref: '#/components/responses/InternalServer' + '503': + $ref: '#/components/responses/ServiceUnavailable' + /logout: + post: + tags: + - account + summary: API-002 ログアウト + operationId: logout + security: [] + responses: + '200': + description: ログアウトに成功しました。 + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/InternalServer' + '503': + $ref: '#/components/responses/ServiceUnavailable' + /signup: + post: + tags: + - account + summary: API-003 会員登録 + operationId: signup + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/SignupRequest' + responses: + '200': + description: 会員登録に成功しました。 + '400': + $ref: '#/components/responses/BadRequest' + '500': + $ref: '#/components/responses/InternalServer' + '503': + $ref: '#/components/responses/ServiceUnavailable' + /account: + delete: + tags: + - account + summary: API-004 会員退会 + operationId: deleteAccount + responses: + '200': + description: 会員退会に成功しました。 + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '500': + $ref: '#/components/responses/InternalServer' + '503': + $ref: '#/components/responses/ServiceUnavailable' + /profile/{trainee_id}: + get: + tags: + - profile + summary: API-005 プロフィール表示 + operationId: getUserProfile + responses: + '200': + description: プロフィールの取得に成功しました。 + content: + application/json: + schema: + $ref: '#/components/schemas/Profile' + '401': + $ref: '#/components/responses/Unauthorized' + '500': + $ref: '#/components/responses/InternalServer' + '503': + $ref: '#/components/responses/ServiceUnavailable' + put: + tags: + - profile + summary: API-006 プロフィール更新 + operationId: putUserProfile + parameters: + - name: trainee_id + in: path + description: トレーニーID + required: true + schema: + type: string + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ProfileRequest' + responses: + '200': + description: プロフィールの更新に成功しました。 + '401': + $ref: '#/components/responses/Unauthorized' + '500': + $ref: '#/components/responses/InternalServer' + '503': + $ref: '#/components/responses/ServiceUnavailable' + /trainers: + get: + tags: + - trainer + summary: API-007 パーソナルトレーナー検索 + operationId: searchTrainers + security: [] + responses: + '200': + description: トレーナーの検索結果を取得しました。 + content: + application/json: + schema: + $ref: '#/components/schemas/Trainer' + '400': + $ref: '#/components/responses/BadRequest' + '500': + $ref: '#/components/responses/InternalServer' + '503': + $ref: '#/components/responses/ServiceUnavailable' + /trainers/{trainer_id}/menu: + get: + tags: + - trainer + summary: API-008 トレーニングメニュー取得 + operationId: getTrainingMenu + security: [] + parameters: + - name: trainer_id + in: path + description: トレーナーのID + required: true + schema: + type: string + responses: + '200': + description: トレーニングメニューを取得しました。 + content: + application/json: + schema: + $ref: '#/components/schemas/TrainingMenu' + '400': + $ref: '#/components/responses/BadRequest' + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/InternalServer' + '503': + $ref: '#/components/responses/ServiceUnavailable' + + /trainers/{trainer_id}/profile: + get: + tags: + - trainer + summary: API-009 トレーナープロフィール取得 + operationId: getTrainerProfile + security: [] + parameters: + - name: trainer_id + in: path + description: トレーナーのID + required: true + schema: + type: string + responses: + '200': + description: トレーナープロフィールを取得しました。 + content: + application/json: + schema: + $ref: '#/components/schemas/Trainer' + '400': + $ref: '#/components/responses/BadRequest' + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/InternalServer' + '503': + $ref: '#/components/responses/ServiceUnavailable' + /trainers/{trainer_id}/reviews: + get: + tags: + - trainer + summary: API-010 トレーナー口コミ取得 + operationId: getTrainerReviews + security: [] + parameters: + - name: trainer_id + in: path + description: トレーナーのID + required: true + schema: + type: string + responses: + '200': + description: トレーナーの口コミを取得しました。 + content: + application/json: + schema: + $ref: '#/components/schemas/Review' + '400': + $ref: '#/components/responses/BadRequest' + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/InternalServer' + '503': + $ref: '#/components/responses/ServiceUnavailable' + /trainers/{trainer_id}/schedule: + get: + tags: + - trainer + summary: API-011 トレーナースケジュール取得 + operationId: getTrainerSchedule + security: [] + parameters: + - name: trainer_id + in: path + description: トレーナーのID + required: true + schema: + type: string + responses: + '200': + description: トレーナーのスケジュールを取得しました。 + content: + application/json: + schema: + $ref: '#/components/schemas/TrainerSchedule' + '400': + $ref: '#/components/responses/BadRequest' + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/InternalServer' + '503': + $ref: '#/components/responses/ServiceUnavailable' + /bookings: + post: + tags: + - booking + summary: API-013 トレーニング予約(仮登録) + operationId: bookTraining + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/BookingRequest' + responses: + '200': + description: 予約が仮登録されました。 + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '409': + $ref: '#/components/responses/Conflict' + '422': + $ref: '#/components/responses/UnprocessableEntity' + '500': + $ref: '#/components/responses/InternalServer' + '503': + $ref: '#/components/responses/ServiceUnavailable' + /bookings/{trainee_id}: + get: + tags: + - booking + summary: API-012 予約済みトレーニング取得 + operationId: getBookings + responses: + '200': + description: ユーザーの予約情報を取得しました。 + content: + application/json: + schema: + $ref: '#/components/schemas/Booking' + '401': + $ref: '#/components/responses/Unauthorized' + '500': + $ref: '#/components/responses/InternalServer' + '503': + $ref: '#/components/responses/ServiceUnavailable' + /bookings/{booking_id}: + delete: + tags: + - booking + summary: API-014 トレーニング予約削除 + operationId: deleteBooking + parameters: + - name: booking_id + in: path + description: 予約ID + required: true + schema: + type: string + responses: + '200': + description: 予約が削除されました。 + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/InternalServer' + '503': + $ref: '#/components/responses/ServiceUnavailable' + /bookings/{booking_id}/confirm: + post: + tags: + - booking + summary: API-015 トレーニング予約(本登録) + operationId: confirmBooking + parameters: + - name: booking_id + in: path + description: 予約ID + required: true + schema: + type: string + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/BookingConfirmationRequest' + responses: + '200': + description: 予約が本登録されました。 + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '409': + $ref: '#/components/responses/Conflict' + '422': + $ref: '#/components/responses/UnprocessableEntity' + '500': + $ref: '#/components/responses/InternalServer' + '503': + $ref: '#/components/responses/ServiceUnavailable' + /booking/{booking_id}/status: + put: + tags: + - booking + summary: API-016 トレーニング受講ステータス変更 + operationId: updateTrainingStatus + parameters: + - name: booking_id + in: path + description: 予約ID + required: true + schema: + type: string + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/TrainingStatusUpdateRequest' + responses: + '200': + description: ステータスが更新されました。 + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + '409': + $ref: '#/components/responses/Conflict' + '422': + $ref: '#/components/responses/UnprocessableEntity' + '500': + $ref: '#/components/responses/InternalServer' + '503': + $ref: '#/components/responses/ServiceUnavailable' + /payment: + post: + tags: + - payment + summary: API-017 決済 + operationId: makePayment + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/PaymentRequest' + responses: + '200': + description: 決済が完了しました。 + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '409': + $ref: '#/components/responses/Conflict' + '422': + $ref: '#/components/responses/UnprocessableEntity' + '500': + $ref: '#/components/responses/InternalServer' + '503': + $ref: '#/components/responses/ServiceUnavailable' + /reviews: + post: + tags: + - review + summary: API-018 口コミ登録 + operationId: postReview + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ReviewRequest' + responses: + '200': + description: 口コミ登録成功 + /reviews/{review_id}: + put: + tags: + - review + summary: API-019 口コミ修正 + operationId: putReview + parameters: + - name: review_id + in: path + description: レビューID + required: true + schema: + type: string + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ReviewUpdateRequest' + responses: + '200': + description: 口コミ修正成功 + delete: + tags: + - review + summary: API-020 口コミ削除 + operationId: deleteReview + parameters: + - name: review_id + in: path + description: 口コミID + required: true + schema: + type: string + responses: + '200': + description: 口コミ削除成功 + /trainer: + post: + tags: + - provider + summary: API-021 トレーナー登録 + operationId: postTrainer + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Trainer' + responses: + '200': + description: トレーナー登録成功 + put: + tags: + - provider + summary: API-022 トレーナー属性更新 + operationId: putTrainer + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Trainer' + responses: + '200': + description: トレーナー属性更新成功 + /training-menus: + post: + tags: + - provider + summary: API-023 トレーニングメニュー登録 + operationId: postTrainingMenu + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/TrainingMenu' + responses: + '200': + description: トレーニングメニュー登録成功 + /training-menus/{menu_id}: + put: + tags: + - provider + summary: API-024 トレーニングメニュー更新 + operationId: putTrainingMenu + parameters: + - name: menu_id + in: path + description: メニューID + required: true + schema: + type: integer + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/TrainingMenu' + responses: + '200': + description: トレーニングメニュー更新成功 + delete: + tags: + - provider + summary: API-025 トレーニングメニュー削除 + operationId: deleteTrainingMenu + parameters: + - name: menu_id + in: path + description: メニューID + required: true + schema: + type: integer + responses: + '200': + description: トレーニングメニュー削除成功 + +components: + schemas: + ProblemDetailError: + description: A Problem Details object (RFC 9457) + type: object + properties: + title: + type: string + description: A short summary of the problem type. Written in English and readable for engineers (usually not suited for non technical stakeholders and not localized). + example: Service Unavailable + status: + type: integer + format: int32 + description: The HTTP status code generated by the origin server for this occurrence of the problem. + minimum: 400 + maximum: 600 + exclusiveMaximum: true + example: 503 + detail: + type: string + description: A human-readable explanation specific to this occurrence of the problem + example: + title: Description of the type of problem that occurred + status: 400 # HTTP response status, appropriate for the problem type + detail: Description of specific occurrence of the problem + + LoginRequest: + type: object + properties: + email: + type: string + format: email + description: メールアドレス + password: + type: string + format: password + description: パスワード + SignupRequest: + type: object + properties: + email: + type: string + format: email + description: メールアドレス + password: + type: string + format: password + description: パスワード + name: + type: string + description: 名前 + ProfileRequest: + type: object + properties: + trainee_name: + type: string + description: トレーニー名 + display_name: + type: string + description: 表示名 + self_introduction: + type: string + description: 自己紹介 + PaymentRequest: + type: object + properties: + amount: + type: number + format: double + description: 支払金額 + method: + type: string + description: 支払方法 + BookingRequest: + type: object + properties: + menu_id: + type: string + description: トレーニングメニューのID + booking_status_typ: + type: string + enum: ["0"] + description: | + 予約ステータス区分 + 0: 仮登録 + trainee_id: + type: string + description: トレーニーID + training_start_at: + type: string + format: date + description: トレーニング開始日時 + training_end_at: + type: string + format: date + description: トレーニング終了日時 + BookingConfirmationRequest: + type: object + properties: + booking_status_typ: + type: string + enum: ["1"] + description: | + 予約ステータス区分 + 1: 本登録 + TrainingStatusUpdateRequest: + type: object + properties: + booking_status_typ: + type: string + enum: ["2", "3"] + description: | + 予約ステータス区分 + 2: 受講中 + 3: 受講済み + ReviewRequest: + type: object + properties: + trainer_id: + type: string + description: トレーナーID + trainee_id: + type: string + description: トレー二ーID + comment: + type: string + description: レビューコメント + ReviewUpdateRequest: + type: object + properties: + review_id: + type: string + description: レビューID + comment: + type: string + description: レビューコメント + Profile: + type: object + properties: + trainee_id: + type: string + description: トレーニーID + trainee_name: + type: string + description: トレーニー名 + display_name: + type: string + description: 表示名 + self_introduction: + type: string + description: 自己紹介 + Booking: + type: object + properties: + booking_id: + type: string + description: 予約ID + menu_id: + type: string + description: トレーニングメニューのID + trainer_id: + type: string + description: トレーナーのID + display_order: + type: string + description: 表示順序 + menu_name: + type: string + description: メニュー名 + menu_description: + type: string + description: メニュー説明 + required_time: + type: integer + description: 所要時間 + price: + type: integer + description: 料金 + start_at: + type: string + format: date + description: 開始日時 + end_at: + type: string + format: date + description: 終了日時 + training_start_at: + type: string + format: date + description: トレーニング開始日時 + training_end_at: + type: string + format: date + description: トレーニング終了日時 + Trainer: + type: object + properties: + trainer_id: + type: string + description: トレーナーID + trainer_name: + type: string + description: トレーナー名 + unit_price: + type: integer + description: 単価 + business_start_at: + type: string + format: date + description: 営業開始時間 + business_end_at: + type: string + format: date + description: 営業終了時間 + public_mail_addr: + type: string + format: email + description: 公開メールアドレス + public_tel: + type: string + description: 公開電話番号 + store_name: + type: string + description: 店舗名 + gym_name: + type: string + description: ジム名 + TrainerSchedule: + type: object + properties: + trainer_id: + type: string + description: トレーナーID + trainer_name: + type: string + description: トレーナー名 + date: + type: string + format: date + description: 日付け + booking_typ_0000: + type: string + enum: ["0", "1"] + description: | + 予約区分 00:00-00:30 + 0: 未予約 + 1: 予約済み + booking_typ_0030: + type: string + enum: ["0", "1"] + description: | + 予約区分 00:30-01:00 + 0: 未予約 + 1: 予約済み + booking_typ_0100: + type: string + enum: ["0", "1"] + description: | + 予約区分 01:00-01:30 + 0: 未予約 + 1: 予約済み + booking_typ_0130: + type: string + enum: ["0", "1"] + description: | + 予約区分 01:30-02:00 + 0: 未予約 + 1: 予約済み + booking_typ_0200: + type: string + enum: ["0", "1"] + description: | + 予約区分 02:00-02:30 + 0: 未予約 + 1: 予約済み + booking_typ_0230: + type: string + enum: ["0", "1"] + description: | + 予約区分 02:30-03:00 + 0: 未予約 + 1: 予約済み + booking_typ_0300: + type: string + description: | + 予約区分 03:00-03:30 + 0: 未予約 + 1: 予約済み + booking_typ_0330: + type: string + enum: ["0", "1"] + description: | + 予約区分 03:30-04:00 + 0: 未予約 + 1: 予約済み + booking_typ_0400: + type: string + enum: ["0", "1"] + description: | + 予約区分 04:00-04:30 + 0: 未予約 + 1: 予約済み + booking_typ_0430: + type: string + enum: ["0", "1"] + description: | + 予約区分 04:30-05:00 + 0: 未予約 + 1: 予約済み + booking_typ_0500: + type: string + enum: ["0", "1"] + description: | + 予約区分 05:00-05:30 + 0: 未予約 + 1: 予約済み + booking_typ_0530: + type: string + enum: ["0", "1"] + description: | + 予約区分 05:30-06:00 + 0: 未予約 + 1: 予約済み + booking_typ_0600: + type: string + description: | + 予約区分 06:00-06:30 + 0: 未予約 + 1: 予約済み + booking_typ_0630: + type: string + enum: ["0", "1"] + description: | + 予約区分 06:30-07:00 + 0: 未予約 + 1: 予約済み + booking_typ_0700: + type: string + enum: ["0", "1"] + description: | + 予約区分 07:00-07:30 + 0: 未予約 + 1: 予約済み + booking_typ_0730: + type: string + enum: ["0", "1"] + description: | + 予約区分 07:30-08:00 + 0: 未予約 + 1: 予約済み + booking_typ_0800: + type: string + enum: ["0", "1"] + description: | + 予約区分 08:00-08:30 + 0: 未予約 + 1: 予約済み + booking_typ_0830: + type: string + enum: ["0", "1"] + description: | + 予約区分 08:30-09:00 + 0: 未予約 + 1: 予約済み + booking_typ_0900: + type: string + enum: ["0", "1"] + description: | + 予約区分 09:00-09:30 + 0: 未予約 + 1: 予約済み + booking_typ_0930: + type: string + enum: ["0", "1"] + description: | + 予約区分 09:30-10:00 + 0: 未予約 + 1: 予約済み + booking_typ_1000: + type: string + enum: ["0", "1"] + description: | + 予約区分 10:00-10:30 + 0: 未予約 + 1: 予約済み + booking_typ_1030: + type: string + enum: ["0", "1"] + description: | + 予約区分 10:30-11:00 + 0: 未予約 + 1: 予約済み + booking_typ_1100: + type: string + enum: ["0", "1"] + description: | + 予約区分 11:00-11:30 + 0: 未予約 + 1: 予約済み + booking_typ_1130: + type: string + enum: ["0", "1"] + description: | + 予約区分 11:30-12:00 + 0: 未予約 + 1: 予約済み + booking_typ_1200: + type: string + enum: ["0", "1"] + description: | + 予約区分 12:00-12:30 + 0: 未予約 + 1: 予約済み + booking_typ_1230: + type: string + enum: ["0", "1"] + description: | + 予約区分 12:30-13:00 + 0: 未予約 + 1: 予約済み + booking_typ_1300: + type: string + enum: ["0", "1"] + description: | + 予約区分 13:00-13:30 + 0: 未予約 + 1: 予約済み + booking_typ_1330: + type: string + enum: ["0", "1"] + description: | + 予約区分 13:30-14:00 + 0: 未予約 + 1: 予約済み + booking_typ_1400: + type: string + enum: ["0", "1"] + description: | + 予約区分 14:00-14:30 + 0: 未予約 + 1: 予約済み + booking_typ_1430: + type: string + enum: ["0", "1"] + description: | + 予約区分 14:30-15:00 + 0: 未予約 + 1: 予約済み + booking_typ_1500: + type: string + enum: ["0", "1"] + description: | + 予約区分 15:00-15:30 + 0: 未予約 + 1: 予約済み + booking_typ_1530: + type: string + enum: ["0", "1"] + description: | + 予約区分 15:30-16:00 + 0: 未予約 + 1: 予約済み + booking_typ_1600: + type: string + enum: ["0", "1"] + description: | + 予約区分 16:00-16:30 + 0: 未予約 + 1: 予約済み + booking_typ_1630: + type: string + enum: ["0", "1"] + description: | + 予約区分 16:30-17:00 + 0: 未予約 + 1: 予約済み + booking_typ_1700: + type: string + enum: ["0", "1"] + description: | + 予約区分 17:00-17:30 + 0: 未予約 + 1: 予約済み + booking_typ_1730: + type: string + enum: ["0", "1"] + description: | + 予約区分 17:30-18:00 + 0: 未予約 + 1: 予約済み + booking_typ_1800: + type: string + enum: ["0", "1"] + description: | + 予約区分 18:00-18:30 + 0: 未予約 + 1: 予約済み + booking_typ_1830: + type: string + enum: ["0", "1"] + description: | + 予約区分 18:30-19:00 + 0: 未予約 + 1: 予約済み + booking_typ_1900: + type: string + enum: ["0", "1"] + description: | + 予約区分 19:00-19:30 + 0: 未予約 + 1: 予約済み + booking_typ_1930: + type: string + description: | + 予約区分 19:30-20:00 + 0: 未予約 + 1: 予約済み + booking_typ_2000: + type: string + enum: ["0", "1"] + description: | + 予約区分 20:00-20:30 + 0: 未予約 + 1: 予約済み + booking_typ_2030: + type: string + enum: ["0", "1"] + description: | + 予約区分 20:30-21:00 + 0: 未予約 + 1: 予約済み + booking_typ_2100: + type: string + enum: ["0", "1"] + description: | + 予約区分 21:00-21:30 + 0: 未予約 + 1: 予約済み + booking_typ_2130: + type: string + enum: ["0", "1"] + description: | + 予約区分 21:30-22:00 + 0: 未予約 + 1: 予約済み + booking_typ_2200: + type: string + enum: ["0", "1"] + description: | + 予約区分 22:00-22:30 + 0: 未予約 + 1: 予約済み + booking_typ_2230: + type: string + enum: ["0", "1"] + description: | + 予約区分 22:30-23:00 + 0: 未予約 + 1: 予約済み + booking_typ_2300: + type: string + enum: ["0", "1"] + description: | + 予約区分 23:00-23:30 + 0: 未予約 + 1: 予約済み + booking_typ_2330: + type: string + enum: ["0", "1"] + description: | + 予約区分 23:30-24:00 + 0: 未予約 + 1: 予約済み + TrainingMenu: + type: object + properties: + menu_id: + type: string + trainer_id: + type: string + description: トレーナーID + display_order: + type: string + description: 表示順序 + menu_name: + type: string + description: メニュー名 + menu_description: + type: string + description: メニュー説明 + required_time: + type: integer + description: 所要時間 + price: + type: integer + description: 料金 + Review: + type: object + properties: + review_id: + type: string + description: レビューID + display_name: + type: string + description: トレーニーの表示名 + trainer_name: + type: string + description: トレーナー名 + comment: + type: string + description: レビューコメント + posted_at: + type: string + format: date + description: 投稿日時 + responses: + BadRequest: + description: 400 Bad Request + content: + application/json: + schema: + $ref: "#/components/schemas/ProblemDetailError" + Unauthorized: + description: 401 Unauthorized + content: + application/json: + schema: + $ref: "#/components/schemas/ProblemDetailError" + Forbidden: + description: 403 Forbidden + content: + application/json: + schema: + $ref: "#/components/schemas/ProblemDetailError" + NotFound: + description: 404 Not Found + content: + application/json: + schema: + $ref: "#/components/schemas/ProblemDetailError" + Conflict: + description: 409 Conflict + content: + application/json: + schema: + $ref: "#/components/schemas/ProblemDetailError" + UnprocessableEntity: + description: 422 Unprocessable Content + content: + application/json: + schema: + $ref: "#/components/schemas/ProblemDetailError" + InternalServer: + description: 500 Internal Server + content: + application/json: + schema: + $ref: "#/components/schemas/ProblemDetailError" + ServiceUnavailable: + description: 503 Service Unavailable + content: + application/json: + schema: + $ref: "#/components/schemas/ProblemDetailError" + securitySchemes: + Bearer: + type: http + scheme: bearer + bearerFormat: JWT + description: 'Bearer トークン認証' diff --git "a/documents/forMarkdown/future_muscle_partner/docs/05_\343\203\207\343\203\274\343\202\277/README.md" "b/documents/forMarkdown/future_muscle_partner/docs/05_\343\203\207\343\203\274\343\202\277/README.md" new file mode 100644 index 00000000..e69de29b diff --git "a/documents/forMarkdown/future_muscle_partner/docs/05_\343\203\207\343\203\274\343\202\277/erd.a5er" "b/documents/forMarkdown/future_muscle_partner/docs/05_\343\203\207\343\203\274\343\202\277/erd.a5er" new file mode 100644 index 00000000..bce2a89f --- /dev/null +++ "b/documents/forMarkdown/future_muscle_partner/docs/05_\343\203\207\343\203\274\343\202\277/erd.a5er" @@ -0,0 +1,429 @@ +# A5:ER FORMAT:18 +# A5:ER ENCODING:UTF8 +# A5:ER Mk-1 Copyright © 2007 m.matsubara +# A5:SQL Mk-2 Version 2.19.2 Copyright © 1997 - 2024 m.matsubara +# https://a5m2.mmatsubara.com + +[Manager] +ProjectName=フューチャーマッスルパートナー +Author= +MaxEntityRowShow=1000 +ReadOnlyRecommend=0 +Page=Main +PageInfo="Main",2,"A3Landscape",$FFFFFF +LogicalView=1 +DecodeDomain=0 +ViewModePageIndividually=1 +ViewMode=2 +ViewFormat=0 +UseNondependenceDashLine=0 +FontName=Tahoma +FontSize=6 +PaperSize=A4Landscape +HeaderLeft= +HeaderCenter= +HeaderRight= +FooterLeft= +FooterCenter= +FooterRight= +ShowPageoutRelation=1 +RDBMSTypeName=Oracle Database +DefaultPkName=%0:s_PKC +DefaultPkIndexName=%0:s_PKI +DefaultIndexName=%0:s_IX%1:d +DefaultFkName=%0:s_FK%1:d +SqlSeparator=0 +UpperCaseKeyword=0 +ShowTag=1 +ShowCommonAttributes=0 +BugFixEntityWidth=1 + +[Entity] +PName=trainee +LName=トレーニー +Comment= +TableInnerOption= +TableOption= +Page=MAIN +Left=900 +Top=400 +Field="トレーニーID","trainee_id","",,,"","",$FFFFFFFF,"" +Field="トレーニー名","trainee_name","",,,"","",$FFFFFFFF,"" +Field="表示氏名","display_name","",,,"","",$FFFFFFFF,"" +Field="自己紹介","self_introduction","",,,"","",$FFFFFFFF,"" +EffectMode=None +Color=$000000 +BkColor=$FFFFFF +ModifiedDateTime=20240711124838 +Position="MAIN",900,400,254,275 +ZOrder=1 + +[Entity] +PName=booking +LName=予約 +Comment= +TableInnerOption= +TableOption= +Page=MAIN +Left=1100 +Top=950 +Field="予約ID","booking_id","",,,"","",$FFFFFFFF,"" +Field="メニューID","menu_id","",,,"","",$FFFFFFFF,"" +Field="トレーニーID","trainee_id","",,,"","",$FFFFFFFF,"" +Field="開始日時","start_at","",,,"","",$FFFFFFFF,"" +Field="終了日時","end_at","",,,"","",$FFFFFFFF,"" +Field="予約ステータス区分","booking_status_typ","",,,"","",$FFFFFFFF,"" +Field="予約受付日時","booking_reception_at","",,,"","",$FFFFFFFF,"" +Field="トレーニング開始日時","training_start_at","",,,"","",$FFFFFFFF,"" +Field="トレーニング終了日時","training_end_at","",,,"","",$FFFFFFFF,"" +EffectMode=None +Color=$000000 +BkColor=$FFFFFF +ModifiedDateTime=20240419165003 +Position="MAIN",1100,950,283,349 +ZOrder=2 + +[Entity] +PName=menu +LName=メニュー +Comment= +TableInnerOption= +TableOption= +Page=MAIN +Left=1300 +Top=400 +Field="メニューID","menu_id","",,,"","",$FFFFFFFF,"" +Field="トレーナーID","trainer_id","",,,"","",$FFFFFFFF,"" +Field="表示順序","display_order","",,,"","",$FFFFFFFF,"" +Field="メニュー名","menu_name","",,,"","",$FFFFFFFF,"" +Field="メニュー説明","menu_description","",,,"","",$FFFFFFFF,"" +Field="所要時間","required_time","",,,"","",$FFFFFFFF,"" +Field="料金","price","",,,"","",$FFFFFFFF,"" +EffectMode=None +Color=$000000 +BkColor=$FFFFFF +ModifiedDateTime=20240711142913 +Position="MAIN",1300,400,238,333 +ZOrder=3 + +[Entity] +PName=trainer +LName=トレーナー +Comment= +TableInnerOption= +TableOption= +Page=MAIN +Left=1650 +Top=400 +Field="トレーナーID","trainer_id","",,,"","",$FFFFFFFF,"" +Field="トレーナー名","trainer_name","",,,"","",$FFFFFFFF,"" +Field="単価","unit_price","",,,"","",$FFFFFFFF,"" +Field="営業開始時間","business_start_at","",,,"","",$FFFFFFFF,"" +Field="営業終了時間","business_end_at","",,,"","",$FFFFFFFF,"" +Field="公開メールアドレス","public_mail_addr","",,,"","",$FFFFFFFF,"" +Field="公開電話番号","public_tel","",,,"","",$FFFFFFFF,"" +EffectMode=None +Color=$000000 +BkColor=$FFFFFF +ModifiedDateTime=20240711124858 +Position="MAIN",1650,400,426,296 +ZOrder=4 + +[Entity] +PName=calendar +LName=カレンダー +Comment= +TableInnerOption= +TableOption= +Page=MAIN +Left=1650 +Top=850 +Field="トレーナーID","trainer_id","",,,"","",$FFFFFFFF,"" +Field="日付","date","",,,"","",$FFFFFFFF,"" +Field="予約区分0000","booking_typ_0000","",,,"","",$FFFFFFFF,"" +Field="予約区分0030","予約区分0030","",,,"","",$FFFFFFFF,"" +Field="予約区分0100","予約区分0100","",,,"","",$FFFFFFFF,"" +Field="予約区分0130","予約区分0130","",,,"","",$FFFFFFFF,"" +Field="予約区分0200","予約区分0200","",,,"","",$FFFFFFFF,"" +Field="予約区分0230","予約区分0230","",,,"","",$FFFFFFFF,"" +Field="予約区分0300","予約区分0300","",,,"","",$FFFFFFFF,"" +Field="予約区分0330","予約区分0330","",,,"","",$FFFFFFFF,"" +Field="予約区分0400","予約区分0400","",,,"","",$FFFFFFFF,"" +Field="予約区分0430","予約区分0430","",,,"","",$FFFFFFFF,"" +Field="予約区分0500","予約区分0500","",,,"","",$FFFFFFFF,"" +Field="予約区分0530","予約区分0530","",,,"","",$FFFFFFFF,"" +Field="予約区分0600","予約区分0600","",,,"","",$FFFFFFFF,"" +Field="予約区分0630","予約区分0630","",,,"","",$FFFFFFFF,"" +Field="予約区分0700","予約区分0700","",,,"","",$FFFFFFFF,"" +Field="予約区分0730","予約区分0730","",,,"","",$FFFFFFFF,"" +Field="予約区分0800","予約区分0800","",,,"","",$FFFFFFFF,"" +Field="予約区分0830","予約区分0830","",,,"","",$FFFFFFFF,"" +Field="予約区分0900","予約区分0900","",,,"","",$FFFFFFFF,"" +Field="予約区分0930","予約区分0930","",,,"","",$FFFFFFFF,"" +Field="予約区分1000","予約区分1000","",,,"","",$FFFFFFFF,"" +Field="予約区分1030","予約区分1030","",,,"","",$FFFFFFFF,"" +Field="予約区分1100","予約区分1100","",,,"","",$FFFFFFFF,"" +Field="予約区分1130","予約区分1130","",,,"","",$FFFFFFFF,"" +Field="予約区分1200","予約区分1200","",,,"","",$FFFFFFFF,"" +Field="予約区分1230","予約区分1230","",,,"","",$FFFFFFFF,"" +Field="予約区分1300","予約区分1300","",,,"","",$FFFFFFFF,"" +Field="予約区分1330","予約区分1330","",,,"","",$FFFFFFFF,"" +Field="予約区分1400","予約区分1400","",,,"","",$FFFFFFFF,"" +Field="予約区分1430","予約区分1430","",,,"","",$FFFFFFFF,"" +Field="予約区分1500","予約区分1500","",,,"","",$FFFFFFFF,"" +Field="予約区分1530","予約区分1530","",,,"","",$FFFFFFFF,"" +Field="予約区分1600","予約区分1600","",,,"","",$FFFFFFFF,"" +Field="予約区分1630","予約区分1630","",,,"","",$FFFFFFFF,"" +Field="予約区分1700","予約区分1700","",,,"","",$FFFFFFFF,"" +Field="予約区分1730","予約区分1730","",,,"","",$FFFFFFFF,"" +Field="予約区分1800","予約区分1800","",,,"","",$FFFFFFFF,"" +Field="予約区分1830","予約区分1830","",,,"","",$FFFFFFFF,"" +Field="予約区分1900","予約区分1900","",,,"","",$FFFFFFFF,"" +Field="予約区分1930","予約区分1930","",,,"","",$FFFFFFFF,"" +Field="予約区分2000","予約区分2000","",,,"","",$FFFFFFFF,"" +Field="予約区分2030","予約区分2030","",,,"","",$FFFFFFFF,"" +Field="予約区分2100","予約区分2100","",,,"","",$FFFFFFFF,"" +Field="予約区分2130","予約区分2130","",,,"","",$FFFFFFFF,"" +Field="予約区分2200","予約区分2200","",,,"","",$FFFFFFFF,"" +Field="予約区分2230","予約区分2230","",,,"","",$FFFFFFFF,"" +Field="予約区分2300","予約区分2300","",,,"","",$FFFFFFFF,"" +Field="予約区分2330","予約区分2330","",,,"","",$FFFFFFFF,"" +EffectMode=None +Color=$000000 +BkColor=$FFFFFF +ModifiedDateTime=20240419162555 +Position="MAIN",1650,850 +ZOrder=5 + +[Entity] +PName=trainer_workspace +LName=トレーナー勤務先 +Comment= +TableInnerOption= +TableOption= +Page=MAIN +Left=2200 +Top=450 +Field="トレーナーID","trainer_id","",,,"","",$FFFFFFFF,"" +Field="店舗ID","store_id","",,,"","",$FFFFFFFF,"" +Field="店舗名","store_name","",,,"","",$FFFFFFFF,"" +Field="ジムID","gym_id","",,,"","",$FFFFFFFF,"" +EffectMode=None +Color=$000000 +BkColor=$FFFFFF +ModifiedDateTime=20240419163344 +Position="MAIN",2200,450 +ZOrder=6 + +[Entity] +PName=gym +LName=ジム +Comment= +TableInnerOption= +TableOption= +Page=MAIN +Left=2350 +Top=200 +Field="ジムID","gym_id","",,,"","",$FFFFFFFF,"" +Field="ジム名","ジム名","",,,"","",$FFFFFFFF,"" +EffectMode=None +Color=$000000 +BkColor=$FFFFFF +ModifiedDateTime=20240419163332 +Position="MAIN",2350,200 +ZOrder=7 + +[Relation] +Entity1=trainee +Entity2=booking +RelationType1=2 +RelationType2=3 +Fields1= +Fields2= +Cardinarity1= +Cardinarity2= +Position="MAIN",0,4131,5869,3628,R,R,"" +Dependence=1 +Caption= +PName= +ModifiedDateTime=20240419165039 +LineMode=0 +Bar1=413 +Bar2=587 +Bar3=363 +TermPos1=R +TermPos2=R +ZOrder=8 + +[Relation] +Entity1=trainer +Entity2=menu +RelationType1=2 +RelationType2=3 +Fields1= +Fields2= +Cardinarity1= +Cardinarity2= +Position="MAIN",0,4675,5325,2864,R,R,"" +Dependence=1 +Caption= +PName= +ModifiedDateTime=20240419165118 +LineMode=0 +Bar1=468 +Bar2=532 +Bar3=286 +TermPos1=R +TermPos2=R +ZOrder=9 + +[Relation] +Entity1=menu +Entity2=booking +RelationType1=2 +RelationType2=3 +Fields1= +Fields2= +Cardinarity1= +Cardinarity2= +Position="MAIN",0,5580,4420,4675,R,R,"" +Dependence=1 +Caption= +PName= +ModifiedDateTime=20240419165146 +LineMode=0 +Bar1=558 +Bar2=442 +Bar3=468 +TermPos1=R +TermPos2=R +ZOrder=10 + +[Relation] +Entity1=trainer +Entity2=calendar +RelationType1=2 +RelationType2=3 +Fields1= +Fields2= +Cardinarity1= +Cardinarity2= +Position="MAIN",0,7800,2200,7644,R,R,"" +Dependence=1 +Caption= +PName= +ModifiedDateTime=20240419165237 +LineMode=0 +Bar1=780 +Bar2=220 +Bar3=764 +TermPos1=R +TermPos2=R +ZOrder=11 + +[Relation] +Entity1=trainer_workspace +Entity2=gym +RelationType1=3 +RelationType2=2 +Fields1= +Fields2= +Cardinarity1= +Cardinarity2= +Position="MAIN",0,4440,5560,4238,R,R,"" +Dependence=0 +Caption= +PName= +ModifiedDateTime=20240419165300 +LineMode=0 +Bar1=444 +Bar2=556 +Bar3=424 +TermPos1=R +TermPos2=R +ZOrder=12 + +[Relation] +Entity1=trainer +Entity2=trainer_workspace +RelationType1=2 +RelationType2=3 +Fields1= +Fields2= +Cardinarity1= +Cardinarity2= +Position="MAIN",0,4585,5415,2851,R,R,"" +Dependence=1 +Caption= +PName= +ModifiedDateTime=20240419165327 +LineMode=0 +Bar1=458 +Bar2=542 +Bar3=285 +TermPos1=R +TermPos2=R +ZOrder=13 + +[Entity] +PName=review +LName=レビュー +Comment= +TableInnerOption= +TableOption= +Page=MAIN +Left=1650 +Top=100 +Field="レビューID","review_id","",,,"","",$FFFFFFFF,"" +Field="トレーナーID","trainer_id","",,,"","",$FFFFFFFF,"" +Field="トレーニーID","トレーニーID","",,,"","",$FFFFFFFF,"" +Field="コメント","comment","",,,"","",$FFFFFFFF,"" +Field="投稿日時","posted_at","",,,"","",$FFFFFFFF,"" +EffectMode=None +Color=$000000 +BkColor=$FFFFFF +ModifiedDateTime=20240711123631 +Position="MAIN",1650,100,132,141 +ZOrder=14 + +[Relation] +Entity1=trainee +Entity2=review +RelationType1=1 +RelationType2=3 +Fields1= +Fields2= +Cardinarity1= +Cardinarity2= +Position="MAIN",0,1183,1379,2885,R,R,"" +Dependence=1 +Caption= +PName= +LineMode=0 +Bar1=118 +Bar2=138 +Bar3=288 +TermPos1=R +TermPos2=R +ZOrder=17 + +[Relation] +Entity1=trainer +Entity2=review +RelationType1=1 +RelationType2=3 +Fields1= +Fields2= +Cardinarity1= +Cardinarity2= +Position="MAIN",0,6333,4889,5822,R,R,"" +Dependence=1 +Caption= +PName= +LineMode=0 +Bar1=633 +Bar2=489 +Bar3=582 +TermPos1=R +TermPos2=R +ZOrder=18 diff --git a/documents/forMarkdown/future_muscle_partner/docs/06_IF/README.md b/documents/forMarkdown/future_muscle_partner/docs/06_IF/README.md new file mode 100644 index 00000000..e69de29b diff --git "a/documents/forMarkdown/future_muscle_partner/docs/07_\343\203\220\343\203\203\343\203\201/README.md" "b/documents/forMarkdown/future_muscle_partner/docs/07_\343\203\220\343\203\203\343\203\201/README.md" new file mode 100644 index 00000000..e69de29b diff --git "a/documents/forMarkdown/future_muscle_partner/docs/08_\345\270\263\347\245\250/README.md" "b/documents/forMarkdown/future_muscle_partner/docs/08_\345\270\263\347\245\250/README.md" new file mode 100644 index 00000000..e69de29b diff --git "a/documents/forMarkdown/future_muscle_partner/docs/09_\343\202\244\343\203\263\343\203\225\343\203\251/README.md" "b/documents/forMarkdown/future_muscle_partner/docs/09_\343\202\244\343\203\263\343\203\225\343\203\251/README.md" new file mode 100644 index 00000000..e69de29b diff --git a/documents/forMarkdown/future_muscle_partner/docs/README.md b/documents/forMarkdown/future_muscle_partner/docs/README.md new file mode 100644 index 00000000..93ccb882 --- /dev/null +++ b/documents/forMarkdown/future_muscle_partner/docs/README.md @@ -0,0 +1,20 @@ +# docs + +設計書を管理する。 + +## フォルダ階層 + +```sh +docs +├── 01_環境構築 # 開発環境の構築手順 +├── 02_開発規約 # 開発ガイドライン、リリース手順など +├── 03_画面 # Figma、画面アクション +├── 04_WebAPI # api.yaml、API処理設計 +├── 05_データ # ERD、区分値 +├── 06_IF # I/F定義+受信/送信BL設計 +├── 07_バッチ # タイマー、イベント起動の非同期処理のBL設計 +├── 08_帳票 # 業務、システム担当者向けのレポート +├── 09_インフラ # ネットワーク設計、監視設計、通知設計、システム構成図、サービス構成図 +├── ... +└── README.md +``` diff --git a/documents/forMarkdown/future_muscle_partner/docs/future_muscle_partner_abstract.png b/documents/forMarkdown/future_muscle_partner/docs/future_muscle_partner_abstract.png new file mode 100644 index 00000000..2f816600 Binary files /dev/null and b/documents/forMarkdown/future_muscle_partner/docs/future_muscle_partner_abstract.png differ diff --git "a/documents/forMarkdown/\343\203\227\343\203\255\343\202\260\343\203\251\343\203\240\350\250\255\350\250\210\346\233\270.md" "b/documents/forMarkdown/\343\203\227\343\203\255\343\202\260\343\203\251\343\203\240\350\250\255\350\250\210\346\233\270.md" new file mode 100644 index 00000000..710aa1c1 --- /dev/null +++ "b/documents/forMarkdown/\343\203\227\343\203\255\343\202\260\343\203\251\343\203\240\350\250\255\350\250\210\346\233\270.md" @@ -0,0 +1,66 @@ +# BAT01 xxx 計算 + +## 処理概要 + +- xxx(なぜこれが必要なのか) +- xxx受信の後続処理で起動し、xxx計算を行いxxxトランに登録する(処理の概略) + +## 処理シーケンス + +```plantuml +@startuml +!theme toy + +participant システム +database DB + +note over システム: 各種インプット取得 + +システム -> DB: 業務日付取得 [日付マスタ] +システム -> DB: 計算対象抽出xxx\n[xxx受信管理トラン]\n[xxx受信ワーク]\n[xxxマスタ]\n[yyyマスタ]\n[zzzマスタ] +システム -> システム: 支払い差し引き金額計算(※ビジネスロジック1) +システム -> DB: 登録\n[xxxトラン] +システム -> DB: 更新\n[xxx予測ワーク] + +@enduml +``` + +## ビジネスロジック + +### ビジネスロジック1 + +```txt +支払金額 = 受信ワーク.商品コード * xxx * xxx - yyyy + +IF xxx 区分 + 支払金額 = 支払金額 * 支払い係数 + (支払金額 - 前回発注金額)/2 +END +``` + +## DB 項目 + +### 取得 + +- xxxマスタ.支払い金額 +- xxxマスタ.特定商品区分 +- yyyマスタ.新古品フラグ +- zzzマスタ.前回発注金額 + +抽出条件: + +- xxx受信管理トラン.業務日付 = 業務日付 +- xxx受信管理トラン.処理連番 = xxx受信管理トラン の最新の処理連番 + +### 登録 + +- xxxトラン.会社コード = xxx +- xxxトラン.処理日付 = xxx +- xxxトラン.xxx区分 = xxx +- xxxトラン.支払金額 = ビジネスロジック1計算結果 + +### 更新 + +xxx 予測ワーク: + +- xxx 予測ワーク.優先度 +- xxx 予測ワーク.処理予定日 diff --git "a/documents/forMarkdown/\343\203\241\343\203\203\343\202\273\343\203\274\343\202\270\350\250\255\350\250\210\346\233\270.md" "b/documents/forMarkdown/\343\203\241\343\203\203\343\202\273\343\203\274\343\202\270\350\250\255\350\250\210\346\233\270.md" new file mode 100644 index 00000000..30175def --- /dev/null +++ "b/documents/forMarkdown/\343\203\241\343\203\203\343\202\273\343\203\274\343\202\270\350\250\255\350\250\210\346\233\270.md" @@ -0,0 +1,15 @@ +# MSG01 + +## メッセージ概要 + +- 目的: ログイン処理周りでのエラー +- スコープ: frontend, backend + +## メッセージ定義 + +| 識別子 | レベル | ステータス | メッセージ | コメント | +| ------ | ------ | ---------- | ------------------------------------------ | ---------------------------- | +| 10001 | E | 400 | ユーザー名またはパスワードが間違っています | ログイン画面で発生 | +| 10002 | W | | 文字数オーバーです | ログイン画面で発生 | +| 10003 | E | 500 | {domain}は無効なユーザードメインです | ユーザーの所属が異なっている | +| 10004 | F | 500 | EntraIDに接続できません | ログインのバックエンドで発生 | diff --git "a/documents/forMarkdown/\345\214\272\345\210\206\345\200\244\350\250\255\350\250\210\346\233\270.md" "b/documents/forMarkdown/\345\214\272\345\210\206\345\200\244\350\250\255\350\250\210\346\233\270.md" new file mode 100644 index 00000000..f92e509c --- /dev/null +++ "b/documents/forMarkdown/\345\214\272\345\210\206\345\200\244\350\250\255\350\250\210\346\233\270.md" @@ -0,0 +1,21 @@ +# ENUM01 ユーザー権限 + +## 区分値概要 + +- 目的: 画面のモードの切り替えに利用する +- 物理名: user permission level +- 型: string +- スコープ: frontend, backend +- マスターテーブル: m_user_role + +## 区分値定義 + +| 論理名 | 物理名 | 値 | バージョン | コメント | +| ------------------ | --------------- | --- | ---------- | -------- | +| ゲスト | guest | 01 | 1 | | +| 未認証ユーザー | unauthenticated | 02 | 1 | | +| 登録ユーザー | user | 03 | 1 | | +| プレミアムユーザー | premium_user | 04 | 2 | | +| 開発者 | developer | 05 | 0 | | +| テスター | tester | 06 | 0 | | +| 管理者 | administrator | 07 | 0 | | diff --git "a/documents/forMarkdown/\347\224\273\351\235\242\350\250\255\350\250\210\346\233\270.md" "b/documents/forMarkdown/\347\224\273\351\235\242\350\250\255\350\250\210\346\233\270.md" new file mode 100644 index 00000000..eb450672 --- /dev/null +++ "b/documents/forMarkdown/\347\224\273\351\235\242\350\250\255\350\250\210\346\233\270.md" @@ -0,0 +1,62 @@ +# [機能ID] xxx売上履歴表示 + +## 概要 + +機能目的: + +- 確認ステータス、スキップステータスをもとに、過去のxxx売上履歴を確認する + +機能概要: + +- 過去1年分の売上履歴を対象に、検索表示する +- スキップ設定や確認ステータスの更新を行う + +## イベント概要 + +| No | イベント名 | イベント分類 |     処理説明 | +|--- |-----------------------------------------|---------------|------------------------------------------------| +| 1 | 初期表示 | 初期表示 | 初期検索条件に従いAPIを実行し、履歴表示する | +| 2 | 履歴検索 | ボタン押下 | 検索条件エリアの条件に従い、履歴の検索を行う | +| 3 | 保存 | ボタン押下 | 履歴テーブルで書き込んだ、スキップ、確認済の保存を行う | +| 4 | 検索結果 ページ送り/戻し | ボタン押下 | テーブルあたりの行数プルダウンで設定された行数に応じて表示切替する | +| 5 | 検索結果 ページ送り(100件以降データ) | ボタン押下 | 検索結果の表で、ページ送りする際、100件以降のデータの場合は再度APIに問い合わせ描画する | +| 6 | 画面入力値チェック | ボタン押下 | 検索条件のバリデーションチェックを行う | + +## イベント詳細 + +### 1. 初期表示 + +起動パラメータ: + +| Name | Value | Memo | +| --- | --- | --- | +| userState | {/* 略 */} | xxx状態 | + +初期表示イベント: + +- xxx + +利用API: + +| ID | オプション | +| --- | --- | +| API031 | /v1/salesresult?q=xxxx&date=${current_ymd} | + +画面表示制御: + +- 0件時 + - 空テーブル表示(メッセージは表示しない) +- HTTPステータスが200以外 + - メッセージID(MSG_BIZ_111)表示 + +### 2. 履歴検索 + +/v1/salesresult?q=xxxx&date=${current_ymd} + +### 3. 保存 + +### 4. 検索結果 ページ送り/戻し + +### 5. 検索結果 ページ送り(100件以降データ) + +### 6. 画面入力値チェック diff --git a/documents/forOpenAPISpecification/OpenAPI_Specification_2.0.md b/documents/forOpenAPISpecification/OpenAPI_Specification_2.0.md index 6e0a8571..942708c6 100644 --- a/documents/forOpenAPISpecification/OpenAPI_Specification_2.0.md +++ b/documents/forOpenAPISpecification/OpenAPI_Specification_2.0.md @@ -17,9 +17,9 @@ meta: [OpenAPI Specification 2.0(Swagger, OAS2)](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md)定義についてのコーディング規約をまとめます。より新しいバージョンとして OAS 3.0.3 規約(作成中)がありますので、ご注意ください。 -本規約の[前提条件](prerequisite.md)に従い作成されています。ToC向けのLSUDs(Large Set of Unknown Developers)なWeb APIにはマッチしない可能性があります。 +本規約の[前提条件](prerequisite.md)に従い作成されています。ToC 向けの LSUDs(Large Set of Unknown Developers)な Web API にはマッチしない可能性があります。 -Web API自体の設計については範囲外としますが、[API 設計標準](API_Design.md)に利用するステータスコードなどは記載しています。 +Web API 自体の設計については範囲外としますが、[API 設計標準](API_Design.md)に利用するステータスコードなどは記載しています。 ## ファイルフォーマット @@ -701,7 +701,6 @@ description: 検索結果の項目数上限(1~100が指定可能) 【注意】API 公開後に、default 値を変更してはならない(API の互換性が崩れるため)。もし変更する場合は、API のバージョンを上げること。 - ### 型・フォーマット 型(`type`)は `string(文字列)`, `number(数値)`, `integer(整数値)`, `boolean(真偽値)` `array(配列)`, `file(ファイル)` のうちどれか指定する. @@ -852,12 +851,12 @@ CORS(Cross-Origin Resource Sharing)のために、options メソッドの追 ## OpenTelemetry Traceparent HTTP Header -OpenOpenTelemetryで用いるられる[traceparent](https://www.w3.org/TR/trace-context/) のリクエストヘッダーはOpenAPIで **原則不要** とする。 +OpenOpenTelemetry で用いるられる[traceparent](https://www.w3.org/TR/trace-context/) のリクエストヘッダーは OpenAPI で **原則不要** とする。 理由は以下である。 -- OpenTelemetryが定めるヘッダー類は、API横断的に設定されるべきものであり、ミドルウェアやフレームワーク側などでの一律の制御を推奨するため -- 記載することにより、OpenOpenTelemetryに対応していることを明記し開発者に周知できるメリットより、各アプリ開発者が生成されたコードで悩んだり、誤解されることを回避したいため +- OpenTelemetry が定めるヘッダー類は、API 横断的に設定されるべきものであり、ミドルウェアやフレームワーク側などでの一律の制御を推奨するため +- 記載することにより、OpenOpenTelemetry に対応していることを明記し開発者に周知できるメリットより、各アプリ開発者が生成されたコードで悩んだり、誤解されることを回避したいため ## API のバージョン管理 diff --git a/documents/forOpenAPISpecification/OpenAPI_Specification_3.0.3.md b/documents/forOpenAPISpecification/OpenAPI_Specification_3.0.3.md index d0ebaf88..84a41cfb 100644 --- a/documents/forOpenAPISpecification/OpenAPI_Specification_3.0.3.md +++ b/documents/forOpenAPISpecification/OpenAPI_Specification_3.0.3.md @@ -16,7 +16,7 @@ meta: # はじめに 本ドキュメントは [OpenAPI Specification 3.0.3](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md)に則った API ドキュメントを記述する際のコーディング規約をまとめている。 -旧バージョンである[OpenAPI Specification 2.0 の規約](OpenAPI_Specification_2.0.md)も存在するため、v2を使用している場合はそちらを参照されたい。 +旧バージョンである[OpenAPI Specification 2.0 の規約](OpenAPI_Specification_2.0.md)も存在するため、v2 を使用している場合はそちらを参照されたい。 本規約は[前提条件](prerequisite.md)に基づいて作成されており、ToC 向けの LSUDs(Large Set of Unknown Developers)向けの Web API には適合しない場合もあるのでご留意いただきたい。 Web API の設計自体はこの規約の範囲外であるが、[API 設計標準](API_Design.md) にステータスコード等の標準を記載しているため、必要に応じて参考にされたい。 @@ -27,8 +27,10 @@ Web API の設計自体はこの規約の範囲外であるが、[API 設計標 ## OpenAPI ドキュメントの構成要素 -OpenAPI ドキュメントを構成する要素はオブジェクトと呼ばれ、ルートオブジェクトは以下の要素で構成される。 -各種規約を理解する上で、これらの要素を大まかに把握しておくことが重要である。 +OpenAPI ドキュメントを構成する要素はオブジェクトと呼ばれ、ルートオブジェクトは以下の要素で構成される。 + +各種規約を理解する上で、これらの要素を大まかに把握しておくことが重要である。 + 各オブジェクトの詳細については[公式ドキュメント](https://spec.openapis.org/oas/v3.0.3#openapi-object)を参照されたい。 | フィールド名 | 必須 | 説明 | @@ -48,7 +50,8 @@ OpenAPI ドキュメントを構成する要素はオブジェクトと呼ばれ ## openapi -OpenAPI ドキュメントが使用する OpenAPI 仕様のセマンティックバージョン番号を記載する。 +OpenAPI ドキュメントが使用する OpenAPI 仕様のセマンティックバージョン番号を記載する。 + 本規約はバージョン`3.0.3`を対象としているため、`3.0.3`とする。 良い例: @@ -65,7 +68,8 @@ openapi: 3.0 ## info -`info`オブジェクトには Web API に関するメタデータを記載する。 +`info`オブジェクトには Web API に関するメタデータを記載する。 + `title`, `description`, `version` を必須項目とする。 | フィールド名 | 必須 | 記載内容 | @@ -79,8 +83,9 @@ openapi: 3.0 ### info > title -Web API の総称を記載する。 -システム名やサービス名 + API のような命名を推奨する。 +Web API の総称を記載する。 + +システム名やサービス名 + API のような命名を推奨する。 良い例: @@ -95,14 +100,15 @@ Web API が提供する機能の概要・想定する利用者やユースケー ### info > version -この API 仕様のドキュメントのバージョンを記載する。 +この API 仕様のドキュメントのバージョンを記載する。 + アプリケーションのバージョン(git tag やリリースで管理するようなバージョン)とは別である。 -- `major.minor` 形式を推奨する - `0.1 `固定で開発を進め、サービスのリリース時に `1.0` とし、その後の項目やオプション、パスの追加ごとにマイナーバージョンをインクリメントしていく +- `major.minor` 形式を推奨する + - `0.1` 固定で開発を進め、サービスのリリース時に `1.0` とし、その後の項目やオプション、パスの追加ごとにマイナーバージョンをインクリメントしていく 良い例: - + ```yaml info: version: 1.0 @@ -119,7 +125,7 @@ Web API が提供する機能の概要・想定する利用者やユースケー ## servers -Web API を提供するサーバの情報を記載する。 +Web API を提供するサーバの情報を記載する。 - `url`, `description` を必須項目とする - ステージ(local, develop, staging など)が複数ある場合は各ステージ分の情報を記載する。 @@ -202,10 +208,8 @@ API の利用可能なエンドポイントと操作方法を記載する。 ```yaml paths: /products: - get: - ... - post: - ... + get: ... + post: ... ``` 悪い例: @@ -213,10 +217,8 @@ API の利用可能なエンドポイントと操作方法を記載する。 ```yaml paths: /products: - post: - ... - get: - ... + post: ... + get: ... ``` - HTTP メソッドの配下に定義されるオペレーションオブジェクトは、下記の項目を必須項目とする @@ -311,7 +313,8 @@ API の操作概要を記載する。 ### paths > {path} > {method} > description -API の振る舞いの詳細や注意点を記載する。 +API の振る舞いの詳細や注意点を記載する。 + 別途参照させるべき設計書があるのであれば、設計書へのリンクを記載しても良い。 良い例: @@ -470,7 +473,7 @@ API のリクエストボディを記載する。 ... ``` -- リクエストボディそのものは通常複数の API を跨いで再利用されるものではないため、原則 `components` オブジェクトとして共通化(コンポーネント化)を行わない +- リクエストボディそのものは通常複数の API を跨いで再利用されるものではないため、原則 `components` オブジェクトとして共通化(コンポーネント化)を行わない - [openapi-generator](https://github.com/OpenAPITools/openapi-generator)を使用する場合は、コンポーネント化をせず、`title` を指定することで名称の指定が可能となる - [oapi-codegen](https://github.com/oapi-codegen/oapi-codegen)を使用する場合は、名称を指定するためにコンポーネント化が必要となるが、極力コンポーネント化せずデフォルトの名称を使用することを推奨する @@ -499,7 +502,7 @@ API のリクエストボディを記載する。 requestBody: # コンポーネント化したリクエストボディを参照 $ref: '#/components/requestBodies/ReqPostProductsBody' - + components: requestBodies: ReqPostProductsBody: @@ -511,7 +514,7 @@ API のリクエストボディを記載する。 API のレスポンスを記載する。 -- 正常系(`2xx`)のレスポンスは通常複数の API を跨いで再利用されるものではないため、原則 `components` オブジェクトとして共通化(コンポーネント化)を行わない +- 正常系(`2xx`)のレスポンスは通常複数の API を跨いで再利用されるものではないため、原則 `components` オブジェクトとして共通化(コンポーネント化)を行わない - [openapi-generator](https://github.com/OpenAPITools/openapi-generator)を使用する場合は、コンポーネント化をせず、`title` を指定することで名称の指定が可能となる - [oapi-codegen](https://github.com/oapi-codegen/oapi-codegen)を使用する場合は、レスポンスの構造体を出力するために `strict-server` オプションを `true` に指定する必要がある。名称を指定するためにコンポーネント化が必要となるが、極力コンポーネント化せずデフォルトの名称を使用することを推奨する @@ -540,7 +543,7 @@ API のレスポンスを記載する。 '200': # コンポーネント化したレスポンスオブジェクトを参照 $ref: '#/components/responses/RespPostProductsBody' - + components: responses: RespPostProductsBody: @@ -550,7 +553,6 @@ API のレスポンスを記載する。 ... ``` - - 異常系(`4xx`, `5xx`)のレスポンスは個別に定義するのではなく、事前に `components` オブジェクトとして定義を行い `$ref` で参照する 良い例: @@ -563,7 +565,7 @@ API のレスポンスを記載する。 '400': # コンポーネント化したレスポンスオブジェクトを参照 $ref: '#/components/responses/BadRequest' - + components: responses: BadRequest: @@ -633,8 +635,8 @@ API 共通的なリソースやエラー等のドメインオブジェクトを - 名称はアッパーキャメルケースで定義する - 名称は単数形で定義する - `type` に複数の型を定義しない -- `type` に `null` は原則指定しない(`null` 値を用いる代わりに、キー自体を含めない) - [差分更新APIの場合](#差分更新-API-の場合)にあるとおり、空更新を行う場合は空文字を利用する +- `type` に `null` は原則指定しない(`null` 値を用いる代わりに、キー自体を含めない) + - [差分更新APIの場合](#差分更新-API-の場合)にあるとおり、空更新を行う場合は空文字を利用する - `allOf`, `anyOf`, `oneOf` は利用しない 良い例: @@ -736,8 +738,8 @@ API 共通的なリクエストパラメータ(パスパラメータ、クエ #### パスパラメータ -- API 全体で利用されるパスパラメータが必要なケースが想定されないため、原則定義しない - 特定リソースの操作(例えば更新と削除)を行う際のリソース ID はパスパラメータとして再利用できるが、コンフリクトを避けるため原則共通化は行わない +- API 全体で利用されるパスパラメータが必要なケースが想定されないため、原則定義しない + - 特定リソースの操作(例えば更新と削除)を行う際のリソース ID はパスパラメータとして再利用できるが、コンフリクトを避けるため原則共通化は行わない #### クエリパラメータ @@ -751,7 +753,7 @@ paths: get: /products: parameters: - - $ref: '#/components/parameters/QueryLimit' + - $ref: "#/components/parameters/QueryLimit" components: parameters: @@ -831,7 +833,7 @@ paths: get: /products: responses: - '200': + "200": headers: XCacheInfo: $ref: '#/components/headers/XCacheInfo' @@ -867,12 +869,12 @@ components: 興味深い機能であり、API のセマンティクスを伝えるのに有用であるが、本規約では記載しないことを推奨とする。 -理由は下記の通りである。 +理由: - 業務システムでは、業務フローを抑えておけば、API 操作フローの理解はそこまで難しくないことが多い - - 逆に、API 同士の関係だけを示すだけでは業務モデリング図とのダブルメンテナンスになったり、中途半端になりうる + - 逆に、API 同士の関係だけを示すだけでは業務モデリング図とのダブルメンテナンスになったり、中途半端になりうる - [OAS 3.0 Support Backlog](https://github.com/swagger-api/swagger-ui/issues/3641) にあるように、2023/12/15時点では Swagger-UI が対応していない - - links を書いたと言って、API ドキュメントに影響しない + - links を書いたと言って、API ドキュメントに影響しない ### components > callbacks @@ -882,7 +884,7 @@ components: 利便性は高い仕様だが、本規約では記載しないことを推奨とする。 -理由は下記の通りである。 +理由: - コールバック URL 呼び出しの、エラーハンドリングが難しい - 業務システムでは欠損が許されない、または将来的に許されなくなる可能性があり、その場合にこの機能に頼ると想定以上の追加作業が発生する @@ -891,7 +893,8 @@ components: ## security -全 API に共通で適用されるセキュリティ設定を定義する。 +全 API に共通で適用されるセキュリティ設定を定義する。 + 業務システムの Web API において認証が全く存在しないケースは考えにくいため、本規約ではルートレベルで認証を設定し、個々の API への適応漏れを無くす。 良い例: @@ -907,8 +910,8 @@ API を論理的にグループ化するためのタグを定義する。 - ドキュメントやツールにとって重要であるため **必須** で指定する - `name`, `description` を必須項目とする -- **単数形** で、小文字かつ半角スペース区切りで記載する - 半角スペース区切りで記載する理由は HTML ドキュメントで参照する場合の可読性を上げるためである +- **単数形** で、小文字かつ半角スペース区切りで記載する + - 半角スペース区切りで記載する理由は HTML ドキュメントで参照する場合の可読性を上げるため - コード生成で利用される(Go においてはパッケージ、 TypeScript においてはクラスに相当する)ため、シンプルな命名にする 良い例: @@ -933,7 +936,8 @@ tags: ## externalDocs -参照情報としての URL を記載できる。 +参照情報としての URL を記載できる。 + ただし、`description` にて参考情報となる URL を記載する方が、複数リンクを指定可能であるなど自由度が高く使いやすいため `externalDocs` は利用せず `description` の利用を推奨する。 良い例: @@ -953,7 +957,7 @@ externalDocs: # 設計上のポイント -OpenAPI ドキュメントを作成する上での設計上ポイントをいくつか記載する。 +OpenAPI ドキュメントを作成する上での設計上ポイントをいくつか記載する。 ## ファイルアップロード @@ -1021,14 +1025,14 @@ A->>B: ③ファイルアップロード完了(受付ID、キー、属性) CORS(Cross-Origin Resource Sharing)のために、options メソッドの追記は **原則不要** とする。 -理由は以下である。 +理由: - サーバ側 - options メソッド対応は、API 仕様ではなく実装レベルの機能横断的な処理(Java における Servlet Filter や Spring の Interceptor、Go における Middleware など)で行うことが大半であり、コード生成が不要 - クライアント側 - options メソッドを用いるのはクライアントがブラウザであり、クライアントのアプリケーションコードが明示的にアクセスしないため、コード生成が不要 - 使用面として - - ` Access-Control-Allow-Origin` がどのような値を返すか、呼び出し元によって動的な値を返したい場合があり、記載が困難なケースがある + - `Access-Control-Allow-Origin` がどのような値を返すか、呼び出し元によって動的な値を返したい場合があり、記載が困難なケースがある ただし、Amazon API Gateway のようなサービスを利用する場合は、options メソッドの記載が必須である場合は除く[^1]。 @@ -1043,7 +1047,7 @@ CORS(Cross-Origin Resource Sharing)のために、options メソッドの追 OpenOpenTelemetry で用いるられる[traceparent](https://www.w3.org/TR/trace-context/) のリクエストヘッダは OpenAPI で **原則不要** とする。 -理由は以下である。 +理由: - OpenTelemetry が定めるヘッダ類は、API 横断的に設定されるべきものであり、ミドルウェアやフレームワーク側などでの一律の制御を推奨するため - 記載することにより、OpenOpenTelemetry に対応していることを明記し開発者に周知できるメリットより、各アプリ開発者が生成されたコードで悩んだり、誤解されることを回避したいため @@ -1102,11 +1106,11 @@ description: 検索結果の項目数上限(1~100が指定可能) - `password`: Swagger UI で入力が隠される - その他、 `email`, `uuid` など Open API 仕様に存在しない任意のフォーマットを独自のドキュメント生成などのために記載しても良い -OpenAPI 3.0では 2.0 に存在した `file` type は存在しない。もし同等の指定をしたい場合は、以下の様に指定する。 +OpenAPI 3.0 では 2.0 に存在した `file` type は存在しない。もし同等の指定をしたい場合は、以下の様に指定する。 ```yaml type: string -format: binary # binary file contents +format: binary # binary file contents ``` ### 桁 @@ -1151,11 +1155,11 @@ paths: /products: get: parameters: - - in: query - name: gender - required: true - schema: - $ref: '#/components/schemas/Gender' + - in: query + name: gender + required: true + schema: + $ref: "#/components/schemas/Gender" components: schemas: Gender: @@ -1195,7 +1199,8 @@ remind_time:
詳細をみる -原則 `null` を用いず、パラメータのキー自体を含めないこと(`undefined`)による表現を行う。 +原則 `null` を用いず、パラメータのキー自体を含めないこと(`undefined`)による表現を行う。 + 詳細は[技術ブログ記事](https://future-architect.github.io/articles/20211028b/)を参照されたい
@@ -1205,8 +1210,9 @@ remind_time:
詳細をみる -OpenAPI ドキュメントは単一のファイルで構成することも複数の分割されたファイルで構成することもできるが、**複数のファイルに分割する**ことを推奨する。 -理由は下記の通りである。 +OpenAPI ドキュメントは単一のファイルで構成することも複数の分割されたファイルで構成することもできるが、**複数のファイルに分割する**ことを推奨する。 + +理由: - API ごとに担当者を分けて設計する場合などに、複数人による編集によって意図しないコンフリクトが発生することを防ぐ - ファイルの肥大化による、可読性の低下を防ぐ @@ -1220,7 +1226,7 @@ OpenAPI ドキュメントは単一のファイルで構成することも複数 ### サンプル説明 -分割方法1, 2の両方に当てはまる場合のサンプルを用いて説明する。`openapi.yaml` とディレクトリ構成は下の通り。サンプルの全量は [サンプルzip Download](./reference/divided_files_sample.zip)からダウンロード可能。 +分割方法 1, 2 の両方に当てはまる場合のサンプルを用いて説明する。`openapi.yaml` とディレクトリ構成は下の通り。サンプルの全量は [サンプル zip Download](./reference/divided_files_sample.zip)からダウンロード可能。 - 機能単位(path, method 単位)にディレクトリを作成して、それぞれの定義ファイルを格納する。ディレクトリ名は `{path}_{method}` とすると管理し易い - `components` の `schemas` には、 @@ -1231,7 +1237,7 @@ OpenAPI ドキュメントは単一のファイルで構成することも複数
ファイル分割例: openapi.yaml - ```yaml + ```yaml openapi: "3.0.3" info: version: 1.0.0 @@ -1262,7 +1268,7 @@ OpenAPI ドキュメントは単一のファイルで構成することも複数 $ref: "./common/pet.yaml" Error: $ref: "./common/error.yaml" - ``` + ```
@@ -1303,7 +1309,7 @@ OpenAPI ドキュメントは単一のファイルで構成することも複数
API別ファイルの記載例: pets-pet-id_get.yaml - ```yaml + ```yaml operation: operationId: get-pets-pet-id summary: Details for a pet @@ -1353,9 +1359,9 @@ OpenAPI ドキュメントは単一のファイルで構成することも複数 $ref: "#/components/schemas/Pedigree" Pedigree: required: - - registration_no - - date_of_registration - - pedigree_image + - registration_no + - date_of_registration + - pedigree_image type: object properties: registration_no: @@ -1369,21 +1375,20 @@ OpenAPI ドキュメントは単一のファイルで構成することも複数 responses: ResPetsPetIdGet: required: - - pet - - pet_detail + - pet + - pet_detail type: object properties: pet: $ref: "../common/pet.yaml" pet_detail: $ref: "#/components/schemas/PetDetail" - ``` + ```
+- OpenAPI の使用用途により、分割ファイルを 1 つのファイルにまとめる必要がある場合には、例えば[swagger-cli](https://apitools.dev/swagger-cli/)を使用して以下コマンドを実行する。 -- OpenAPI の使用用途により、分割ファイルを1つのファイルにまとめる必要がある場合には、例えば[swagger-cli](https://apitools.dev/swagger-cli/)を使用して以下コマンドを実行する - ```bash swagger-cli bundle openapi.yaml --outfile openapi.gen.yaml --type yaml ``` @@ -1399,7 +1404,7 @@ OpenAPI ドキュメントは単一のファイルで構成することも複数 license: name: MIT servers: - - url: 'http://petstore.swagger.io/v1' + - url: "http://petstore.swagger.io/v1" tags: - name: pets description: Everything about your Pets @@ -1420,7 +1425,7 @@ OpenAPI ドキュメントは単一のファイルで構成することも複数 maximum: 100 format: int32 responses: - '200': + "200": description: A paged array of pets headers: x-next: @@ -1502,7 +1507,7 @@ OpenAPI ドキュメントは単一のファイルで構成することも複数 tag: dog10004 ResExample2: value: [] - '404': + "404": description: not found error content: application/json: @@ -1517,12 +1522,12 @@ OpenAPI ドキュメントは単一のファイルで構成することも複数 format: int32 message: type: string - '500': + "500": description: unexpected error content: application/json: schema: - $ref: '#/paths/~1pets/get/responses/404/content/application~1json/schema' + $ref: "#/paths/~1pets/get/responses/404/content/application~1json/schema" post: summary: Register a pet operationId: post-pets @@ -1537,7 +1542,7 @@ OpenAPI ドキュメントは単一のファイルで構成することも複数 type: object properties: pet: - $ref: '#/paths/~1pets/get/responses/200/content/application~1json/schema/items' + $ref: "#/paths/~1pets/get/responses/200/content/application~1json/schema/items" examples: ReqExample1: value: @@ -1552,21 +1557,21 @@ OpenAPI ドキュメントは単一のファイルで構成することも複数 tag: dog10005 required: false responses: - '201': + "201": description: Null response - '404': + "404": description: not found error content: application/json: schema: - $ref: '#/paths/~1pets/get/responses/404/content/application~1json/schema' - '500': + $ref: "#/paths/~1pets/get/responses/404/content/application~1json/schema" + "500": description: unexpected error content: application/json: schema: - $ref: '#/paths/~1pets/get/responses/404/content/application~1json/schema' - '/pets/{petId}': + $ref: "#/paths/~1pets/get/responses/404/content/application~1json/schema" + "/pets/{petId}": get: summary: Details for a pet operationId: get-pets-pet-id @@ -1580,7 +1585,7 @@ OpenAPI ドキュメントは単一のファイルで構成することも複数 schema: type: string responses: - '200': + "200": description: Expected response to a valid request content: application/json: @@ -1591,7 +1596,7 @@ OpenAPI ドキュメントは単一のファイルで構成することも複数 type: object properties: pet: - $ref: '#/paths/~1pets/get/responses/200/content/application~1json/schema/items' + $ref: "#/paths/~1pets/get/responses/200/content/application~1json/schema/items" pet_detail: type: object properties: @@ -1629,25 +1634,70 @@ OpenAPI ドキュメントは単一のファイルで構成することも複数 tag: dog10001 pet_detail: breeder: BreederName - date_of_birth: '2023-10-31' + date_of_birth: "2023-10-31" pedigree: registration_no: 11111111 - date_of_registration: '2023-10-31' + date_of_registration: "2023-10-31" pedigree_image: 9j2wBDAA...8QAPxAAAQQABAMGBAYDAAEDAg - '404': + "404": description: not found error content: application/json: schema: - $ref: '#/paths/~1pets/get/responses/404/content/application~1json/schema' - '500': + $ref: "#/paths/~1pets/get/responses/404/content/application~1json/schema" + "500": description: unexpected error content: application/json: schema: $ref: '#/paths/~1pets/get/responses/404/content/application~1json/schema' + components: + schemas: + PetDetail: + type: object + properties: + breeder: + type: string + date_of_birth: + type: string + format: date + pedigree: + $ref: "#/components/schemas/Pedigree" + Pedigree: + required: + - registration_no + - date_of_registration + - pedigree_image + type: object + properties: + registration_no: + type: integer + format: int64 + date_of_registration: + type: string + format: date + pedigree_image: + type: string + responses: + ResPetsPetIdGet: + required: + - pet + - pet_detail + type: object + properties: + pet: + $ref: "../common/pet.yaml" + pet_detail: + $ref: "#/components/schemas/PetDetail" + ``` - ``` +
+ +- OpenAPI の使用用途により、分割ファイルを1つのファイルにまとめる必要がある場合には、例えば[swagger-cli](https://apitools.dev/swagger-cli/)を使用して以下コマンドを実行する + + ```bash + swagger-cli bundle openapi.yaml --outfile openapi.gen.yaml --type yaml + ``` diff --git a/documents/forOpenAPISpecification/file_standards.md b/documents/forOpenAPISpecification/file_standards.md index 607b6006..a618043a 100644 --- a/documents/forOpenAPISpecification/file_standards.md +++ b/documents/forOpenAPISpecification/file_standards.md @@ -8,13 +8,13 @@ OpenAPI ドキュメントは JSON 形式、YAML 形式いずれかのフォー ## ファイル名 -ファイルの拡張子は `yaml` とする。通常ファイル名は `api.yaml` や `swagger.yaml`(v2の場合) を推奨する。 +ファイルの拡張子は `yaml` とする。通常ファイル名は `api.yaml` や `swagger.yaml`(v2 の場合) を推奨する。 もし、複数の Swagger 定義を管理するため区別したい場合は `${service}_api.yaml` とする。 `${service}` にはサービス名を指定する -## YAMLバージョン +## YAML バージョン [YAML v1.2](https://yaml.org/spec/1.2.2/#61-indentation-spaces)を用いる。 @@ -44,7 +44,7 @@ description: "何かしらの説明" - Bool として認識させたくない("true", "false", "yes", "no", "y", "n", "on", "off") - `#` で始まる文字列(`#` はコメントを示す記号のためである。例: `#/definitions/Users`) -## YAML配列スタイル +## YAML 配列スタイル - 複数項目を指定する場合は、 **Flow style(配列スキーム)** を用いることを推奨する diff --git a/documents/forOpenAPISpecification/prerequisite.md b/documents/forOpenAPISpecification/prerequisite.md index 9abc9e35..932fc883 100644 --- a/documents/forOpenAPISpecification/prerequisite.md +++ b/documents/forOpenAPISpecification/prerequisite.md @@ -5,9 +5,11 @@ - 業務システム向けの Web API 提供 - サードパーティ向けに広く開発する Web API ではなく、限られたクライアントやシステムと連携すること - いわゆる、LSUDs(Large Set of Unknown Developers)ではなく、SSKDs(Small Set of Known Developers)を対象とする -* RESTish なWeb API - * 原理的なRESTを必ずしも守る必要はないが、例えばHTTPメソッドは、参照はGET、登録はPOST、更新はPUTやPATCH、削除はDELETEで使い分けていたり、Web APIの要求が成功すれば200(OK)、204(No Content)を返し、リソースが無ければ404(Not Found)、操作に失敗すれば500系のエラーを返すといったことを指す - * 本規約を利用するに当たり必須条件ではないが、定義例などはそれに基づいて記載しているので注意する + +* RESTish な Web API + - 原理的な REST を必ずしも守る必要はないが、例えば HTTP メソッドは、参照は GET、登録は POST、更新は PUT や PATCH、削除は DELETE で使い分けていたり、Web API の要求が成功すれば 200(OK)、204(No Content)を返し、リソースが無ければ 404(Not Found)、操作に失敗すれば 500 系のエラーを返すといったことを指す + - 本規約を利用するに当たり必須条件ではないが、定義例などはそれに基づいて記載しているので注意する + - スキーマファースト - OpenAPI Specification の定義ファイルを駆動に、クライアント・サーバサイドのコード生成やモック時の利用に用い、高速な Web API 開発につなげることを前提とする - Python における、FastAPI・Django REST Framework のように、アプリケーションコードから OpenAPI document を自動生成する開発手法も存在するが、本規約はこれは想定しない diff --git a/documents/forOpenAPISpecification/reference/DB_OpenAPI_Mapping_Example.md b/documents/forOpenAPISpecification/reference/DB_OpenAPI_Mapping_Example.md index 52dfdd31..2ad456c7 100644 --- a/documents/forOpenAPISpecification/reference/DB_OpenAPI_Mapping_Example.md +++ b/documents/forOpenAPISpecification/reference/DB_OpenAPI_Mapping_Example.md @@ -1,18 +1,18 @@ # DB OpenAPI Mapping Example -|データの種類|DB型|DDL定義|OpenAPI
項目必須/非必須|OpenAPI
Type/その他定義|API
リクエスト/リスポンス|備考| -|:----|:----|:----|:----|:----|:----|:----| -|区分値|varchar|NOT NULL, カラム名 <> ''|required|string/enum|項目必須、空値は許容しない| | -| | |NOT NULL default ''|-|string/enum|項目非必須、空値はundefinedまたは空文字として定義|空値を空文字で定義する場合、enumに空文字を含む必要がある。| -|フラグ|varchar|NOT NULL, カラム名 <> ''|required|string/enum|項目必須、空値は許容しない| | -| | |NOT NULL default ''|-|string/enum|項目非必須、空値はundefinedまたは空文字として定義|空値を空文字で定義する場合、enumに空文字を含む必要がある。| -|数値|integer|NOT NULL|required|integer|項目必須、空値は許容しない| | -| | |-|nullable: true|integer|項目非必須、空値はundefinedまたはnullとして定義| | -|数値(精度有)|numeric|NOT NULL|required|string/正規表現pattern|項目必須、空値は許容しない| | -| | |-|nullable: true|string/正規表現pattern|項目非必須、空値はundefinedまたはnullとして定義| | -|日付/時刻|date / timestamp|NOT NULL|required|string/format指定または正規表現pattern|項目必須、空値は許容しない| | -| | |-|nullable: true|string/format指定または正規表現pattern|項目非必須、空値はundefinedまたはnullとして定義| | -|コード/番号|varchar|NOT NULL, カラム名 <> ''|required|string/正規表現patternや桁数指定|項目必須、空値は許容しない| | -| | |NOT NULL default ''|-|string/正規表現patternや桁数指定|項目非必須、空値はundefinedまたは空文字として定義| | -|名前 / メモ|varchar / text|NOT NULL, カラム名 <> ''|required|string/正規表現patternや桁数指定|項目必須、空値は許容しない| | -| | |NOT NULL default ''|-|string/正規表現patternや桁数指定|項目非必須、空値はundefinedまたは空文字として定義| | +| データの種類 | DB 型 | DDL 定義 | OpenAPI
項目必須/非必須 | OpenAPI
Type/その他定義 | API
リクエスト/リスポンス | 備考 | +| :------------- | :--------------- | :----------------------- | :------------------------- | :--------------------------------------- | :-------------------------------------------------- | :---------------------------------------------------------- | +| 区分値 | varchar | NOT NULL, カラム名 <> '' | required | string/enum | 項目必須、空値は許容しない | | +| | | NOT NULL default '' | - | string/enum | 項目非必須、空値は undefined または空文字として定義 | 空値を空文字で定義する場合、enum に空文字を含む必要がある。 | +| フラグ | varchar | NOT NULL, カラム名 <> '' | required | string/enum | 項目必須、空値は許容しない | | +| | | NOT NULL default '' | - | string/enum | 項目非必須、空値は undefined または空文字として定義 | 空値を空文字で定義する場合、enum に空文字を含む必要がある。 | +| 数値 | integer | NOT NULL | required | integer | 項目必須、空値は許容しない | | +| | | - | nullable: true | integer | 項目非必須、空値は undefined または null として定義 | | +| 数値(精度有) | numeric | NOT NULL | required | string/正規表現 pattern | 項目必須、空値は許容しない | | +| | | - | nullable: true | string/正規表現 pattern | 項目非必須、空値は undefined または null として定義 | | +| 日付/時刻 | date / timestamp | NOT NULL | required | string/format 指定または正規表現 pattern | 項目必須、空値は許容しない | | +| | | - | nullable: true | string/format 指定または正規表現 pattern | 項目非必須、空値は undefined または null として定義 | | +| コード/番号 | varchar | NOT NULL, カラム名 <> '' | required | string/正規表現 pattern や桁数指定 | 項目必須、空値は許容しない | | +| | | NOT NULL default '' | - | string/正規表現 pattern や桁数指定 | 項目非必須、空値は undefined または空文字として定義 | | +| 名前 / メモ | varchar / text | NOT NULL, カラム名 <> '' | required | string/正規表現 pattern や桁数指定 | 項目必須、空値は許容しない | | +| | | NOT NULL default '' | - | string/正規表現 pattern や桁数指定 | 項目非必須、空値は undefined または空文字として定義 | |