スクラムの取り組みをメンバー視点で見る

f:id:kubotak:20220112183348p:plain

こんにちは、こんばんは、kubotak(@kubotak_public)です。

昨年末より弊社では「真のスクラム」という名のスクラム開発を実施しています。
今までは「なんちゃってスクラム」というわけではないんですが、スクラム開発のエッセンスを多少取り入れたような今にして思えば全くスクラム開発ではないなにかをやっていました。

私はスクラムマスターではなく「真のスクラム」を熱く語れるわけではないのでメンバー視点で「真のスクラム」になった結果何が変わったのかを紹介したいと思います。

スプリントが2週間から1週間に

以前は1スプリントを2週間として実行していました。
これを1週間と短くし、月曜日にスプリント計画、金曜日にスプリントレビューとレトロスペクティブを行うように変わりました。
私個人としては短くなったことで単純に忙しないな!と思うのと、開発時間の多くは火・水・木曜日になり余計に短いと感じます。
また、短くなったことで以前に比べるとスプリント全体で完了する成果物の大きさが小さく・細かくなりました。
小さいサイクルを回してすぐに出すことでよりアジャイルな開発になったのかなと思います。

スプリント計画をメンバー全員で実施

以前はPO及び一部のメンバーでスプリント計画を実施し、タスクのポイントなどをつけていました。
これを全員で実施するように変更しました。
プランニングポーカーを用いてデザイナー含めたスクラムメンバー全員でタスクに対するポイントを出し合い、合議により見積もりを行っています。
これによりメンバー全員が個別のタスクの詳細を理解することができ、誰がタスクにアサインされても問題ない状態になりました。
もちろんタスク毎に向き不向き、得意不得意があるかもしれませんが全員で見積もり行うことで平均化されますし、そのタスクに必要な情報の詳細を持っている人が明確になるので聞きに行くということも可能になります。

今までは一部のメンバーしか情報を共有できていなかった部分も、透明性が上がったといえると思います。

タスクにユーザーストーリーとACを追加

タスクにはユーザーストーリーが追加され、なぜ、誰のためにその実装が必要なのかを明文化しました。
また、ユーザーストーリーとともにAC(acceptance criteria)も追加し、そのタスクはどういう状態であればユーザーストーリーが完了になるかも明文化されました。

この2つは作業者としては非常に重要で、「なぜわたしたちはこのプロダクトを作っているのか」が明確化されて納得感を持ってタスクに取り組めます。
また、何を持ってこれは完成と言えるのかも記載されているので品質の担保ができます。
そしてこれは自動テストのストーリーとしても役立っています。

DoD(完了の定義)はタスク毎ではなく全体の完了の定義としているため、ここではACを取り上げています。(完了と受け入れ基準の定義 Definition of Done vs Acceptance Criteria

スプリントレビューを実施

PO以外にも、タスクにおけるユーザーストーリーから影響がある人を呼んでそのスプリントで完成したプロダクトを見たり触ったりしてもらうような時間を作りました。
このとき、「顧客が本当に欲しかったもの」やその顧客に近いCSの声などをフィードバックとしてもらうことができるようになりました。

これにより、「私達が作っていたものは間違っていなかったんだ」という自信を持った上でリリースに挑むことができます。
もちろん実際にはデータを元にその追加機能の優劣は後から判明することとは思いますが、少なくとも「この機能使われないのでは?ほんとに喜ばれるのか?」という不安を払拭し、モチベーション高く開発に挑める良い施策だと思っています。

まとめ

細かい話などはおそらくスクラムマスターから今後紹介されることと思いますが、現在スクラムメンバーとしてスクラム開発を実施して良いなと思った点をあげてみました。
正直最初は新しい用語や取り組みによってやや混乱を覚え「これホントに良い開発できるのか?」と思いましたが初回のスプリントレビューで払拭された感じがします。
スクラム開発によって顧客に向き合った開発ができるようになったんだと実感しています。

さいごに

まだまだスクラム開発駆け出しの弊社ですが、もっと改善したい、一緒にスクラム開発したい、と思った方はぜひ応募ください。
ちなみに、データエンジニアや機械学習エンジニアも積極採用中ですのでお声がけください。

www.wantedly.com

2022年 新年のご挨拶

f:id:kazuhei0108:20220104091310j:plain

あけましておめでとうございます。

M&AクラウドでCTOをしている荒井です。

年末はPythonのFastAPIというフレームワークをいじっていました。APIドキュメントの自動生成機能がついていて画期的なので、どこかで使いたいなあ。

fastapi.tiangolo.com

昨年は大型の資金調達もあり、チームメンバーも増え、とてもにぎやかな1年になりました。

去年末から弊社開発チームは、スクラムの原点に立ち返り、エンジニアだけではなくPOとデザイナーも含むスクラムチームを組成して再出発しました。

せっかくですので、今年からはこのテックブログもエンジニアの枠にとらわれずに、スクラムチーム全体で記事を書いて行けたらと考えております。

それでは本年もよろしくお願いいたします。

記事をお楽しみに!

【Athena】M&Aクラウドの2021年を絵文字で振り返る【使ってみた】

f:id:zacky2:20211220150627j:plain

はじめに

この記事はM&Aクラウドアドベントカレンダー2021の21日目の記事です。

adventar.org

みなさんどうもこんにちは。エンジニアの津崎です。 普段はPHPとTypeScriptを使ってマッチングプラットフォームの開発を行っています。

今日はデータ分析全然わからないけどやってみチャオ!というノリで、M&AクラウドのSlackで使われている絵文字の使用数ランキングを出してみました。 分析にはAWSのデータ分析ツールであるAthenaを使っています。 Athenaを使って実際にデータを分析するのは今回が初めてだったので、SlackのメッセージデータをAthenaに格納する作業に時間の9割が持っていかれました。

結果発表🎉

まずは、集計結果をみてましょう!

(再生ボタンをクリックしてください)

動画版はこちら:

youtu.be

  • 集計物:メッセージに対するリアクションとして使われた絵文字の使用数(メッセージ本文の絵文字を含まない)
  • 対象チャンネル:publicチャンネルすべて
  • 対象の絵文字:カスタム絵文字
  • 対象期間:2021/01/01 ~ 2021/12/13 くらい
  • データサイズ: 800MB程度(無圧縮)
  • 分析対象メッセージ:11万

【3位】お大事に

f:id:zacky2:20211218184948p:plain

3位は「お大事に」でした。これは予想外。 f:id:zacky2:20211218185857p:plain

おっと、大丈夫です。M&Aクラウドの社員の健康状態は良好ですよ。 体調不良メッセージに対して「1 Team」な精神で部署をまたいで「お大事に」をつけているので使用数が多くなっているんじゃないかなと思います。

また、別の意味の「お大事に」でも使われているのも使用数が多い要因になっていそうです。

f:id:zacky2:20211218185748p:plain f:id:zacky2:20211218185817p:plain

【2位】1 Team (Fever)

2位は「1 Team」でした。 「1 Team」はM&Aクラウドのバリューの一つです。M&Aクラウドの社員はみんな「1 Team」が好きなのがよくわかりますね。笑 この絵文字は、シンプルに「1 Team」な行動に対してよく利用されます。一丸となって仕事を成し遂げたときや、他メンバーを思いやるメッセージなどです。

f:id:zacky2:20211218185925p:plain

f:id:zacky2:20211218190400p:plain

【1位】 ナイスシェア

f:id:zacky2:20211218182341p:plain

「ナイスシェア」がぶっちぎりの1位でした。 M&Aクラウドのバリュー「1 Team」の要素として「共有・共感・共鳴」があります。「ナイスシェア」というのはまさに「1 Team」を表しているなと思います。 この「ナイスシェア」は、部署間でのよい情報共有や、ニュースやネット記事などの有益な情報をシェアした時、大事なことのリマインドといった「ナイスシェア」なタイミングによく利用されています。

f:id:zacky2:20211218190902p:plain f:id:zacky2:20211218190934p:plain f:id:zacky2:20211218190923p:plain

ランキング振り返り

さて、いかがだったでしょうか? 上位3つとも「1 Team」な絵文字になっていて、M&Aクラウドらしさがよくでたランキングでした。

ちなみに、今回はただのランキングだと面白くないのでBar Chart Raceというグラフ形式で作ってみましたが、 序盤から「ナイスシェア」が独走状態で、2〜4位が熾烈な争いをしている様子もみれて面白かったかなと思います。

個人的には「f:id:zacky2:20211218205855p:plain:w40」が健闘しているのが興味深かったです。これはカスタマサーサクセス部の若手である西川君のためのスタンプです。彼の頑張りっぷりが現れています。

どうやってやったかざっくり

ここからは集計結果ではなく、どのようにこれを作ったかという話をします。

Slackのエクポート機能(手動) 
     ⬇️
S3にアップロード(手動)
     ⬇️
Lambda (Athenaに投入する前にデータの変換処理)
     ⬇️
Glue クローラでテーブル作成
     ⬇️
AthenaでSQLを使ってデータ集計
     ⬇️
Google SpreadSheetで表作成
     ⬇️
flourishでグラフ化 

Lambdaとは、AWSのサーバレスでプログラムを実行してくれるサービスです。サーバを用意せずクラウド上でプログラムを実行できるのでとても便利です。

Athenaとは、AWSビッグデータ分析ツールです。AWSのS3というクラウドストレージに格納されたファイルをSQLで分析できます。最近はS3以外にも色々連携ができてなんでもできる感じに進化しているようです。

Glueクローラとは、S3に格納されたデータを解析してAthenaが分析できるようにテーブル化してくれるものです。

flourishとは、グラフ作成ができるWebサービスです。Bar Chart Raceを簡単に作れるということだったので利用しました。

(以下はエンジニア向けな内容となります。)

今回はAthenaを使ってみたいというモチベーションがあったため、試行錯誤しながら時間をかけて分析の準備を行いました。 簡単に分析したい場合は、PHPなどのお好みのスクリプトJSONを集計してあげれば、数十分程度で集計できるかなと思います。

Slackのエクポート機能(手動)

Slackの標準機能でメッセージのログをエクスポートします。 (これには多分管理者権限クラスの権限が必要です)

S3にアップロード

S3にバケットを作ってファイルをアップロードします。 ZIPだと数十MBなのに解凍すると数百MBになってアップロードに数時間かかりました。

Lambda

SlackのメッセージはJSON形式で保存されているのですが、Athenaで読み込めるJSON形式と違ったため変換の必要がありました。(これに気づくまでかなりの時間を溶かした) Athenaでは1行1オブジェクトの形になっている必要があります。 例えば以下のような形です。

{id:1, text:"taro"}
{id:2, text:"jiro"}

Slackメッセージは簡単にいうと以下のような感じになっていました。

[
  {
    id:1,
    text:"taro"
  },
  {
    id:2,
    text:"jiro"
  }
]

Lamddaの関数を作り、JSON形式を変換する処理を書きました。また、Athenaに食わせるために試行錯誤した結果、以下のような機能も追加しています。

  • メッセージ以外のJSONファイル(channels.json, users.jsonなど)を除外する
  • ディレクトリ名(Slackチャンネル名)をランダム文字列に変換する(ディレクトリ名に日本語があるとGlue クローラーが途中で落ちるっぽい)
  • ディレクトリをフラットにして格納する(Slackチャンネルごとにディレクトリが切られているとクローラーが別テーブルとして認識してしまい、1000個以上のテーブルに分割されてしまうので、苦肉の策として)
  • 処理に最大処理時間の15分以上かかってしまうので、引数で処理範囲を渡して分割して実行できるようにした
    • 本来こういう処理はGlue ジョブでやるべきなのかもしれません

f:id:zacky2:20211218193934p:plain 並列実行が完了した図

Glue クローラーでテーブル作成

Glue クローラーでS3内にある変換後のJSONを解析しテーブルを作ります。 テーブルが1000個以上できたり、途中で処理が止まったりしてかなり苦しめられましたが、Lambda側での工夫によりなんとかなりました。

f:id:zacky2:20211218194144p:plain テーブルを単一にしたくてチェックしても全くいうことを聞いてくれなかった。本当にじゃじゃ馬。

f:id:zacky2:20211218194041p:plain

大量にできてしまったテーブルを100個ずつ手動で頑張って消してる図(SQLスキーマごと消せば簡単であることに途中で気づいた)

AthenaでSQLでデータ集計

待ちに待ったこの瞬間。 10万のSlackメッセージがAthena上から検索できます。 PHPスクリプトで分析すればAthenaにデータを入れるために数時間溶かすことなく分析できたのに、いろいろな苦労を経てようやく分析の準備ができました。

f:id:zacky2:20211218195100p:plain

メッセージが単一テーブルとしてはいった・・・!

f:id:zacky2:20211218195020p:plain

11万レコード!

元のデータがJSONなのでカラムの中に配列データがあり、配列データの中に配列データがあるといったデータ構造をしています。 クエリはSQLなのでMySQLなんかと似てますが、配列の分析をするところでちょっと苦労しました。

いつどの絵文字が何回使われたかを日別で出力します。

WITH reaction_record AS (
    WITH reactions_table AS (
        SELECT client_msg_id,
            reactions,
            ts
        FROM "slack-data"."dest2"
        where reactions is not null
    )
    SELECT date_format(from_unixtime(cast (ts as double)), '%Y/%m/%d') AS date_ymd,
        reaction.name,
        reaction.users,
        reaction.count,
        ts
    FROM reactions_table,
        UNNEST(reactions_table.reactions) AS t(reaction)
)
SELECT reaction_record.date_ymd,
    reaction_record.name,
    sum(count)
FROM reaction_record
group by date_ymd,
    name
order by 
    date_ymd

UNNEST()という関数で配列データを展開してテーブル化したりしています。 調べながらやればなんとかなりました。

f:id:zacky2:20211218200201p:plain

11万レコードありますが、わずか2.7秒で処理が終わっています。 まあ普通のRDSで実行した場合に11万レコードがどのぐらい時間がかかるかはちょっとわかりません。(このデータ量じゃ大差ないかも)

スキャンしたレコードが150MBとなっていますが、無圧縮のJSONだと800MB程度あったはずなので、WHERE句の絞り込みによって余計なデータの読み込みを抑えてくれていそうです。

GoogleSpreadsheetでさらに集計

flourishでBar Chart Raceを作るには以下のような表が必要です。

f:id:zacky2:20211218200841p:plain

AthenaのSQLで上記のような表を作る方法を思いつかなかったので、GoogleSpreadSheetで加工します。

ステップとしては以下です。

  • 2021/1/1 ~ 2021/12/31までの列を作る
  • Athenaで出力した表から特定日の絵文字使用数を取ってくる
  • 上記の表を累積の表にする(前日までの累積+今日の値)
  • 後述のemojiの画像URLを表に追加する
  • カスタム絵文字以外を除外する

カスタム絵文字以外は絵文字の画像URLを取得するのが難しかったため捨てました。 ちなみに、本当に一番使われてる絵文字は「+1 (👍)」でした。

emojiのkeyと画像URLのマッピングを取得する

APIを叩く

curl -H "Authorization: Bearer {token}" https://slack.com/api/emoji.list > emoji.json

csvに変換する

 jq -r ".emoji|to_entries|.[]|[.key, .value]|@csv" emoji.json > emoji.csv

Flourishでグラフ化

app.flourish.studio

簡単にサインインでき、使い方も適当にやったらできました。簡単です。 グラフのグループ化や速度、画像の表示など調整して完了です。

まとめ

以前PHPスクリプトでシンプルなランキングの集計をしたことがあったのですが、 Athenaで分析作業をすること自体が初めてだったので、かなりトライアンドエラーで進めていきました。

  • Lambda ほとんど初めて使った件
    • 実行してログ確認して修正するのめっちゃ地道
    • 15分の実行上限を超えるので、レンジを区切って手動で並列実行
  • Glue クローラじゃじゃ馬問題
    • 実行完了したはいいものの、JSONがぶっ壊れていてAthenaで読めない (1行のJSONにしなくてはいけない)
    • Glue クローラ なぜか途中で落ちる
    • 単一のテーブルではなく大量のテーブル(1000テーブル)として生成される
  • jqわからんw
  • Google Spreadsheet上でゴリゴリ表を作る(最終的にflourishに食わせるデータを作るために)

Thank you for reading !

次のアドベントカレンダーは営業部の南戸さんです。お楽しみに!

【fyui_001】中途入社しました。

f:id:fyui001:20211213170049p:plain

この記事はM&Aクラウドアドベントカレンダー15日目の記事になります!

皆さん、おはこんばんにちは。 9月からM&Aクラウドにジョインした@fyui_001こと國村です。

入社までの経歴

M&Aクラウドに入社するまでは3社ほど転々としていました。 主にPHPでWebアプリケーションを作りながら、インフラ構築やちょっとしたマーケティングとかもやらせて頂いたり、 マルチにいろんな仕事をしてきました。以下が簡単な経歴説明になります。

  1. 高校を休学して都内の受託web系開発に従事。

  2. 高校を中退し、ポータブルオーディオのリテールビジネスにおいてテクノロジーソリューションに従事し、 自社オウンドメディア・各種アプリケーションの開発・運用、自社eコマース及びリアルショップのコンバージョン・マーケティング戦略に貢献。

  3. デジタルソリューション事業にて自社の新規案件へ生産性・保守性の高い土台提供や新規技術の研究及び展開を担当

今回前職でもうあまり成長できないなと感じており、転職を考えていたところLapras経由でCTOの荒井さんからお声掛け頂いたので ジョインする運びとなりました。

入社してみて感じたこと

開発プロセスやコミュニケーション、採用しているアーキテクチャなど様々な変化がありました。 その中で自分が感じたことをいくつか紹介したいと思います。

アーキテクチャを意識した開発思想

自社開発・受託開発と様々な職場で経験を積んで来ましたが、アーキテクチャをしっかり意識した開発や負債解消などする機会がありませんでした。

一方M&AクラウドではDDDなどの開発思想を取り入れて開発しており、ビジネスサイドと技術サイド両方の要求に応えられるような設計になっています。 また、進行中のプロジェクトでも頻繁に実装方針の意見交換が行われており、開発チームのメンバー全員が設計・開発に高い関心を持って日々の開発を進めているように感じています。 今まで完成度はもちろんのこと、設計・アーキテクチャに高い関心を持ってより良いシステム開発を意識している環境に居たことがなかったので、最高だなと感じています。

メンバーの意識の高さ

いい意味でメンバーの意識の高さを感じています。 UI・UXや設計、技術トレンドなどを追っていたり、Nuxt道場などの勉強会をしておりとても向上心の高いメンバーが集まってると思いました。

また、毎週スプリントを進めた中で良かったところと悪かったところをディスカッションして日々の開発にどう活かすかなど熱く語りあっていたりなど、すごい真面目に開発に取り組んでいてドンドン上を目指してチームやサービス、会社としてどう成長行くか考えて行く文化が、とても刺激的で素敵だと思います。

この先は

M&Aは専門知識が多く、会社の事業ドメインを理解するのは大変でやらないといけないことはてんこ盛りですが、未知の知識が得られる機会を楽しんで行きたいと思ってます。

事業ドメイン知識も浅く、慣れないアーキテクチャ・設計でまだまだメンバーに助けられていますが、これからどんどんキャッチアップして事業・プロダクトの成長を支えられるように頑張りたいと思います!

最後に

M&Aクラウドでは、エンジニアを絶賛募集中です! 興味がありましたらぜひ以下からご応募ください!

https://www.wantedly.com/projects/513494

Slack,Zapierに連携アプリが無くても大丈夫! LambdaでPuppeteerを動かせばいいのさ

f:id:tsukahara1991:20211209022736j:plain

みなさんこんにちは。M&Aクラウドでエンジニアをしています塚原(@AkitoTsukahara)です。 弊社のアドベントカレンダーの12日目を担当させてもらっています!

弊社では様々な業務を自動化する取り組みが活発です。エンジニアチームであれば、GitHubのPR通知やFigmaのメッセージ連携などSlackアプリやZapierを利用して、自動化しており、SlackアプリやZapierのお陰で自動化の幅はかなり広がっています。

f:id:tsukahara1991:20211208232252p:plain よく利用するSlackアプリ

一方で連携機能が提供されていないサービスは自動化し辛くなっています。 1つの例として、勤怠管理システムで考えていきましょう。弊社ではリモートワーク時に勤怠管理システムにログインして、出退勤のボタンを押す必要があります。ちょっとの手間ですが、ついつい忘れてしまったりして、月末に勤怠漏れ修正の報告依頼しないといけません。報告するだけで済めば良いのですが、修正報告は上長、コーポレート担当者の承認が必要です。1つの報告あたり1人1分かかるとして、全社員が数回打刻漏れしているとすれば、結構な時間を修正報告に時間を費やしていることになります。この非効率な作業を少しでも減らせるように、勤怠入力を自動化していきたいですね。

そこで今回はSlackやZapierで連携機能が提供されていないツールでも自動化する方法を紹介いたします🙋‍♂️

アーキテクチャ

f:id:tsukahara1991:20211209180814p:plain

  1. Slackの入力をトリガーにAWS Lambdaに実装されたAPIにPOSTリクエス
  2. AWS Lambdaではpuppeteerを利用して、ブラウザ操作して「出退勤」入力
  3. AWS Lambdaからのレスポンスデータを受け取り、Slackメッセージを送信

このアーキテクチャのポイントはAWS LambdaでZapierからのリクエストを受けて、Puppeteerを起動させているところになります。

※Puppeteer
PuppeteerはHeadlessChromeを利用して機械的にブラウザを操作できるNode.jsライブラリです。今回は「MF勤怠にログインして、出退勤ボタンを押す」という一連の操作を自動化しています。

AWS Lambda
AWS LambdaはAWSが提供するサーバレスコンピューティングサービスです。利用者はプログラムコードを準備し、Lambdaにアップロードするだけでプログラムを実行することができるようになります。今回はPuppeteerを利用するコードをLambdaにアップロードして、Slackから呼び出せるようにしています。

STEP1

エンジニアチームではメンバー同士の稼働状態を確認するために、出勤時に「SK」、退勤時に「TK」とSlackにメッセージするルールになっています。今回のMF勤怠入力のトリガーはこの「SK」、「TK」というワードがSlackにメッセージされることにしましょう。出退勤報告とMF勤怠入力が両方できてまさに一石二鳥ですね。

STEP1ではSlackでの入力を受けて、APIにリクエストできるようにZapierを設定しています。

まずはSlackの入力を検知します。 ZapierのSlack連携トリガー「New Message Posted to Channel in Slack」で出退勤報告するチャネルを指定し、 次のAction「Only continue if...」で自分のアカウントのみで実行されるようにSlackのUserIDが設定されています。 Action「Conditionally run...」では出勤と退勤処理を分けられるようになっています

f:id:tsukahara1991:20211209015709p:plain

次にAPIにリクエストできるようにします。 出勤(PathA)の処理を設定していきます。 ActionのPOSTに必要になるデータを入力します。 URLにはAWS Lambda APIのPATH、 Id,mail,passwordにはMF勤怠に必要なログインデータを入力します。

f:id:tsukahara1991:20211209015739p:plain

STEP2

Puppeteerを起動するAPIの設置場所にAWS Lambdaを利用しています。

Puppeteerを利用するにはchrome-aws-lambda をLambda Layerとして登録しておく必要があります。詳しくはこちら

Lambda上で実行されるコードは以下のものを用意しました。 「MF勤怠にログインして、出退勤ボタンを押す」という操作をコードに直したものになります。

'use strict'
const chromium = require('chrome-aws-lambda')
const puppeteer = require('puppeteer-core');

exports.handler = async (event, context) => {
  
  const stamp = event.stamp;
  const id = event.id;
  const mail = event.mail;
  const password = event.password;
  
  const browser = await puppeteer.launch({
    //headless: true,  // ブラウザが動く様子を確認する
    //slowMo: 300,  // 動作確認しやすいようにpuppeteerの操作を遅延させる
    args: chromium.args,
    defaultViewport: chromium.defaultViewport,
    executablePath: await chromium.executablePath,
    headless: chromium.headless,
  });
  const page = await browser.newPage();

  //chromeを開く
  await page.goto('https://attendance.moneyforward.com/employee_session/new');
  // ログイン情報を入力
  await page.type('#employee_session_form_office_account_name', id, { delay: 50 });
  await page.type('#employee_session_form_account_name_or_email', mail, { delay: 50 });
  await page.type('#employee_session_form_password', password, { delay: 50 });
  //ログイン
  await page.click('input[type="submit"]');

  // 2秒読み込みをまつ
  await page.waitForTimeout(2000);

  if (stamp === 'SK') {
      //「出勤」
      await clockIn(page);
  } else {
      //「退勤」
      await clockOut(page);
  }
  
  await browser.close();
  return context.succeed('OK');
};

const clockIn = async (page) => {
  await page.click('.attendance-card-time-stamp-clock-in');
};

const clockOut = async (page) => {
  await page.click('.attendance-card-time-stamp-clock-out');
};
コードをかけなくても大丈夫?

エンジニアでない方にはいきなり出てきたソースコードでびっくりさせてしまったかもしれませんね。。 でも「自分はコードは書けないから無理かな」と諦めるにはまだ早いですよ!

Google ChromeではWebブラウザ上の操作を記録、再実行、編集、保存さらにはPuppeteerスクリプトのエクスポートができる機能がリリース予定。この機能を活用すれば、ほとんどコードを書かずとも上記のコードと同じようなものを用意できるかもしれません。 リリース時期は2022年の1月頃となっています。期待してこの機能リリースを待ちましょう!

Chrome DevToolsドキュメント「Record, replay and measure user flows

STEP3

打刻に成功しているとAPIから”OK”とレスポンスが返ってくるので、それを受け取ってSlackに打刻完了しました。とメッセージを送信できるように設定しています。

f:id:tsukahara1991:20211209020122p:plain

以上がおおまかな設定方法と処理の流れとなっております。 今回のようにAWS LambdaにAPIを設置するとネットワーク経由で自動化のリクエストができるようになり、Puppeteerを利用してブラウザ操作を自動化することができます。この組み合わせを応用していけば、多くの業務が自動化できるのではないでしょうか。

補足

自動化しようと試行錯誤する前にやっておきたい事前確認

  • 業務データに関わることは関係者に自動化OKか
  • すでにSlackなどで連携機能が提供されていないか

自動化してみたものの利用できなかったり、同じようなものがあったりと無駄な作業が発生しないようにしましょう。 自分も社内メンバーに事前確認したり、連携機能がないか確認しました。 リリース当初からSlackアプリを検討していると記述がありましたが、その記事は2年前。。。 是非ともMoney ForwardさんにはSlackアプリを提供いただきたいです🙏

今回の勤怠入力自動化は自分個人しか利用できない形になっていますが、今後は仕様・機能を整備して社内メンバーが利用できるように拡張していこうと考えています。 そのために越えないといけない課題は

  • 打刻失敗時の検知方法
  • 複数人のSlack ID管理
  • MF勤怠のログインID・パスワードの管理 etc

もっと良い実装方法がないのか社内エンジニアにレビューしてもらって、機能拡張やっていきます💪

まとめ

いかがだったでしょうか? 連携アプリが提供されていなくてもAPIを自前で用意することができれば、ツール同士の連携・自動化が可能になります。 自動化したいけれど諦めたままになっている業務があれば、ぜひ今回の手法を応用して挑戦してみてください。

みなさんの業務自動化に少しでも力になれましたら幸いです🙇‍♂️

明日は中名生さんです!

PHPコードを消すライブラリを作った

f:id:kubotak:20211207104943p:plain この記事はQiita AdventCalendar 2021 PHPの8日目の記事です。

こんにちは、こんばんわ、kubotak(@kubotak_public)です。
早速ですがタイトルの通り「PHPコードを消すライブラリ」を作りました。

packagist.org

まずはこのライブラリの生まれた背景と用途について説明します。もしよければstarつけてください。

これはなに?

以下のようにコメントでコードを挟み、composerで導入したコマンドを実行することで対象のコードを削除します。

before

public function code() {
    /** php-del start flag-a */
    $something = 1;
    /** php-del end flag-a */
}

run command

vendor/bin/php-del flag-a

after

public function code() {
}

なぜ作ったのか?

使い方は簡単ですね。しかしこんな仕組み、いつ使うんでしょうか?
話が変わってしまうんですが、弊社ではスクラム開発を行っており、Feature Flag(Toggle)を利用してデプロイとリリースを分離しています。
変更影響があるコードはFeature Flagによって管理され、それがONになることで有効化するようになっています。

(イメージ)

if ($featureFlag) {
  // 新しい処理
  return;
}
// 既存の処理

※弊社のFeature Flagについては過去記事を参照ください
Feature toggles を複数の環境へ即時反映する仕組みを開発しました - M&Aクラウド開発者ブログ

察しの良い方はすでにお気づきかと思います。
このコード、Feature FlagをONにした後はif文及び既存の処理は不要になります。
今まではこれを消すタスクを積んで消す必要がありました。
また、このコードを追加していない開発者が見た場合、どのコードを消すべきかちゃんとコードを読み解く必要もあります。

ほしいもの

つまり、Feature Flagを使うコードを実装する時点で、消すことも想定してコードを書いておいて、後から自動で消えてしまえば負担が少ないのではないか・・・
という思いから出来上がったのがこのphp-delです。

先程のコードに適応すると次のようになります。

/** php-del start flag */
if ($featureFlag) {
/** php-del ignore start */
  // 新しい処理
/** php-del ignore end */
  return;
}
/** php-del end flag */
// 既存の処理

※ignoreコメントで挟んだ箇所は削除対象から除外されるので残ります。

弊社以外にも需要があれば是非どうぞ、ということでOSSとして公開しています。

さいごに

今回OSSとしてComposerで配信するコマンドを作ってみて、次のようなことを感じました。

需要は自分たちだけのものでも良い

誰もが喜ぶライブラリじゃなくても、自分たちのニーズに答えられるものなら開発意欲も湧いて良いなと思いました。

他のOSSコードを読むようになる

他のOSSはこの処理どうやって実装してるんだろう?という疑問からPHPUnitやPHPStanなどの実装をチラ見したりしました。
普段あんまり見に行かないコードなのでそういうものに触れる機会にもなって良いと思います。
composer.jsonのbinに追加するだけでvendor/binに配置される仕組みめっちゃ良いです。

少しでもいいな、と思ったらぜひstarつけてください。

【離職率0%】弊社エンジニアが辞めない理由とは【スタートアップ】

f:id:yamotuki:20211129183843p:plain

(これはM&Aクラウド Advent Calendar 2021の12/3の記事です)

こんにちは。M&Aクラウドのエンジニアの鈴木です。ネット上では@yamotukiという名前で活動しています。

「エンジニアといえば転職してキャリアアップ」「キャリアアップといえばエンジニア」(要出典)などと言われる昨今ではありますが、弊社は7期目にして奇跡的にもまだエンジニアが離職していません。

その奇跡はどこから来るのか?
同僚のエンジニア達にヒアリングをして、起源を突き止めたいと思います。

【仮説】エンジニアはいつ離職を考えるのだろう?

エンジニアが離職を考える時期として、以下のような年次と理由があるかなと思っています。これは完全に主観です。以下のようなものに当てはまらなければ、特段辞める理由は無いのではと仮説を立てました。

  • 1年
    • そもそも職場にマッチしてなかった。「思っていたんと違う」
    • 労働条件が言われたのと違う。「ブラックじゃん?」
  • 2年
    • ジョブホッパー的な気質の場合には2年もやると転職を考える頃。「経験を積んだので昇給すると思っていたのにしなかった。」
    • 苦手なタイプの同僚が増えた。「あいつ嫌い」
  • 3年
    • 仕事に飽きてきた。「チャレンジさせてもらえない」
    • 技術スタックの固定化。「いつもおんなじ技術使ってるわ」(2年目でも言えるかも。まあ理由は二つずつくらいが収まりがいいのでこちらへ)
  • 4年
    • 求められる役割が増えた。「マネージメントなんてやりたくないよ」
    • 色々できるが故に仕事がたくさん降って来すぎる。「マジで忙しい」

さて、実際に聞いてみたらどんな感じでしょう?

ヒアリングしてみた

同僚たちをそれぞれ slack の huddle で突然呼び出して、ざっくばらんに理由を聞いてみました。
弊社には1年目から4年目のエンジニア社員が居るので、年次が浅い方から聞いていきましょう。(※CTOは現在は入社5年目かと思いますが、エンジニア職から離れておりPdMとして活躍しているので今回スコープから外しました。またサービスが2018年5月に開始してからまだ3年半ほどしか経っていないので、実質4年目が最長です。)

1年目

國村さん(入社2ヶ月と10日)

――「入ったばかりではありますが、辞めないで続けている理由ってどんなのがありますか? まずは雑な質問から。」

國村「入ってみて、みんないい意味で真面目だな、と思いました。タスクを終わらせることに真面目に取り組んでいて、課題を解決しようという姿勢が整っている。それがいいなと思ってます。特にみんなチーム一体になってタスクを終わらせようという姿勢が良い。」
國村「あとは事業として可能性がある未開拓領域を掘り進めて開拓しているところですかね。」

――「なるほど。入社直後に辞めたくなる理由があるとしたらミスマッチだと思いますが、それはどうですか?」

國村「特になかったです。」

――「それはなんでだと思います?」

國村「面接で色々聞けたから。逆に、荒井さん(※CTO)に結構きっちり聞かれたと感じました。だからミスマッチしないのかなと。」
國村「あとは内定が決まった後のアトラクト会でチームの空気感を掴みました。それが入社の決め手でした。そこで感じたチームの雰囲気と、入ってみたあとで変わらなかったです。」

仮説にあった「思っていたんと違う」はなかったようです。

塚原さん(入社8ヶ月)

――「とりあえず大きな質問からするのですが、続けている理由ってどんなのがありますか?」

塚原「メンバーに受け入れてもらって、ここでも仕事できるという手応えを感じています。」
塚原「転職の目的だったスキルアップとしては、最初に比べて結構できるようになったので目的は達成しているかなと。高いレベルを求められるし、社内のエンジニアのレベルが高いので刺激的です。」

――「入社前と後でミスマッチとかありました?」

塚原「スキル面で言うと、入社前に荒井さんからは『入ってから頑張ってキャッチアップしてほしい。今の実力のままだと大変なので頑張れ』と言われていました。そう言う意味ではギャップはないです。」
塚原「あと、人間関係の面で言うと、雰囲気良く受け入れてもらったと思ってます。この前エンジニア飲み会(※塚原さん主催による塚原さん&國村さん歓迎会)も開けたので、楽しくやってます。ただ、私は気にしいなので、自分はミスマッチを感じていないが、周りがどう思っているかは心配ではありますね。」

――「なるほど。私はミスマッチなかったと思いますよ。人間関係面で言うと完全に馴染んでいると思います。スキル面で言うと、今は開発総合窓口対応やアラート一時受けなどやってもらってますよね。最初は結構頻度高く私も見に行かないといけない感覚だったけど、今は見る頻度減ってきてます。それはちゃんとやってもらっているという安心感を感じているからだと思います。」

塚原「逆質問なのですが、タスク振っている側(鈴木側)として何か考えていることってあったりします?」

――「明示的にそこまで考えているわけではないけど、特定分野の仕事でめっちゃ詰まっていて、終わった後にメンタル落ちているかなーと思ったりすると、同種の仕事を一時的に振らないでコンフォートゾーンの活躍してもらえる仕事を振っているかもしれないです。」

塚原「なるほど。そういうのも離職率減っている理由かもしれないですね。実はインフラ系タスクとか、フロントエンドのタスクとか難しくて辛い時期があったので。その時は、自分が活躍できず、進んでいる感がなかったです。」

塚原さんについても、仮説にあった「思っていたんと違う」はなかったようです。
逆に求められる水準が高すぎても辛くなってしまうので、塩梅は大事だなと感じました。  

2年目

濱田さん(入社1年と9ヶ月)

――「辞めないで続けている理由って何がありますかね? 最初に思いつくもので。」

濱田「飽きてないから。ですかね。直近だとスクラムマスターやるという話とか。単にコード書くだけで既存の保守だけだと成長が止まってしまう。今の環境だと課題が新たに見つかって改善していこうというサイクルがあるので飽きないですね。転職して改めて成長機会を探す必要がないです。」

――「課題がでてくる、というのはやはりスタートアップだから、とか会社が成長しているからというのはありますかね?」

濱田「そうですね。前職の大手プロバイダだと、事業内容の関心ごとがほとんど変わらないというのがありました。大きく成長していないので目指すべき目標がそんなに変わらないというか。」
濱田「新しい役割で言うと、他にはサブチームリーダーとかファシリテーターとか役割を新たに任せてもらってますね。成長環境として、役割を通してや生産性向上委員会(※実質的なリーダー会)の中で自分にフィードバックがあり『自分の中でどういう課題があるか』というのを意識する機会になってます。」

仮説にあった3年目の「チャレンジさせてもらえない」がないというのが良さそうです。濱田さんはまだ2年目ですが、3年目を超える古参の風格を漂わせています。

3年目

久保田さん(入社2年0ヶ月)

――「ざっくりとした質問なのですが、辞めないで続けている理由って何がありますか?」

久保田「僕は多分特殊ですね。いつ辞めるか入る時に考えてます。前職もそうでした。」

――「時期で決めているってことですか?」

久保田「IPOしてから転職は考えたいんです。IPO無理だとなったら考えるかもしれないけど。IPOに至るまでのチームの変わっていく姿とか技術スタックが変わっていく姿とか、それに技術的適材適所を見極める経験をしたい。そうすると次に行っても再現性のあるスキルが手に入るかなと。」

――「IPOしたらすぐなのか、ベスティング(※ストックオプションから生株変換までの期間)の間は残るのか。」

久保田「その後の世界が重要かどうか、は自分は知らない。その時のことがわかっていないのでまだ分からないです。経営は多角化していくとかしていけば、そのフェーズで僕が必要なのかわからないですね。」
久保田「SOがどれくらいとかあんまり気にしていないですね。あったらあったで嬉しい。それは居る居ないに関わっていないです。一応期待していない。上場後に(株転換で)毎年1000万入ってくるとかだったらちょっと居てみるかーとはなるかも。」

――「経験したいと言うのが強そう?」

久保田「そうですね。僕自身の成長としては、自分は努力していない気がしてます。人の成長は環境次第だと思っていて、僕自身が努力家ではない。やらなきゃいけない環境とか、やらなければいけない環境で成長を促そうというところです。前職にずっといたらダメ人間になっていた。」  

――「楽すぎて?」

久保田「ずっと変わらない繰り返しに入ったというのと、周りに学ぶ人が減った。僕よりできる人というのが周りを見渡すとあんまりいなくなってしまった。」
久保田「今は会社自体が足掻いている。それに合わせて自分も足掻いていく。それで成長していく。今スクラムを真面目に取り入れようとしているのもいい流れ。」

――「スクラムのいいところが自然に身についていく?」

久保田「スクラムに悪いところがあるかはまだわからないですが。上手くいくように濱田さん主体でやっているが、我々も働きかけていく。それが学びになると思いますね。」  

――「周りが求めてくれることをやれば良い?」

久保田「不得意分野はあるし、やりたくないところはある。そういうものを無理矢理やることになれば話が違うよってなる。例えば荒井さんのCTOの立ち振る舞いとか、それは自分には難しい。」

「いつもおんなじ技術使ってるわ」はなさそうでした。久保田さんは、大きな流れに身を任せて自分も成長しよう、というタイプですが、そういう人はスタートアップにマッチしてそうです。

津崎さん(入社2年6ヶ月)

――「辞めないで続けている理由ってなんでしょう? あえてざっくりした質問なのですが。」

津崎「ひとつじゃなくていいですか?」

――「もちろん」

津崎「まだ上場に向かってやっているので、その上場した時の景色をみたいです。」
津崎「あとは、学ぶこともまだあります。データ分析とか大臣制度でチャレンジできる余地が残されているので。」
津崎「停滞感が長く続くと辞めたくなると思います。今は事業も爆発的な成長はないけど、堅実に成長はしている。エンジニアチームの仲間が1人辞めます、2人辞めますというのが増えたら『ぐぬぬ』ってなると思います。むしろ人が減ってやること増えるので辞めてる場合じゃないんでしょうけど。」

――「停滞感を感じている時期はありましたよね?」  

津崎「入社してからはあんまり感じてないです。けど、SKE2(※募集と検索周りのリニューアルプロジェクト。4ヶ月。)の長いトンネルの中にいる時には思ってました。憂鬱に思ってましたね。」

――「今の定常保守だと思っていない?」

津崎「普通ですね。来期が始まるし、スクラムも始まるしという期待感があります。」

――「変わらないというのが辛い?」

津崎「そうかもしれないですね。個人的にはすごく飽き性なので。入社したばかりだと、『新しい新しい』ってなるけど、時間が経つと慣れてしまって刺激が減ったように感じます」

以降、停滞感を感じないために”自分の中のあるべき姿”に向かってどうやったら進んでいけるのだろう?とお悩み相談になりました。
任された仕事を着実に自分のものにして、また次の新しい仕事を任せてもらうループを作ると、停滞感を感じている暇などないのでは無いか、という仮説を鈴木は持ちました。
津崎さんは”あるべき姿”に向かうために自分に定期リマインダをかけたり、付箋を貼ったり工夫はしているけど、「すぐ脳内から消去されてしまう」というのを悩んでいました。機械がやる自動リマインダは無視されがちですね。
津崎さんから"鈴木へ対して"自動定期リマインダをかけることで鈴木が人力チェックと人力リマインダをすることになりました。

こういう話をする機会大事ですね。

4年目

鈴木(入社3年3ヶ月)

セルフインタビューです。私が続けている理由ってなんでしょう?

  • スキル面ではまだやれることがあると思っている
    • リーダー業務やPM業務をやってみているが、まだ完全にうまくできるようになったとは思っていない。また別の会社に行って0からドメイン知識を得て学んでいくのだと効率が悪い
    • 設計のスキルは、自分が考えた設計が長期保守に耐えられるかという視点で同じコードを保守し続けた方がスキルが上がると思っている。時間によるフィードバックを受け取りたい
    • 弊社で身につけられないスキルは、数百万単位のアクセスあるような高トラフィック環境における実務だと思っているが、それは今は自分が必要としていない。また、インフラについては既に前職である程度やったので必要ない。 
  • 金銭面では、SOを持っていて、給料の高い他社に転職するよりまだ残ったほうが期待値が高いと思っている

仮説との対応でいうと、求められる役割が増えた。「マネージメントなんてやりたくないよ」が別に問題になっていないパターンですね。

終わりに

なかなか面白いヒアリング結果でした。

入社から間も無いエンジニアに対しては、入社でのフィルタや期待値調整がうまくいっており、ミスマッチが少ないのが良いポイントかと思いました。面接した人のうち内定までの倍率が10倍を超える(※ぼかします。許可が取れたら書き換えます。)と言われている弊社エンジニア採用はうまくいっているようです。

入社年度にかかわらず、弊社のエンジニアは変化に強いというより「変化が無いと死んじゃう」泳ぎ続けるタイプが多いかもしれないなと感じました。
それぞれが活躍できるタスクを割り振りつつ、一段難しいタスクも捌けるように成長してもらう。そういう職場作りが肝要ですね。

インタビュー見て「同じような志向を持っているなあ」と思ったそこのあなた。多分弊社とマッチしていると思うのでぜひカジュアル面談からいかがでしょうか。CTOでもいいですし、他のメンバーとカジュアル面談したいと指名してもらっても良いかと思います。

www.wantedly.com

おまけ: 入社理由については以下の記事にまとまっています。ぜひ合わせてご覧ください。

update.macloud.jp

アドベントカレンダーを成功させるためのDX

f:id:kubotak:20211203133527p:plain この記事はM&Aクラウドアドベントカレンダー2021の記念すべき1日目の記事です。

みなさんこんにちはこんばんは、M&AクラウドでWebエンジニアをしている久保田(@kubotak_public)です。

M&Aクラウドとしての初めてのアドベントカレンダーです。
詳しくは以下の記事を見ていただけると嬉しいです。

update.macloud.jp

さて、今回弊社のアドベントカレンダーを行うにあたって私が実行委員として旗振り役となりました。
今年のアドベントカレンダーの目標はズバリ、「だれも記事を落とさずに公開すること」です。
簡単かな?とも思われる目標ですが、今回のアドベントカレンダーを担当するメンバーはWebエンジニアだけではありません。
つまり「アドベントカレンダー?なにそれ?」と馴染みのない方も多いと思われます。

Webエンジニアであれば12月には「記事書かなきゃ」とソワソワすることが多いのではないでしょうか。
ということで、実行委員としてみんなに”ソワソワ”してもらうためのリマインダーを作りました。

f:id:kubotak:20211128230650p:plain

このような形で公開の3営業日前にSlackで担当者あてに通知が行われます。 今流行のNoCode、と言いたいところですが一部JavaScriptを利用しています。

アーキテクチャは次のようになっています。

f:id:kubotak:20211128232644p:plain
アーキテクチャ

①zapier

タスク自動化ツールであるzapierを利用して定期実行を作成します。
zapierではあらゆるサービスの連携だけでなく、プログラミングコード(Python, JavaScript)を実行させることができます。

Googleスプレッドシート

Googleスプレッドシートにはアドベントカレンダーの記事を書く担当者名やSlackメンション用のユーザーID、担当日などを管理します。
f:id:kubotak:20211128233245p:plain

zapierではまずこのスプレッドシートのデータを読み出します。

JavaScript

続いてCode by Zapierを利用してJavaScriptを実行します。
先程のスプレッドシートのデータを加工しつつ、実行したタイミングから3営業日後の担当者を抽出する処理を作ります。
ここで気をつけなければならないのは休日の扱いです。
アドベントカレンダーには休日も関係なく記事を公開する必要があります。ですが、例えば休日に3日後の通知を送るというのは些か会社としてよろしくないですよね?
ということで通知が行われるのは平日のみに限定し、3営業日前通知ということに設定したいので土日を挟むことを考慮した通知設計が必要です。
幸い(?)にも12月は祝日がありません。祝日を考慮する必要がないので簡単に次のようなルールで通知を設計しました。

const scheduleList = [
    [], // 日曜日 -> 通知なし
    [3], // 月曜日 -> 木曜日
    [3], // 火曜日 -> 金曜日
    [3, 4, 5], // 水曜日 -> 土・日・月曜日
    [5], // 木曜日 -> 火曜日
    [5], // 金曜日 -> 水曜日
    [], // 土曜日 -> 通知なし
];

scheduleListの配列内の数値は、実行した日付に加算する日付を表しています。ですので、コメントに付いているように月曜に実行された場合は3日後の木曜の担当に通知、水曜に実行された場合は3日後、4日後、5日後のそれぞれ土、日、月曜の担当に通知を送る設計です。

スプレッドシートとCode by Zapierの落とし穴

この実装を作っているときにちょっとした落とし穴がありました。
zapierで取得したスプレッドシートの行は、JavaScriptで配列として受け取れると思ってましたが文字列で取得されました。
カンマ区切りの文字列なのでCSVとしてパースできるのかな?と思ったんですが改行コードがなかったので仕方なく列のサイズで別配列になるようにパースしました。

const { rows } = inputData;
const rowsToArray = rows.split(',');
const rowsFormatted = [];
let i = 0;
let row = [];
rowsToArray.forEach((item) => {
    ++i;
    row.push(item)
    if (i > 8) {
        rowsFormatted.push(row);
        row = [];
        i = 0;
        return;
    }
}); 

④Slack

JavaScriptの処理が実行されると次のようなデータが生成されます。

output = [{ result: true, message }]

通知する内容がある場合はresultがtrueとなり、ない場合(土日や開始日前や終了後)はfalseとなります。
Filter by Zapierを利用して後続のタスクを実行するかどうかを分岐させます。

最後にSlackへの通知を実行することで一連の処理が完了します。

さいごに

今年のM&Aクラウドアドベントカレンダーのテーマは「テック」です。
実行委員として「テックを利用してアドベントカレンダーの旗振りを行う」を実践できたのではないかと思います。
本日を皮切りに25日まで、弊社エンジニアのみならずあらゆる業種の面々が記事を投稿します!ぜひご期待ください。

PHPerKaigi 2022のプラチナスポンサーになりました

f:id:kazuhei0108:20211119105044p:plain

こんにちは、M&AクラウドCTOのかずへいです。 この度、弊社ではPHPerKaigi 2022のプラチナスポンサーをさせていただくことになりました。

毎年弊社のメンバーの多くが参加しているPHPerKaigiさんのスポンサーをさせていただけること、ありがたいです。

前回のPHPerKaigi 2021では弊社から5名登壇させていただきました。

去年の弊社メンバーの登壇内容についてはこちらをご覧ください。 tech.macloud.jp

今回は、弊社でスポンサーさせていただくとともに、また、メンバーみんなでプロポーザルを出していく所存ですので、 何卒宜しくお願いいたします。

また、登壇スケジュール等決まりましたら、こちらのブログでお伝えさせていただければと思います。

ファシリテーター & 議事録係の型

f:id:hamakou108:20211105144923j:plain

こんにちは。 エンジニアの濱田( @hamakou108 )です。

弊社の開発チームでは特定の役割をうまく果たすための知見を「型」として文書化し、チーム内で共有しています。

tech.macloud.jp

tech.macloud.jp

今回はその一つである「ファシリテーター & 議事録係の型」を紹介します。

弊社の開発チームでは週に1回、加えて隔週に1回のタイミングで定例ミーティングが開催され、ファシリテーターはエンジニアが担当しています。 ファシリテーターを担当したことがある方であれば、会議の中で様々な問題に直面することは想像に難くないと思います。 議論するのに十分な情報が事前に収集されていない、議論が発散し続けて結論が得られない、会議後に誰がいつまでに何をすべきなのか記録されていない、などなど。

弊社の開発チームではこういった問題に対する解決策の一つとして、ファシリテーターが議事録係を兼ねるという取り組みを実践しています。 その戦略の意図と狙っている効果、またファシリテーターと議事録係のそれぞれの役割において望まれる振る舞いについて「型」を通して紹介できればと思います。


これは何

開発チームにおいて会議を回すファシリテーターと主書記は同じ人がセットでやることになっている。 会議をスムーズに進行し、有用なものとするために何をしたら良いかの型を模索するための資料。

前提説明: ファシリテーターと主書記について

主書記とサブの役割について

議事録係には主書記と、サポートするサブがいる。 それぞれの役割は以下の通り。

  • 主書記
  • サブ
    • 主書記が書かなかった(書けなかった)議論や情報の細部を書いていく人

議事録係を分割した理由

議事録係(ファシリテーターと分離されている「全ての記録を残す」役割)は難しい。 何が難しいか。

  • 議事録のリアルタイム性が重視されているので、会議の議論に遅れずについていかなければいけない
  • 全ての発言を書くのは現実的ではないので、話していることを正しく要約する必要がある
  • 上記のため、議事録係は積極的に議論を止め、話している方向を確認し、要約や結論を促す必要がある

この役割を果たすにあたって、ファシリテーターと議事録係が別だと以下のような不都合が起こる。

  • ファシリテーターが話していることと議事録係が書いていることの間でニュアンスがズレることがあるので、補正が必要
  • ファシリテーターと会議全体が暴走すると議事録係がついていけない

議事録係を専任でやるのは、会議をファシリテーター同様にコントロールすることと、記録を残すことの両方をやる必要があり、高いスキルが要求される

ファシリテーターと主書記を同じ人がやるメリット・デメリット

  • メリット
    • 会議の骨格を作っている人と、骨格を書いている人が一緒なのでニュアンスがずれない
    • 議論の内容を要約しながら進めるので、ファシリテーター自身が会議の方向性を自覚しやすい
    • 言葉で説明され、要約を文字で読めるのでメンバーが話について行きやすい
    • 上記のことから、会議が暴走しずらいことを期待する
  • デメリット

将来的な話

将来的には、ファシリーテータ & 議事録係のセットで経験を積んだら、議事録係単体でも上記の難しさを乗り越えるスキルが付くはずなので分離しても良い。

一番重要なこと

参加者の時間を使っていることを意識する

会議の参加者が多ければ多いほど、その出席者の時間を有効に使うことが求められる。

その会議をやることで、やらないよりチームにリターンがある場合に開催すること。 リターンがなければ解体する。

会議の目的をはっきりさせる

会議が何を目的にしているかはっきりさせる。 複数の目的が含まれている場合、必要に応じて会議を分離する。

誰を呼ぶか

会議の目的に合わせて過不足ない人を呼ぶ。

事前準備

誰も何も考えていない、または決めていない時間は無駄な時間となってしまうので、事前準備が大事。 誰の持ち込みの議題で、何を相談したいかはっきりさせてから会議に臨むのが望ましい。

ファシリテーターの仕事は参加者にこれを促し、やってもらうこと。 必要に応じてチャットツール上であらかじめ議事録を共有し、必要な内容を書いてもらえるようにメンバーに促す。

議題が用意されたら、会議内で議論する必要があるポイントを整理し、それ以外を会議の外に持っていく。

  • 議題の起案者に論点を明確にしてもらう
    • 場合によってはたたき台を用意してもらう
  • 一部の関係者のみでチャットや会話で議論し、結論だけ持ってきてもらう

議論する内容が定まったら、優先度に応じて議題の順序と目標時間を整理し、会議のゴールを設定しておく。

進行

会議のゴールを共有する

会議のゴールを参加者全員がわかるように共有する。 定例などでも、たまに忘れ去られてそうだったら改めて共有する。

また議題の順序と目標時間を共有し、参加者に議論を時間内に収めてもらうよう促す。

まず情報を集める

情報を持っている人を明確にして、ヒアリングをする。 会議の参加者が同じ前提の情報を持って話せるように議事録に落とし込む。

意見を募る

たたき台があればそれを使う。 なければ雑でもいいので自分で捻り出す。たたき台もないとみんなが発言しづらいので、自分の案が 💩 だと思っても何か出す。

情報を持ってそう or ちゃんと考えてそうなのに話していない人がいたら話をふる。 うまく参加できていない人がいたら、突然のボールでもあえて振ってみるのもいいかもしれない。 その後会議に積極的になってくれたらもうけもの。

今は何の時間か?

ファシリテーターは今何の時間なのか明確に発言し、遊びの時間を減らす。 察してもらえるだろう、というレベルのものも明確にする方が良い。

たとえば

  • 「画面共有しますね」みたいな数秒で終わる発言
  • 「この資料を見て〇〇をする時間です。✖️✖️分までです」
  • 「〜〜の立場として△△さんの意見を聞いてもいいですか?」

着地点を探す

情報や意見が集まったら着地点を探す。 結論は明記しておく。

結論の書き方はフォーマットは自由だが、チームとして共通認識のある表現にする。 「誰が、何を、いつまでに」の3点が要素として含まれていると望ましい。

  • 結論: 〜〜 みたいな書き方で明記しておく
  • (これは弊社の開発チームのみで定着している)議論の過程でこれが結論になったというところを太文字にしておく

時間内に収まらないような長い議論の場合でも、中間地点として方向性が決まることもあるので「中間結論」を明記できると良い。 次の会議に議題を持ち越す場合は、以下の点を明確にしておく

  • 今回は何が決定されたか(中間結論)
  • 次回は何を決定するか
  • 次回までに何をする必要があるか(宿題)

会議の結論と宿題を共有する

会議の終わりに、出た結論を振り返り、本当にその結論でよかったのか確認する。

次に「誰が、何を、いつまでに」する必要があるかを共有する。 次のアクションが決まっていないものをはっきりさせる。

議論が白熱すると共有のための時間がなくなる可能性があるので、ファシリテーターは余裕を持って時間管理をしておく。

議事録

意識

ミスタイプを恐れない。 会議を進めることを重視する。 サブがサポートする。 

役割

ファシリテーターが議論の骨格を書く。 得たい結論の方向性から逆算して、大まかな話を誘導し、議事録係としてリアルタイムに反映させる。 他のメンバーが同時編集できる一つの議事録を見て現在地点がわかるのが理想。 例えば esa であれば編集モードでカーソル位置がわかるので、より明確にどこを見ているかわかる。編集モードでみんなが編集、閲覧するのを促す。

議論が明後日の方向に行ってしまったり、ファシリテーターを置き去りにして進んでしまう場合には、一旦止めて「こういう話ですよね?」がはっきりするまでメンバーを待たせる。

発言者について

同じ職種や近い情報を持っている人のみの会や、意思決定者で無い人の発言は匿名発言として名前を書くことは強制されない。

全て書いてもいいが、慣れていないと大変なので必要なポイントに絞るのも良い。 以下のパターンで名前を明記しておくと良い。

  • それぞれの意見を順番に聞いたパターン
  • 役職として決定権がある人の結論
    • 最終的に議論が割れたケースで、決定者がえいやと決めた場合に、後から振り返ってなぜそうなったか分からないケースがあるため
      • ただし、決定権がある人が決めたとしても、理由も無しに決めたわけでは無いはずなのでちゃんと理由を明記しておく。理由がなかったらメンバーは納得できていないことが常なので、それを積極的に聞いて議事録に残す。

終わった後の処理

会議の後に議事録は必要に応じて整形する。 次のアクションとして振り分けたタスクが進むように改めて通知したり、自分で作業したりする。

  • Try ボード 1 に積む
  • issue を作る
  • 調査する
  • 次週までに決めておく

伝える

議事録を整形し終わったら、宿題をまとめてそれぞれの担当者に通知する。

次の会議でやること

前回の会議で決まったもので、置き去りになっているアクションをはっきりさせて、アクションを促す。


おわりに

エンジニア、デザイナー積極募集中です! ぜひカジュアルにご応募ください!

www.wantedly.com

www.wantedly.com

www.wantedly.com


  1. 弊社の開発チームでは KPT で言うところの TRY をかんばんボードで管理しており、それを Try ボードと呼んでいます。