enigmo(BUYMA運営企業)のコーポレートIT(社内SE・情シス)運営方法と将来像

こんにちは、コーポレートエンジニア(コーポレートIT[CO-IT]チーム) の 横川 です。 この記事は Enigmo Advent Calendar 2023 の 17 日目の記事です。

この記事では社内ITサービスを支えるチームの組織作りをテーマにどのような観点でチーム運営を行っているかをご紹介したいと思います。

コーポレートIT領域は、年々取り扱うサービスや技術が広くなり、様々なスキルセットが要求されてきていますが、本記事は特定技術の話ではなく組織運営にフォーカスした内容となります。 これから社内SEを目指される方や現在コーポレートエンジニアとして活躍されている方々に少しでも参考にしていただける内容となっていれば幸いです。

はじめに

自己紹介とCO-ITチームの紹介

私はITベンダーでネットワークエンジニアとしてキャリアをスタートし、その後セキュリティ製品の代理店にてプリセールスエンジニアを担当してきました。その後、キャリアチェンジし、デベロッパーでの社内SE(情シス)、SaaS提供企業でのコーポレートIT担当を経て、昨年10月よりenigmoにjoinしました。 コーポレートITという大きな領域全体を俯瞰して自社の最適なコーポレートITを自由に作ることができるという環境に惹かれて入社を決断しており、実際にそのミッションに日々向き合える環境で働いています。

CO-ITチームはコーポレートオペレーション本部の人事総務グループに属し、社内ITサービス全般を担当しています。 ブログ執筆時点(2023年12月)では、マネージャ[人事総務グループ部長]を除くとチームメンバーは私を含め3名で現在4人目のエンジニアを募集している状態です。 最終的な意思決定はマネージャが担いますが、当社のコーポレートIT領域の対応は現在私がリードする役割を担っています。

コーポレートエンジニア・社内SE・情シスについて

近年、コーポレートエンジニアやコーポレートITといったワードを見かけることも多くなってきており、従来の社内SEや情シスという表現との明確な違いを説明するWebページ等も増えてきているかと思います。 ざっくり両者の違いは、「見る範囲・視点の違い」とされていることが多く、コーポレートエンジニアは従来の社内SEや情シスのスコープよりも広範囲に及ぶ(企業全体を視野に入れ、ITスキルを活用して提案・企画を行う)と定義されています。*1

コーポレートエンジニアはバックオフィス部門に所属し、会社の売上に直接貢献することはできません(プロダクト部門メンバーの業務効率向上に資することで間接的に貢献する)。企業によっては、プロダクト側に強い優遇(力が強い傾向)があったり、バックオフィス側は利益を生まない部門として不遇な環境になっている場合も見聞きしますが、プロダクト側・バックオフィス側どちらかに優劣があってはならないし、どちらも(会社の成長に貢献する部門として)リスペクトし合える企業風土が醸成できていることが望ましいと感じます。*2

そして、シンプルにコーポレートIT部門が会社から求められることを表現すれば、

自社に最適なコーポレートITをいかに低コスト・最速で実現し、安定稼働を継続できるか

になります。

予算が無限であれば、何も考えず最新で優れたサービスをフルライセンスで導入し、外部の専門ベンダーに要件定義〜運用まで全て外注して、トラブル対応や今後のアップデートも含めて24h365dでフルサポートされるオプションを付帯すれば他社を圧倒するコーポレートITの運用が可能となります。*3しかしながら、自社の社内ITサービスに実プロダクト以上の予算を割ける企業がどれだけあるでしょうか?この点にコーポレートエンジニアの存在意義があるものと考えられます。コーポレートエンジニアは、しっかり自社の状況を俯瞰して会社のフェーズに合わせて、必要十分なサービス提供に日々向き合うことが求められる職種です。

1.組織運営の前提を整理する

私自身が実際に実施していることを含め、組織運営にあたりクリアすべきと考えていることについて記載していきます。

ミッションを理解する

以下にMVVを掲載します。当社のミッションは こちら の通りですが、CompanyのMVVに応じてCO-ITチームでもMVVを定義しています。

MVV(ミッション・ビジョン・バリュー)
このMVVは、私が入社前から定義されていたものですが、現時点で変更の必要性はないと判断し、そのまま継続利用しています。 近年、特にスタートアップ企業では、MVVを掲げている企業が多くなっている印象を受けますが、会社側がただ掲げているというよりは、従業員がそのMVVを自分事として意識するようにMVVに向き合う時間を業務時間の中に組み込んでいる企業も増えてきているのではないでしょうか。MVVというのは、非常に重要であり、各自の担当タスクは全てMVVに紐づいたものと考えることができます。

会社の方針と現在のフェーズをすり合わせる

ワーディングは違っても、多くの企業のコーポレートIT部門のMVVは当社のものと重なる部分が多いのではないでしょうか。 それは企業活動における基本的な役割が同じであることに起因しますが、MVVが同じでも各企業・担当者の業務内容は例えば下記のような理由によって大きく異なります。

  • 会社の規模や方針によって対応範囲やチーム構成が様々である
  • 企業規模の拡大や事業成長に伴って縦割りが進み、サービスや製品毎にチームや担当者が限定されている
  • 要件定義だけ・設計構築だけ・運用だけのようにスコープが限定されている

したがって、具体的なチームビルディングに移る前にまず現在のフェーズを整理し、組織運営方針についての合意形成が必要になります。その大前提として、社内ITサービスを外注するのか内製するのかの判断を行います。一昔前までは専門のエンジニアが担当せず総務担当者が兼務や片手間で社内システム(情シス)を担当することも多かったように感じますが、昨今では求められるスキルや要件の複雑化によってそういった体制では対応しきれなくなってきているのではないでしょうか。事業規模の比較的小さな企業やスタートアップ企業などプロダクト側にフルコミットする必要がある場合は、社内ITサービスの外注化を行う場合もあるかと思いますが、以下のようなリスクがあるため慎重な判断が求められます。

  • 顧客伴走型と謳っているサービスであっても顧客視点の小回りがきくサービスにはなりにくく、他企業共通のテンプレ利用による対応となるリスク
  • システム化や仕組み化のベースとなるプラットフォームを顧客側ではなく発注先ベンダー側環境で構築され、顧客側では関知できないリスク
  • 設計や設定、ナレッジ自体が顧客側に蓄積されず基本的にブラックボックス化してしまうリスク
  • 各種リスクを解決するような契約を試みた場合、自社で専門のエンジニアを採用するよりコストが高くなるリスク
  • 発注先都合で突然サービス終了となり、自社の社内ITサービスが停止してしまうリスク

また、社内ITサービスというのは、自社独自の要件を年々積み重ねて構築していく要素も大きいため、例えばIDaaS製品の設計だけ、社内NWの構築だけを切り出すのではなく、社内ITサービス全体のバランスや連携も視野に入れた高い視座で最適なサービス運営を行う必要があります。加えて、各種サービスの発注先ベンダー等との価格交渉や要件すり合わせについても一定の知識が必要になりますので、その意味でも自社で専門のエンジニアを採用して運営していくことは重要であると言えます。

CO-ITチームは、私が入社する直前まで暫定的にマネージャ自身がプレイヤーを兼務し、多くの実務は(ヘルプデスク業務を外注できるような)外部サービスを利用することで社内ITサービスを維持管理している状態でしたが、私は業務状況を確認した上でチーム運営を再設計するフェーズ(初期フェーズ)と判断しました。なお、マネージャとは定期的に「As is」/「To be」について大枠の目線合わせを行っています。*4

プロダクト、スコープ、役割を整理する

大枠の方針がフィックスした後は、少しずつ具体化していきます。まず、プロダクトとスコープの定義です。 一般的には、事業活動において顧客に提供するものをプロダクト(当社の場合、BUYMAというサービス)と呼び、コーポレートITがプロダクト?と違和感を感じられるかもしれませんが、顧客(従業員)に対してサービスを提供する部門である以上当然プロダクトがあって良いと思いますし、意識すべきと考えています。そして、そのプロダクトを提供するためのスコープの定義も併せて必要です。

プロダクト/Job Titleとスコープのマッピング

上記がCO-ITチームのプロダクトと大枠のスコープになります。スコープは大項目のみ表記していますが、例えば今回のような「techブログへの投稿」業務は「ブランディング貢献」の中に含まれるという感じです。 また、スコープは視座や技術的な難易度等々によってピラミッド型になるので、メンバーの役割の大雑把なプロットも行っています。*5

メンバー構成(チームの総リソース)を整理する

ここまででチームが目指す方向性が見えてきたので、次に具体的なメンバー構成や必要リソースの整理に移ります。 なお、この項目については、各企業の人員計画・予算・業績・既存のメンバー構成等々複雑な要素を踏まえた経営判断になるかと思います。 結果だけの記載となりますが、CO-ITチームは、4名体制を目指すべく現在4人目のエンジニアを募集している状態です。

まとめますと、CO-ITチームは以下のように年間の投下リソースで表現されるValue(アウトプット)が会社から求められる期待値をアウトパフォームすることを意識しなければなりません。

チーム(総リソース[年間約7,680h*6])のValue > 会社からCO-ITチームへの期待値

裁量と責任、働き方

採用業務を行っているとよく質問を受ける項目ですので、ここで触れたいと思います。 CO-ITチームは、各担当者毎にスコープを限定するようなことはなく、基本的に各自のミッションサイズ(会社が各自に期待すること)に応じてコーポレートIT領域全てに携わる方針としております。*7 ミッションサイズの中で最大限の裁量と責任を持っていただき、自由に業務時間を使うことで最大のValueを発揮いただくのが最良という考えに基づいています。

また、当社はオフィスワーク・リモートワークの選択も一定の裁量が許容されていますので、CO-ITチームでもその範囲内で自由選択としています。 基本的にオフィスワークが必要な業務(デバイスのキッティング等)を中心に行うメンバーは出社頻度が高くなりますが、リモートワークすることでオフィスワークする以上のアウトプットが出せるのであればリモートワークの頻度が高くても良いという方針です。なお、業務スコープの特性上(ITサービスデスクを担当しているため)、必ず一人以上のチームメンバーがオフィスワーク(本社に出社)することで物理的なインシデントやユーザサポート対応を可能にしています。

2.現状を俯瞰する

チーム運営の前提の整理が終わった後は、現状の把握に移ります。

課題を整理する

サービスを整理する

プロダクトを理解した上で顧客に提供するサービスの整理が必要です。近年のコーポレートIT領域はオンプレからクラウド化の流れが急速に進んでいるため、SaaSのことばかりに目が行きがちですが、従来の社内NW運用業務をはじめ、企業によってはオフィスファシリティやセキュリティ領域も含まれます。 また、SaaSによっては他のバックオフィス部門(経理等)やプロダクト側が慣例的に運用しているサービスもあり、各サービス毎で主管している部門は企業によって差異があり、正確な把握が必要です。

コストを整理する

主管するサービスが洗い出せた後は、具体的なコスト感の把握です。 自チームが提供するサービスのコスト感がパッと答えられないというのは問題外であり、そのコスト感に見合うメリットを会社にもたらしているのかを常に意識する必要があります。 また、SaaSであったとしても、単純にライセンス費用や月額利用料といった費用だけでなく、導入から日々の維持管理に必要な人的リソースのコスト(1人日の単価を具体的に設定した上で年間何人日、何人月の工数が掛かりどのような金額になるのかまで想定)を含めて該当サービスのコスト妥当性が判断される必要があります。*8

CO-ITチームでは、下記のような主管サービスを網羅した一覧を作成・運用しており、提供サービスの総合計を従業員数で割ったサービスコストの算出を行っています。 この一覧には、サービスのコストをはじめ、サポート窓口の情報や稟議・請求書対応、更新のタイミング等々を含め、サービス別に串刺しして比較でき、これだけを確認すれば運用に必要な情報が取得できるように一元管理しています。

提供サービス一覧

なお、現時点では見える化したところまでしか到達しておらず、コストの最適値はどのくらいなのか、今のコストは妥当なのかという分析や評価を実施するフェーズには至っておりません。 近い将来、このコストを一つのパラメータとして適切なサービス導入のガイドラインを策定することを見据えております。

手続き・運用を整理する

次に見積・稟議・発注・請求のような一連のサービス導入手続き、導入後の実運用について把握します。実現したいことは各企業大体同じであるにも関わらず、企業によって利用しているワークフローは様々であり、実現するまでに理解すべきことのボリュームに大きな違いがあります。

会議コストを考え、会議体を整理する

ファシリテーションや会議に関するビジネス書で数多く述べられていますが、「会議コストは非常に大きなもので意味のある会議をすべき(無駄な会議は廃止すべき)である」といった主旨のトピックが記載されています。

例えば、4人のエンジニアが1hのMTGをする場合、そのコストは超ざっくり¥25,000程度になります。*9ですので、その1hのMTGのアウトプットに会社はその金額を払うことになるので、その期待値を超えるValueが必要になります。特に会議は複数人で行うものなので、各自が単独で行うTodoよりも大きな人件費が計上されてしまうことになります。また、とりあえず参加するだけで仕事をした気になってしまうので注意が必要です(会議に参加すること自体にValueはなく、その会議でどのようなアウトプットを出したかが重要)。

ということで、CO-ITチームでは必要な会議体を整理し、チームのフェーズに合わせた会議運営を行っています。

情報共有・ナレッジ化を意識する

まだまだ続きますが、続いてはチームレベルのナレッジマネジメントです。一人情シスのような状態でなければ、基本的に業務を進めていくとチームメンバーへの具体的な手順共有は当然として、各種設計指針やそもそもの要件定義内容等々、チーム独自のナレッジを複数人で共有するシーンが多々あるかと思います。ナレッジ共有を全く行わない(何もかも属人化)のような組織はないと思いますが、共有の仕方に課題感が残っている組織は少なくないかと思います。CO-ITチームでは以下のポイントを実行し運用しています。

  • 共有の仕方を定義する
  • 共有すべき粒度を定義する
  • ナレッジ化に惜しみなくリソースを投下する

タスクを整理する、バックログ化する

そして、最後にタスクの整理です。PJ管理やタスク管理を実施するためのツールや方法は様々なので省略しますが、当社では私が入社前の段階からAsanaを利用していたため一旦そのまま継続利用しています。タスク整理にあたり、ポイントとしたことは、以下の通りです。

  • 必ず各タスクの目的を明確化する
    • 不明瞭な(誰も自分事としていない)タスクが管理ツール上に表示されていない状態
    • マネージャは意思決定のみを担当(タスク担当者にマネージャをプロットしない)
  • 全体を同じ箱の中に含め他メンバーの業務状況も見える化する*10
    • スポット、割り込みタスクが入ってもチーム全体のタスク一覧に起票する
    • 個人のローカルTodoで処理しない、オープンにする
    • 基本的に起票する(よほど数分でクローズするようなタスクは例外)

本来であれば、アジャイルの考え方に沿って、チーム全体でスクラムを用いてスプリント毎に同じMissionに向かって組織運営(バックログ消化)を行いたいのですが、CO-ITチームではまだまだそういったフェーズにないと判断し、現状はバックログ化することまでに留まっています。

CO-ITチームの課題

以上の課題整理を行った結果、CO-ITチームでは以下のような課題が見えてきました。 既にある程度クリアできてきているものもありますが、日々最適化すべく現在も業務推進中です。 何をどのように解決したかの話は、また機会があればご紹介させていただきます。

  • 資産管理の精度が低い、管理できていないものが存在する
  • サービスのスコープ、責任分界点が不明瞭
  • ナレッジが点在している、不足している、陳腐化している
  • ブラックボックス化(実務の外注サービス依存にも起因)、属人化している
  • 業務分析できる基盤が整っていない(定量化できていない)
  • 意思決定した背景・経緯・ポイントが体系化されていない
  • 中長期的な視点で要件定義・設計・設定が行われていない
  • 暫定対応でタスククローズした内容のまま形骸化している
  • ユーザ要望を単純に解決することにフォーカスされている

3.将来を想像する

前項の通り、課題は山積みであったため、各課題に対してできる範囲(新規サービスの導入やシステム化・インテグレーションは後回し)で将来を見据えた改善を行う方針としました。

見える化定量化に向けた(KPI・KGI策定を見据えた)足固め

冒頭で記載したようにコーポレートIT領域というのは取り扱うサービスや技術が広く、様々なスキルセットが求められると言えますが、個々のPJやタスクサイズは小さいことが多々あります。 しかしながら、タスクサイズが小さいからと言って、個々のタスクを全て点で捉えて個別にクローズし続けるといつまで経っても組織運営が最適化されません。 この観点において、CO-ITチームでは将来の対応リソースの削減も見据え、タスクを定量化することに注力しています。

見える化定量化は多くの企業で実施されているかと思いますが、その粒度や精度については様々かと思います。 CO-ITチームも私が入社する前から全くできていないということではなく、粒度や精度に課題があったという話になります。

私が特に重要視しているのは提供サービス全体での体系化と最小限のリソースを目指す運用サイクルの構築になります。 この観点で言えば、CO-ITチームではまだまだ足固めが必要な状態であり、新規サービスの導入やSaaS間のインテグレーションを考えるフェーズにないと判断しました。 ですので、CO-ITチームではこの一年立ち止まって当たり前のことを実現できる最低限の準備を進めてきました(導入済みサービスはリプレース検討フェーズに移らず基本的に一旦継続利用して精査する)。その中のほんの一例が下記になります。

  • 資産管理の精緻化
  • 問い合わせ対応のワークフロー改善、見える化定量
  • 提供デバイスのラインナップ整理とユーザへのガイドライン提供
  • キッティング業務のワークフロー化
  • 備品貸与ガイドラインの策定
  • バイス提供スピードの向上、提供コストの削減
  • 入退社復職休職のような人事イベントに伴うアカウントフローの整理
  • 社内手続き・稟議の整理
  • サービスの保守期限の統一、サポート窓口の整理
  • ナレッジ共有方法の統一、ナレッジの質・量の向上

業務改善の話(SaaSのインテグレーションだけが全てじゃない!)

採用業務で様々なエンジニアの方とお話する機会があるのですが、コーポレートエンジニアを目指されている方には「業務改善」にやりがいや面白さを強く感じられていて、プログラミングを行って自動化処理の仕組みを作ることが全て(若干誇張していますが・・・)という志向をお持ちである方(そういった印象を受ける方)にお会いすることがあります。確かにコーポレートエンジニアの業務の中でSaaSのインテグレーションというのは、より技術的な要素が強く自身の満足につながる、かつ他の方(特に非エンジニア職の方)からの評価が高くなる傾向がありますので合理的ではあります。

しかしながら、一度立ち止まって以下の質問に向き合うことも必要ではないでしょうか。

  • 本当にシステム化、自動化することだけが正なのでしょうか?
  • 本当に自動化することでコストは下がっていますでしょうか?

参考:運用自動化、不都合な真実

CO-ITチームでは、SaaS運用だけでなく全てのコーポレートIT領域に含まれるサービスにおいて業務改善を行うことが必要であり、実現する方法(コードを書くことが全てではない)に優劣はなく、アウトプットに対する評価は常にフラットでありたいと考えています。例えば、CO-ITチーム内の一例を紹介させていただきますが、以下のような対応も十分一つの業務改善であり、同等に評価されるものと考えています。

業務改善の一例

  • 左側の写真:会議室のモニタスタンドを壁寄せモニタで可動式に変更
    • レイアウト変更を容易にするという要件の充足と机上スペースの拡張を実現
  • 右側の写真:管理するサーバルーム内の棚に共通の収納ボックスを導入
    • 備品管理を最適化(必要な備品に最短でアクセスできる導線の確保とコストの最適化)

サービス導入・施策を開始することについて考える

CO-ITチームではこの一年立ち止まって足固めをしているため主だった新規サービスの導入は見送っている(他にもっとやるべきことが多い)のですが、新規サービスの導入(リプレース含む)業務に魅力を感じるエンジニアの方は多いのではないでしょうか。逆に既存のブラックボックス・複雑化した環境を考慮して体系的に再整理するような業務は(やりたくないとは口には出さないものの)敬遠される傾向が多いように感じます。

この傾向は、自身の直接的なスキルアップや評価へのつながりやすさに起因するものと思います。加えて、ゼロベースでの設計難易度に比べ、複雑な既存環境の再設計は難易度が非常に高く、ボリュームが大きくなる割にはアウトプットが(新規サービス導入に比較すれば)地味になります。また、実際に稼働しているサービスの場合が多く、放置してもスポットでは課題感が多少あるかもしれないが何とかやり過ごせることが多いことも要因の一つにあるように感じます。

ビジネス書(amazonのすごい会議)の中にもまさに同じような視点のコラムが掲載されていましたのでご紹介させていただきます。 PDCAサイクルにおいてAmazon社ではPDだけの人(立ち上げ屋[企画業務])は重視されないが、日本企業ではPDが重視されがちというものです。まさにコーポレートIT領域でも同じように感じます(下記のような状態です)。

  • サービス導入することにだけ大きなコスト・アテンションが払われる*11
  • 導入担当者の主観・感覚のままローンチされることがある
  • 肝心の設計・設定・運用はレビューが薄い*12
  • 問題が顕在化した後に再設計を検討する(再設計の中心人物がヒーローになる。。。) *13

CO-ITチームでは、近い将来新規サービスの導入を必要に応じて行いますが、上記のような課題が残らないようなPJ運営を行うつもりですし、一部の声の大きなメンバー*14だけが新規サービス導入に携わるような組織にならないよう最適な仕組みづくりを日々模索していきます。

チームの安定した運営を考える

チーム運営を安定化するポイントとしては、システム化(人に依存しない運用を構築する)やリソースの安定化(メンバーの頻繁な入れ替わりを防ぐ)といったことが挙げられます。前者については各所で述べられているように感じますが、後者はそれに比較すると情報量が少ない印象です。ここでは後者について深掘りします。

各種サービスのシステム化・自動化が非常に重要であることは自明ですが、それ以上にリソースの安定化は非常に重要です。以下にチームメンバー入れ替わりに関するデメリットを整理してみます。

  • 一時的にリソース不足に陥る
  • 新規メンバーの採用コストが必要となる
  • 新メンバーの立ち上がりに1ヶ月〜半年程度を見込む必要がある

では、逆にメリットがないかと言えばそうではなく、以下のようなチームに新陳代謝が起こるメリットはあります。

  • 旧メンバーより更に良い人材がチームに加入するかもしれない
  • これまで慢性化や形骸化していた業務に良い影響を与えるかもしれない

しかしながら、安定したリソースでの運用を目指す方がチームとしての総合戦闘力は高いと感じますし、各自のスキルアップやチームの新陳代謝はチーム運営方法によりカバーできるものと考えますので、メンバーの不要な入れ替わりは避けたいものです。メンバーが離脱する理由を考えると、

  1. 待遇面(給与やワークライフバランス[会社の規定])の問題
  2. 会社や部署方針との根本的な価値観の不一致
  3. 会社の業績、業種の市場動向
  4. ジョブチェンジを目指す、またはプライベートな問題
  5. 部署内でのコミュニケーションの問題
  6. 志向の問題(自社ではスキルアップが見込めないと感じる)
  7. 足元の担当業務の問題(同じ業務ばかり、丸投げばかりされる、不公平感を感じる)

といったところでしょうか。 この中で1-4まではチーム運営ではどうすることもできないものになりますが、5-7を理由にメンバーの入れ替わりが発生するというのは、当該チームのマネージャやリード担当者に責任があると感じますし、こういった理由が発生しないよう常に改善を続ける必要があります。CO-ITチームでは、将来的なチームの安定運営を目指すために日々 カイゼン に向き合っています(具体的な話は機会があれば・・・)。

終わりに

今回は具体的なサービスの設計や設定内容、サンプルコード等のご紹介にフォーカスできませんでしたが、CO-ITチームの将来に向けた足固めは着々と進みつつあります。 来年以降ようやく新規サービス導入や施策などのコーポレートITサービス拡充をスコープとしていくフェーズを見込んでおりますので、(個人的には)ようやく楽しい業務にリソースを大幅に割けるタイミングとなります。

2023年12月現在、一緒にコーポレートITを推進いただける方を募集中です。 上記チーム運営に共感いただける方や同じような視座で物事を捉えられる方とともに一緒に当社のコーポレートITを作っていけることを楽しみにしています♪

今回の記事は以上になります。 最後まで読んでいただき、ありがとうございました。


株式会社エニグモ すべての求人一覧

hrmos.co

*1:当社でも数年前まで「情シス」というワードが各所で用いられていましたが、少なくとも私が入社後は意図的に情シスというワードは使用せず、コーポレートITという表現を使用するようにしています。

*2:私個人の視点ですが当社はフラットな環境に感じます。

*3:当然ベンダーには自社の独自要件を踏まえたオーダーメイドの最適な設計でチューニングを行うように追加コストを支払う

*4:CO-ITチームの場合、マネージャと私の方向性が元々大枠で一致していたことと、経営陣とマネージャが既に同様のコミュニケーションを行っていたことで非常にスムーズにすり合わせが完了しています。企業によっては、このすり合わせが非常に難航し、そもそもすり合わせせずに実務に移ることがありますが、後々重大な課題につながるのでオススメできません。

*5:あくまで目安であり、ピラミッドのベースにある項目が頂点にある項目に劣るというような優劣は全くありません。全ての項目がコーポレートIT領域には重要です。また、これは一般的に定義されたものではなく、私自身の経験その他から表現したものとなりますので一意見としてご理解ください。

*6:8時間 × 20営業日 × 12ヶ月 × 4名

*7:ミッションサイズは、全社共通の指標があり、入社時を含め半期毎に行われる評価によって適宜決定されます

*8:あくまで私の個人的な意見ですが、業務として責任を負っている(報酬(給与)を獲得している)以上は合理的な説明責任があります(定量化することは必要です)。

*9:SE費¥50,000/人日 × 0.5人日[0.125人日 × 4名]

*10:チームは同じMissionに向き合っているため、各タスクを項目分けすることはあってもブラックボックス化しない(隠さない)。各メンバーのValueをそれぞれが参考にしたり、評価するために必須。

*11:導入すること自体にバリューはなく、そのサービスで何を実現するかにバリューがある。

*12:マネージャやリードエンジニアは、実担当でなくても高い視座でシステムの重要トピックや仕様を明確化してレビューを行う必要がある

*13:そもそも新規導入時の考慮不足・レビュー不足に起因して問題が発生する場合が多い。問題が発生する前にチームで再設計が議論され、バックログ化されているのが正しい運営であり、ヒーロー(救世主)のような特定個人のスキルセット頼みになるのは問題です。

*14:誤解を恐れずに記載すると、いいとこ取りだけして面倒事は他メンバーにぶん投げるような自分本位のようなメンバーのことを指しますが、業務への慣れ等によって知らず知らずの内に意図せずそのような振る舞いになることもあるかもしれません。お互いリスペクトし合える組織を目指したいものです。

Rails7でHotwireのTurboを使う

こんにちは、エンジニアの太田です。

この記事は Enigmo Advent Calendar 2023 の16日目の記事です。

はじめに

TurboはRails7からデフォルトで搭載されており、VueやReactなどjavascriptの記述が必要だったDOMの更新をjavascriptを(あまり)書かずに実現させてくれます。 フロントエンドにあまり触れない方にとっては、SPA風のwebアプリへのとっつきやすさが出たと思います。
本記事では、私が初めてTurboに触れて使い方を覚える際に作成したサンプルの一部と使った感想を備忘録的にまとめたものになります。
各公式ドキュメントでも使い方を確認できます。
Rails で JavaScript を利用する - Railsガイド *1
Turbo Handbook *2

サンプルコード

以下は私が主に使用した形です。 ransack*3とkaminari*4を使ったリストの更新と追加・編集・削除をしてみます。

controllers

class CountriesController < ApplicationController
  def index
    @q = Country.ransack(params[:q])
    @q.sorts = 'name asc'
    @countries = @q.result.page(params[:page])

    # Request HeadersにTurbo-Frameが設定されているとpartialがreturnされて、
    # 対象の要素がpartialに置換される
    if turbo_frame_request?
      render partial: 'list', locals: { countries: @countries }
    end
  end

  def show
    @country = Country.find(params[:id])
  end

  def edit
    @country = Country.find(params[:id])
  end

  def create
    @country = Country.create!(country_params)
  end

  def update
    @country = Country.find(params[:id])
    @country.update!(country_params)
  end

  def destroy
    @country = Country.find(params[:id])
    @country.destroy!
  end

  private
    def country_params
      params.require(:country).permit(:code, :name)
    end
end

models

class Country < ApplicationRecord
  # ransackで検索項目にしたカラムを記載したのみ
  def self.ransackable_attributes(_auth_object = nil)
    %w[name]
  end
end

views

index.html.erb

# このフォーム内からのリクエストはヘッダーにTurbo-Frameを設定する
# レスポンスのpartialによってid属性がlistのturbo-frame要素が置換される
<%= search_form_for @q, html: { data: { turbo_frame: 'list' } } do |f| %>
  <div>
    <%= f.label :name_cont, 'name' %>
    <%= f.text_field :name_cont %>
  </div>
  <div>
    <%= f.submit '検索' %>
    <%= link_to 'リセット', countries_path, data: { turbo_frame: "_top" } %>
  </div>
<% end %>

<%= render 'list', countries: @countries %>

<%= render 'form' %>


_list.html.erb

# id属性がlistのturbo-frame要素
<%= turbo_frame_tag :list, autoscroll: true, data: { autoscroll_block: 'start' } do %>
  <ul id="countries">
    <li>
      <div>国コード</div>
      <div>国名</div>
      <div></div>
      <div></div>
    </li>
    <%= render countries %>
  </ul>
  <div>

    # turbo_frame_tag内は自動的に直近の親を対象としたTurbo-Frameのリクエストになる
    # なのでkaminariにTurbo用の設定は不要
    <%= paginate countries %>

  </div>
<% end %>


_country.html.erb

# id属性がcountry_{country.id}のturbo-frame要素
<%= turbo_frame_tag country do %>
  <div><%= country.code %></div>
  <div><%= country.name %></div>

  # 直近の親 (id属性がcountry_{country.id}のturbo-frame要素)が対象のTurbo-Frameのリクエストになる
  # edit.html.erbに置換される
  <div><%= button_to '編集', edit_country_path(country), method: :get %></div>

  # GET以外のメソッドではTurbo-Streamのリクエストになる
  # destroy.turbo_stream.erbの処理を実行
  <div><%= button_to '削除', country_path(country), method: :delete %></div>
<% end %>


edit.html.erb

# id属性がcountry_{@country.id}のturbo-frame要素
<%= turbo_frame_tag @country do %>
  <div>
    <%= form_with model: @country do |form| %>
      <%= form.text_field :code %>
      <%= form.text_field :name %>

      # 直近の親 (id属性がcountry_{@country.id}のturbo-frame要素)が対象のTurbo-Streamのリクエストになる
      # destroy.turbo_stream.erbの処理を実行
      <div><%= button_to '保存', action: :update %></div>
    <% end %>

    # GETメソッドなのでTurbo-Frameのリクエストになる
    # show.html.erbに置換される
    <div><%= button_to '中止', country_path(@country), method: :get %></div>
  </div>
<% end %>


show.html.erb

<%= render 'country', country: @country %>


update.turbo_stream.erb

# id属性がcountry_{@country.id}のturbo-frame要素をupdate後に置き換える
<%= turbo_stream.replace @country %>


create.turbo_stream.erb

# id属性がcountriesの要素の末尾に_country.html.erbを追加
<%= turbo_stream.append 'countries', @country %>

# 登録フォームを入力をリセット
<%= turbo_stream.replace 'register' do %>
  <%= render 'form' %>
<% end %>


_form.html.erb

# 登録フォームのid属性registerを設定しておく
<%= form_with model: Country.new, id: 'register' do |form| %>
  <div><%= form.label :code %><%= form.text_field :code %></div>
  <div><%= form.label :name %><%= form.text_field :name %></div>
  <div><%= form.submit %></div>
<% end %>


destroy.turbo_stream.erb

# id属性がcountry_{@country.id}のturbo-frame要素を削除
<%= turbo_stream.remove @country %>

turbo-frame

turbo-frameは画面内のturbo-frameタグを一つだけを対象として置換することができます。id属性必須です。
リストの更新が主な使用ケースでした。

turbo-stream

turbo-streamは画面内の複数要素をid属性で指定して対象とすることができ、それぞれに対して下記の7つの処理*5を実行できます。

  • 先頭追加
  • 末尾追加
  • 直前追加
  • 直後追加
  • 置換(対象要素含む)
  • 更新(対象要素含まず中身だけ)
  • 削除

この時、対象とする要素はturbo-frameタグではなくて普通のdivタグなども指定可能です。注意点はGET以外のリクエストにする必要があることです。
登録時にリストへ要素を追加すると同時にフォームをリセットするなどが主な使用ケースでした。フラッシュを表示したりで複数箇所の更新が必要になりがちなDB操作が絡むリクエストでの使用機会が多いと思います。

動きのイメージ

リストを更新
検索をリセットして初期化
編集フォームに置換
編集を保存して反映
編集をやめる
データを削除
データを登録

細かい話

Hotwireとは、Turboとは

下記の公式の説明やimport文からHotwireという開発アプローチがあって、それを実現させるためのパッケージにTurboというパッケージがあるという感じのようです。

Hotwire is an alternative approach to building modern web applications without using much JavaScript by sending HTML instead of JSON over the wire. *6

import * as Turbo from "@hotwired/turbo"

HotwireにはTurbo以外にもStimulusとStradaがあり、この三つの要素から成ります。 Rails7以降ではデフォルトでTurboとStimulusが使えるようになっています。

# Hotwire's SPA-like page accelerator [https://turbo.hotwired.dev]
gem "turbo-rails"

# Hotwire's modest JavaScript framework [https://stimulus.hotwired.dev]
gem "stimulus-rails"

ReactやVueとの違い

前述の公式説明には「without using much JavaScript by sending HTML instead of JSON over the wire.」とありますが、これがHotwireがReactやVueと異なるポイントです。
RailsでReactやVueを使う場合は、サーバサイドのrailsがcontrollerでデータをreturnし、そのデータを取得するようにクライアントサイドのReactやVueの実装をするかと思います。
一方でHotwireでは、上に挙げたサンプルコードのようにリクエストに対してcontrollerがHTML(render partial)をreturnするだけになります。
確かに、JavaScriptを使わずにJSONではなくてHTMLを送信するようになっています。

Turboを使った感想

ransackやkaminariといったviewsを構成するファイルに対するgemをそのまま使えて、わざわざフロントエンド用にnpm installとかしなくて済むのがとてもよかったです。
DOM更新はほとんどJavaScriptを記述しなくてもよかったのもあり、作業工数もそこそこ少なく済むのではないかと思います。
使いづらいところとしては、turbo-frameタグで全体を囲わなければならないのでスタイルの当て方が少し面倒になる場面がありました。cssフレームワークを使う場合は結構気を使う必要があるかもしれません。
また、各アクションでhtmlを返す必要があるので、必然的にviewsディレクトリのファイルが多くります。jsの記述が必要無くなった分という感じです
。 一般公開する大きなサービスではちょっと頼りなさそうな感じはしましたが、他の業務もしながら開発する社内ツールくらいの規模であれば十分なものだと思いました。


最後までご覧いただきありがとうございました。

明日の記事の担当は、コーポレートエンジニア(コーポレートIT[CO-IT]チーム) の横川さんです。お楽しみに!


株式会社エニグモ すべての求人一覧

hrmos.co

「心理的安全性」とソフトウエア開発

はじめに

こんにちは、株式会社エニグモの開発を担当しているグループでエンジニアリングマネージャーをしている後藤です。

この記事は Enigmo Advent Calendar 2023の15日目の記事です。

私は、開発グループでエンジニアリングマネージャーという役割をしています。この記事では、チームメンバーとの関わりの中で大切にしている「心理的安全性」についてポエムを書かせていただきます。

この記事の対象者

この記事の対象は、「心理的安全性」という言葉は聞いたことあるけどモヤッとしかわからないが大切そうだ、みんなが「心理的安全性」といっているから上っ面だけでも理解してドヤ顔をしたいという人を対象にしています。

この記事を通して、読者の方に「心理的安全性」がどうソフトウエア開発に影響を与えていると感じているのか、どうしたらソフトウエア開発チームにとって良い「心理的安全性」のある環境を作れるのかを自分で解釈する手助けになればと思っております。

あくまで、私の解釈ですのでこの記事を参考に自分の考え、理解を勧めていく手助けになれば幸いです。

因みに、私が思っている「心理的安全」なチームは以下のイラストのイメージです。

安心できるチーム

心理的安全性の定義とソフトウエア開発現場における私の理解

まずはじめに、「心理的安全性」という言葉ですが、Googleが発表した「成果を出すチーム」の条件に出てきて有名になったと理解しています。私もこの記事で知りました。それからずっとこの「心理的安全性」が引っかかっていました。

なぜならマネージャーと名のつく役割を担っている以上、「成果」を出すことを期待されています。それに、最も影響を与えるとなれば理解しないわけにはいきません。

ところがです、「心理的安全性(psychological safety)」について調べると、組織の中で自分の考えや気持ちを誰に対してでも安心して発言できる状態のこと、と出てきます。また、そのような環境を作るために、自分の病気のことを話したり、プライベートなことも話せる関係を作っていくと良いと結ばれていました。

そうなのかー、私には無理じゃん、というのが正直な感想でした。エンジニア上がりでエンジニア仕事大好きなどちらかというとコミュ障寄りの私にとって、プライベートな話をしたり雑談をしながらチームを作って行くなんてできっこないと思ったわけです。

それでも、この「心理的安全性」を放置しておくわけにもいかないですし、別にプライベートな事が話せる事が必須条件ではないだろうという思いもあり私なりに噛み砕いてみました。

心理的安全性」が低いとどんな問題があるのか

心理的安全性」を理解するにあたり、「心理的安全性」が低いとどんな問題があるのかを考えてみました。

いろいろあるのですが、私が考えている一番の弊害は、開発をしていて「この部分少し不安だ」、「あの部分、実は問題がある気がする」といった「もやっと」した気持ちを他のメンバーに伝えることができない、伝えることに抵抗がある、ということではないかと考えました。

なぜなら、「この部分少し不安だ」、「あの部分、実は問題がある気がする」という部分は、なぜだか本番にリリースするとかなりの確率でエラーが起きたりします。そして、分かっていた本人は心のなかで「やっぱりか!」と思いながら修正に追われるわけです。

この「もやっと」を事前に伝えられていれば、トラブル対応に追われるという状況を回避できたはずです。

この、少し不安だが確信が持てない、間違っているかもしれないけど、みたいな事を伝えられるチームである事が生産性に影響を与えるのではないかと考えたのです。

「もやっと」を伝えられるチームにするために何をしているのか

私達のチームでは、毎週金曜日にKPTフレームワークをつかって振り返りをしています。この場でこの「もやっと」を伝えられる雰囲気を作る事を心がけました。

そうはいっても、「もやっと」を伝えてくださいね、と言ってみたところで意見が出てくるわけではありません。

そのため、1on1で出てきた、困ったことや解決した事を、些細なことでも良いので週次の振り返りに上げてもらうよう伝えることを根気よく繰り返しています。また、私自身が見つけた問題や、解決した事も話すようにしています。

このような事を繰り返していくことで、小さな事でも伝えて良いんだ、という空気ができてくる。また他の人が伝えてくれた小さな事が役に立った!という経験の積み重で、「もやっと」を伝えていこうという空気が出てくるのではないかと思っています。

まとめ

ソフトウエア開発の現場で「心理的安全性」は、小さな「もやっと」を伝えられるか、に影響すると考えています。

この小さな「もやっと」を意識的に引き出していくことで、ソフトウエア開発で発生する問題の芽を早いうちに摘む事ができ、開発生産性を改善できるのではないかと考えています。

そのために、小さな発見を伝えられる場作りを大切にしています。

おまけ

週末に BIBLIOTHECA というラジオ番組を聞いていたら、この「もやっと」が伝えられないチームの状況を適切に表す言葉に出会いました。この状況は、「集団浅慮(しゅうだんせんりょ)」と呼ばれる状況と一致しているのではないかと思います。

「集団浅慮(しゅうだんせんりょ)」とは、優秀な人達が集まって議論した結果、とても残念な結論を出して大失敗するという状況です。

そのラジオ番組によると、過去にケネディ大統領がこの失敗に陥り、そこからどう改善していったのかという事が以下の本に書いてある、と紹介されていました。この本の中に、マネージャーとして気をつけるべきことが潜んでいるのではないかと思っています。もっとも、集団浅慮に陥りやすいのは強いカリスマ的なリーダーがいるとき、というのがあったのでその部分は当てはまらない気がしますが、今度読んでみたいと思っています。

一緒に働く仲間を募集しています!

株式会社エニグモでは一緒に働く仲間を募集しています。興味のある方は以下の求人をご参照ください。

株式会社エニグモ すべての求人一覧

hrmos.co

【コンバージョン数3倍増!!】HTMLメルマガの改修事例をご紹介します

こんにちは、デザイナーの細田です。
この記事はEnigmo Advent Calendar 2023 の 15日目の記事です。

日頃の業務ではBUYMAの様々なコンテンツのデザインを担当しています。
中でもHTMLメルマガのデザインに関しては、数年前から改修に携わるようになり、ABテストによるデザイン検証に取り組んできました。

今回はその中でも、改修によって、お問い合わせフォームへの流入数が前月比で140%増加し、本施策のコンバージョンとなるお問い合わせ数も約3倍に増えた成功事例をご紹介します。

改修前のデザイン

まずは、今回改修依頼を受けたメルマガの概要をご紹介します。

対象者

高額な商品を複数回閲覧しているユーザー

内容

BUYMAコンシェルジュ*1というサービスを紹介し、お問合せフォームへ誘導する

デザイン

このメールを見て、皆さんはどう感じましたか?

私は、「なんだか唐突だな」と感じました。

例えるなら、お店で洋服を見ていたら突然声をかけられ、 「なにかお探しですか?コンシェルジュへご相談ください」と名刺を渡され去っていく・・
そのような唐突さを感じました。この内容では、お問合せしてみようと思う人は少ないかもしれません。

それでは、どうすれば唐突な印象を解消し、BUYMAコンシェルジュというサービスに興味をもってもらえるのでしょうか。

改修後のデザイン

改修後のデザインは以下のようになりました。順番に解説していきたいと思います。

【💡POINT 1 】ヘッダーに送信理由を記載する

私が、メルマガにおいて1番重要だと感じていることは、受信者に“自分宛” と思わせることです。

メルマガは “チラシ” と ”手紙” の両方の役割を担っています。
サッと見てゴミ箱行きのチラシとなるか、じっくり読んで返事を書きたくなる手紙になるか。
それにはそのメルマガが無作為に送られたものではなく、“自分に宛てて送られたものである” と感じてもらえるかどうかが重要となります。

そのために有効な手段として、上記のようにヘッダーに “どういう理由でこのメールを送信したのか” を記載する、という方法があります。
今回であれば、「高額な商品をご検討中の方へ特別なご案内です。」と記載することで、受信者がなぜこのメルマガが自分へ届いたかを理解し、「自分宛だから見てみよう」と感じる可能性を高めることができます。

【💡POINT 2 】タイトルは1番伝えたいことを簡潔に

メルマガ内で1番目を引くタイトルには、そのメルマガで1番伝えたいことを簡潔に記載します。

改修前のタイトルでは、「お探しの商品は見つかりましたか?」とありますが、このメルマガで1番に伝えたい事はBUYMAコンシェルジュの紹介です。
そこで、改修後のデザインでは「BUYMAコンシェルジュがバイマ太郎様のお買い物をサポートいたします。」と変更しました。
そうすることで、「BUYMAコンシェルジュって何だろう?」と興味を抱いてもらうことができます。

また、タイトルに受信者の名前を挿入し強調することで(例ではバイマ太郎となっています)
【 POINT 1 】で取り上げた“自分宛である” ことの演出を、より一層強めることができます。

【💡POINT 3 】分かりやすい見出しで離脱を防ぐ

改修前のメルマガにはBUYMAコンシェルジュについての説明がなく、「そもそもBUYMAコンシェルジュってなに?」と受信者を戸惑わせてしまう可能性がありました。

そこで改修後のデザインでは、BUYMAコンシェルジュについての説明エリアを追加したのですが、重要となるのが見出しです。
今回は、「BUYMAコンシェルジュとは?」という見出しをかなり目立つ形で挿入しています。
こうすることで、BUYMAコンシェルジュの説明エリアであることを明示し、タイトルを見て「BUYMAコンシェルジュって何だろう?」と興味を示したユーザーの目線をそのまま説明へと誘導する役割を担っています。

これが見出しのない、ただの文章としてそこに配置されていた場合、
特にスマートフォンの小さい画面で見た時に、反射的に読み飛ばされてしまったり、「読むのが面倒だ」とメルマガ自体から離脱されてしまう恐れもあります。

しっかり読んでもらいたい文章を配置する時こそ、目立つ見出しで分かりやすく区切ったり、文章自体も極力簡潔にまとめるなどの、細かい気配りが必要となります。

【💡POINT 4 】ボタンはベタ塗りで視認性を高める

改修前はボーダーであったボタンを、改修後はベタ塗りに変更しました。

その理由は、BUYMA全体のデザインルールに合わせるという目的もあったのですが、
スマートフォンの小さな画面で見た時の視認性の高さが、やはりベタ塗りの方が圧倒的に高いからです。

また、最近ではメルマガをダークモードで閲覧しているケースも増えており、
ダークモードで見ると特に、ベタ塗りボタンの視認性の高さが顕著になります。

まとめ

以上のような改善を行った結果、BUYMAコンシェルジュのお問い合わせフォームへの流入数が前月比で140%増加し、本施策のコンバージョンとなるお問い合わせ数も約3倍に増えました。

弊社ではデザイン改修に加え、MAツールの導入により、コンテンツ内容のパーソナライズ化や、配信対象の最適化など、よりユーザー1人1人に寄り添ったメルマガ作成を行なっており、確実に成果を生み出しています。

今後も地道なABテストを積み重ねながら、このような成功例を蓄積し、発信していければと考えています。


株式会社エニグモ すべての求人一覧

hrmos.co

*1:BUYMAコンシェルジュとは、特別なお客様限定の招待型プライベートサービスです。ご希望商品のお探しからお取引の相談まで、BUYMAのご利用に関するあらゆるサポートを専任のコンシェルジュが行なっています。

自社サービスで必ず達成しておきたいウェブアクセシビリティ対応についてまとめました

こんにちは。株式会社エニグモにてフロントエンドエンジニアを務めています新井です。

こちらは Enigmo Advent Calendar 2023 および アクセシビリティ Advent Calendar 2023 の 14 日目の記事です。

はじめに:ウェブアクセシビリティとは?

X(旧 Twitter)や各種テック記事などを見ていると、多くの人がウェブアクセシビリティを、障がいを持つ人々、特に視覚障がいのある人々への配慮として認識しています。

これは正しい認識の一部ではありますが、ウェブアクセシビリティの範囲はもっと広いです。実際には、全ての年齢層や様々な身体的、精神的条件を持つ人々が、多種多様な環境下でウェブサイトやアプリケーションを利用可能にすることを目指しています。

障がいがない人も、健康問題、マウスやトラックパッドの故障、音声再生の不可能な環境など、様々な状況に直面することがあります。ウェブアクセシビリティとは、これら多様なユーザーがウェブサイトやアプリケーションを容易に利用できるように設計することを意味します。

この記事では、ウェブアクセシビリティを向上させるための重要な10の項目を紹介します。私たちが運営するショッピングサイト「BUYMA」も今年からアクセシビリティへの取り組みを進めており、これらの項目を今後達成することを目指しています。

1. ページ内の見出しの最適化

具体的にはページ内で使用されている h1〜h6 タグを、階層構造の深さに応じて最適化します。

多くの方が見出しの最適化と聞いて SEO の改善を連想するのではないでしょうか?実際に、見出しの整理が SEO に好影響を及ぼすことはあるかもしれません。しかし、もっと注目すべきなのは、この最適化が SEO のみならずアクセシビリティにも大きく貢献するということです。

スクリーンリーダーなどの支援技術を利用するユーザーは、見出しを通してページ全体の構造を理解します。また、見出しジャンプ機能を使って必要な情報に素早くアクセスすることもあります。WebAIM のアンケートによると、約 7 割のユーザーが見出しジャンプ機能を使用しているとのことです。

webaim.org

見出しを用いてウェブサイトの情報構造を適切に整理することで、ユーザーが情報を迅速に理解できるようになります。

Google Chrome拡張機能Web Developer」を使用することでページの見出しのアウトラインを可視化することができます。見出しレベルを視覚化して検証することで、ページの構造が明確になり、改善点を見つけやすくなります。見出しの正確さや一貫性を確認するために、見出しレベルは可視化して検証することをおすすめします。

参考:達成基準 2.4.6: 見出し及びラベルを理解する

2. リンクや状態の判別を色の変化だけで行わないようにする

リンクや状態(フォーカスやホバーなど)の判別を色のみでデザインしてしまうと、色覚異常を持つユーザーにとって判別が困難になる可能性があります。 この問題に対処するためには、色だけでなく形状やその他のビジュアル変化を用いて区別ができるようにすると良いでしょう。

具体的な対策としては次のようなものがあります。

  • テキストリンクは色の変更に加えて、下線を表示する
  • 状態が変化する際に、アイコンを変更する
  • ボタンがホバーされた時は、背景色を変えるだけでなく枠線も表示する

特にホバーの状態は、透明度の変更のみでデザインされることが多いので、デザイナーと協力して状態の変化が明確に分かるデザインを作成することが望ましいです。

また、以下の CSS コードをデベロッパーツールで適用することで、ウェブサイトをグレースケールに変換し、色に頼った UI がないかどうかを検証するのに役立ちます。

body {
  filter: grayscale(1);
}

BUYMAのトップページをデベロッパーツールでグレースケールにしたサンプルです

ただし、濃い赤のような色はグレースケールへの変換では確認しにくい場合があるため、検証のコストとのバランスを考慮しながら、色覚特性のタイプごとに見え方をシミュレーションすることも有効かもしれません。

参考: 達成基準 1.4.11: 非テキストのコントラストを理解する

3. キーボード操作時のフォーカスインジケーターは非表示にしない

リンクやボタンがクリックされた際に表示されるフォーカスインジケーターは、しばしばデザイン上の理由で非表示にされがちです。しかし、フォーカスインジケーターを非表示にしてしまうと、キーボードでウェブサイトを操作するユーザーはコンテンツの利用が困難になってしまいます。

クリック時のフォーカスインジケーターを非表示にしつつ、キーボード操作時のフォーカスインジケーターを維持するには、以下のような CSS をベースで指定しておくと良いでしょう。

:focus:not(:focus-visible) {
  outline: none;
}

:focus-visible 擬似クラスはキーボード操作によりフォーカスされた場合に適用され、マウス操作によりフォーカスした場合には適用されません。

もしサイト内に複数の CSS が読み込まれ、各要素に outline:none が適用されているような場合、以下のような CSS を指定することでキーボード操作時のフォーカスインジケーターを復活させることができます。

@layer focus {
  :focus-visible {
    outline: revert;
  }
}

この方法では、Cascade Layers という機能を用いて優先度を高めています。 このスタイルは ID セレクタで定義されたスタイルよりも優先されますが、インラインスタイル( style 属性)や !important 指定されたスタイルよりは優先度が低いため、 !important を使用するよりも安全です。 ただし、 outline プロパティを上書きする場合は新たに @layer を設けて上書きする手間があるので、あくまで応急処置として扱うのが賢明です。 Cascade Layers は、現在すべてのモダンブラウザで使用可能です。

さらに、フォーカス時の状態をより分かりやすくするために、インジケーターに加えてホバー時のスタイルも適用しておくとフォーカスの判別がよりわかりやすくなります。

.button:focus-visible {
  /* ホバー時のスタイル */
}

@media (hover: hover) and (pointer: fine) {
  .button:where(:any-link, :enabled, summary):hover {
    /* ホバー時のスタイル */
  }
}

タッチデバイスでのホバーは動作に支障が出る場合があるため、hover メディアクエリを利用してタッチデバイスでのホバーは無効化しておくと良いでしょう。

参考:達成基準 2.4.7: フォーカスの可視化を理解する

4. クリッカブルな要素の実装には a タグまたは button タグを使用する

クリッカブルな要素を div タグや span タグを用いて実装すると、支援技術を使用するユーザーやキーボード操作に依存するユーザーがその要素を選択できなくなることがあり、結果としてコンテンツのアクセシビリティが損なわれる可能性があります。

リンクは a タグを、ボタンは button タグを使用して、適切にマークアップしましょう。支援技術は a 要素を「リンク」、button 要素を「ボタン」と読み上げます。

既存のコードで a タグや button タグに変更するのが難しい場合、tabindex 属性と keydown イベントを使ってクリッカブルな振る舞いを実装することができます。以下は、BUYMA で使用されている React のコードの一例です。

<tr
  key={item.id}
  className="catalogs-table__row"
  onClick={() => handleSelectItem(item)}
  onKeyDown={(e) => {
    if (e.key === "Enter" || e.key === " ") {
      // Enter or Space で実行
      handleSelectItem(item);
    }
  }}
  tabIndex={0}
>
  ...
</tr>

このコードでは、tr要素に onClick イベントと onKeyDown イベントが設定されており、tabIndex={0}によってキーボード操作で選択可能になっています。

5. 画像の代替テキストの指定と装飾的な画像の取り扱い

原則的にコンテンツ上意味のある画像には必ず代替テキストを指定し、装飾的な画像は読み上げしないようにします。

img 要素の代替テキストは alt 属性で指定します。

<img alt="BUYMA" src="logo.png" width="130" height="25" decoding="async" />

アイコンフォントや SVG 要素に代替テキストを指定する際には、role="img" と aria-label 属性を併用して指定します。span や div、svgaria-label を指定すると、支援技術によっては適切に読み上げられない場合があります。また、 span や div の暗黙のロールが WAI-ARIA 1.2 より generic となったことで aria-label を付与するのは仕様違反となっています。安定した読み上げを確保するためにも、必ず role="img" を指定しましょう。

<span role="img" class="fab-icon fab-icon-facebook" aria-label="Facebook"></span>
<svg role="img" aria-label="X" viewBox="0 0 20 20"></svg>

装飾的な画像として img 要素を使用する場合は、alt 属性を空にします。alt 属性を省略すると、支援技術は URL を読み上げる可能性があります。

<img alt="" src="crown.svg" width="20" height="20" decoding="async" loading="lazy" />

装飾的なアイコンフォントや SVG 要素は、読み上げから除外するために aria-hidden="true" を指定します。

<span class="fab-icon fab-icon-information" aria-hidden="true"></span>
<svg aria-hidden="true" viewBox="0 0 20 20"></svg>

代替テキストの作成時には、画像が伝える情報を正確かつ適切にユーザーに届けることを心掛けるようにします。また、画像に関連しない情報をSEOのために加える行為はNGです。代替テキストはコンテンツの重要部分であり、他のテキストと同様、コンテンツ設計の初期段階で検討すると良いでしょう。

さらに、意味を持つ画像は CSS の background-image を使って背景として設定しないようにします。背景画像として設定してしまうと、支援技術を使用するユーザーが画像を認識できなくなります。また、background-image は loading 属性や decoding 属性を指定できないため、ウェブサイトのパフォーマンスに影響を及ぼす可能性があります。

参考:達成基準 1.1.1: 非テキストコンテンツを理解する

6. フォームコントロールには必ずラベルを付与する

フォーム内の入力欄やテキストエリア、セレクトボックス、チェックボックスラジオボタンなどのフォームコントロールには、label 要素を使って明確にラベルを付けるようにします。

label 要素の使用にはアクセシビリティの観点から大きな利点があります。フォームコントロールにフォーカスが合わされた際に要素の名前を読み上げることが可能になり、またクリックやタップの範囲が広がり、利用しやすくなります。

フォームコントロールとラベルを関連付ける方法としては、ラベルとフォームコントロールを label 要素で包むか、フォームコントロールの id 属性を label 要素の for 属性に紐付ける方法があります。

<label>
  ニックネーム
  <input type="text" name="nickname" />
</label>
<label for="nickname">ニックネーム</label>
<input id="nickname" type="text" name="nickname" />

デザイン上、フォームコントロールのラベルが UI 上に表示されていない場合でも、支援技術利用者のために aria-labelledby 属性や aria-label 属性を使用してラベル付けを行うことが望ましいです。

aria-labelledby 属性を使用した例

<form>
  <p id="keyword_label" style="display: none">検索キーワード</p>
  <input type="search" name="keyword" aria-labelledby="keyword_label" />
  <button>検索</button>
</form>

aria-label 属性を使用した例

<form>
  <input type="search" name="keyword" aria-label="検索キーワード" />
  <button>検索</button>
</form>

また、ラジオボタンチェックボックスなど、複数のフォームコントロールが意味的に一つのグループを形成する場合、fieldset 要素を使用してこれらをグループ化するようにします。この方法を採用すると、支援技術を使用してフォームコントロールを操作する際に、そのコントロールが属するグループの名前も読み上げられるようになります。

以下は、fieldset 要素を使用してラジオボタンをグループ化した例です。性別のコードは ISO 5218 で定められたものに従っています。

<fieldset>
  <legend>性別</legend>
  <ul>
    <li><label><input type="radio" name="gender" value="1" /></label></li>
    <li><label><input type="radio" name="gender" value="2" /></label></li>
    <li><label><input type="radio" name="gender" value="9" />その他</label></li>
    <li><label><input type="radio" name="gender" value="0" />不明・回答しない</label></li>
  </ul>
</fieldset>

また、ラベルをプレースホルダーで代用するUIも時折見かけますが、以下の観点から避けたほうがいいでしょう。

  • 記入時にラベルが消えてしまうためユーザーの短期記憶に負荷をかけることとなる
  • フォームの送信前にユーザーがどの項目に何を書いたのか判別できなくなる可能性がある
  • キーボード操作でフォーカスが当たるとラベルが消えることによる利便性の低下

参考:達成基準 2.4.6: 見出し及びラベルを理解する

7. フォームの入力欄のオートコンプリートを有効にする

オートコンプリートを有効にすることにより、ブラウザに保存された補完機能を利用できるようになり、結果としてユーザーは素早くフォームの入力を完了することができます。

<label>
  電話番号
  <input type="tel" name="tel" placeholder="(例) 090-0000-0000" autocomplete="tel" pattern="\d{2,4}-?\d{2,4}-?\d{3,4}" title="電話番号は正しく記入してください" />
</label>

サービス内でよく使用する autocomplete 属性の値は以下の通りです。

補完する要素
on autocompleteを許可する
off autocompleteを許可しない
name 氏名
given-name ファーストネーム(名前)
additional-name ミドルネーム
family-name ラストネーム(名字)
tel 電話番号
email メールアドレス
username ユーザー名orアカウント名
postal-code 郵便番号
address-level1 都道府県
address-level2 市区町村
address-level3 町域
address-level4 番地など
organization 企業・団体・組織名
cc-name クレジットカード登録名
cc-number カード番号
cc-exp カードの有効期限

多くのサービスでは、電話番号やクレジットカード番号などでオートコンプリート属性を活用します。一部の UI デザインでは、電話番号やクレジット番号の各部分を別々の入力欄で要求することがありますが、これは単に使いにくいだけでなく、オートコンプリートの利用を妨げる可能性があるため、デザイナーはこれらの情報を一つの入力欄で収めるよう配慮すると良いでしょう。

8. ラジオボタンチェックボックスを装飾する際は元の input の隠し方に気をつける

display:nonevisibility:hiddenされている input はキーボード操作でのフォーカスが不可能になってしまうため、ラジオボタンチェックボックスを装飾する際は別のアプローチで隠すようにしましょう。

<label class="checkbox">
  <input class="checkbox__input" type="checkbox" />
  <span class="checkbox__icon" aria-hidden="true"></span>
  <span class="checkbox__text">規約に同意する</span>
</label>
.checkbox__input {
  height: 1px;
  opacity: 0;
  position: absolute;
  width: 1px;
  z-index: -1;
}

さらに、装飾されたチェックボックスラジオボタンがフォーカスされた際には、その状態がユーザーに明確に認識できるようにしましょう。 以下の CSS は、フォーカスされた際にチェックボックスの周りにアウトラインを表示し、関連するテキストを下線で強調する方法の例です。

.checkbox__input {
  height: 1px;
  opacity: 0;
  position: absolute;
  width: 1px;
  z-index: -1;
}

.checkbox:has(.checkbox__input:focus-visible) {
  outline: 1px solid blue;
}

.checkbox__input:focus-visible ~ .checkbox__text {
  text-decoration: underline;
}

9. アコーディオン UI は可能な限り details 要素を利用する

アコーディオン UI を details 要素で実装すると、非アクティブな要素内のテキストもページ内検索で見つけることができ、キーボード操作や支援技術によるナビゲーションも可能になります。さらに、JavaScript を使わないためパフォーマンスが向上し、JavaScript が動作しない場合でもアコーディオンが利用可能になります。

<details>
  <summary>見出し</summary>
  <p>コンテンツ</p>
</details>

例えば、BUYMA ではスマートフォン表示のフッターメニューに details 要素が使用されています。

BUYMAでdetails要素が取り入れられているサンプルです

ただし、jQuery の slideToggle のようなアニメーション効果を追加したい場合、閉じる際に CSS の transition が効かないため別途 JavaScript が必要になります。

余談ですが、jQuery の slideToggle のようなアニメーションを実装する際、現代では折りたたむ要素に display: gridtransition: grid-template-rows .3s ease-out (所要時間とイージングはお好みで調整してください) を指定し、 開閉時に grid-template-rows の値を 0fr ↔ 1fr に変更するだけで対応が可能です。

参考:detailsとsummaryタグで作るアコーディオンUI - アニメーションのより良い実装方法 - ICS MEDIA

10. モーダル表示時は背面のコンテンツを読み上げ・選択不可能にする

モーダルコンテンツ(ダイアログやドロワーメニューなど)が表示されている際には、背後にあるコンテンツがキーボードや支援技術からアクセスされないよう設定します。

背面コンテンツに inert 属性を付与することで実現できます。inert 属性があると、ブラウザはその要素に対するユーザーの入力イベント(フォーカスイベントや支援技術からのイベントを含む)を無視します。

<body>
  <div id="wrapper" inert>
    <header>...</header>
    <main>...</main>
    <footer>...</footer>
  </div>
  <div role="dialog" aria-modal="true" aria-labelledby="modal_1_title" tabindex="-1">
    <h2 id="modal_1_title">モーダルタイトル</h2>
    <p>モーダルコンテンツ</p>
  </div>
</body>

inert 属性は多くの現代のブラウザで利用可能ですが、未対応の環境での使用を検討している場合は、Polyfill が利用可能です。

www.npmjs.com

参考:HTMLElement: inert プロパティ

おわりに:BUYMA でウェブアクセシビリティを促進する理由

ウェブアクセシビリティを考慮することにより、サービスをより広範なユーザーに提供することが可能になります。これにより、アクセシビリティの問題からサービスの利用を諦めていた人々を取り戻し、機会損失を防ぐことができます。

さらに、使いやすいサービスを提供することで、全体的なユーザー体験を向上させることにもつながります。

弊社では、アクセシビリティチャンネルを Slack で設立し、アクセシビリティに関する Redmine チケットを作成するなど、取り組みを進めています。まだ完全に対応しきれていない部分は多いですが、近い将来、これらの「必ず達成しておきたいアクセシビリティ対応」を実現する目標に向けて努力を続けています。

明日の記事の担当は SELL チームの後藤さんです。お楽しみに!


株式会社エニグモ すべての求人一覧

hrmos.co

Emacs Orgmode を使ったタスク管理で生産性を爆上げしよう!

こんにちは、サービスエンジニアリング本部の寺田です!

この記事は Enigmo Advent Calendar 2023 の13日目の記事になります。

私はエンジニアとして BUYMA の決済システム・配送システムの保守/運用や、またこれらのシステム領域を中心としたサービスの新規開発などを主に担当しています。

この記事では Emacs Orgmode を使ったタスク管理の方法について紹介していきたいと思います。

みなさんはタスク管理に何を利用しているでしょうか??

紙とペン、OS 標準の Reminder アプリ、Google Calendar など、人それぞれ普段お使いのものがあるかと思います。

私は実際に普段の業務で Emacs Orgmode を利用したタスク管理を行っています。

これを使っていく中で私は以下のようなメリットを感じています。

  • 仕事の抜け・漏れを起こさなくなる。
  • 自分のキャパを最大限活かせる。(キャパオーバーになるのも避けられる。)
  • 日々の仕事に達成感を得られる。

今現在のタスク管理の方法がしっくりこない...と感じている方は、 ぜひこの記事をご覧いただき、一つ選択肢に加えてみてはいかがでしょうか?

Emacs Orgmode とは

Orgmode は Emacs拡張機能の一つです。独自のマークアップ言語を利用できるシンプルなテキストエディタですが、 非常に高機能でタスク管理などに便利な数多くの機能をサポートしています。

https://orgmode.org/ja/

当然 Emacs を必要とするので、Emacser ではない方には関係ない...とお思いかもしれません。 しかし私も普段の開発では VSCode + Vim キーバインディングを使っており、 Emacs は何もかもが素人中の素人です。

そういった方におすすめしたいのが Spacemacs です。

https://www.spacemacs.org/

Emacs ベースのエディタですが、デフォルトで Vimキーバインドが利用できます。 私も Spacemacs を利用していますが、ほぼほぼ Vim と同じ操作感で扱うことができています。

Orgmode を利用したタスク管理の流れ

ここからは私が実際に行っているタスク管理の流れを、Orgmode の機能の紹介とともに説明していきます。

ファイル構成

私はタスク管理のために3種類のファイルを用意しています。

.
├── TODO.org
└── weekly
    └── YYYYMMDD.org
└── daily
    └── YYYYMMDD.org

TODO.org

自分が担当することになったタスクはひとまず全て TODO.org に追加します。 まさしく TODO リストの役割を果たしており、こちらにタスク全量がリスト化されることになります。

weekly/YYYYMMDD.org

1週間分のタスクリストを表すファイルです。 TODO.org からタスクをピックアップして作成します。

daily/YYYYMMDD.org

1日分のタスクリストを作成する場所です。 weekly/YYYYMMDD.org からさらにタスクをピックアップして作成します。

(随時)TODO リストを作成する

何かタスクにアサインされたらまずは TODO.org に追加していきます。 合わせてここで作業時間の見積もりを行います。

Effort Estimates を利用すると見積もった時間をタスクに対して簡単に設定できます。

https://orgmode.org/manual/Effort-Estimates.html

また、TODO リストの未済管理には Multi-state Workflow を利用してステータス管理を行うと良いでしょう。

https://orgmode.org/guide/Multi_002dstate-Workflow.html

あらかじめ TODO, DONE ステータスを設定しておき、コマンド一発で遷移できるようにしておきます。

見積もり、ステータス設定を行った後の TODO.org は以下のようになります。

#+SEQ_TODO: TODO(t/!) | DONE(d) // Multi-state Workflow で遷移可能なステータスの定義。タスクに対して C-c C-t でステータスを変更できる。
#+PROPERTY: Effort_ALL 1:00 2:00 3:00 5:00 8:00 13:00  // Effort Estimates で設定可能な見積もり時間。タスクに対して C-c C-x e でここで定義した時間を設定できる。
  
*** 新規配送システム導入 
  **** TODO 購入者は新規配送方法を指定して商品購入を行うことができる
    :PROPERTIES:
    :Effort:   5:00
    :END:
  **** TODO 出品者は新規配送方法に利用できる配送用ラベルを発行できる
    :PROPERTIES:
    :Effort:   8:00
    :END:
  **** TODO 出品者は新規配送方法を利用して配送を実施することができる
    :PROPERTIES:
    :Effort:   13:00
    :END:

(毎週月曜日)1週間のやることリストを作成する

週初めの業務開始のタイミングで1週間のやることリストとして weekly/YYYYMMDD.org を作成します。

まずは自分が1週間で作業に充てられる時間を計算していきます。

ただし1週間のうち全ての時間を作業時間に使えるわけではないのでこれを考慮しましょう。

私の場合、勤務時間のトータルは 40 時間です。(週5日、1日8時間勤務で 5 * 8 = 40 時間)しかし定例や打ち合わせの時間を除くと大体 20~30 時間くらいが作業に充てられる時間となることがほとんどです。

当然休みの日や早退の日があればこれも考慮します。

計算が終わったらファイルにこの時間をメモしましょう。

次に TODO.org から計算した作業時間内でこなせるだけのタスクを選んで weekly/YYYYMMDD.org に追加します。

ここでのポイントですが、 週はじめの段階では作業時間の 80 % 程度でできるタスク量にしておいた方が良いです。

エンジニアは不具合の修正対応など突発的なタスクが発生しがちです。 こういった事態も吸収できるようにバッファを持たせておくことが重要です。

Work time: 20 hrs (80 %: 16 hrs) // 純粋に作業に充てられる時間だけを見積もる。
                                 // また、突発的なタスクに対応できるよう、80%程度の時間でできることに収めた方が良い。

*** 新規配送システム導入 
  **** TODO 購入者は新規配送方法を指定して商品購入を行うことができる
    :PROPERTIES:
    :Effort:   5:00
    :END:
  **** TODO 出品者は新規配送方法に利用できる配送用ラベルを発行できる
    :PROPERTIES:
    :Effort:   8:00
    :END:
  **** TODO 出品者は新規配送方法を利用して配送を実施することができる
    :PROPERTIES:
    :Effort:   3:00
    :END:

ここに追加したタスクの見積もりの合計が、作業時間内で収まっているかどうかを確認するには Column View を活用すると良いでしょう。

https://orgmode.org/manual/Column-View.html

親タスクに対して C-c C-x C-c とすると簡単に子タスクの見積もり時間の合計時間を表示することができます。

#+COLUMNS: %ITEM %Effort{:} // ITEM: タスク名, Effort: 見積もり時間 を表示

| *** 新規配送システム導入     | 16:00 | # 子タスクの合計時間が表示されている
| **** 購入者は新規配送方法... | 5:00 |
| **** 出品者は新規配送方法... | 8:00 |
| **** 出品者は新規配送方法... | 3:00 |

1週間分のやることを週初めの段階で決めることで次のようなメリットがあります。

まずキャパオーバーになることを避けられます。 既に予定しているタスクで今週分の作業時間が埋まっているならば、 これ以上の仕事を受けて、早急に対応することは難しいとすぐに判断できます。

逆にこの段階で作業時間が余るようであれば、 新しいタスクを拾ったり、忙しい時にはできないようなカイゼン系のタスクなどに取り組もうと、 週初めの段階で決めてしまえば良いのです。

後者は暇になってから考えても同じじゃないの?とも思いますが、 無計画に暇を迎えるとただただ時間を潰すだけになりがち。人間とは弱い生き物なのです...

こうして無理のない範囲に収めながらも、 自分の時間を最大限活用することが可能になっていきます。

(毎日朝)今日やることのリストを作成する

毎日業務を開始するタイミングで今日一日でやることのリストを daily/YYYYMMDD.org に作成します。

週初めの weekly/YYYMMDD.org の作成と同じように一日の作業時間を計算して、 その日に行えるだけのタスクを weekly/YYYYMMDD.org からこちらにコピーして追加します。

1週間分のやることリストの作成と同じように、 ミーティングの時間などは除いて、純粋に作業に充てられる時間に対してタスクを当てこみましょう。

Work time: 5 hrs

*** 新規配送システム導入 
  **** TODO 購入者は新規配送方法を指定して商品購入を行うことができる
    :PROPERTIES:
    :Effort:   5:00
    :END:

(業務時間中)作業時間を記録する

作業した時間は原則タスクに対して記録していきます。 Orgmode には Clocking commands というものが用意されています。

https://orgmode.org/manual/Clocking-commands.html

作業開始時には C-c C-x i、終了時には C-c C-x o を入力することで、各タスクに対して作業時間の記録が行えます。

*** 新規配送システム導入 
  **** TODO 購入者は新規配送方法を指定して商品購入を行うことができる
    :PROPERTIES:
    :Effort:   5:00
    :END:
    :CLOCKING:
    CLOCK: [2023-12-04 月 09:30]--[2023-12-04 月 10:00] => 0:30 // 作業時間が記録される
    :END:

またポモドーロテクニックを使いながら作業時間を記録できる org-pomodoro というサードパーティのライブラリもあります。

https://github.com/marcinkoziej/org-pomodoro

こちらは作業開始時に C-c C-x p を実行すると、 あらかじめ指定した時間が経過したら自動的に作業終了となり時間が記録されます。

作業終了時にはチャイムが鳴ってお知らせもしてくれます。

作業時間中はタスクに全集中で取り組みましょう。X のタイムラインを見ながらダラダラと...なんてのはダメです(笑)。休憩する時は Clocking commands を停止してメリハリをつけましょう!

予定していた1日の作業時間を消化できたら、業務は一旦おしまいにします。おつかれさまでした!

(業務終了時)1日の作業を振り返る

予定していた作業時間に対してどのくらい自分がコミットできたかは、前述した Column View で簡単に確認することができます。

#+COLUMNS: %ITEM %Effort{:} %CLOCKSUM // CLOCKSUM: 記録した時間の合計 を表示

| *** 新規配送システム導入     | 5:00 | 5:12 |
| **** 購入者は新規配送方法... | 5:00 | 5:12 |

次に daily/YYYYMMDD.org に記録した作業時間を、weekly/YYYYMNDD.org に転記していきます。 こうすることで1日を経る毎に1週間分の作業時間の記録が溜まっていきます。

*** 新規配送システム導入 
  **** TODO 購入者は新規配送方法を指定して商品購入を行うことができる
    :PROPERTIES:
    :Effort:   5:00
    :END:
    :CLOCKING:
    CLOCK: [2023-12-04 月 17:00]--[2023-12-04 月 18:12] =>  1:12
    CLOCK: [2023-12-04 月 13:00]--[2023-12-04 月 15:00] =>  2:00
    CLOCK: [2023-12-04 月 10:30]--[2023-12-04 月 12:00] =>  1:30
    CLOCK: [2023-12-04 月 09:30]--[2023-12-04 月 10:00] =>  0:30
    :END:
  **** TODO 出品者は新規配送方法に利用できる配送用ラベルを発行できる
    :PROPERTIES:
    :Effort:   8:00
    :END:
    :CLOCKING:
    CLOCK: [2023-12-05 火 15:30]--[2023-12-05 火 18:00] =>  2:30
    CLOCK: [2023-12-05 火 10:00]--[2023-12-05 火 12:00] =>  2:00
    :END:

このように日々、予定に対してどのくらい実際にコミットできたかを時間で確認できると、自分の仕事にかなりの達成感が出るのではないでしょうか??

モチベーションを維持することは、業務に対するパフォーマンスを最大化するためにはとても重要です。

(毎週金曜日)1週間の作業を振り返る

毎日の振り返りのタイミングで weekly/YYYYMMDD.org に作業時間の記録をしています。 なので週末の業務終了時点では1週間分の作業時間の合計が記録されているはずです。

大元の TODO リストとなっている TODO.org に1週間の作業結果を反映していきましょう。 作業時間の記録を転記して、もし完了になったタスクがあればステータスを変更します。

#+SEQ_TODO: TODO(t/!) | DONE(d)
#+PROPERTY: Effort_ALL 1:00 2:00 3:00 5:00 8:00 13:00
  
*** 新規配送システム導入 
  **** DONE 購入者は新規配送方法を指定して商品購入を行うことができる
    :PROPERTIES:
    :Effort:   5:00
    :END:
    :CLOCKING:
    CLOCK: [2023-12-04 月 17:00]--[2023-12-04 月 18:12] =>  1:12
    CLOCK: [2023-12-04 月 13:00]--[2023-12-04 月 15:00] =>  2:00
    CLOCK: [2023-12-04 月 10:30]--[2023-12-04 月 12:00] =>  1:30
    CLOCK: [2023-12-04 月 09:30]--[2023-12-04 月 10:00] =>  0:30
    :END:
  **** DONE 出品者は新規配送方法に利用できる配送用ラベルを発行できる
    :PROPERTIES:
    :Effort:   8:00
    :END:
    :CLOCKING:
    CLOCK: [2023-12-07 木 09:00]--[2023-12-07 木 10:00] =>  0:30
    CLOCK: [2023-12-06 水 16:00]--[2023-12-06 水 18:00] =>  2:00
    CLOCK: [2023-12-06 水 11:00]--[2023-12-06 水 12:00] =>  1:00
    CLOCK: [2023-12-05 火 15:30]--[2023-12-05 火 18:00] =>  2:30
    CLOCK: [2023-12-05 火 10:00]--[2023-12-05 火 12:00] =>  2:00
    :END:
  **** TODO 出品者は新規配送方法を利用して配送を実施することができる
    :PROPERTIES:
    :Effort:   13:00
    :END:
    :CLOCKING:
    CLOCK: [2023-12-08 金 17:00]--[2023-12-08 金 18:00] =>  1:00
    CLOCK: [2023-12-08 金 11:00]--[2023-12-08 金 12:00] =>  0:30
    CLOCK: [2023-12-07 木 13:00]--[2023-12-07 木 14:30] =>  1:30
    :END:

DONE になったタスクをそのまま TODO.org においておくと、 ファイルがどんどん巨大になってしまいます。Orgmode にはこれを Archive として他ファイルに移動してくれる機能がありますのでこちらを利用しましょう。

https://orgmode.org/guide/Archiving.html

タスクに対して C-c C-x s を実行することで、あらかじめ指定したファイルにタスクを移動させることができます。

#+ARCHIVE: ~/dev/orgmode/archives/myArchive.org:: # Archive 先の指定。

*** 新規配送システム導入 
  **** DONE 購入者は新規配送方法を指定して商品購入を行うことができる

まとめ

以上が Emacs Orgmode を利用したタスク管理の紹介になります。

冒頭にも話したことになりますがこのタスク管理を行うことで、

  • 仕事の抜け・漏れを起こさなくなる。
  • 自分のキャパを最大限活かせる。(キャパオーバーになるのも避けられる。)
  • 日々の仕事に達成感を得られる。

こういった恩恵を受けることができると私は感じています。

本記事を読んで気になった方は一度試してみてはいかかでしょうか??

明日の記事の担当は UXD(UI, UX の改善に主に取り組んでいるチーム)の新井さんです。お楽しみに!


株式会社エニグモ すべての求人一覧

hrmos.co

BUYMAのUXリサーチ『ユーザ理解を深めるためにアンケートとインタビューを進めている話』

こんにちは!UIUXデザイナーの和田です。

こちらはEnigmo Advent Calendar 2023 の12日目の記事です。

この記事では、BUYMAのサービスやアプリ・WebサイトのUIUXをより良くすることを目的に進めているUXリサーチ(ユーザ調査)についてご紹介します。

1.なぜUXリサーチ(ユーザ調査)をするのか?

より多くの方にBUYMAのファンになっていただけるように【真にユーザの体験価値にマッチしたお買い物体験を実現する】ためには、より深い顧客理解に基づいたPDCAが必要だと考えています。

そのために、現在BUYMAをご利用いただいているお客さまの利用文脈・背景(ユーザコンテキスト)を深掘りして、ユーザインサイトについての理解を深められるような調査を心がけています。

「どのようなお客さまなのか?」
→ ユーザ属性に加えて、家族構成や生活スタイルなど

「お客さまがどのような価値観・嗜好をお持ちなのか?」
→ ファッションアイテム全般についての価値観・潜在ニーズや行動特性

「どのようなことをBUYMAに期待してくださっているのか?」
→ BUYMAに対するニーズや期待値

BUYMAについて期待と現状のギャップはどのようなところにあるか?」
→ BUYMA利用における AS-IS(現状)とTO-BE(理想)のギャップ

上記のような点について、定量的・定性的それぞれの側面から現状把握と改善のヒントを得られるように、 ユーザアンケートとユーザインタビューを組み合わせて調査を実施しています。

2.BUYMAのUXリサーチ体制

弊社では、UIUXデザイナーとデータアナリストの調査チームでUXリサーチを企画・進行しています。 またテーマによって、他部署のメンバーと連携・協働することで調査に幅広い視点が盛り込めるように工夫を進めています。

複数の職種からなるチームで調査に取り組むことで、UXリサーチの企画→実施→分析→施策化→デザイン・実装→効果検証・・・のように調査メンバーが主体的にPDCAを回しやすい体制ができていると感じています。(UXリサーチ専任ではないため、各自がその他の業務を調整しながらUXリサーチを進行するため、調査期間中はどうしても忙しくなってしまうこともあります。)

3.調査テーマに沿ったUXリサーチ企画・進行のながれ

弊社では、設定した調査テーマに沿ってユーザ調査を実施しています。 1回のユーザ調査につき、約3〜4ヶ月で企画から分析までが完結するようなスケジュール感で予定を立てて進めています。 以下、調査の流れをご紹介します。

1.企画・準備(1.5ヶ月)

調査テーマは、社内で相談して関心の高いテーマを設定するようにしています。 テーマに沿って対象者の選定や、ヒアリングポイントを整理して、 アンケート設問やインタビューシナリオについて、レビューを繰り返して準備を進めています。

2.アンケート・インタビュー実施(1ヶ月)

アンケートはテーマや対象者に合わせて、メールのほか、LINEやアプリからも回答いただけるようにしています。 アンケート設問の中でインタビューにご協力いただける方を募る形で、インタビューにつなげられるようにしています。
アンケート回答期間が約1週間、インタビューセッティング期間が1週間、インタビュー実施期間が約2週間と、とにかく忙しい1ヶ月間です。

3.分析・まとめ(1.5ヶ月)

インタビューの実施が完了した後に、分析とまとめ作業をしています。 アンケートとインタビューそれぞれについて、分析結果・ヒアリング結果を記事にまとめて社内で共有するようにしています。 最後にチームでKPTの形式で調査のふりかえり会を実施して、調査の1サイクルが完了となります。

4.UXリサーチに利用しているユーザセグメントの分類軸

UXリサーチでは、ユーザや利用傾向を把握・グルーピングをしやすくするために、独自のユーザセグメント分類軸を定義して利用しています。
アンケート配信対象者を選定する際にも、 調査テーマに沿って「直近利用(R)・利用頻度(F)・価格志向(M)・年代(U)」の分類軸を選定条件に利用しています。

  • 直近利用(R)
    最終購入日時(直近購入)または会員登録日時を基準にした直近利用に関する軸

  • 利用頻度(F)
    最終購入から遡った1年間における購入頻度の軸

  • 価格志向(M)
    生涯購入における最高購入金額の軸
    ※どんな価格帯のアイテムに関心の高いユーザなのか分類するために生涯購入金額ではなく最高購入金額で分類しています

  • 年代(U)
    ライフスタイル変化に合わせた年代グループ

※ご興味のある方は、ぜひ昨年のAdvent Calendar 2022の記事もご覧ください!

tech.enigmo.co.jp

5.傾向・改善ヒントを掴むためのユーザアンケート

前述した通り、RFMUのユーザセグメント分類軸を利用して、調査テーマに沿ったアンケート配信対象者を選定してアンケート配信をしています。
アンケートの設問は以下のような形式の設問を利用しながら、定量的な傾向、定性的なご意見をキャッチアップできるような設問体系にしています。 アンケートツールは、Googleフォームを利用しています。

  • 単一選択形式/複数選択形式の設問
    仮説から選択肢を用意できるような場合は選択形式を利用して定量的に傾向を掴めるようにしています。

  • フリーアンサー(自由記述)設問
    選択肢に挙げられていなかったユーザインサイトを掴むために、積極的にフリーアンサーを用いてユーザのリアルな声をいただけるようにしています。 仮説として全く挙げられていなかったご意見を多数いただくこともあり、フリーアンサー回答の集計も非常に重要だと考えています。

  • 段階評価の設問
    尺度を測りたい場合に段階評価を用いています。

アンケート回答は、回答全体の分析に加えて、セグメント別の分析や回答を掛け合わせたクロス集計による傾向分析も実施しています。

6.ユーザインサイトを深掘るためのユーザインタビュー

アンケート集計後は、回答者のユーザセグメント傾向を分析して、インタビューしたいユーザグループをいくつかに分類するようにしています。 それぞれのユーザグループについて数名ずつインタビューを実施できるように、アンケート回答やBUYMAのご利用傾向をもとに候補者の方にお声がけをさせていただくようにしています。

弊社ではZoomを利用した60分のオンラインインタビューを実施しています。 オンラインでご参加いただけるため、地方にお住まいの方やテレワークで休憩中の方、お仕事先からご参加いただける方など・・・、本当にさまざまなご職業・ライフスタイルの方にご参加いただけています!

インタビューの内容は主に以下のセクションごとに進行しています。 また、後述するユーザプロフィールシートに基づいて注力したいヒアリングポイントを中心にお話をお聞きするようにしています。

ユーザーインタビューの内容

  • ユーザ自身について
    日中の過ごし方やファッション情報のチェック先などをお聞きしています。

  • ファッション全般の嗜好やお買い物について
    好きなブランドや普段のお買い物の傾向についてお聞きしています。

  • BUYMA利用について
    BUYMA認知・利用のきっかけやご利用の体験談などをお聞きしています。

  • 調査テーマヒアリング
    調査テーマに沿った内容について、価値観やニーズ、普段の行動、BUYMAにおけるペイン・ゲインなどをお聞きしています。

  • コンセプトヒアリング
    Figmaのプロトタイプを利用して新機能やUIのコンセプトについてのヒアリングを実施しています。

7.ユーザープロフィールシートの作成と活用

インタビュー対象者ごとにユーザの情報がまとまったユーザプロフィールシートを作成するようにしています。(個人が特定されるような情報は含まれていません。)
また、ユーザプロフィールシートに対象者のRFMUユーザセグメント分類軸も付与しておくことで、近しい傾向を持つユーザを探しやすくする工夫をしています。

ユーザプロフィールシートの内容

  • ユーザ基本情報:ユーザ属性やRFMU分類軸

  • BUYMA利用情報:BUYMAにおける利用・購入に関する情報

  • アンケート回答:アンケートのご回答まとめ

  • インタビューレポート:インタビュー議事録・記録など

ユーザインタビューの前に、あらかじめユーザプロフィールシートを作成することで、 ヒアリングポイントを精査して対象者の方に合わせたインタビューができるようにしています。

また、ユーザインサイトについて深掘りしたくなった際に、対象となるユーザプロフィールシートを探して活用できるように、 UXリサーチ資産としての整備を進行しています。

8.UXリサーチから得るもの

調査が完了した後、チームメンバーで分析結果・まとめをもとに施策ブレストを実施しています。
そこから、サービス・UIUX改善につながる施策化を進めるかたちで調査を役立てるようにしています。

実際に、UXリサーチで得られたインサイトから生まれた機能やサービスもBUYMAにどんどん盛り込まれています! さらなるBUYMAのUX向上に期待していただけますと幸いです!

明日の記事の担当は・・・
BUYMAのサーバーサイドアプリケーション開発をされている寺田さん】です!
お楽しみに!


株式会社エニグモ すべての求人一覧

hrmos.co