フランスの小規模チーム(開発5人、運用兼務)で、障害対応の記録に使う社内ツールのラベルを現地語(フランス語)にしていた時期がある。対象はインシデントのステータスと重要度の2箇所だけ。ツール自体は自前の小さなWebフォームで、DBはPostgreSQL、ステータスはenumで持っていた。件数は月40〜60件、同時に開いているインシデントが多くて10件程度の規模。
現象は単純で、フランス語ラベルにした直後から「同じ状態なのに人によって選ぶ値が違う」が起きた。原因はenumの値そのものを表示名にしたこと。具体的にはこうしていた。
CREATE TYPE incident_status AS ENUM (
'nouveau', 'en_cours', 'en_attente', 'resolu'
);
これを画面でもそのまま出していたので、en_attente を「顧客待ち」と読む人と「社内確認待ち」と読む人が混在した。結果、週次の集計で en_attente の滞留時間が実態と合わず、障害の振り返りが噛み合わなくなった。
やったことは、DBの値は英語のまま固定し、表示だけを翻訳辞書に分離した。マイグレーションは値の追加なしで、既存データをそのまま活かす形。
STATUS_LABELS = {
"new": "新規",
"in_progress": "対応中",
"waiting_customer": "顧客待ち",
"waiting_internal": "社内確認待ち",
"resolved": "解決",
}
def label(status: str) -> str:
return STATUS_LABELS.get(status, status)
en_attente は waiting_customer と waiting_internal に分割した。既存行は「顧客待ち」に寄せ、社内確認待ちだったものは手で数件直した。分割の判断は当時のメモと担当者の記憶に頼ったので、ここは正直に言って精度が低い。
なぜ表示だけ分離したか。enumの値を表示名にすると、翻訳の変更がデータの変更になる。実際、ラベルの言い回しを直したいだけの作業でマイグレーションが必要になり、そのたびに既存データの意味がずれるリスクを負う。表示辞書なら変更はアプリ側だけで済む。代償は、辞書にキーがない場合に生の値が出ること。これは許容して、未知の値はログに警告を出すだけにした。
効かなくなるのは、外部に値をそのまま出している箇所。CSVエクスポートとAPIレスポンスは英語のままなので、フランス語を期待している取引先には別途変換が必要になる。あと、辞書をアプリ側に置いたことで、複数サービスから同じラベルを使いたくなったときに重複する。今は2サービスだけなので放置しているが、3つ目が出たら共有パッケージに切り出すつもり。
同じように、現地語のラベルをどこまでデータ層に通すかで悩んだ経験のある人がいたら、境界をどこに置いたか聞いてみたい。
0 条评论
还没有评论,写下第一条。