ニフティ株式会社のブログ - TECH PLAY

TECH PLAY

ニフティ株式会社

ニフティ株式会社 の技術ブログ

524

初めに 最近全てのシステムは人間というシステムの運用開発であるという考えを持ち始めた, 会員システムグループの2年目社員の関です. システムにおいて最も重要なことは人間がいかに使いやすいかである と考えてアクセシビリティに興味関心を持ち, 社内に広げたいと考えています. TechDayという社内イベントのLTでアクセシビリティに関して話したりもしました. 今回は社内で開いたオーサリングプラクティス輪読会という勉強会の中での課題の話をしたいと思います. オーサリングプラクティス輪読会とは オーサリングプラクティス輪読会はオーサリングプラクティスを輪読する会です. オーサリングプラクティスって? 一言で言うと HTML/CSS/JavaScript/WAI-ARIA* を使用してどのようにアクセシブルなWebシステムの機能を作成するかについて実践的な記述方法が学べるWeb上のコンテンツです. *WAI-ARIAとは : HTMLだけでは表すことのできない構造や状態を表現するための仕様のことです. 以下のページで読むことができます. ARIA Authoring Practices Guide-patterns . 輪読会では上記のPatterns一つ一つを読んで, どのようにHTML/CSS/JavaScript/WAI-ARIAを使って機能を作成すれば良いのかということを学んでいます. オーサリングプラクティス輪読会で出した課題 オーサリングプラクティス輪読会では7回目までの理解度を測るための中間課題を出しました. 課題 ダイアログ要素を使用したTODOリストをアクセシブルに作成する 要件 React, Vue, Svelte, Solid.jsなどのライブラリは使っても良いが, React-modalなどのライブラリは使わずに自分で実装を行う 作ってほしいシステムのイメージ(以下のイメージを元にシステム作成を行なってもらいました) TODOリストメイン画面 TODOの追加画面.ダイアログとして作成する TODO編集画面.ダイアログとして作成する TODO削除画面.ダイアログとして作成する. 以上です. 課題としてはモーダル要素部分以外は正直大したことはないように思えますが, 実は考慮することは結構あります. 課題の答え 課題の答えも自分で考えて作成しました(ゆえに不足している点がある気がします). 答えにおいて肝になる点を何点か以下で紹介します. モーダルウィンドウを表示しているときのキーボードフォーカスについて これがモーダルを自分で実装する際の最も難関な部分だと思います. アクセシブルなモーダルを1から作るとなると以下の部分を考えなければなりません. フォーカスの移動 モーダルを開いている間はフォーカスをモーダル上に留めなければならない モーダルだということを 支援技術* に伝える( *支援技術 : スクリーンリーダーなどの障がい者等が使用する装置, ソフトウェアの総称です.) role=modalなどを使用して支援技術*にモーダル要素であることを伝える必要があります モーダルのデザイン 視覚的にモーダルだとわかるように, モーダルが表示されているときは元のページは灰色などでマスキングすることが理想です これを一から作るとなると大変です. 現状のHTMLにはdialogという要素が存在しており, これを使うことで簡単に上の要件を満たしたモーダルを作成することが可能です. <dialog>: The Dialog element . dialog要素は2022のInteropにて2022年以内に現在の主要ブラウザの全てで対応するようにすり合わせを行なっています.そのため, 2022年7月現在すでに主要なブラウザは対応している状態です. Interop 2022: browsers working together to improve the web for developers . そのため, 今回のシステムではHTMLのdialog要素を使用してモーダルウィンドウを作成しました. <dialog></dialog> dialog要素を使うことで非常に簡単にモーダルが作成できるため, 非常に便利だと感じました. 音声でそれぞれの操作が認知できるか チェックボックスをチェックしたかどうか?は目が見えないなど視覚にハンデを持っている人にとっては認識できないかもしれません. その場合には, そのような操作は逐次音声として伝える必要があります. どのように実装したか 今回はこれを解決するために以下のように画面には表示されないが, 支援技術には認識されるHTML要素を作成しています. <div className={styles.visuallyHidden} id='notes_save_status' role='alert' > {alertText} </div> 要素には role='alert' を設定して中身に変更があった場合は支援技術が検知するようにしています. React側のコードは以下のようになっています. setAlertText(`${title}のTODOを完了しました`); 上記は完了の例ですが, setStateでalertTextを切り替えることでTODOリストへの追加, 編集, 削除, 完了, 未完了などが支援技術を通してユーザに伝わるようにしています. WAI-ARIAを適切に設定しているか 今回のモーダル要素は複数存在するため, どのモーダルが表示されたのかをWAI-ARIAを使って支援技術に伝える必要があります.そのため, 今回は以下の二つのWAI-ARIAを設定しなければなりません. ariaの名前 説明 aria-describedby Dialog要素の中にタイトル以外にダイアログを説明する要素がある場合にそのIDを指定する aria-labelledby Dialog要素内のタイトル要素のIDを指定する HTML内に記述するaria要素とその説明 実際に設定すると以下のようなHTMLになります.(実装ではDialogコンポーネントを作っていたので微妙に違います). <dialog aria-describedby='deleteDialogDesc' aria-labelledby='deleteDialogLabel' .../> <h2 id="deleteDialogLabel">{title}</h2>   <div aria-describedby='deleteDialogDesc' > {`${todoVal[parseInt(selectTodoId)]?.title}`}のTODOを削除しますか? </div> </dialog> 上記は削除要素の例ですが, タイトルであるh2を aria-labelledby , 削除の文章に aria-describedby を指定しています(削除の確認の文章は説明ではないので設定する必要はなかったかもしれません). 削除以外の要素はフォーム以外に説明する要素はないのでaria-describedbyは設定していません. まとめ 今回の勉強会で課題の作成と答えの作成をしてみて, 現在のモダンフレームワークでどのようにアクセシブルなシステムを作成するのか, どのように要件を考えていくのかなどがなんとなくわかってよかったと思います. 将来的にこの経験を業務にも活かして, 全ての人間が使いやすいシステムの構築を目指していきたいと思います. We are hiring! ニフティでは, さまざまなプロダクトへ挑戦するエンジニアを絶賛募集中です! ご興味のある方は以下の採用サイトよりお気軽にご連絡ください! ニフティ株式会社採用情報 Tech TalkやMeetUpも開催しております! こちらもお気軽にご応募ください! Event – NIFTY engineering
ニフティ株式会社でマネージャーをしている北浦です。 今回は私がマネジメントしている基幹システムグループ 課金システムチームのマネジメントについて紹介します。とはいえ自身のマネジメント歴が浅い(2022年4月〜)ので、今回は僕たちのチームがどのようにスクラムを導入していったのかを書いてみたいと思います。 (0) スクラム導入前 2017年まで課金システムチームの前身のチームではウォータフォール開発を採用し、ほぼ全ての開発業務を外注していました。社員の業務は要件整理や社内外調整、プロジェクトマネジメントなどがメインであり、自ら開発を行うシーンはとても少なかったと思います。社内向けツールや運用作業の自動化などで開発を行うメンバーもいましたが、コードを一切書かないメンバーもいました。 また、属人化もかなり進行しておりシステムごとに人(社員&協力会社メンバー)が張り付いており、同じチーム内でも隣のシステムについては全く分からず手が出せない状況でした。 このような環境の中でチームメンバーが大きく変わっていきましたが、いざシステムを引き継いでみると多くの問題が発生しました。”ドキュメント化されていない業務仕様”、”ドキュメントがなくリポジトリ管理されていない謎のプログラムがプロダクション環境で動いている”、”ビジネス部門の担当者が不在”、”社員が仕様を把握しておらず協力会社メンバーしかわからない(そのメンバーは既にプロジェクトから離れている)”など、とても苦労しました。 このままではまずいということで、主に属人化の解消とエンジニアの技術力向上を目指しスクラムを導入することにしました。 (1) 1チームスクラム: 1プロダクトを開発 2018年からスクラムを導入しました。既存プロダクトの全面刷新をスクラムで完全内製開発しました。ポイントは以下です。 スクラムマスター研修に参加してスクラム開発を学ぶことで導入時のハードルを下げた 比較的規模の小さい既存プロダクトを対象として全面刷新する方針とした ビジネス部門に相談してPO(プロダクトオーナー)を立ててもらった 職制上のチームを跨いでスクラムチームを構成、若手メンバーに多く参加してもらった ウォータフォール開発に慣れていたメンバーにとって、最初はスクラムガイドや書籍で勉強してもなかなかスクラム開発のイメージを掴むのは難しいので、一部メンバーがスクラムマスター研修に参加して学んできたことはスクラム導入がスムーズに進められた要因の一つだと感じています。 以降、各フェーズごとにKPT法でふりかえってみたいと思います。 良かったこと ビジネス部門とシステム部門が協力して”プロダクトを育てる”という意識が芽生えはじめた 小さく始めることで無理なく少しずつスクラムに慣れていくことができた 完全内製によるチーム開発の土台づくりができた 開発スキルを向上できた 改善したいこと 暫定で組んだスクラムチームだったので”チームの成長”をメンバーが意識しづらかった スクラムチームメンバーは職制上チームのタスクも継続して担当していたため、スクラムに注力できないメンバーが発生してしまった 初期リリース実施前に職制上チームのタスクが忙しいメンバーはスクラムチームから外れることになってしまった メンバーが職制上チームを跨ぐのでマネジメントが難しい トライ(実験) チームを跨ぐ状況を改善して職制上チームとスクラムチームを一致させる (2) 1チームスクラム: 複数スクラムを同時に実施 2019年からは職制上チームとスクラムチームのメンバーが一致するようチームを再編しました。また、別プロダクトでもスクラム開発したいものがでてきたので、新規にスクラムを立ち上げて複数のスクラムを同時に実施してみました。以下がそのふりかえりです。 良かったこと 新規にスクラムを開始したプロダクトはプロトタイプを小さくリリースしてPOから早期にフィードバックをもらうことで必要な機能を素早く提供できた 改善したいこと 同時期に複数のスクラムを1チームで実施することによるオーバーヘッドが想像以上に大きく、開発時間の確保が難しかった(スイッチングコスト、各種スクラムイベントなど) スクラム対象プロダクト以外にもチームが担当しているプロダクトがあるが、それに割り当てる時間がなくなってしまった トライ(実験) 全てのプロダクトを1つのスクラムで管理してみる (3) 1チームスクラム: 複数プロダクトを対象とした1つのスクラムを実施 1つのスクラムチームが複数のスクラムを同時に実施するのはかなり厳しいことがわかりましたので、2020年からは1つの職制上チームが担当する全てのシステム・サービス・プロダクトを1つのスクラムで管理してみることにしました。ただし、全ての関係者のスケジュールをあわせることが難しかったため、各プロダクトのPOと簡易スクラムイベントを個別設定することで対処しました。以下がそのふりかえりです。 良かったこと スクラムイベントのオーバーヘッドが削減できた 職制上チームが担当する全てのプロダクトに関するタスクが可視化され属人化解消に役立った 簡易スクラムイベントの導入によって各種イベント実施が効率化できた 改善したいこと プロダクトを跨ぐ優先順位付けが困難 社内システムへの要望やシステムリプレース対応のような技術的負債の改善につながる活動は、相対的に優先順位が常に低くなってしまう レガシーシステムに関するプロダクトバックログアイテムは認知負荷が高く多くのドメイン知識が必要となるため共有が進まない トライ(実験) チームが担当するプロダクトのPOを集めて、各プロダクトのスケジュール共有会を定期的に実施してみる (4) サブチーム同士が協力してスクラムを実施(検討中) 各プロダクトのPOを集めて実施するスケジュール共有会の実施により、事前にスケジュールのバッティングが確認できるようになり、早い段階で関係者と調整するなど対策が立てられるようになりました。 また、2021年には大規模スクラム(LeSS:Large-Scale Scrum)を採用し新規接続サービスの内製開発も行いました(こちらは別途ブログ化される予定です)。 2022年現在では、”複数プロダクトを扱う1チームスクラム”と”LeSS”の2つのスクラムを同時に実施しています。一般的にスクラムは”1つのチームは1つのスクラムに専念する”という大原則があるのですが、現実はなかなか難しい状況ですので現在の形となりました。2つのスクラムで可能であればスクラムイベントを共通化するなど、できる限り複数スクラムを実施することによるオーバーヘッドの最小化を目指しています。 現在は途中でもう1つサブチームが合流して2つのサブチームで課金システムチームとなったのですが、サブチーム間の協力がまだまだ弱いのでより良いチーム体制を模索しています。 チームにどのようにスクラムを導入していったのかを紹介させていただきました。”スクラムは理解するのは簡単だけど実践するのは難しい”と言われています。上記の内容がどこかのチームの参考になれば幸いです。 We are hiring! ニフティでは、さまざまなプロダクトへ挑戦するエンジニアを絶賛募集中です! ご興味のある方は以下の採用サイトよりお気軽にご連絡ください! ニフティ株式会社採用情報 Tech TalkやMeetUpも開催しております! こちらもお気軽にご応募ください! Event – NIFTY engineering
NIFTY Tech Talkは、ニフティ株式会社の社員が主催するトークイベントです。 本イベントではニフティ社員が業務を通じて学んだことを発信しています! 第三回目のテーマは「AWSコストダウン」。ニフティでは各チームコストとパフォーマンスの最適化を行っています。 ニフティが取り組んでいる「AWSコストダウン」について、現場のエンジニアを中心にパネルディスカッション形式でリアルな現場の声をお伝えします。 概要 日程:7月26日(火)19:00〜20:00 配信方法:YouTube Live 視聴環境:インターネット接続が可能なPC/スマートフォン 参加方法 Connpassイベントページ より参加申し込みください! こんな方におすすめ AWSのコストを下げたい方 コスト削減のベストプラクティスを知りたい方 組織でのコスト削減の取り組みに興味ある方 タイムテーブル 時間 コンテンツ 19:00-19:05 オープニング+会社紹介 19:05-19:15 登壇者紹介 19:15-19:55 メインディスカッション 19:55-20:00 クロージング ディスカッション テーマ 「AWSコストダウン」をメインテーマとして以下のような話題についてディスカッションします。 コストダウンの取り組みについて コスト意識醸成のための行ったこと 登壇者プロフィール 福田 紫穂(ファシリテータ) ニフティ株式会社 インフラシステムグループ クラウド・仮想化環境・ネットワークなどインフラ全般を担当。現在はハイブリッドクラウドのあるべき姿を検討中。 小松 初(登壇者) ニフティ株式会社 基幹システムグループ 新卒入社4年目。チーム内のクラウドコスト削減担当の一人として活動中。 河野 曜平(登壇者) ニフティ株式会社 インフラシステムグループ 新卒入社4年目。クラウドインフラ周りの整備をしています。最近はISUCONに夢中です。 深田 健太 (登壇者) ニフティ株式会社 会員システムグループ 新卒入社3年目。@nifty安心メールパックの開発・運用を担当しています。SAP勉強中。 ニフティでは一緒に働く仲間を募集中 ! 新卒採用、キャリア採用を実施しています。 ぜひ リクルートサイト をご覧ください。 ニフティエンジニアのTwitterアカウントを作りました NIFTY Tech Talkのことや、ニフティのエンジニアの活動を発信していきます。 https://twitter.com/NIFTYDevelopers
はじめに インフラシステムグループの河野です。 最近集計・分析系のクエリを書く機会が多くなっています。 その中でGROUPING SETSに出会って感動したのでこの気持を分かち合いたいと思います。 記事中ではクエリエンジンとしてpresto 0.217を使用しています。 GROUPING SETSとは GROUPING SETSはGROUP BY句に付与する構文で、複雑なGROUP BYを実現するときに使用できます。 具体例を見ていきましょう。例えば、以下のようなstockテーブルを考えます。店舗ごとにフルーツの在庫がいくつあるか、値段はいくらなのかをまとめたテーブルです。 SELECT * FROM ( VALUES ('orange', 1, 100, 51), ('lemon', 2, 50, 102), ('melon', 3, 1025, 23), ('banana', 1, 25, 154), ('orange', 2, 104, 105), ('lemon', 3, 55, 55) ) AS t (name, shop_id, price, qty) 商品ごとの合計を出しつつ、全体の合計も出したいときが来たとします。この場合GROUPING SETSを使わないとすると以下のようなクエリで実現できます。 SELECT name, SUM(price) AS total_price FROM stock GROUP BY name UNION ALL SELECT NULL, SUM(price) AS total_price FROM stock # 実行結果 name total_price 1359 banana 25 orange 204 melon 1025 lemon 105 これをGROUPING SETSで書き換えると以下のようになります。 SELECT name, SUM(price) AS total_price FROM stock GROUP BY GROUPING SETS((), name) # 実行結果 name total_price 1359 lemon 105 melon 1025 orange 204 banana 25 このように複数の基準でGROUP BYしなければならないものを、GROUPING SETSで一つにまとめることができます。 実務ではクラウドコストを集計してグラフ表示するときに非常に役に立ちました。クラウドベンダごとに別のグラフを描く。合計値も同時に描画したい。といった要件が出てきて、はじめは愚直にUNIONしていて、30行程度のクエリになっていました。その後prestoのリファレンスを見ていたらGROUPING SETSを見つけたので試しに書き換えてみたら、15行ほどにすっきりとクエリを書き替えることができました。 ROLLUP、CUBEとの関係性 GROUPING SETSと似た構文にROLLUPとCUBEがあります。ROLLUPでは小計、総計をまとめて取得することができます。CUBEではすべての組み合わせに対して総計を取得することができます。 それぞれ先程のstockテーブルに対して適用した結果を見てみましょう。 ROLLUP: SELECT name, shop_id, SUM(price) AS price, SUM(qty) AS qty FROM stock GROUP BY ROLLUP(name, shop_id) # 実行結果 name shop_id price qty 1359 490 banana 25 154 orange 204 156 orange 1 100 51 lemon 3 55 55 melon 1025 23 lemon 2 50 102 melon 3 1025 23 lemon 105 157 banana 1 25 154 orange 2 104 105 CUBE: SELECT name, shop_id, SUM(price) AS price, SUM(qty) AS qty FROM stock GROUP BY CUBE(name, shop_id) # 実行結果 name shop_id price qty 1359 490 banana 25 154 2 154 207 orange 1 100 51 melon 3 1025 23 lemon 3 55 55 melon 1025 23 1 125 205 orange 2 104 105 orange 204 156 lemon 2 50 102 banana 1 25 154 lemon 105 157 3 1080 78 これらをGROUPING SETSで書き換えると以下のようになります。 ROLLUP → GROUPING SETS: SELECT name, shop_id, SUM(price) AS price, SUM(qty) AS qty FROM stock GROUP BY GROUPING SETS((), name, (name, shop_id)) # 実行結果 name shop_id price qty 1359 490 banana 25 154 melon 1025 23 lemon 2 50 102 melon 3 1025 23 lemon 105 157 banana 1 25 154 orange 2 104 105 orange 204 156 orange 1 100 51 lemon 3 55 55 CUBE → GROUPING SETS: SELECT name, shop_id, SUM(price) AS price, SUM(qty) AS qty FROM stock GROUP BY GROUPING SETS((), name, shop_id, (name, shop_id)) # 実行結果 name shop_id price qty 1359 490 banana 25 154 2 154 207 orange 1 100 51 melon 3 1025 23 lemon 3 55 55 lemon 105 157 3 1080 78 orange 204 156 lemon 2 50 102 banana 1 25 154 melon 1025 23 1 125 205 orange 2 104 105 それぞれの差分だけ見るとどういう動きをしているかわかりやすいと思います。 ROLLUP(name, shop_id) → GROUPING SETS((), name, (name, shop_id)) CUBE(name, shop_id) → GROUPING SETS((), name, shop_id, (name, shop_id)) 例えば、組み合わせが一個増えたときの対応はこうなります。ROLLUPでは一番左のカラムを基準としたときの組み合わせ、CUBEではすべての組み合わせをそれぞれグルーピングしています。 ROLLUP(name, shop_id, qty) → GROUPING SETS((), name, (name, shop_id), (name, shop_id, qty)) CUBE(name, shop_id, qty) → GROUPING SETS((), name, shop_id, qty, (name, shop_id), (name, qty), (shop_id, qty), (name, shop_id, qty)) GROUPING SETSで書くことで、どの組み合わせで集計しているのかがわかりやすくなるため、個人的にこの書き方が好みです。 終わりに 今回はGROUPING SETSについて使い方と、他の類似構文との関連性をまとめました。有効に使えるとクエリをすっきりとさせられるので機会があれば使ってみてください。 参考記事 https://prestodb.io/docs/0.217/sql/select.html We are hiring! ニフティでは、さまざまなプロダクトへ挑戦するエンジニアを絶賛募集中です! ご興味のある方は以下の採用サイトよりお気軽にご連絡ください! ニフティ株式会社採用情報 Tech TalkやMeetUpも開催しております! こちらもお気軽にご応募ください! Event – NIFTY engineering