Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
LeanLanguage2019 リニューアル、こうして不具合は起こった
Search
daponta
August 24, 2019
Programming
0
730
LeanLanguage2019 リニューアル、こうして不具合は起こった
daponta
August 24, 2019
Tweet
Share
Other Decks in Programming
See All in Programming
Goで作る、開発・CI環境
sin392
0
240
20250628_非エンジニアがバイブコーディングしてみた
ponponmikankan
0
710
RailsGirls IZUMO スポンサーLT
16bitidol
0
190
『自分のデータだけ見せたい!』を叶える──Laravel × Casbin で複雑権限をスッキリ解きほぐす 25 分
akitotsukahara
2
650
Composerが「依存解決」のためにどんな工夫をしているか #phpcon
o0h
PRO
1
320
チームで開発し事業を加速するための"良い"設計の考え方 @ サポーターズCoLab 2025-07-08
agatan
1
450
明示と暗黙 ー PHPとGoの インターフェイスの違いを知る
shimabox
2
580
AI Agent 時代のソフトウェア開発を支える AWS Cloud Development Kit (CDK)
konokenj
4
530
フロントエンドのパフォーマンスチューニング
koukimiura
4
1.5k
Startups on Rails in Past, Present and Future–Irina Nazarova, RailsConf 2025
irinanazarova
0
150
型で語るカタ
irof
0
350
Webの外へ飛び出せ NativePHPが切り拓くPHPの未来
takuyakatsusa
2
570
Featured
See All Featured
Site-Speed That Sticks
csswizardry
10
690
Gamification - CAS2011
davidbonilla
81
5.4k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
26k
Product Roadmaps are Hard
iamctodd
PRO
54
11k
Mobile First: as difficult as doing things right
swwweet
223
9.7k
Agile that works and the tools we love
rasmusluckow
329
21k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
130
19k
Music & Morning Musume
bryan
46
6.7k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
3.9k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
Scaling GitHub
holman
460
140k
Navigating Team Friction
lara
187
15k
Transcript
リニューアル、 こうして不具合は起こった LearnLanguage2019 @da_ponta
4/15に大規模な システムリニューアルをしました
前提 リニューアル箇所 - DB、テーブル構造 - サーバサイド - インフラ - アプリ
- UI - フロントエンド - 不要な機能の削減 ⇒ システムすべて
今回はリリース後に発覚した 不具合事例を紹介します
技術関連の詳細はTechCon2019資料をどうぞ https://bit.ly/2Z5lnqn
自己紹介 井田 祐太 @da_ponta 所属:株式会社ディー・エヌ・エー 担当サービスの開発全般を担当 - Ruby - Kubernetes
- Node.js - Android ろくろも回します
本題
リニューアルの不具合は えてしてデータで起こる
時間いっぱいまで紹介していきます - リレーション先がないデータ - 実はユニークではないカラム - nullは許容するが空文字は許容外のデータ - レコード化されていなかったデータ -
ハッシュ化ロジックの継承 - 大文字と小文字で一致しないメールアドレス - 整合性のあってないカウントカラム - 移行先のカラムの認識違いによる齟齬 - リリース直後に壊れるライブラリ - SJIS問題 まだまだあるよ★ データの更新ができない 表示に関する不整合 暗号化・ハッシュ化の闇
① 移行データの更新ができない リニューアルにおけるデータにまつわる変更 - テーブル構造・構成を変えた - カラムの方と制約を変えた - 一部マスター系のデータは削除ステータスを間引いて移行した -
バリデーションロジックは強化した
① 移行データの更新ができない 1-1 リレーション先が存在しない 例えばコメント削除, 投稿先のtopicは存在しない class Comment < ApplicationRecord
belongs_to :topic, foreign_key: :topic_id def remove! self.update!(deleted: true) end end > comment.remove! ActiveRecord::RecordInvalid: Validation failed: Topic must exist
① 移行データの更新ができない 1-2 実はユニークではなかったカラム 認証のメールアドレスは 重複登録できないという前後共通の仕様 実際に移行してみると同一のアドレスが別々のユーザに登録されている ⇒ 結果想定と異なるログイン挙動に
① 移行データの更新ができない 1-3 nullは許容するが空文字は許容外のデータ title未入力はnullであるはずが空文字で登録されているデータが存在する class Novel < ApplicationRecord validates
:title, length: { in: 1..100 }, allow_nil: true end > novel.title => “” > novel.validate! ActiveRecord::RecordInvalid: Validation failed: Title is too short (minimum is 1 character)
① 移行データの更新ができない 1-3-2 仕様の長さを超えていることもある リニューアル前後ともにタイトルは100m文字まで ⇒ 実際には数千文字のレコードは存在する ⇒ 「仕様」は信じてはいけない class
Novel < ApplicationRecord validates :title, length: { in: 1..100 }, allow_nil: true end
① 移行データの更新ができない 1-4 そもそもDBにレコードが存在しない 初期のころHTMLのみで運用されていた機能のデータは移行していなかった 例えば「運営からのお知らせ」
① 移行データの更新ができない なぜ気づかなかったのか? - 移行処理の高速化のためにデータ移行時にはバリデーションしていない - 太古のデータのみ発生する - 太古のデータの状況再現・検知は困難 ⇒
手動の検証では検知不可能 データ移行のチェックうはサンプルではなく網羅的にやりましょう
② 暗号化・ハッシュ化の闇 2 - 2 ハッシュ化ロジックの継承 パスワードなどのハッシュ値は復号できないので ロジックを引き継がなければならない かつ、社内基準に則ったハッシュ化を施す必要がある この時点で辛い
ログインフォーム ↓ 旧ハッシュ化(弱) ↓ 新ハッシュ化(強) ↓ 旧パスワードと照合 生パスワード ↓ 新ハッシュ化(強)
↓ 新パスワードレコードを登録
② 暗号化・ハッシュ化の闇 2 - 1 ハッシュ化ロジックの継承 特定のキーのときに旧ハッシュ化処理が PerlとRubyで一致しなかった ⇒Perlを呼び出すことに def
self.legacy_hash(password, key) script_path = Rails.root.join("script", "perl", "hash.pl").to_s stdout, stderr, status = Open3.capture3("perl", script_path, password, key) stdout end
② 暗号化・ハッシュ化の闇 2 - 1 大文字と小文字で一致しないメールアドレス 入力されるアドレス:
[email protected]
移行前に登録されている:
[email protected]
当然ながら暗号化後の結果が異なるため認証は通らない ⇒ 全ユーザデータ修正へ User.find_each do |users| email = decrypt(user.email) email.downcase! user.update(email: encrypt(email)) end
③ 表示に関する不整合 3 - 1 整合性のあってないカウントカラム 「小説の閲覧数」(以前から存在)と「閲覧した人一覧」(新規)が一致しない※ だいたいモバゲー時代の名残 ⇒ カウントデータ修正へ
※実際には小説の閲覧ではありません
③ 表示に関する不整合 3 - 2 移行先のカラムの認識違いによる齟齬 - レコードの更新日 - 読者向けの作品最終更新日
- 作家向けの最終保存日 これらの元のデータがない・表示される想定の値ではなかった・入れ替わってしまった ⇒ 表示側で加工 バックエンド・フロントエンド間の認識違い
④ ライブラリのバージョンが上がって壊れる 小説のエディタ機能に Vueのtiptapというライブラリを使用 → エディタ「ではない」ページのリリース → 突如iOSにてエディタが起動せず ⇒ 原因:tiptapの依存するライブラリの方でマイナーアップデート
→ バージョンをもどして解決かと思われたが …? → 全環境にて起動しなくなる ⇒ 原因:特定のエンジニアが生成した package-lock.jsonでnpm installすると壊れる バージョンの固定・管理は必須
⑤ SJIS問題 5-1 URLのパスも変更になっているためリダイレクトする必要があった 旧:/search?keyword=ファンタジー ⇒ /search?keyword=%83t%83%40%83%93%83%5E%83W%81%5B 新:/novels?keyword=ファンタジー ⇒ /novels?keyword=%E3%83%95%E3%82%A1%E3%83%B3%E3%82%BF%E3%82%B8%E3%83%BC
SJISでエンコードされたURLをリダイレクトしてもシステム側でデコードできない ⇒ 対応見送り…
まとめ - DBまで変えるとまず間違いなく不整合は発生する ⇒コア機能については事前に同等のバリデーションをかけるべき - 暗号化ハッシュ化ロジックの置き換えには注意 - 新旧の機能仕様・データ移行の実装・フロントの実装すべての認識のすり合わせは怠らず - できることなら全て一度にリニューアルしないことをおすすめします
次はあなたの番かもしれない
ありがとうございました LearnLanguage2019 @da_ponta