こんにちは。エンジニアの片岡です。
最近の大きな出来事として、w2の改善合宿に参加してきました!
そこで今回はw2の改善合宿とは何なのかと、その成果物について紹介します。
目次
改善合宿について
改善合宿とは
製品の根本となる部分の改善や、より開発を楽にする仕組みづくりなど、普段の業務ではできないことを行うための合宿です。
今ある製品の保守を続けるだけでは新たな技術についていけなくなってしまいます。製品をよりよくするために、そして、会社の成長によってメンバーが増加するに伴って、新たな試みを試す場として開催されるのが「改善合宿」です。
毎年CTOを含む5名前後のEGが集まり、オフィスとは別の場所で業務から隔離された状態で行います。
今年は富士山の見える河口湖周辺で改善合宿が行われ、コロナ対策もあり普段より少ない4人のメンバーで開催されました。
改善合宿に参加して
今回はこの4人のメンバーのうちの1人として選んでいただき、参加することになりました。昨年の改善合宿を見て参加したいと思っていたためとても嬉しかったです。
昨年参加された方の記事はこちら → 離島で開発!?w2の改善合宿
改善合宿では、w2のValueの中にもある Work Hard, Play Hard ということで様々なイベントも行いました。
BBQをしたり、河口湖を自転車で一周したり、樹海の洞窟に入ったり、バギーに乗ったり・・・ 平日は業務、休日は懇親会も含めたアクティビティと、とても充実した1週間でした!
また、最も大きかったメリットとして、業務から離れているためチャットを無視して作業を進められるという点があげられました。
スイッチングコストというものは自分が思っている以上に響いているなと感じましたし、今後は「この1時間だけは何があってもこのタスクに集中する」みたいな時間を作るのもありなのかなと思いました。
改善合宿については他の方も書いておられるのでこの辺にして、本題である成果物の紹介に入っていきたいと思います。
成果物について
概要
今回私が作成したものはCheckListCreatorというWebアプリケーションです。
かんたんにチェックリストのテンプレートが作成でき、そのチェックリストを使ってチェックを行った後エビデンスとして保存することができます。
下の画像はチェックリストを作成する画面と、作成されたチェックリストです。自由に項目を増やしてチェックリストを作成できます。
1週間(約40h)という短い時間の中、1サービスを作成するという難易度の高いゴールに取り組みました。
制作背景や実装方法等を細かく書いていきますので、ぜひご覧ください!
制作背景
w2では作業の漏れを防ぐため、エビデンスを残すため、業務の中で様々なチェックリストを利用しています。
しかしチェックリストの管理は各チームに一任されており、各チェックリストの置き場も様々、形式もExcelであったりBacklogに残したりとバラバラですし、古いバージョンのチェックリストを使いまわしていて項目が追加されていることに気付かないことも。。。
そこで、テンプレートを1か所で管理でき、使いやすく、チェックをすることが苦痛にならない、楽しくチェックが行える仕組みづくりということで開発に取り組みました。
機能要件
楽しくチェックできるということで見やすいこと、アニメーションがあり動きが楽しいことは必須です。
またストレスをなくすために動作が重くなく使いやすいこと、メンテナンスがしやすいことを意識し、今回は更に下記の機能を加えました。
- Webページ上でチェックしてローカルにhtmlファイルとして保存できる
- 1度保存したファイルをローカルで更新でき更新日が記録される
- 目的のリストに早く到達できるように検索機能などを設ける
などなど。
実装方法
要件を上げていきましたがそれ以外にも様々な工夫を凝らしています。
しかし全ての内容を話すと長くなりすぎてしまいます。
今回はWebアプリケーションの設計にあたって考えたことを中心にまとめていきます。
使用した技術について
初めに、作成にあたってフレームワーク等を検討しました。
検討の結果・・・
せっかくの改善合宿なのでなるべく1から自分の手で作成することにしました!
別のWebアプリケーションを作る際にはプラグイン目当てでWordPressを土台にして作成したこともありましたが、どうしても重くなってしまいました・・・
やはり無駄なコードがないというのはWebアプリケーションの軽さにつながります。
使用言語は HTML, CSS, JavaScript (jQuery, Ajax), PHP
DB は SQL Server を利用しています
PHPファイル1枚1枚、CSSの最初の行からすべて自分で書いています。
PHP ↔ DB へのアクセスは PDO を利用しました。
画面設計
画面設計については重複部をなるべく省くためパーツ管理し、親ページがURLのパラメータによってコンテンツを内容を出し分ける形式としました。
- 親ページ
- [PHPの共通クラス]
- ヘッダー
- [CSSファイル]
- フッター
- [JSファイル]
- サイドバー
- ページのコンテンツ(追加・一覧・詳細・Wikiなど)
- 各コンテンツの内容
- [各コンテンツの処理]
こうしておくことでフッターの文言を変更したい場合に、全ページ分のPHPファイルを編集しなければいけないとかそういったことがなくなりますね!
DB設計
次にDB設計についてです。こちらはあまり人によって工夫のしようはないと思いますが、
- テンプレートテーブル(PK:テンプレートID)
- チェックリストテーブル(PK:テンプレートID, アイテムNo, FK:テンプレートID)
の2つを用意しています。
テンプレートテーブルはテンプレートの内容を保存しておくテーブルです。そのままですね。
チェックリストテーブルはテンプレートIDを主キーの1つとして持っていることからわかるように、テンプレートに対して複数紐づいており、一つ一つの入力項目を表しています。
この設計により、1つのチェックリストテンプレートにチェック項目を複数自由に設定できる状態を実現しています。
今回はユーザーテーブルやチェックリストに入力した内容を保存しておくテーブルの実装を見送りました。
ユーザーテーブルについては作成者がわかったり権限周りが設定できるという利点もあったのですが、やはりログインが手間という欠点が大きく、社内ツールであることから悪用するものはいないだろうと性善説を信じることとしました。
Wikiにも書いておいたので安心です!👍
チェックリストに入力した内容についてはローカルに保存でき、ローカルに保存したファイルを編集することもできるのでなくてOKという判断ですね。
htmlダウンロードの実装
このチェックリストで最もこだわった部分になります。
1度にすべてのチェックリストをチェックできるのであればいいのですが、ちょっと別の仕事をしたい場合など一時保存したいときありますよね。
1回保存したらHTMLが読めないと編集できない仕様などはナンセンスです。
であれば、自分のHTMLファイルに書かれているデータを表示の際に復元、その場で変更でき、保存ボタンを押すともう一度保存される必要がありました。
それを実現するために利用したのがBlobです。
JavaScriptのinnerHtmlなどを駆使してチェックリストの部分のみのHTMLを取得します。
JSやCSSが効くように相対パスで記載されている部分については絶対パスになるようにデータで置き換え、各チェックボックスの状態や入力されているテキストなども反映します。
// チェック状態を設定
var checkboxes = checklist.querySelectorAll(".checklist-item .checkbox");
for (var i=0, n=checkboxes.length; i<n; i++) {
if (checkboxes[i].checked) { checkboxes[i].setAttribute('checked', 'checked'); }
}
いい感じにhtmlタグやbodyタグで囲んだhtmlのテキスト情報をBlobに変換し、ダウンロードします。
// ソースコードを Blob オブジェクトに変換してURLを取得
var blob = new Blob([doctype, '\n', htmlTag, '\n', head, '\n', '<body>', '\n', src, '\n</body>\n', foot, '\n</html>']);
var url = window.URL || window.webkitURL;
var blobURL = url.createObjectURL(blob);
// <a> を新たに作成し、ダウンロード用の設定をいろいろ
var a = document.createElement('a');
// URI を元にダウンロード時のファイル名を決定
a.download = decodeURI(location.pathname+location.hash).replace(/\//g,'__').replace(/#/g,'--') + '.html';
a.href = blobURL;
a.click();
こうすることによって画像のように、JS、CSSが効いており、保存時の入力状態が保持されている、チェックリスト部だけのhtmlファイルが保存されるというわけですね。
もちろんJSは読み込めていますので、もう一度保存ボタンを押せば新たなhtmlファイルとして保存されます。
保存する際に更新日時を自動で入れるようになっていますので、新たに保存されたファイルを最新ファイル、今触っているファイルをoldファイルとして残すことで更新履歴のように扱うこともできますね。
運用方法によってかなり自由度の高いものに仕上がったと思います。
Version Up
先ほどの項目でローカルに保存したチェックリストもサーバーのJSやCSSを読み込めるようにしていると言いました。
では本体の方でDOMを変更し、それに伴ってCSSを変更した場合はどうなってしまうのでしょうか?
もちろんhtmlとしてローカルに保存しているのでDOMは変わりません。
しかしCSSはサーバー上のものを読みに行くため最新のものを見ます。
その結果デザイン崩れが起きてしまう懸念がありました。
ここが最も頭を悩ませた部分かもしれません。
もちろんCSSやJSの中身を全部まとめてローカルに保存してしまう選択肢もありましたが、ファイルが長くなりすぎたり、複数ファイルになってしまったりというデメリットがあります。
そこで考えたのが、CSSをバージョン分けするという方法です。
最初ローカルにダウンロードされたチェックリストはCommonV1.cssを読み込んでいるとします。
大きなデザインの変更があった際はサーバー上のCommonV1.cssをベースにCommonV2.cssを作成し、Webからアクセスした場合はそのCSSを読み込むようにします。
こうすることで、V1の時点でローカルにダウンロードされたチェックリストはV1のCSSを、V2になってからローカルにダウンロードされたチェックリストはV2のCSSを読み込むという設計となりました。
サーバーにCSSファイルがたまっていくことだけが難点ですが、「追加」ではなく「DOMの変更」に対応するCSSの変更は相当珍しいと思うので、大きな問題にはならないかと思います。
まとめ
いかがだったでしょうか?
飛ばし飛ばしでわからないことも多かったかと思うのですが、Webアプリケーションを作成するときどんなことを考えて設計しているのか、各要件をどのようにして実現しているのか、少しでも参考にしていただければ幸いです。
また、今回は設計部分について紹介したのですが、次回は細かい面で使いやすいようにとこだわった個所について取り上げようと考えています。
利用する方向けの内容となってしまい申し訳ないのですが、もしかしたら皆様が何かサービスを作る上でのヒントがあるかもしれませんのでぜひお楽しみに!
コメント