# TeamWorks 宛 共有文書（第1回）の原稿 — これを正とする

> **2026-09-03 追記**: この原稿は一時ディレクトリにしか存在せず、消えると復元できない状態でした。
> リポジトリへ移動しています（元: `scratchpad/share/CONTENT.md`）。
> **PDF はこの原稿から `docs/handoff/pdf/make_ddl_review_pdf.py` で生成します。**
> 生成物の検査は `docs/handoff/pdf/check_ddl_review_pdf.py`。詳細は `docs/handoff/pdf/README.md`。
> 第2回の原稿は `docs/handoff/TeamWorks確認事項_第2回_20260903.md` です。

宛先: TeamWorks（DB開発側）
差出: DFA Robotics
作成日: 2026-09-03
表題: 実DDL照合結果と確認事項

---

## 冒頭に置く背景説明

2026-09-02 付でご提供いただいた `clean_watch_20260902.sql`（CREATE TABLE 39個）を、
こちらで手書きしていた Prisma スキーマと機械的に照合しました。

照合は独立した2つの方法で行い、結果が一致することを確認しています。

1. DDL からローカルに実データベースを構築し、`prisma db pull` で生成したスキーマと比較
2. DDL を直接パースしてカラム定義を抽出し、比較

差分は49件でした。そのうち **42件はこちらで実DDLに合わせるだけで完結**します。
本書には、**こちらだけでは判断できない3件**と、**共有しておきたい3件**、
および**仕様の確認1件**を記載しています。

---

## サマリ表（冒頭に置く）

| 区分 | 件数 | 性質 |
|---|---|---|
| A. 合意が必要 | 3件 | 返答が無いと実装を決められない |
| B. 情報共有 | 3件 | 返答は必須でない。DB側でしか対処できないものを含む |
| C. 仕様確認 | 1件 | 以前の合意事項の解釈 |

こちらで完結する42件については本書に記載していません。

---

## A. 合意が必要（3件）

### A-1  robot_error_reports の主キーと id の意味

**最も影響が大きい項目です。**

実DDL の状態:

```sql
`id`       varchar(50) NOT NULL,   -- 主キーでも UNIQUE でもない。制約なし
`error_id` varchar(50) NOT NULL,
UNIQUE KEY `robot_error_reports_report_id_unique` (`error_id`)
```

`PRIMARY KEY` が定義されておらず、一意制約は `error_id` のみです。

一方こちらの API 契約と型定義は次のようになっています。

```
PrecheckItem.id : number
PATCH /prechecks/{id}/status
```

具体的な帰結です。アラート一覧で担当者が「対応中」を押すと、画面は id を送ります。しかし、

- id は一意でないため、その値で1行を特定できません
- id は文字列なので、number として扱うと不一致が起きます
- 更新できるのは error_id だけです

**このため対応状況の更新（PATCH）が設計として成立しません。**

伺いたいこと:

1. id に一意制約を付ける予定はありますか。それとも error_id が正式なキーですか
2. こちらの API が画面に返すべき ID は id と error_id のどちらですか
3. id が文字列である前提でよろしいですか（こちらの型を number から string に変更します）

### A-2  履歴テーブルの id は誰が採番するのか

`clean_status_histories` の状態:

```sql
`id` bigint unsigned NOT NULL,   -- AUTO_INCREMENT ではない
UNIQUE KEY `clean_status_histories_id_unique` (`id`)
```

`PRIMARY KEY` が無く、`AUTO_INCREMENT` も付いていません。一方で `UNIQUE` 制約はあります。

これが元テーブル `clean_statuses.id` を引き継ぐ設計だとすると、
**1つの清掃状態につき履歴を1件しか作れません。**
履歴テーブルとしては不自然に見えるため、意図を確認したいです。

`clean_timetable_histories.id` も同様に AUTO_INCREMENT がありません。

伺いたいこと:

1. これらの id は誰が採番しますか（アプリ側で連番を振る想定でしょうか）
2. 元テーブルの id を引き継ぐ設計ですか。その場合、同じ清掃状態の履歴が
   複数回作られることはない前提でよろしいですか

こちらが検証用のダミーデータを作る際に、採番方法が決まらないと投入できません。

### A-3  先の回答（contact 系の型）はいつ反映されますか

先の確認事項 B-6 について、次のようにご回答いただきました。

> typo です。contact_type は unsigned tinyint とします。email は varchar(100) とします。

いただいた DDL（2026-09-02 付）には、まだ反映されていないようです。

| カラム | ご回答 | 実DDL |
|---|---|---|
| customer_contacts.contact_type | unsigned tinyint | **bigint unsigned** |
| customer_contacts.email | varchar(100) | varchar(100)（一致） |
| facility_contacts.contact_type | unsigned tinyint | tinyint unsigned（一致） |
| facility_contacts.email | varchar(100) | **varchar(255)** |

顧客側と施設側で型が食い違った状態が残っています。

伺いたいこと:

1. 当面は現行の DDL に合わせて実装してよろしいですか
   （後で変更が入れば `prisma db pull` の差分に出るため追随できます）
2. 変更を入れる時期の目安があればお知らせください

なお customer_contacts.contact_type が bigint の場合、
こちらでは JavaScript の bigint 型として受け取ることになり、
JSON へ変換する際に明示的な数値変換が必要になります（実装側で対応します）。

---

## B. 情報共有（3件）

返答は必須ではありません。こちらは現状のまま実装を進められます。

### B-1  外部キーが3本欠けています

定義書では `fk` と記載されているものの、実DDL に制約が見当たりませんでした。

| テーブル | カラム | 定義書上の参照先 |
|---|---|---|
| clean_statuses | clean_timetable_id | clean_timetables(id) |
| clean_status_histories | clean_timetable_id | clean_timetables(id) |
| robot_task_versions | clean_schedule_id | clean_schedules(id) |

意図的なものか、付け忘れかをご確認いただければ幸いです。
付け忘れであれば DB 側で追加いただくのが適切と考えます。
意図的であれば、こちらは参照先が存在しない行（孤児行）を想定した実装にします。

**返答をお待ちせず、孤児行を想定した実装で進めます。**

### B-2  インデックスが1つ欠けています（DB側でしか対処できません）

`robot_task_versions.clean_schedule_id` にインデックスがありません。
外部キーも無いため、MySQL による自動作成も行われていません。

この列で絞り込む検索が全件走査になります。
300施設分のタスク履歴が積み上がるテーブルのため、
運用が進むにつれて表示が遅くなることが見込まれます。

**こちら側に回避手段がないため、DB 側でのご対応をお願いしたい項目です。**

### B-3  timestamp NOT NULL に DEFAULT 句がありません

| テーブル | カラム |
|---|---|
| clean_task_reports | created_at, updated_at |
| security_status_histories | reported_at |

いずれも `timestamp NOT NULL` ですが DEFAULT 句がなく、
INSERT 時に明示的な値の指定が必要です。

アプリ側で時刻を管理する設計であれば意図的と理解しますが、
created_at に既定値が無いのは珍しい形のため念のため共有します。

**こちらは参照のみのため実装への影響はありません。**

---

## C. 仕様確認（1件）

### C-1  アドバイス規則 R3 の条件に「出発失敗」を含みますか

こちらの実装規約では、行展開アドバイスの規則を次のように定めています。

```
R3 = 完了率が△以下の状態が2日以上連続
R4 = 出発失敗 または △以下 の状態が3日以上連続
```

R3 と R4 で条件を書き分けていますが、実装は両方とも
「連続問題日数」という1つの値を見ており、区別できません。

さらに連続問題日数の定義が「△以下 **または** 出発失敗」であるため、
**現状では2日連続の出発失敗で R3 が発火します。**

伺いたいこと:

1. R3 の条件に出発失敗を含めるのが正しいですか
2. それとも R3 は完了率の低下のみを対象とし、出発失敗は R4 だけの条件ですか

後者の場合、連続日数を「△以下のみ」と「出発失敗を含む」の2種類に分けて
数える必要があるため、実装方針が変わります。

---

## 参考: 照合により解決した事項

いただいた DDL により、こちらで保留していた判断が確定しました。あわせてご報告します。

| 保留していた事項 | DDL での確認結果 |
|---|---|
| 対応日時のカラム名 | **responded_at**（正しい綴り）。定義書の responsed_at は誤記と確定 |
| control_reports のシリアル番号 | **serial_number**。定義書の sireal_number は誤記と確定 |
| clean_status の -1 問題 | 実DDL は符号あり tinyint。**定義書の型表記が誤りで、備考が正しかった** |
| makers テーブル | DDL に存在せず、devices からの外部キーも無し。**ご回答どおり** |
| controls.facility_id の外部キー | **存在を確認**。ご回答どおり |
| clean_timetables.precheck の既定値 | **0**（本清掃）。定義書の 9 は誤りと確定 |
| clean_link_schedules | **不要テーブルとご確認済み**。link_schedules を参照します |
| section_robot_statuses.indicatived_at | **綴り違いではなく、列自体が廃止**されていました |

また、こちらが定義書から手書きしたスキーマは、
28テーブル中12テーブルが実DDLと完全一致していました。
残りの差分も、大半は定義書側の記述と実DDL の食い違いに起因するものでした。

---

## 末尾に置く文

本書の A（3件）についてご回答をいただければ、
対応状況の更新機能とダミーデータによる検証に着手できます。
B・C については実装を止めるものではありませんので、お手隙の際にご確認ください。
