読者です 読者をやめる 読者になる 読者になる

品質をトゥギャザーするために、不具合を見える化している話

こんにちは、freeeでQAエンジニアをやっている西出(@ichikoich)です。freeeのQAエンジニアは、E2Eテストを作ったり、ドメインスペシャリストを巻き込む仕組みを作ったり、手動テストのアウトソースをしたり、品質に関する様々なことをしています。

その中でも今回は、不具合の見える化にフォーカスして話します。freeeでは不具合のことを「ハッピー」と呼んでいます。(ハッピーと呼ばれている背景

難しい運用

今までもハッピーの見える化にはトライしていたのですが、いろいろな問題がありました。

freeeでは長年、不具合報告に関するサポート⇄エンジニア間のコミュニケーションやタスク管理をAsanaのタスクとして起票することで運用していました。この運用をはじめた当時のAsanaには、タスクに「対応中」や「デプロイ待ち」というような「ステータス」を表現できるフィールドがなかっため、「すぐ対応する」「あとでやる」のような「優先度」と同じフィールドで「ステータス」を管理していました。

<Asanaの画面例>

f:id:ichikoich:20170428133518p:plain

例えば、「すぐ対応する」に振り分けられているタスクを、エンジニアが修正に取りかかるときには、「開発者対応中」ステータスに変更します。ところが、それをすると、優先度の情報が消えてしまいます。逆もしかりで、優先度をつけると、ステータスの情報が消えてしまいます。

温かみのある見える化

Asana上の不具合の報告数や消化数の見える化は、Googleスプレッドシートで運用していました。最初はシンプルで、Google App ScriptでAsanaのAPIを叩いて調理するだけでしたが、エンジニアやサポートの運用が変わるたびに、集計が複雑になってしまい、いつの間にか集計するのに1ヶ月にトータル30時間ほどの手作業が発生するようになっていました。

f:id:ichikoich:20170428133600p:plain

もちろん、ステータスや優先度の情報がよく消えるため、集計した結果も正しいとは限りませんでした。

品質トゥギャザーの誕生

そこで、思い切って、仕組みを変えて定量的に品質改善を測定できるようにしました。この取組みを品質トゥギャザーと呼んでいます。品質を良くしていくためには、みんなでやっていくのが一番ということで、印象づけのためにトゥギャザーと連呼していくことにしました。

JIRAとembulkとRedshiftとRedashをトゥギャザー

まず、より正しく情報を扱うために、AsanaからJIRAへ移行しました。チケットのステータスと優先度が別々のフィールドであるのはもちろんですが、それ以上に柔軟にカスタマイズができることがJIRAへ移行した理由です。これまでビジネスや組織の成長により、集めたい、見たい情報やその運用が変わっていくことを経験してきたので、柔軟にカスタムフィールドを追加したり、ワークフローをシステム上で定義できることが魅力的でした。また、バグトラッキングツールとしてマジョリティなので、他サービスとの連携プラグインが豊富にあるところにも将来性を感じました。

次に、集めた情報を調理しやすいように、スプレッドシート × Google App Script からRedshift × Redash に切り替えました。データの調理がしやすいように、会社の中の様々な情報をできるだけひとつのデータウェアハウス(freeeではRedshiftを採用)に蓄積させていきたいので、デイリーでJIRAの全チケットをAPI経由で取得し、Redshiftに保存しています。毎日作られるチケットはそれなりの量になりますが、バルク処理に特化したembulkを採用することで簡単に実現することができました。treasure-data/embulk-input-jira というJIRA用のインプットプラグインを使っています。

あとは、Redash上で集計用のSQLを書いておけば、グラフや表などの見える化されたものが日次で更新されるので、コストほぼ0で最新の集計結果を見ることができるようになりました。

f:id:ichikoich:20170428134124p:plain

RedshiftやRedashなどの仕組みは既にfreeeが誇るすごいデータ基盤エンジニア(@krt)が構築していたので、ただそこに乗っかるだけでした。あっ、すみません、トゥギャザーですね。

freeeのデータ分析基盤について speakerdeck.com

ビジネスチームもトゥギャザー

社内の誰もが簡単にハッピーを起票できるように、JIRAに直接起票するのではなく、質問形式のGoogleフォームに用意しました。起票される内容に不具合の内容や発生条件などの対応に必要な情報の漏れがないようにするためです。Asanaの時も一部の製品に関してはGoogleフォーム経由での起票を試しており、これが好評だったのでJIRA移行を機に全製品のハッピー起票をGoogleフォームにしました。

f:id:ichikoich:20170428134224p:plain

実は、JIRA移行する時に一番苦労した点はハッピー運用フローの構築でした。Asanaでは、運用自体が複雑だった上に、エンジニアと他チームの責務分担や優先度の認識が明確ではありませんでした。そこで、各チームの関係者と一緒に話をして下記のような運用を明確にして、そこからフローを改善していくことにしました。明確なベースがないと改善していくことはできないので、大きな一歩だと思います。

f:id:ichikoich:20170428134316p:plain

エンジニアもトゥギャザー

freeeのエンジニアはローテーションでハッピーの対応を担当しています。この対応エンジニアたちをハッピーピーポーと呼びます。ハッピーピーポーは毎朝集まってハッピー朝会をします。ハッピー朝会ではハッピーピーポーたちが物理的に集まって2つのことをやります。

  • 新しく起票されたハッピーの優先度振り分けと一次回答
  • ハッピーのアサイン

これをみんなでやることで、ハッピーによるユーザのインパクトや、解決までにどれくらいの時間がかかりそうかが共有されるのを期待しています。始めた頃はみんなでやるのは高コストかなと思っていましたが、やっていくと今まで知らなかったことをたくさんインプットできるので、しばらく続けていきたいなと思っています。

f:id:ichikoich:20170428141042j:plain

簡単にハッピー消化のパフォーマンスが見られるようになったため、ハッピーピーポーを増やさなければまずいのか、逆に減らしても大丈夫なのかといったこともアラートしやすくなりました。

おわり

品質の可視化を話そうと思ったら、トゥギャザーの話ばかりになってしまいました(「・ω・)「

トゥギャザーしていきましょう!!

ビジネスチームを支える縁の下の力持ちGYOMUハック

エンジニアをしている廣野(@mirygoaround)です。今日はGYOMUハックというエンジニアとしてもちょっと特殊な立場にいる私の仕事についてお話します。

freeeという会社は、2012年7月に創業してから急激な勢いで成長を続けています。 そして、最初はエンジニアだけだった会社も、サポート、マーケティング、セールスとどんどんと違う役割のチームを増やしてきました。

ビジネスチームの人数が増えたとき、彼らの業務をエンジニアリングで支える役割が必要となりました。 それが、GYOMUハックという役割です。

2017/04/26にGYOMU Hackers Night vol.1〜ビジネスチームを支える立役者・業務効率UPの仕組みづくりをするGYOMUハックエンジニアのつどい〜というイベントを行います。そこで同じような仕事をしている方と交流できればと思っていますので、気になる方はぜひご参加ください!(`δωδ´)

GYOMUハックのミッション

GYOMUハックというチームのミッションは、社内の各チームが突き抜けた生産性で働ける環境をつくるために、業務の観察を通じて本質的な問題点を見つけ、適切なソリューションで解決することにあります。

具体的に、ビジネスチームの実現したいことにあわせてfreeeのプロダクトを修正したり、ビジネスチームで利用しているSalesforceというツールをカスタマイズしたりしています。

すごい勢いで成長してきた社内のビジネスチームは、たくさんのアイデアややり方を無理くりつなげて業務を回してきた面もあり、管理コストが高かったり、作業コストが高かったりします。 そんな彼らの業務を支え、改善に導くのがGYOMUハックという仕事です。

きれいな庭をつくるおしごと

GYOMUハックの仕事は、きれいな庭をつくることに似てるかなと思っています。

ゴミだらけの荒地を想像してみてください。 その荒地をきれいな庭にするためにはステップがあります。

  1. ゴミを取り除く
  2. 土を耕す
  3. きれいな芝を育てる
  4. 池やオブジェクトをおく

このステップがすごくGYOMUハックの仕事に似ていて、

  1. 目に見える課題・リクエストをつぶす(ゴミを取り除く)
  2. チームが本来の力を発揮できるように導く(土を耕す)
  3. もっとよくするためのHackをする(きれいな芝を育てる)
  4. みんながビックリするような大改善をする(池やオブジェクトをおく)

こんな感じで各チームの状況を把握しています。

f:id:mirygoaround:20170410141130p:plain 1をこなすための労力は、ぶっちゃけ頭数さえあれば大したことありません。 頑張ってゴミ掃除すればいいだけです。

目に見えている課題については潰して、リクエストに関してはヒアリングをして本当にそのリクエストが妥当なのかの精査をしつつリクエストをこなします。 ここでちょっと気をつけないといけないのは、上がってくる課題やリクエストが本当のボトルネックではないことがあることです。 その辺りも見極めながらゴミ掃除をします。ゴミの分別みたいなものです。

f:id:mirygoaround:20170410141137p:plain 2をこなすためには、目に見えない課題を発見する必要があります。地中に巨大な石が埋まってるかもしれないし、土に栄養がなかったり毒素があったりするかもしれません。それを見つけて一つづつ解決していくのには時間といろんな人の協力が必要です。

一度出来上がった仕組みを壊して組み立てることも辞さず、より良い仕組みを考え、新しくしていくフェーズです。 巨大な石をそのままにしておいたら、木を植えようと思っても根っこが伸びないですよね。なので土を一回掘り起こして石を取り出して、また土をきれいに戻すということをしないといけません。

f:id:mirygoaround:20170410141142p:plain 3は、整った地盤で何をやるかを考える必要があります。 この頃になると、ビジネスチームはある程度戦略的に業務を回すことができてきているので、そこに+αをするのがGYOMUハックの仕事になります。今まではマイナスをゼロ、あるいはプラスに転じさせる仕事でしたが、ここからはさらになにをするか、にかかってくるのです。

各チームのミッションに沿って、彼らの武器となるべき仕組みを投入していきます。

f:id:mirygoaround:20170410141150p:plain 4は完全に発想力を求められます。考えもつかなかったような大Hackが生まれるかもしれません。そのための発想力が必要です。

今までやってきたことから離れて、こういう仕組みを入れたら劇的に変わるのではないか。どうあるのが理想なのか。というふうに脳みそをフル回転させないと、庭に置くべきかっこいいオブジェクトを思いつきません。freeeの価値基準の一つである「理想ドリブン(理想から考える。現在のリソースやスキルにとらわれず挑戦しつづける。)」でGYOMUハックとしても挑戦を続けています。

実際にやっていること

効率化する、改善する、と一言で言ってもやり方は様々ですが、私はエンジニアなのでやはり開発をします。

ビジネスチームのメンバーが利用するための機能を埋め込むためにfreeeのプロダクトを修正することもありますが、私が触ることが多いのはSalesforceです。 freeeでは、プロダクトでサインアップするとSalesforceに連携する仕組みがあります。その連携周りを修正したり、Salesforceのカスタマイズそのものを行ったりしています。

Salesforceの開発はApexという独自言語で行われていますが、最近作ったものだと、セールスのメンバーがコールするための一覧をSalesforce標準のレポートから作成する機能などが結構大きめの案件でした。

その他にもfreeeを利用する税理士さんのために事業所を大量に作成する機能を作るためにRubyを触ったり、ビジネスチームが利用したいデータを取得するためにSQLを書いたりと、いろいろなことをやる日々です。

苦労する点としては、開発言語のコンテキストスイッチもそうですが、各チームでやる業務内容も全く違うので、関わる案件ごとのコンテキストスイッチもかなーり大変です。ミーティングも多くまとまった実装時間が取れなかったりもします。

しかしfreeeのミッションは「誰もが創造的な活動ができる社会」「スモールビジネスが強く、かっこよく活躍する社会」を実現すること、なので、私も「freeeのビジネスチームが創造的な活動ができる」ことを目指して日々Hackを続けています٩(๑òωó๑)۶

さいごに

エンジニアというとプロダクトの開発に携わる人をイメージするかもしれませんが、GYOMUハックのような仕事をしている人もいるんだよ、というところを少しでも知ってもらえたらなと思います。

Electronの入門書を書きました

こんにちは、エンジニアの野口(@joe_re)です。

freeeでは会計の法人向けの機能開発を主に担当しています。 この度Electronの入門書を執筆しましたのでご紹介させていただきます。

Electronを用いたアプリケーションでは、CafePitchというMarkdownで書けるプレゼンテーションツールを個人で作っています。まだまだ発展途上ですが、これからも開発していくつもりですので、もし興味がおありの方はお試しください :) (そしてフィードバックをいただけるととてもありがたいです!)

書いた本は「Electronではじめるアプリ開発 ~JavaScript/HTML/CSSでデスクトップアプリを作ろう」です。

f:id:ymrl:20170327210736p:plain

Electronではじめるアプリ開発 ~JavaScript/HTML/CSSでデスクトップアプリを作ろう

Electronではじめるアプリ開発 ~JavaScript/HTML/CSSでデスクトップアプリを作ろう

本書は株式会社WACUL@Quramyさんと共著で書かせていただきました。

査読は@Linda_ppさん、@bokuweb17さん、弊社メンバーから和暦に情熱を燃やす男こと@_tohashiさんにお願いしました。

おかげさまで、本の精度を格段に高めることができました。ありがとうございました。

内容紹介

本書は「JavaScriptはある程度わかるけど、Electronでの開発には経験がない人」を対象にした、Electronの入門書です。

  • JavaScriptの基礎があれば取りかかれる
  • 手を動かして、実際にアプリケーションを作って学べる
  • 1通りやれば、Electronのアプリケーションを作る上で必要なことが身につく

といったことを目標としています。

以下が目次です。

  • 第1章 Electronとは何か
  • 第2章 開発の流れを体験してみよう
  • 第3章 チャットアプリケーションを作ろう
  • 第4章 Markdownエディタを作ろう
  • 第5章 キャプチャアプリケーションを作ろう
  • 第6章 テストを書こう
  • 第7章 アプリケーションの配布
  • 第8章 安全なアプリを作るために

各章はチュートリアル形式になっていて、実際にアプリケーションを作っていく流れの中で、Electronを用いたデスクトップアプリケーション開発に必要な知識やテクニックを身につけられるようにしています。

アプリケーション開発では、3章、4章、5章の「チャットアプリケーション」「Markdownエディタ」「キャプチャアプリケーション」をメインの題材にしています。

加えて、SpectronというElectronのE2Eテストのフレームワークを用いたテストや、配布時のパッケージング、セキュリティ面で気をつけるべきことを盛り込んでいます。

入門向けの内容なので、本書1つあればElectron開発を極められるというものではありませんが、開発環境の構築を含むElectronのアプリ開発から配布までの流れの中で、基本的なことは1通りカバーしています。

Electronを用いたデスクトップアプリケーション開発に興味はあるけど、まだ手を出せていないという方の一助になれば幸いです。

本著は本日(3/28)発売になります。

会計ソフトを作る上で避けては通れない和暦の話

エンジニアの大橋 @_tohashi です。会計freeeで確定申告や記帳機能などの開発を担当しています。

Webに限らず、日本向けのアプリケーションにおける特有の要素として和暦があります。プロダクトによっては最初から和暦を扱わずに西暦に統一してしまうという手もありますが、弊社のプロダクトのように会計や労務管理に関わるものの場合、決算書上の表記など和暦が必要とされる場面は多々あるため避けて通ることはできません。本記事ではUIや実装における和暦の扱いについてご紹介したいと思います。

f:id:t930:20170321155846j:plain

和暦の範囲

そもそも「和暦」とはどこからどこまでの期間を指すのでしょうか。Wikipediaによれば

和暦(われき)は、元号とそれに続く年数によって年を表現する、日本独自の紀年法である。邦暦(ほうれき)とも。また「和暦」は、西暦に対する表現としても使用されることが多い。 この手法自体は東アジアで広く行われてきたが、日本独自の元号を用いているため日本固有の紀年法となる。飛鳥時代の孝徳天皇によって西暦645年に制定された「大化」がその始まりであり、以来15世紀に亘って使われ続けてきている。 たとえば、西暦2000年は平成12年に当たる。明治改暦(明治6年/西暦1873年)以降、グレゴリオ暦を採用しており西暦とも月日が一致している。

とかなり広い期間が和暦とされています。

一方、日時の国際標準規格である ISO 8601 の日本独自の拡張である JIS X 0301 では、グレゴリオ暦に改暦された明治6年1月1日以降を規格の適用範囲内としています。

実際に利用する範囲から考えてみると、例えば弊社のプロダクトで日付入力が発生する箇所としては

  • 取引の発生日
  • 従業員の誕生日
  • 会計期間の設定
  • 固定資産の取得日

などがありますが、固定資産の耐用年数は最長でも水道用ダムの80年、公式に認定されている寿命の最長記録は122歳です。この場合システム上における「和暦」は、2017年現在においては JIS X 0301 の通り明治6年1月1日以降を考慮しておけば問題ないと言えるでしょう。

UI

日付選択UIにおける和暦の扱いとしては例えば下記のようなものが挙げられます。

元号選択

f:id:t930:20170321140018g:plain

和暦をユーザーに選択させる方法です。直感的ではありますが、入力したい年が西暦でしかわからない場合は調べる必要があります。実装面では「昭和100年」といったケースのバリデーションや、DBにDate型のカラムとして保存するのであればどこかでキャストするといった事が必要になります。

西暦と併記

f:id:t930:20170321140032g:plain

西暦と和暦を併記する方法です。西暦・和暦の片方しかわからなくても入力可能ですが、セレクトボックスが縦に長くなりがちという欠点もあります。

DatePicker

f:id:t930:20170321140034g:plain

JavaScriptによる実装もありますが、画像は Google Chrome において input type="date" を使用したもの1です。前後1年間ぐらいの日付を選択するのには便利ですが、生年月日のように数十年遡るような場合はあまり向いているとは言えないでしょう。

自由入力

f:id:t930:20170321140036g:plain

西暦・和暦どちらも入力可能にしておき、適宜パースして扱う方法です。扱うフォーマットの数によっては実装コストがそれなりに大きくなるでしょう。

いずれもメリット・デメリットがあるので、日付の用途に応じて最適なUIを選択していくのが大事ですね。

実装

続いて実装面における和暦の扱いを言語ごとに見ていきます。

Ruby

Ruby の Date クラスには JIS X 0301 書式の日付を返す jisx0301 というメソッドが用意されているため、このように簡単に和暦を得ることができます。

require('date')
Date.new(2017, 3, 15).jisx0301 # => "H29.03.15"

境界値も問題ありません。

Date.new(1989, 1, 7).jisx0301 # => "S64.01.07"
Date.new(1989, 1, 8).jisx0301 # => "H01.01.08"

上述したように明治6年以前は JIS X 0301 の対象外であるため、そのまま西暦(ISO 8601 拡張形式)が返ります。

Date.new(1873, 1, 1).jisx0301 # => "M06.01.01"
Date.new(1872, 12, 31).jisx0301 # => "1872-12-31"

逆に和暦をパースすることも可能です。

Date.parse('H29.01.01') # => #<Date: 2017-01-01 ((2457755j,0s,0n),+0s,2299161j)>
Date.parse('S50.01.01') # => #<Date: 1975-01-01 ((2442414j,0s,0n),+0s,2299161j)>

JIS X 0301 の範囲外でもパースできますが、グレゴリオ暦と太陽太陰暦のずれが考慮されていない点は留意が必要でしょう。

Date.parse('M5.12.31') # => #<Date: 1872-12-31 ((2405159j,0s,0n),+0s,2299161j)>
Date.parse('M1.01.01') # => #<Date: 1868-01-01 ((2403333j,0s,0n),+0s,2299161j)>

ちなみにこのような日付もパース可能です。

Date.parse('M50.01.01') # => #<Date: 1917-01-01 ((2421230j,0s,0n),+0s,2299161j)>

Java

locale を ja_JP_JP に設定することで和暦への対応が可能となります。

import java.util.*;
import java.text.*;

public class Wareki {
    public static void main () {
      Locale locale = new Locale("ja", "JP", "JP");
      Calendar calendar = Calendar.getInstance();
      DateFormat dateFormat = new SimpleDateFormat("Gyy.MM.dd", locale);

      // 西暦から和暦へ
      calendar.set(2017, 2, 20);
      dateFormat.format(calendar.getTime()); // H29.03.20

      calendar.set(1989, 0, 7);
      dateFormat.format(calendar.getTime()); // S64.01.07

      calendar.set(1989, 0, 8);
      dateFormat.format(calendar.getTime()); // H01.01.08

      calendar.set(1872, 11, 31);
      dateFormat.format(calendar.getTime()); // M05.12.31

      // 和暦から西暦へ
      dateFormat.parse("H29.01.01"); // Sun Jan 01 00:00:00 JST 2017
      dateFormat.parse("M6.01.01");  // Wed Jan 01 00:00:00 JST 1873
      dateFormat.parse("M1.01.01");  // Wed Jan 01 00:00:00 JST 1868
    }
}

Ruby と異なり明治6年以前もそのまま和暦に変換されるため、厳密には JIS X 0301 に準拠していないとも言えます。

その他

他にも Swiftなでしこなどが和暦に対応しているようですが、多くのプログラミング言語はそうではないため、ライブラリを使うか自前で変換ロジックを用意する必要があります。

例えば JavaScript では日付を扱うライブラリとして Moment.js が有名ですが、残念ながら和暦には対応していないようです。以下は西暦を和暦に変換する拙作のライブラリ wareki を基にした実装の一例です。

const eraDataList = [
  {
    code: 'H',
    firstDate: '1989-01-08',
  },
  {
    code: 'S',
    firstDate: '1926-12-25',
  },
  {
    code: 'T',
    firstDate: '1912-07-30',
  },
  {
    code: 'M',
    firstDate: '1873-01-01'
  }
];

function fillZero(value) {
  return `0${value}`.slice(-2);
}

function toWareki(value = Date.now()) {
  const dateObj = new Date(value);
  const year = dateObj.getFullYear();
  const month = dateObj.getMonth() + 1;
  const date = dateObj.getDate();
  let wareki = value;

  for (let i = 0; i < eraDataList.length; i++) {
    let eraData = eraDataList[i];
    let eraFirstDateObj = new Date(eraData.firstDate);
    if (dateObj - eraFirstDateObj >= 0) {
      let eraYear = year - eraFirstDateObj.getFullYear() + 1;
      wareki = `${eraData.code}${fillZero(eraYear)}.${fillZero(month)}.${fillZero(date)}`;
      break;
    }
  }
  return wareki;
}

toWareki('1989-01-01');
// => "S64.01.01"

新元号について

現在、天皇陛下の譲位に伴い平成31年元日より新元号となることが検討されています。当然 JIS X 0301 においてはまだ未定義のため、現時点では未来の日時は全て平成として扱いつつ、新元号の制定に伴うアップデートの準備をしておくのが良さそうです。

さいごに

日付を扱う上で和暦の対応は面倒なところもありますが、本記事が一助となれば幸いです。

ちなみに僕は昭和64年生まれなのですが、たまにこういう悲しい目に合います。

f:id:t930:20170321140039p:plain

freeeでは和暦にこだわりのあるエンジニアを募集しています!


  1. 一部ブラウザでは未対応