TECH PLAY

KINTOテクノロジーズ

KINTOテクノロジーズ の技術ブログ

936

Introduction Last weekend, original article published on Jul 2023, there was an announcement from OpenAI, and a ChatGPT (GPT-4) function called Code Interpreter was released. It is a convenient service programmed in Python that allows you to analyze data without code just by giving instructions in Japanese or English. Japanese text cannot be displayed when drawing graphs or doing other tasks, but I have found a way to display Any fonts, and I will explain it in this article. Code Interpreter had its name changed to Advanced Data Analysis on August 29, but it is called Code Interpreter in this article In this article, you can replace Japanese font with any fonts which you prefer to use on ChatGPT. What You Can Learn from This Article The steps to outputting graphs, images, and PDF files with Japanese fonts using Advanced Data Analysis (formerly Code Interpreter) How to analyze X (formerly Twitter) log analytics with Advanced Data Analysis (formerly Code Interpreter) If you don't need an introduction and just want to know how to output graphs, images, and PDFs with Japanese fonts in Code Interpreter, click here . Self-Introduction Though it's a belated introduction, I am Aoi Nakanishi , the lead engineer of KINTO FACTORY . In addition to development, which is my main job, I manage events, the Tech Blog, and the official account from X (formerly Twitter), so I also manage Technical Public Relation activities in our company. Prerequisites To have paid for ChatGPT (ChatGPT Plus) To have Code Interpreter enabled Only the above two are required Enabling Code Interpreter Enable Code Interpreter from Settings -> Beta Features -> Code Interpreter as shown in the image below. You can skip this step. Advanced Data Analysis is already regular feature on GTP-4 Steps to Switching to Japanese We know that Code Interpreter does not draw in Japanese automatically without instructions, so let's explore ChatGPT and what it can do. Draw this in Japanese! First of all, I tried instructing "Draw this in Japanese" but it returned that Japanese fonts cannot be embedded in the current environment. Try to Find Out Why It Cannot Draw Japanese Font Notice that it says, in Japanese, “ in the current environment .” Let's ask how the graph image is generated. Ask How to Draw Japanese Font Since we know that it uses Python and Matplotlib, I will ask it how to display Japanese. As an example, here is the code that came out. It said that I could not download fonts or change my system settings because my Internet access was disabled. I can upload files, but it seems that I cannot download them. I did a separate check, and it seems that I cannot use system functions. Uploading Japanese Font Files It says, " Cannot download ", so I will immediately ask if I can upload, instead. It is possible to upload files, so I will try it right away. Downloading Japanese Fonts The font Noto Sans was written in the sample code that ChatGPT taught me, so I will use Noto Sans. Download fonts from: https://fonts.google.com/noto/specimen/Noto+Sans+JP (There are other usable fonts, although I haven't tested them) Uploading Japanese Fonts and Switching matplotlib to Japanese Let's try generating a graph in Japanese, or any language's fonts. Uploading Japanese(any) Fonts Upload a file by clicking the plus button at the bottom of the screen. In addition, instruct it to use the Japanese font that was uploaded when drawing graphs by telling it, " Please use this Japanese font when drawing graphs ." ↓ ↓ ↓ Summary of How to Use Japanese Fonts in ChatGPT (GPT-4)'s Code Interpreter You can now display graphs in Japanese by following the steps below. Download Japanese(any) fonts locally Upload the fonts to ChatGPT Specify a font to use when drawing graphs in ChatGPT Upload the required data and draw a graph Also, if the title is not in Japanese when the graph is drawn, you can say; Switch the title to Japanese, and see that the title are regenerated in Japanese. Remember to instruct ChatGPT to draw in Japanese using the uploaded Japanese font file. You can use these steps for PDFs and other file types to output files that can display Japanese correctly. Analyzing Logs from X (formerly Twitter) Now that you are ready to output results of analyses in Japanese, let’s start analyzing logs from X right away. https://x.com/KintoTech_Dev We will analyze data for this X account. You can download detailed data from X Analytics and perform various analyses, but today we will do conduct them using publicly available data. We will use the following information: Main body of the tweet Date and time of the tweet Number of retweets Number of replies Number of likes This data is publicly available and can be accessed by anyone, not just the owner of the account. Uploading a CSV File Select a file by clicking on the Upload button just like when uploading a font, and upload the data you want to analyze. I uploaded a CSV file this time, but it seems that it is possible to read basically any data that can be handled by Python. Also, when I checked the maximum file size that can be uploaded, it did not give the exact number, but it said that several hundred MB were acceptable. I upload the file to ChatGPT and ask it to analyze the file. After answering some questions from ChatGPT, it gave the following analysis results. The following are the results, including explanations of the analyses of the number of impressions, number of retweets, number of likes, and main body. Analysis of Impressions ChatGPT: There is no clear trend at any particular time of day or day of the week. However, it seems that the number of impressions is slightly higher at a particular time on Tuesdays than at other times. KINTO Technologies often posts articles on Tuesdays and makes a tweet when they are published. That seems to be the reason for this result. Analysis of the Number of Retweets ChatGPT: Again, there is no clear trend at any particular time of day or day of the week. However, it seems that the number of retweets is slightly higher at a particular time on Tuesdays than at other times. It seems that the number of retweets is proportional to the number of impressions. Analyzing the Number of Likes ChatGPT: There is no clear trend at any particular time of day or day of the week regarding the number of likes, as well. However, it seems that the number of likes is slightly higher at a particular time on Tuesdays than at other times. You can see that impressions, retweets, and likes are correlated. ChatGPT: Since the number of Tweets in this analysis is relatively small, it is recommended that you keep these results for reference only. This is stated because there are parts that are difficult to understand even if you look at the heat map in the results of the analysis, and it seems that it is necessary to increase the number of tweets and followers first. Analyzing the Main Body of the Tweet Here are the results of a topic modeling analysis of the top ten tweets with the most impressions made with ChatGPT. You can see that our desired information is in the results of the analysis. Item Description Visual element that attracts attention Attracts users' attention and increases engagement Use of hashtags Makes tweets easier to find Clear explanation of the subject of the article Explains the subject of the article clearly Specific call to action Includes the specific call to action, "If you are having trouble building and managing your development environment, please take a look!" Advance notice of upcoming articles Garners interest from users and increases engagement by notifying them when a new article is published Emphasize a specific theme Emphasizing themes will attract users who are interested in an event or the company's activities Summary of the Results of the Tweet Analysis From the analysis thus far, we found that the time posted, content, and use of URLs are key factors in optimizing Tweets. Item Description Post time optimization Although it is not obvious, engagement tends to be higher on Thursday and Friday nights. It is possible that users have more free time and search for content more when it is close to the weekend Tweet content optimization A Tweet that is related to an event or the topic of a new article has a high level of engagement Tweets that contain a URL Tweets with a URL to the Tech Blog have a high level of engagement Summary In this article, I explained how to analyze data with ChatGPT's Code Interpreter and create graphs and other files in Japanese. I hope that it will be useful to you in your daily analyses. We will continue to publish useful articles. If you are interested in reading the latest news, please follow us here. https://x.com/KintoTech_Dev KINTO Technologies is looking for talent to contribute in shaping the future of mobility together. If you are interested, please feel free to contact us for a casual interview. https://www.kinto-technologies.com/recruit/
アバター
はじめに 「KINTOテクノロジーズに入社するまで、Web業界は未経験だった」と言うと、えっ?という顔をされます。そんなキャリアの人が何で入社した(できた)んだろうという戸惑いの顔。しかも20代の若手じゃなくて、40代のおっさんが、何で? 異世界の歩き方 もともとは、家電の組み込みソフト開発のプログラマー。そこから車載ECUの制御ソフトを経験して、前職では欧州系の会社でエンジンなどの試験設備を導入するプロジェクトマネージャーをやってました。ソフトはあくまで全体の一部であり、機械/電気/計測/流体/シミュレーションなど、色々なものを組み合わせてシステムを構成していました。 4線式3相交流 の 中性点接地 や 配管のフランジ接続 に 熱交 の 圧損 と ねじり振動解析 や CFD みたいな世界から、クラウドのモダンアーキテクチャの世界です。 まるっきり異世界に飛び込んでから3年と少々。どんな風に歩いてきたか振り返ってみたいと思います。 ![40代のWeb未経験者](/assets/blog/authors/hamatani/20231223/40s_beginner.jpg =480x) 40代のWeb未経験者を生成AIに描いてもらうとこんな感じ プロGのお仕事 配属されたのは、さすがにWebシステムをゴリゴリ開発するエンジニア枠ではなくて「プロデュースグループ」への配属でした。社内では「プロG」と呼ばれています。1名が育休中なので、いま稼働しているのは4名。KINTOテクノロジーズで一番小さなグループです。 バウンダリースパナー プロGの役割について語るとき、人と組織を繋ぐ「バウンダリースパナ―」というのが、いちばん近いと思います。KINTOのやりたいことを実現するためにどんなシステムを作るかを、ビジネス部門のメンバーと一緒に考えて、システム開発部門と繋いでいく仕事です。中でも私は、大~中規模の案件のいちばん上流工程で「システム構想検討」を主に担当しています。 ![プロデュースグループ](/assets/blog/authors/hamatani/20231223/produce_group.jpg =480x) ビジネスとシステムを繋ぐプロデュースグループ(なんか若い) つくりすぎない どんなシステムを開発するか。ビジネスニーズが満たされていることは大前提ですが、それだけでは不十分だと思います。「つくりすぎない」ことが、とても大事です。初期のシステム化要望は、あれもこれも詰め込んだリッチなものになりがちです。ビジネス部門が求める幹となる部分を理解し、本当に必要な機能を特定して、必要十分な開発スコープに落とし込んでいくように心がけています。 KINTOが手掛けるビジネスは、ほかに前例がないものが大半です。事前に頭の中であれこれ想像してシステムを作りこんだとしても、実際にそれが全て役に立つとは限りません。やってみて初めて分かることもあります。まずは必要最小限のシステムでビジネスをスモールスタートし、そこからビジネスの成長に合わせて、システムも段階的に育てていくのが良いと思います。 また、内製開発部隊はKINTOの貴重な戦力なので、そのリソースは無駄なく活用しなければなりません。案件ごとの優先度とターゲット日程に応じて効率的に割り当てる必要があります。開発スコープをコンパクトにすることで、できるだけ短期間で開発し、いちはやく市場に投入していく。そうしたスピード感はKINTOの文化であり強みだと思います。  ビジネス部門の担当者さんは、システム開発への要求出しに不慣れなことがあります。システムを利用することはあっても、なかなか立ち上げに関わる機会はないので、全く初めてというケースも珍しくありません。システムの立ち上げは、家を建てることに似ているとも言われます。どんな家にしたいか、施主さん自身も初めてでよく分からない。プロGは、そうした担当者さんをリードする役割も担っています。 内製開発部隊だからこそ、ビジネス部門と対等にやりあったり、時にはリードしたりして、絶妙な「つくりすぎない」システムを提案することができます。KINTOテクノロジーズ全体に浸透している意識だと思いますが、プロGのミッションはその中核にあると思います。  狩猟系民族 プロGは基本的に自分で獲物(案件)を見つけに行く狩猟系のスタイルです。グループミーティングで新しい大規模案件の噂が出ると皆が目を輝かせます。そして、向こうの山でマンモスを見つけたときのネアンデルタール人みたいに、いそいそと狩り支度を始めます。そうして一番最初に獲物に飛びついた勇者が、その案件の主担当になる。そういうしきたりになっています。 ※実際は勤務地や得意分野を加味して担当割り振りされることもあります。 半分活かして、半分手放す 異世界を歩きはじめるときは、できるだけ身軽にしておくのが良いと思います。 経験をフル活用、しない 新しい場所で心機一転スタートするとき「これまでの経験をフル活用して」と思うかもしれません。即戦力を期待されているのだから丸腰で飛び込むのはちょっと怖い。新しい環境での不安感を支えてくれるのは、これまでの経験しかないような気がします。けど、経験や価値観を抱えたままだと重たいですし、新しいものを取り入れるスペースもありません。過去の実績はもう動かないものだから、抱えていると足に根が生えたみたいになってしまいます。私も初めての転職のとき、それで失敗したことがありました。  忘れてても、ちゃんと助けてくれる だから、半分は手放します。こだわりとかスタイルみたいなものは真っ先に手放してしまいます。半分活かして、半分手放すくらいがちょうどよいバランスではないでしょうか。手放すのは「失う/否定する」ではなく、いったん「置いておく/忘れる」ということ。普段は忘れていても、必要な時にスッと引き出しが開いてちゃんと助けてくれる。誰かが盗んでいくわけではないのだから、ずっと両手に抱え続けることはない。そう考えるとラクになるので、そうしています。 ![経験のストック](/assets/blog/authors/hamatani/20231223/stock_of_experience.jpg =480x) 自分の経験のストックを仕分けする <活かしているもの> プロマネの気持ち 私くらいの世代だと「うさぎって寂しいと死んじゃうんだよ」というのがありましたが、同じくらいプロマネも孤独に弱い生き物です。前職ではひたすらプロマネをやってまして、うまくいってるプロジェクトは良いのですが、うまくいかないと加速度的に孤立化が進むのを知っています。メンバー/顧客/オーナー/上司/財務部門/営業部門/サービス部門/本国/外注先/協業先と、各方面から同時に圧迫されて、あっというまに逃げ場がなくなります(そしてトドメに家庭が…っていう人もいました)。KINTOだと皆優しい感じなのでそこまでには至らないと思いますが、それでも孤独でしんどい仕事です。応援したいと思います。  炎上するプロジェクトは、そもそものベースライン(スコープ, 日程, 完了条件)がグダグダになっているケースが大半です。プロGの自分にできることとしては、そこをちゃんと整えたうえでプロジェクトを渡していくことです。 結局なんとかなる 前職の6年間だけでも40件弱のプロジェクトを回してきました。場数だけいえば多い方だと思います。失敗して青くなったり、予算が赤になってしまったり、先行きが真っ暗になったり色々ありましたが、どのプロジェクトも結局はなんとかなりました。イメージ通りに格好よくゴールできなくて、息も絶え絶えに転がり込んだとしてもゴールはゴール。行き止まりで万事休すと思っても、必ずどこかに打開策はあるはずだという気がします。さんざん痛い目に合いながら性懲りなくそう思えるのが、自分でも不思議です。 多様性があたりまえ 色んな人と仕事をしてきました。国籍だと、ドイツ、オーストリア、フランス、スウェーデン、チェコ、イギリス、インド、スリランカ、マレーシア、タイ、インドネシア、シンガポール、台湾、韓国など(なぜか、アメリカと中国には縁がない)。職種としても、ソフト開発、機械設計、電気工事、配管工事、搬入設置工事、営業、財務、調達、倉庫、ゼネコン、消防署、自動車の設計開発、産業用ロボット、コラボしたライバル企業 などなど。プロジェクトには多様な人々が参加するのが当たり前で、違うから参加してもらう意味があるという感覚です。KINTOにも色んな職種の人や、癖のある人がいて面白いです。 <手放したもの> プロマネは決めるのが仕事 前職の上司が「プロマネは決めるのが仕事」と言っていて、私の実感としてもその通りだと思っていました。判断ミスよりで責められることよりも、判断しないことを責められるほうがより深刻。決めないというのは「プロマネとして仕事をしていない」ということを意味していました。上司に助言を求めることはあっても、判断を委ねることは絶対にありえません。それは、運転席に座りながらハンドルを自分で操作しないのと同じこと。誰かに判断を委ねるようではプロマネとして失格で、運転席から降りるときでした。グローバル企業でしたが、どこの国のプロマネもそんな感じだったと思います。  そんな価値観で過ごしてきたので、驚きでした。KINTO/KINTOテクノロジーズのプロマネの皆さんを見ていると、自分で決めるのではなく、関係者の合意をもって決定としている。このギャップにはかなり戸惑いましたが、そのうち、これもプロジェクトマネジメントの実践としてアリなのだと理解できました。私の前職が Decision and Order の直接的なマネジメントだとすると、KINTOは Facilitate and Agreement とでも言うべき間接的なマネジメントをやってるんだなというのが今の認識です。むしろ、とても高度なことをやられているなと尊敬する気持ちです。全て自分で決めるほうがシンプルで簡単です。 とはいえ、間接的な "合意の促進" だとスピード感には欠けます。直接的な "判断と命令" も個人に委ねるリスクがあります。それぞれの良いとこどりができないものかと思います。 思い立ったら直電 仕事道具といえばガラケーでした。何か思い立ったらすぐに電話。発信も着信も多くて、1日の履歴が数十件になることも普通です。プロジェクトメンバーが全国の現場に散っているので、すぐ捕まえるには電話しかありません。夜中でも平気で電話してました。KINTOテクノロジーズだともちろんそんなことはなくて、Slackを中心にスマートなコミュニケーションが浸透しています。そんな当たり前のことに驚いていた私は、まるで過去からタイムスリップしてきた人みたいだったと思います。 とはいえ、1分の電話で片付く要件が、Slackのやり取りだと30分かかることもあるので、コミュニケーションツールの使い分けというのは必要です。皆さん実践されてると思いますが。 組み込みソフトの常識 私のルーツであり、思い入れが深いのですが、さすがにこれは手放さざるを得なかったです。Webシステムなので、リアルタイム性の要求が無い(応答速度の要求はあるけど、別物)ですし、Event-Mode-Action のステートマシンで動くわけでもない。PIDみたいな連続系の制御システムとも違う。基本的にはハードウェア非依存なので、リソース制約も限定的です。なので泣く泣く、引き出しの奥にしまい込んでいます。AWSのSQSなんかは、昔手作りしたFIFOのリングバッファを思い出して懐かしい気分になります。 それでも、この先もしかしてSDV(Software Defined Vehicle)や IoTみたいなエッジ領域と、KINTOのクラウドに接点ができたら出番が来るかも?と、少し引き出しがウズウズしています。 ざっくり適当に理解する 異世界なので、ただ歩いているだけでも未知のあれこれに出会います。 アルパカを理解する 初めてアルパカを見たとき「首の長いヒツジみたい」と思う人。「毛の白いラクダみたい」と思う人。漢字で 羊駱駝(ひつじらくだ)と書くくらいなので、どっちもアリです。その人の生まれ育ちや直観的な感じ方に素直に従うしかありません。初心でアルパカと向き合って、ゼロから理解するのは今さら無理なので。だから、自分の知ってる〇〇みたいだなと、最初はざっくり適当に理解すれば良いと思っています。  ![アルパカを観察](/assets/blog/authors/hamatani/20231223/alpaca_watchers.jpg =480x) そこまで一所懸命に観察しなくても大丈夫 違うけど、だいたい同じ 違いに着目するより、同じに着目したほうが、異世界に慣れる助けになるはずです。自分も組み込みソフトやエンジン試験装置についての経験から、ざっくり適当に理解することをよくやります。ただそれは「分かったふりをする(他人を欺く)」ではなく「分かった気になる(自分の深掘りをいったん止める)」ということ。知識を実際に使って仕事をするときは「分かっていない」という事実と向き合う必要があります。逆に言えば、それまではいったん浅いところで置いといても、たぶん大丈夫ということ。 正しさよりも全体感 足元をみて丁寧にひとつずつ正しく理解するより、少しくらいの思い込みや未消化な部分があっても良いので、浅く広く全体感を把握するほうが自分には合っているみたいです。点の集合でも、眺めてるうちに隠されたストーリーを何となく感じ取ったり(星座みたいなもの?)、登りたいところへたどり着くための手がかりになったりします(ボルダリングみたいなもの?)。特にプロマネやバウンダリースパナ―みたいな役割は、そういう全体感の把握が助けになると思います。  素潜りできるところまで 全体感を眺めて読み取れるのはあくまで仮説です。「〇〇だとすると、こんな風に進められそうだ」みたいな仮説が浮かんで来たら、必要に応じて深掘りします。今からその領域のプロになる気はない(なれない)けれど、プロの人と会話できるくらいになれれば十分です。私の場合、それでだいたい仕事は進みます。素潜りの副産物としては、それまで点だった知識が繋がって、線みたいになっていくこと。そうやって少しづつ線を繋げて地図をつくっていきます。 反抗期の過ごし方 仕事に慣れてくると、だんだんと湧いてくるものがあります。 違和感とイライラ 誰でも新しい仕事に慣れるまでは謙虚で、少し臆病なくらい周囲の様子を伺いながら過ごしていくと思います。そのうち仕事に慣れてくると、だんだんと湧き出てくるものがあります。「あれ? この会社の仕事のやり方おかしくないか?」みたいな、これまでのキャリアで経験してきたやり方とのギャップから生まれる違和感です。それ自体はとても貴重な気付きで、うまくすれば何かの改善に繋がるかもしれません。けれど、私の場合だけかもしれないですが、そこにフラストレーションが伴うことがあります。なんだかイライラした気持ち。 転職後反抗期 個人的に「転職後反抗期」と呼んでいます。早ければ3ヶ月頃から始まって、2年目くらいまで続きます。3回の転職を経験しましたが、毎度必ずやってきます。違和感自体は良いとしても、イライラを周囲にまき散らすわけにはいきません。自分の場合は 1 on 1 を使って消化させてもらいました。直属の上司と、2コ上の上司と、3コ上の上司に、それぞれ話を聞いてもらいました。話を聞いてもらうためには違和感を言語化する必要があって、まずその過程で客観視するので少し冷静になれます。少し格好つけて提言っぽくまとめたくなります。そうやって率直に対話をしていくと、だんだんと違和感が消化されていきます。 2コ上は副社長、3コ上は社長という距離感。フラットさはKINTOテクノロジーズの魅力です。 違和感を整理していくと、そのいくつかは自分のミッションに落とし込めることがあります。 ![大人の反抗期](/assets/blog/authors/hamatani/20231223/rebellious_adult.jpg =480x) 生成した “大人の反抗期”(1枚目と同じ人が出てきた) おわりに たぶん、今がいちばん積極的に新しい技術や知識に気持ちが向いているかもしれません。 昔の引き出しが開くとき 社内の色んな職種の人の話を聞くのも、社外の展示会や他の企業さんと話をするのも面白い。刺激を得て考え方を再構築するうちに、さび付いていた昔の引き出しがスッと開いて、新しいものと古いものが化学反応を起こすことがあります。ボルダリングの例えを書きましたが、ほんの少し登ると景色が変わって、次に手が届きそうだとか、思ってたのと違うから考え直そうとか、色々と分かってきます。そういう変化を素直に受け入れると、次の変化も楽しめる。逆に苦しい気持ちになる時は、たいていそこに留まろうとしているときでした。 そうやって生き延びていく 「 タイガー手回し計算機 を使っていた」とか「 パンチカード が読める」とか。新卒で入社したころ、そうしたベテランエンジニアの方が現役で活躍されていました。「クラウドネイティブなモダンアプリケーション」も「LLMの生成AI」も、いずれ枯れた技術としてコンピューターの年表に並ぶことになります。技術は移り変わり、求められる役割も変わっていきます。そのとき何をしているか想像もつかないけれど、自分の半分をどんどん入れ替えながら、しぶとく生き延びていければ良いなと思います。 ![コンピューターの歴史](/assets/blog/authors/hamatani/20231223/history_of_computer.jpg =480x) かつての最先端技術とリンゴが並ぶ
アバター
取材対象 KINTOテクノロジーズ内のグローバル開発部には、多国籍で多様な背景を持つDevOpsチームが存在します。 メンバーそれぞれが得意とする言語、技術、経験は異なりますが、チームとしては非常にスムーズに仕事を進められています。 今回は、そのチームリーダーである李さん( Flyway記事の作者 )に取材を行いました。多国籍チームの運営に興味があれば、ぜひご一読ください。 自己紹介とチーム状況紹介 自己紹介 KINTOテクノロジーズグローバル開発部でDevOpsチームリーダーをしています、李です。 卒業後、日本のメーカーのIT子会社で5年間働きました。その間、社内の共通言語が日本語だったため、日本語や日本の文化、さらには異文化とのコミュニケーションスキルを学びました。当時は、Webアプリケーションの開発、設計、評価から始め、システムエンジニアとプロジェクトマネージャーとしての経験を積みました。開発経験だけでなく、開発プロセスとマネジメントの知識も身につけました。 その後、大学で3年間講師を務め、新しい技術と教育学を学びました。これにより、効率的な学習方法についても理解を深めました。 日本に移住した後、次女が保育園に入園したのをきっかけに、IT分野に復職しました。 これまでの異文化コミュニケーションスキルや開発経験、マネジメント能力や人材育成の経験を活かし、現在はグローバル開発部でDevOpsチームのリーダーを務めています。 チーム状況紹介 現在、私たちのDevOpsチームはCI/CD、インフラ、テストの3つのサブチームで構成されています。チーム内6人が下記のように、国籍も専門分野もそれぞれです。 DevOpsチーム設立当初からの理念は、あえて異なるスキルセットを持つメンバーを組み合わせることで、アプリケーション開発チームをサポートすることです。 No. サブチーム 前職経験 国籍 英語力 日本語力 1 CI/CD 開発、プロジェクト管理、品質保証、システム設計 中国 B B 2 Infra Infraエンジニア、プロジェクト推進、インテグレーション、設計 中国 C A 3 Infra Infraエンジニア、開発、プリセールス 中国 C B 4 Test ネットワークエンジニア、プロジェクト管理 ニュージランド A C 5 Test 開発エンジニア インド A C 6 Test テスト、開発、設計 ミャンマー B C *語学力: A:細かいニュアンスまで再構成して表現できる B:幅広い複雑な話題でも議論可能 C:自分の考えとその理由を表現できる D:日常会話可能 Q&Aコーナー 多様な言語、文化、技術背景を持つチームの日常業務は、想像しにくいかもしれません。 そこで、今回はチームリーダーの李さんにいくつか質問をしてみました。ここではQ&A形式でまとめ、チームの様子を少しでも皆さんに伝えられればと思います。 Q&Aその1 質問: チーム内に様々な専門経験を持つメンバーがいる中で、皆をDevOpsチーム共通の目標に向かわせるにはどのようにしていますか? 回答: 私たちは、下記のようにチーム内で明確なロードマップを共有し、それに基づいて目標を具体的にし、メンバー全員が同じ方向を目指すようにしています。 チーム内には、品質保証をしたい人、インフラを担当したい人、開発に携わりたい人など、様々な希望を持つメンバーがいます。私たちは、それぞれの強みや志向を理解し、皆が納得できるロードマップの作成に努めています。 ロードマップ(例) Q&Aその2 質問: チーム内の7人は4つの異なる母国語を話します。コミュニケーションにはどの言語を使用していますか?文書やメッセージはどうですか? 回答: 口頭でのコミュニケーションや文書の作成は、その人が得意とする言語(英語または日本語)を使用しています。 チーム全員が英語を理解できるため、メッセージは主に英語で送信しています。また、理解を深めるために翻訳ツールの利用も推奨しています。 多言語コミュニケーションでは、発表者がゆっくりと話し、簡単な単語を使用するよう努め、わからないことはすぐに質問する雰囲気を作っています。 Q&Aその3 質問: 文化的にも技術的にも多様なチーム内での知識共有はどのように進めていますか? 回答: 私たちのチームでは知識共有を重視しており、下記の三つの方法を用いています。 期間 手段 内容 目的 アイスブレーキングフェーズ 各メンバーの専門分野について知識共有会 今までの領域の知識 お互いに理解し、自身の知識を広げること 配属から一年後 オンラインコース学習(Udemyにある自動テストツールやマイクロサービスアーキテクチャなどのコース) 仕事に使うスキルで足りない部分(システムアーキテクチャとか、自動テストツールとか、AWSとか) 今の仕事上必要なスキルの向上 随時(異なるタスクが終わった後) ドキュメント化して残す 手順やノウハウなど( 自動テストのブロック  ) 将来横展開しやすくするため Q&Aその4 質問: 母親として、異文化間のチームをリードするのは難しいですか? 回答: 私が母親であることに対して、チームは非常に理解があり、親切です。グローバル開発部の文化として、多様性を尊重し、互いに敬意を払い、適切な距離感で接しています。自分は小学生の子供を2人持っており、学校行事への参加が必要な時、チームメンバーは日程調整やタスクの再配分を通じてサポートしてくれます。 例えば、最近家族全員がインフルエンザにかかった時、約2週間出勤できませんでしたが、チームメンバーが積極的に業務を引き受け、私の負担を軽減してくれました。 そのサポートにはとても感謝しています。 Q&Aその5 質問: 多国籍なチームを管理する際、どのようにして様々な標準(労働倫理やプロフェッショナルな基準など)を統一し、メンバーのモチベーションを維持しつつ、一定水準の成果を出すことができますか? 回答: 異文化の合理性を認め、尊重することが重要です。私自身も外国出身であるため、日本と海外の慣行の違いを理解しており、この視点からチームに説明することができます。ここは日本なので、基本的には日本の標準を遵守していますが、外国人の視点からの解説も提供しています。 また、管理学やPMP(プロジェクトマネジメントプロフェッショナル)などの知識を活用し、業界共通のやり方を取り入れています。 チームでは、メンバーに広範な裁量を与え、彼らが望む仕事を行うことでモチベーションを維持することを重視しています。 最後に 質問: こういった多国籍なチームをまとめる上で、李さんが一番大事にしていること、または工夫しているところは何ですか? 回答: やはりコミュニケーションが最も重要だと思います。PMPの理念に沿っています。私たちのチームでは、皆が明確かつ具体的に自分の考えを伝えることを心掛けています。仕事の中で、いつも「5W1H」を用いてコミュニケーションを取っています。また、異なる考え方にも敬意を払います。基本的に、人々が異なるということを認識した上でコミュニケーションを行っています。 質問: チームメンバーからもサポートがもらえるのは信頼があるからだと思います。その秘訣はありますか? 回答: 普段の業務では、私自身もメンバーのサポートと指導に意識的に取り組んでいます。メンバーがそれぞれの目標を達成できるよう協力しています。私たちは一つのチームとして、各々が欠かせない一員であり、共に目標達成を目指しているため、リーダー・メンバーというポジションの関わらず、お互いにサポートし合えているのだと思います。やはり素直な心が必要だと思います。 まとめと今後の展望 この記事ではグローバル開発部DevOpsチームのリーダーである李さんにインタビューをし、多国籍なチームでの異文化間コミュニケーションや知識共有の方法、母親とチームリーダーのバランス、そして多国籍なチームのマネジメントなどについて取り上げました。 最後の回答にあったように、多様な背景を持つチームであっても、常に「人は異なる」ということを意識し、異なることに敬意を払い、5W1Hなどを通じて考えをわかりやすく伝える。こういったことの積み重ねによって信頼が生まれ、同じ目標に向かって効率的に互いをサポートし合えることがわかりました。これは決して多国籍なチームだけではなく、同じ国籍であっても同じことではないでしょうか。 多様な背景を持つチームのマネジメントに悩んでいる方にとって、この記事が少しでも参考になると幸いです。 今後、DevOpsチームは事業の展開やテクノロジーの進化に伴い、さらなる挑戦に直面することでしょう。 しかしこれまでの取り組みと、多様性を受け入れられるチームの精神があれば、どんな障害も乗り越えていけると、チームの今後の成功と成長に期待しています。
アバター
はじめに Mabuhay!前回のブログからほぼ1年が経ちましたが、私は今でもKINTOテクノロジーズのグローバル開発グループの陽気なメリーです。(ちなみに、私の最初のブログは こちら でチェックできます。) さて、昨年から何が変わったでしょうか?担当しているタスクでまったく余裕がないときがあり、パーソナルアシスタントがいたらいいなと思う時があります。必須と思われるタスクで、でも自分自身でやると時間がかかりすぎるものを追跡するのを助けてくれます。アシスタントをつけることができれば、他にやらねばならない、より重要な事柄に集中することができます。 パーソナルアシスタントのこういった役割は、フロントエンドの状態管理に似ています。状態管理とは、変更点やアクションを追跡し、アプリケーションが期待通り正しく実行されているか確認することを言います。stateはアプリを動かすために必要な情報であり、アプリケーション開発全体を通して管理する必要があります。 状態管理の力を解き明かす 💪 KINTOのバックオフィスシステムには、ウェブサイト全体で複数のデータをダウンロードできるものがあります。最初は、1回のダウンロードが完了するまでに1、2秒しかかかりませんでした。しかし、時間が経過するとデータ量が大きくなり、ダウンロードするのに数秒から数分かかってしまうようになってきました。そうなると、処理中には何も表示されないため、ダウンロードボタンをクリック後、ユーザーが何が起きているかわからず、混乱させてしまいます。こういった混乱を避けるため、ダウンロード通知コンポーネント画面を表示させることにしました。ダウンロードのステータスを表示し、残りのダウンロード件数もわかるようにします。 ![Download Component](/assets/blog/authors/hundanmz/downloadComponent.png =370x) 私は、このプロジェクトに関わる中で状態管理について知り、フロントエンド開発において、状態管理が大変効果のあるものだとわかってきました。 レスポンシブユーザーインターフェイス - 当ウェブサイトにはダウンロードボタンのあるページが複数あり、ユーザーがそのボタンをクリックするとカウントアイコンが更新され、進行中のダウンロード件数が表示されます。 精度 - ダウンロード通知コンポーネント内の表示は、ウェブサイトのダウンロードボタンに依存しています。stateは信頼できる情報源であり、ユーザーがダウンロードボタンをクリックするたびに更新されるため、ユーザーに表示する内容の正確性を担保することができます。 簡単なデバッグ - stateが1 か所に保存されるため、より迅速にデバッグできます。 メンテナンス - 状態管理で再利用可能なコードを作成できるため、コードの可読性が担保され、維持が容易になります。 VueXではなくPiniaを選択 ![Pinia VueX Logo](/assets/blog/authors/hundanmz/piniaVueXLogo.png =150x) 私はこのプロジェクトを通して初めて状態管理を意識するようになったため、同僚からPiniaと VueXについて教えてもらいました。これらはどちらも Vue.jsの状態管理ライブラリであり、どちらを使用するかは自由に選択できます。これら2つのライブラリをある程度調査した結果、主に次の理由により、VueXではなくPiniaを使用することにしました。 モジュラー・バイ・デザイン - Piniaでは複数のストアを作成し、必要なコンポーネントのみにインポートできます。一方、VueXでは1つのストアしか提供していません。このプロジェクトで必要なのはダウンロード用のストア1つだけでしたが、将来的にはこれだけでは足りません。遅かれ早かれ別のモジュールを追加する必要がある場合には、管理が簡単になります。 よりシンプルなAPI - シンプルなAPI のおかげで、状態管理を簡単に始めることができました。stateはアクションで直接更新でき、mutationsは廃止されています。 Vueの公式状態管理ライブラリ - これが、私が VueXよりもPiniaを選んだ一番の理由です。Piniaは現在、Vueの公式状態管理ライブラリです。VueXは引き続き使用できますが、すでにメンテナンスモードになっており、新しい機能追加はありません。 状態管理ライブラリの代替について検討 状態管理/ステート管理ライブラリを一切使用しないことにした場合、ステートを管理する方法は他にもあり、これらのソリューションのうちどれが私たちのニーズに合っているかを評価する必要があります。以下にソリューションの一部を示します。 Propsとイベント - 親子間のコミュニケーションが必要なら、これが一番の選択肢です。親はデータを子に渡すことができます。一方、子はイベントを送信して変更を親に伝えることができます。 ローカルストレージ/セッションストレージ - 永続化したいデータがある場合は、ブラウザのローカルストレージ/セッションストレージを使用できます。 これは、ユーザー設定を保存するなどのシナリオに最適です。 イベントバス - 伝達を円滑に進める必要のある関連性のないコンポーネントがある場合は、イベントバスを使用できます。この方法は推奨されませんが、単純なシナリオでは使用できます。 終わりに 状態管理はフロントエンド開発において重要な役割を果たします。アプリケーションが大きくなるにつれて、管理する必要のある状態がますます増える可能性があります。Piniaは使いやすい状態管理ライブラリで、私のような経験の少ない開発者にもわかりやすいです。 こちらの投稿では、技術的な詳細は延べませんが、Piniaを使用したときにもいくつか問題が起きています。また次のブログでお話ししたいと思います😊 参考 Pinia What is Vuex? | Vuex The Power of State:A Deep Dive into State Management State Management in Frontend Development:An Overview and Case Study Advantages of Pinia vs Vuex Vue.js State Management:Pinia vs.Vuex Vue.js Events API | Vue 3 Migration Guide
アバター
Hello, I am Saju Mathradan, Cyber Security Expert from KINTO Technologies (a Toyota Group company). In this blog, let me write down some of my experiences in working for tech companies in Japan, from cultural nuances to professional growth opportunities. This article is one of five articles in a series exploring diversity, delving into various work styles and perspectives at KINTO Technologies. I am always fascinated about the technological innovation of companies in Japan, given that it stands in a very attractive destination with a cutting-edge and high end technological landscape. My experience in Japan In my 26 years of professional experience, I lived in Japan for 15 years, in between staying in other countries and working for global projects too. However, I was lucky to have worked with some of the leading companies in Japan to manage and transform their IT environment to the latest technologies. Before joining KINTO Technologies, I was working in the IT Security Department of Japan’s number one and world’s third largest apparel company for 6 years, and before that, with Asia's largest Japanese pharmaceutical company, and other local and global large enterprises part of IT outsourcing deals. Cultural Connection In my experience, technology in Japan is in its transformational period. Japanese companies have a larger global outlook than before, eager to expand business internationally and tapping into diverse global talent pool. Global workstyle and processes are followed for greater international integration in tech companies, and this often involves a strong emphasis on teamwork, collaboration, and dedication to the collective goals of the organization. I found that KINTO Technologies is also not far behind as a 100% Toyota owned company, working well within the “Toyota way of culture” and providing a global environment that helps employees collaborate across regions. Together, we strive to create the future of mobility and contirbute to make the world a better place. Language Requirements In Japan, language always creates barriers to global workforce integration. While English is widely used in the tech industry these days, having a basic understanding of the Japanese language can be an asset. At KINTO Technologies, we never faced any big challenges using English for our daily work. Having diverse team members from different countries helped us to use English as a more of common medium along with Japanese. Challenges in Daily Work In my experience, Cyber Security awareness is low in many companies as the cultural thinking in Japan is that bad things can’t happen to anyone, and trust is placed in a very high level. However, with the prevalence of fraudulent access, data hacking or money laundering being common on the Internet these days, there is no boundary for threats. Japanese companies appear too vulnerable in this regard. As a Cyber Security expert, it is quite challenging for me to prepare fool proof security control and framework to protect a company's critical applications, infrastructure, data, and access to the services securely from the internet. This is particularly true when dealing with new and emerging technology requirements of “Mobility as a Service” as well as associated E-Commerce transactions and the increasing use of online services by both customers and employees. Preparing the security framework as given below in the picture and working to ensure the data and its access is safe and protected end to end is complex and needs a heterogeneous approach. Technology fascinated employees and supportive management of KINTO Technologies make my life easier to achieve the required goals. Moreover, I am very happy to be involved in the various levels of Mobility as a Service IT Environment. Technology Landscape When I experienced Japan's IT landscape, I noticed that some of the companies are still using very old and obsolete technologies and are slow in upgrading. However, at KINTO Technologies, I found that all new generation cloud technologies and tools are already in place. Whether you're interested in artificial intelligence or cutting-edge software development, KINTO Technologies offers a diverse range of opportunities to align employees’ career with their passions, or networking events such as meetups (NomiKai), and industry conferences to connect with like-minded professionals and stay abreast of the latest trends. Professional Development Whether it is management or technical ladders, tech companies in Japan provide employees with ample opportunities for professional growth, and I was fortunate to be able to get such good opportunities in my career from all my employers. At KINTO Technologies, it is always at par with the global industry standards. The management always encourages employees to attend industry conferences to collaborate with top-notch experts, and maximize the learning curve, enhance skill development and progress in their careers. Work-Life Balance Whether it was my previous companies or now in KINTO Technologies, I was always explained by HR team the importance of maintaining a healthy work-life balance and that it's a cornerstone of the Japanese ethos. These days companies are increasingly recognizing the importance of employee's well-being, offering flexible work hours, remote work options, and wellness programs, etc. Striking a balance between professional and personal life is not only encouraged but is also seen as a sign of a well-rounded and effective team member. Conclusion In my opinion, working for a tech company like KINTO Technologies or others in Japan, will be an exciting journey filled with professional growth and technological innovation. As Japan continues to be a global tech powerhouse of manufacturing and high-end technology, the experience of working in tech companies in Japan can be a transformative chapter in one's career, offering chances into the future of technology connected with the beauty of Japanese culture. Join and Experience!
アバター
はじめに こんにちは、KINTOテクノロジーズ新車サブスク開発グループの阿出川です。 アプリケーションエンジニアとして国内のトヨタ新車サブスクリプションサービス「KINTO ONE」の開発・保守・運用に3年間従事しております。 自動車が大好きなので仕事を通して関われてとてもハッピーです。 今は家族優先でミニバンに乗っておりますがいつかトヨタのGR車種に乗りたいです! 好きなエンジン機構は「カムギアトレーン」です! そんなわたしが今まで関わったプロジェクトで特に印象深く達成感が大きかったお話を紹介しようと思います。 新型プリウス発売に備えよ 2023年1月10日 新型プリウス(5代目)が発売されました。 プリウスといえばハイブリッド車の先駆けで環境車としての確固たる地位を築いたトヨタの中でも注目度高い車種ですよね。 しかしプロジェクト発足当時のプリウス(先代)は既に発売からだいぶ経過していたこともあってKINTO ONE取扱い車種の中で特に人気が高いわけではなかったです。なので個人的には新型が出ても特段反響が大きいとは考えておりませんでした。 しかし掲げられた目標は*,990 PV/分 耐えられる事! (この数値は過去最高負荷時の10倍) その時点で許容可能だったのは目標値の3%程度でした。 主な対策ポイントは③点です。 対策① Databaseの接続先調整 RDBはライターインスタンス、リーダーインスタンス1台という構成でしたがフロントからは参照系のアクセスの方が圧倒的に多かったのでリーダーインスタンスに負荷が偏りライターのインスタンスの方は余裕がありました。 暫定的にフロントからの接続先を参照・更新問わずライターインスタンスへ接続させるよう設定変更しました。 結果、意図したとおりに負荷が分散されました。 リーダーインスタンスを追加するより手軽だったのでまずはこの方法を取り入れました。 対策② 見積画面の改善 トップ画面に次いでアクセスが多いのは車種ごとの見積画面になります。 ここでは自動車のグレード、パッケージ、オプションなどを選択しますがその車両マスター情報をリレーショナルデータベーステーブルから取得しておりました。 これをインメモリのkey/valueキャッシュ(Elasticacheのredis)に格納された車両マスタ情報から取得するよう変更し、DB負荷軽減とフロントレスポンスの改善を図りました。 次にキャッシュ化出来なかった情報でDB負荷の高い箇所を特定しました。 見積~申込までは車両情報の他、販売店店舗情報のマスタテーブルの参照しており、slow queryに挙がってくるような問い合わせは行われていないのですが発行回数が多いので塵も積ればとやらで比較的costの高い箇所は対象テーブルへINDEXを追加しquery costは全て一桁台に改善させました。 対策③ インフラ増強 ①、②の対策に加え目標数値に耐えられるよう後はインフラの構成見直しで調整します。 特別な一時的な対応という事で手動スケーリングで次の通りインフラ増強を図りました。 スケールアウト AWS service 台数-変更前 台数-変更後 EC2 Front End 6 36 EC2 Back End 2 15 スケールアップ AWS service タイプ-変更前 タイプ-変更後 EC2 スケールアウトのみ Elasticache t3.medium r6g.large RDS r5.xlarge r5.12xlarge その他 急激なアクセス増加に耐えらるよう予めALBの拡張を行う為、暖気運転が必要との事で下記の情報を添えAWSへ暖気申請をしました。 予測されるピーク時間帯 予測されるピーク時のリクエスト数 トラフィックパターン ユースケース etc 発売当日を迎えて 負荷としては準備していた許容範囲に対して実際のアクセスはピークで10%程度でしたがトラブルもなく発売当日から安定し稼働しました。 お客様からの反響もよくKINTO専用グレード含めたプリウス全体の流入(見積・申込)は期待通りだったようです。 しばらく推移を見守り落ち着いたところで暫定的に対応していた箇所は元に戻し終了しました。 さいごに 滅多にない大きなイベントだったので大変貴重な経験だったなと思っております。街中でプリウスを見かける度に気になり目で追ってしまうようになってしまいました。KINTOのかな~?って 結果をみるとインフラのスペックは過剰であったようですが事前に正確に流入を予測する事は不可能且つミスするわけにもいかなかったので良かったのだと思います。 年末から年始にかけての忙しい時期にも関わらず様々な方々にご協力いただき無事に乗り越える事が出来たと思っております。 負荷のテストプラン、スケジュールを管理してくださったベンダー会社の方々。 サーバ増強に伴うサービス停止に付き合ってくれた対向システムのメンバー。 インフラ増強に関してはプラットフォームGメンバーにアドバイス助言を頂きました。 この場でもお礼の言葉を残しておきたいと思います。ありがとうございました。
アバター
Hi, this is Mori again from KINTO Technologies (KTC). I’ve been writing blogs, including co-authored ones, and I just can’t believe this one is already my 10th article! Almost all my posts in the Tech Blog are about event reports, but today, let me talk about a story from my daily work. Well, I usually work as a Product Manager (PdM) of the Global KINTO Web and project lead of PII (Personal Identifiable Information) related tasks in the Global Development Division. Since PII tasks are mainly about the user pool of each KINTO services around the world, both of my tasks are rarely linked together. But for once, it did! We took care of activities to comply with GDPR on the Global KINTO Web. Finally, the time has come for my two main jobs to intersect! 👏👏👏 If you would like to know more about our GDPR compliance activities related to transferring personal information globally between each KINTO user pool, you can check out my previous article Compliance with GDPR in the Global KINTO Looking back, since it was my debut article, it’s amusing to see how the writing is too stiff and serious😂 What is GDPR? Who is the Target? Before starting to write this article, I reread my previous one and realized that there is no explanation of 'What is GDPR?' OMG🤦‍♀️ Let me explain about it now. GDPR is the acronym for the General Data Protection Regulation and it’s a legislation within Europe. It regulates how to protect and process personal data within the European Union (EU) and the European Economic Area (EEA) The purpose is to protect the personal data of individuals residing within the territory. The target is residents, regardless of their nationality This of course means that companies in the EU should comply with the GDPR. However, even companies outside of the EU might be targeted for the following reasons: When a company has branch or a subsidiary in the EU When a company provides products or services for the EU When a company is entrusted to process personal data of EU residents to a third party For example, even if the language of a website is English, it might be out of the scope of GDPR if EU customers are not the target. On the other hand, if your services target inbound customers visiting your country, you are likely to be subject to this regulation. Global KINTO Web and GDPR Tasks The Global KINTO Web is a brand website of KINTO services which are available in +40 countries around the world. Since many KINTO services are available in Europe, European customers are also the target audience of this website. That is why compliance with GDPR cannot be ignored. Of course, we set up policies at the time of release. However, the situation has changed significantly since the beginning, with changes in operational structure, updates to features, and revisions to regulations, among other things. We have decided to re-establish policies and other compliance activities with the support of an external lawyer. In the Global KINTO Web, we collect customer information, such as names, email addresses, phone numbers, etc., through the inquiry form. Additionally, we use cookies to enhance our website. Cookies are classified as “Information related to personal information” according to Japanese regulation, but they are considered as “Personal Information” in GDPR. Thus, if the website is targeting European customers, compliance with GDPR is necessary even though the website collects only cookies from users. As a side note, in GDPR itself, cookies are only briefly mentioned in Recital 30 . For details, they are more concretely and comprehensively regulated in the ePrivacy Directive (EPD) , also known as the cookie law. Well, what should we do to collect cookies? Here are the specific tasks: Receive users’ consent before you use any cookies except strictly necessary cookies. Provide accurate and specific information about the data each cookie tracks and its purpose in plain language before consent is received. Document and store consent received from users. Allow users to access your service even if they refuse to allow the use of certain cookies Make it as easy for users to withdraw their consent as it was for them to give their consent in the first place. Cookies, the GDPR, and the ePrivacy Directive - GDPR.eu GDPR requires establishing a Privacy Policy and other measures, but the tasks mentioned above are additionally requested to collect cookies. I guess you’ve all seen various websites with pop-ups or banners regarding cookie collection (Cookie consent pop-up). THAT is mainly what it is. Cookie Types 🍪 Cookies can be classified as 4 categories by its purpose. Category Contents Strictly necessary cookies These cookies are necessary for the website to function properly. For example, these cookies may store items in the cart of an e-commerce site or maintain language settings. Disabling these cookies may result in the website not functioning properly. Consent from the users is not required. Also, they do not store information that can identify individuals. Functionality cookies These cookies are used to personalize the experience by remembering choices users have made in the past. For example, these cookies determine which area's weather news should be shown or what the user's name is, etc. They are also known as “Preferences Cookies” Information that can identify individuals is not stored. Performance cookies These cookies are used to improve websites. They collect information about how a user uses a website such as pages visited, links clicked and so on. All data is anonymized, and information that can identify individuals is not stored. They are also known as “Statics Cookies” Targeting cookies These cookies track user’s online activity and show personalized ads based on their interests. This information might be shared with other organizations or advertisers to measure the performance of ads. Targeting cookies are also known as “Advertising Cookies” since they are mainly used for advertising. Global KINTO Web collects “strictly necessary cookies” and “performance cookies” from the above categories. As mentioned in above, since strictly necessary cookies are mandatory for the proper functioning of the system, such as keeping language settings or items in an e-commerce site’s cart, user’s consent is not required. However, we had to implement a mechanism to acquire consent and withdraw consent easily in order to collect performance cookies. Issues on Cookie Consent Pop-up While we consider the implementation of the cookie consent pop-up, we have faced one issue: the sample size of user data might be significantly reduced compared to what we currently could. That’s because there are many users who reject the collection of cookies feeling anxious to provide this mysterious data called cookies. There may be some readers among you who find it annoying and click on "just reject for now!🙅‍♀️" as they are repeatedly displayed on the screen, don't you think? Thus, we will deep-dive on the need of this cookie consent pop-up. As mentioned earlier, the pop-up is necessary to comply with the European GDPR. However, according to the interpretation of Japanese regulations (such as the Personal Information Protection Act and the Cookie regulations based on the Telecommunications Business Act), it may not be required in some cases. For our Global KINTO Web case, too, we have judged there is no need to implement it globally, except for Europe. (Of course, with advice from our external lawyer.) Please note that although it’s not required from a legal point of view, a website might display a cookie consent pop-up intentionally as a form to display CSR. We reached this decision by weighing the practical operation against other advantages. For more information regarding the interpretation of Japanese Amendments to the Act on the Protection of Personal Information, you can visit this article from TOPCOURT Law firm which explains it well. Preliminary Study We decided to display the pop-up only for Europe, but we studied how other websites do it, just in case. Luckily for us, there was a team member who traveled back to her home country in Europe! So we asked her to research how other websites display them, given that cookie consent pop-up is not shown in Japan 😎 Let me show you some side by side screenshots below: Website Japan Europe Facebook ![facebook_ja](/assets/blog/authors/M.Mori/20231205/Facebook_ja.png =200x) ![facebook_eu](/assets/blog/authors/M.Mori/20231205/Facebook_eu.png =200x) Google ![google_ja](/assets/blog/authors/M.Mori/20231205/google_ja.png =200x) ![google_eu](/assets/blog/authors/M.Mori/20231205/google_eu.png =200x) Booking.com ![booking.com_jp](/assets/blog/authors/M.Mori/20231205/Booking_ja.png =200x) ![booking.com_eu](/assets/blog/authors/M.Mori/20231205/Booking_eu.png =200x) Toyota Motor ![toyota_ja](/assets/blog/authors/M.Mori/20231205/toyota_ja.png =200x) ![toyota_eu](/assets/blog/authors/M.Mori/20231205/toyota_eu.png =200x) When we accessed websites in the European region, what surprised us was that there were tons of websites showing pop-ups to request consent, no matter the content! Not only were there cookie consent pop-ups, but it also seemed like there were various solutions, such as switching URLs for display through redirects, switching policies, and so on. Consent Acquisition Flow Now, we have confirmed that many websites take special care in Europe when collecting cookies, and also confirmed the fact that we definitely should have a pop-up. This time, based on the advice from our external lawyer, we decided to acquire consent from users in Europe as the below image. How can a user withdraw their consent? They can do it from the [Cookie Preference] button in the Privacy Policy whenever they want. Additionally, we designed it so that consent expires every 6 months. This is for providing users an opportunity to re-consider the privacy setting periodically, and ensure transparency Actual Screen After that, we finally released our new cookie consent pop-up with an updated privacy policy on Nov 1. Different views are shown depending on regions, as follows: Japan Europe A pop-up to notify Privacy Policy update is shown to anyone around the world since it’s required by various countries. Cookie consent pop-up is shown only for Europe. No pop-up or banner is shown after closing the notification pop-up. Users can adjust their consent for Performance Cookies through the “Cookie Preferences”. To Sum It Up As this PII related world including GDPR is so deep and complicated, there are many things that I still don’t know even over 2 years has passed since I was assigned to it. New violations continue to be sentenced, and regulations and guidelines are enacted or revised daily in various countries. Yet, we don’t want to lose usability and limiting the range of actions we can perform. Figuring out this balance is really important 🤔⚖️ The story I’ve shared today is just only an example case supported by external lawyers and it can’t always be applied to other scenarios. For example, to counter the challenge of increased rejection rates like we've faced, designing a UI/UX which makes the pop-up less likely to be rejected is one possible solution. How to comply with each regulation depends on the website’s purpose, target audience, contents and the situation. And since regulations like this are interpreted differently by different people, we can’t completely say "it is absolutely safe if you do it this way!”. The Global KINTO Web should be updated continuously, according to the varying situation of countries where it’s present. If you see a cookie consent pop-up on our website, it would be great if you think “Ah, they are trying to comply with each regulation properly👍”. Thank you for reading this long article, see you next time at my 11th blog🙋‍♀️ Reference Cookies, the GDPR, and the ePrivacy Directive - GDPR.eu クッキーは個人情報?規制の対象となるクッキーについて | BizRis Cookie(クッキー)同意ポップアップの実装率と設置場所 Global Reach - グローバル展開する企業を支援 Cookie types
アバター
自己紹介・記事要約 こんにちは。KINTOテクノロジーズの共通サービス開発グループ[^1][^2][^3][^4]で会員管理のエンジニアを担当している宮下です。 今日は、私たちの開発現場で直面したS3互換のローカルストレージ環境構築の課題をどのように解決したかをお話しします。 具体的には、オープンソースの MinIO を活用してAWS S3の機能をエミュレートする方法について、実践的なアプローチを共有します。 この記事が、同様の課題に直面しているエンジニアの方々にとって、参考になれば幸いです。 MinIOとは? MinIOはS3互換機能を備えたオープンソースのオブジェクトストレージサーバーツールです。NASのように、ファイルをアップロードやダウンロードすることができます。 この分野には LocalStack という似たようなサービスもあります。LocalStackはAWSのエミュレーションに特化し、S3をはじめとするLambda, SQS, DynamoDBなどのサービスをローカルでエミュレートできるツールです。 これらは目的が異なる2つのツールですが、ローカル環境でのS3互換環境を設定するための要件はどちらも満たしています。 MinIO website LocalStack website MinIO と LocalStack で ツール選定 開発の要件 開発の要件として、docker-composeを実行するだけで、自動で任意のS3バケットを作成し、そのバケットにメールテンプレートやCSVファイルなどが登録されていることが必要でした。 コンテナが起動してからコマンドやGUIでファイル登録するのは面倒くさいですからね。 また、自動化されたローカルでのS3接続テストを行う際も、コンテナが起動すると同時にバケットとファイルが準備済みでなければなりません。 ツールの比較 どちらのツールが簡単に要件を実現できるか比較した結果、LocalStackはaws-cliでバケット作成やファイル操作をするのに対し、MinIOは専用のコマンドラインツールであるmc(MinIO Client)を提供しています。これにより、より簡単にシステムの構築が可能でした。 さらに、GUIによる管理コンソールにおいても、MinIOの方が洗練されていると感じました。Google Trendsでの比較では、MinIOがより人気があることが分かります。これらの理由から、MinIOを採用する事に決定しました。 composeファイル MinIOのローカル環境をセットアップするために、最初に「compose.yaml」ファイルを用意する必要があります。 以下のステップに従って進めましょう。 任意のディレクトリを作成します。 そのディレクトリ内にファイル名「compose.yaml」のテキストファイルを作成します。 下記のcompose.yamlの内容をコピペして保存します。 ※docker-compose.ymlは非推奨になりました。 composeファイルの仕様はこちら ※docker-compose.ymlでも後方互換性機能で動作します。 詳細はこちら services: # MinIOサーバーコンテナの設定 minio: container_name: minio_test image: minio/minio:latest # MinIOサーバーを開始し、管理コンソール(GUI)のアクセスポートを指定 command: ['server', '/data', '--console-address', ':9001'] ports: - "9000:9000" # APIアクセス用 - "9001:9001" # 管理コンソール(GUI)用 # USERとPASSWORDを省略する事も可能です。 # その場合は minioadmin | minioadmin に自動で設定されます。 environment: - "MINIO_ROOT_USER=minio" - "MINIO_ROOT_PASSWORD=minio123" # minioが管理する設定ファイルや、アップロードしたファイルを # ローカルで参照したい場合や、登録したファイルを永続化したい場合は # ローカルのディレクトリをマウントします。 # volumes: # - ./minio/data:/data # PC再起動後にminioコンテナが自動で起動してほしい場合など # 停止していたら自動で起動していてほしい場合は有効化します。 # restart: unless-stopped # MinIOクライアント(mc)コンテナの設定 mc: image: minio/mc:latest container_name: mc_test depends_on: - minio environment: - "MINIO_ROOT_USER=minio" # 上と同じユーザー名 - "MINIO_ROOT_PASSWORD=minio123" # 上と同じパスワード # mcコマンドでバケット作成と、作成したバケットにファイルを配置します。 # まずは aliasを設定して、それ以降のコマンドで簡単にminio本体を # 指定できるようにします。 # 今回は myminio というエイリアス名にしました。 # mbは、バケットの新規作成を行う。make bucketの略 # cpは、ローカルのファイルをminioにコピーします。 entrypoint: > /bin/sh -c " mc alias set myminio http://minio:9000 minio minio123; mc mb myminio/mail-template; mc mb myminio/image; mc mb myminio/csv; mc cp init_data/mail-template/* myminio/mail-template/; mc cp init_data/image/* myminio/image/; mc cp init_data/csv/* myminio/csv/; " # minioにアップロードしたいファイルが入っているディレクトリをマウントします。 volumes: - ./myData/init_data:/init_data ディレクトリとファイル構成 適当なダミーファイルを作成し、以下のディレクトリとファイル構成で起動してみます。 minio_test# tree . . ├── compose.yaml └── myData └── init_data ├── csv │   └── example.csv ├── image │   ├── slide_01.jpg │   └── slide_04.jpg └── mail-template └── mail.vm 起動と動作確認 MinIOとそのクライアントをDocker上で稼働させて、その後の動作を確認する流れを紹介します。 Dockerコンテナは、以下のコマンドでバックグラウンドで起動させます(-d フラグを使用)。 Docker Desktop(for Windows)をインストールした場合は、コマンドプロンプトや PowerShellといったコマンドラインで、コンテナの作成が可能です。 ※ Docker Desktopのダウンロードはこちら docker compose up -d ※docker-compose の真ん中のハイフンは付けなくなりました。 詳細はこちら Docker Desktop Docker Desktopを開いて、コンテナの状態をチェックします。 minio_test コンテナは起動していますが、mc_test コンテナが停止していることが確認できます。 mc_test コンテナの実行ログを確認してみましょう。 mcの実行ログ MinIOクライアント(mc)が実行され、すべてのコマンドが正常に終了したことがログから分かります。 管理コンソール 次に、MinIOのGUI管理コンソールを見てみます。ブラウザで localhost の 9001 ポートにアクセスします。 http://127.0.0.1:9001 ログイン画面が表示されたら、compose.yaml で設定したユーザー名とパスワード (この例では minio と minio123)を入力します。 バケット一覧 左側のメニューから「Object Browser」を選択すると、 作成したバケットとそこに保存されているファイルの数が一覧で表示されます。 ファイル一覧 例として「image」バケットを選んで中を見てみます。 予めアップロードされているファイルが見えます。 ファイルの隣にあるアクションメニューから「プレビュー」を選ぶと、ファイルを直接確認できます。 ファイルプレビュー機能 弊社のマスコットキャラクター 謎の生き物K がプレビューされました。 MinIOの管理コンソールで画像を直接プレビューできる機能は非常に便利です。 mc(MinIO Client)のインストール GUIよりコマンドラインを使った方が、大量のファイル操作が効率的な場合があります。 また、開発時にソースコードからMinIOにアクセスしてエラーが出たとき、 ファイルパスの確認を行うにはコマンドラインが非常に便利です。 ここでは、MinIOクライアントのインストール方法と基本的な操作を説明します。 ※GUIの管理コンソールで必要十分という方はこのセクションをスキップしてください。 # 以下のコマンドを使用して、mcをダウンロードしてください。実行ファイルは任意のディレクトリに保存されます。 minio_test/mc# curl https://dl.min.io/client/mc/release/linux-amd64/mc \ --create-dirs \ -o ./minio-binaries/mc # 動作確認 # インストールしたmcが最新版か確認し、バージョンを表示させて正しくインストールされたかをチェックします。 # mcコマンドをPathに通すかはお好みで。今回は通さずにいきます。 minio_test/mc# ./minio-binaries/mc update > You are already running the most recent version of ‘mc’. minio_test/mc# ./minio-binaries/mc -version > mc version RELEASE.2023-10-30T18-43-32Z (commit-id=9f2fb2b6a9f86684cbea0628c5926dafcff7de28) > Runtime: go1.21.3 linux/amd64 > Copyright (c) 2015-2023 MinIO, Inc. > License GNU AGPLv3 <https://www.gnu.org/licenses/agpl-3.0.html> # エイリアスの設定 # MinIOサーバへのアクセスに必要なエイリアスを設定します。 minio_test/mc# ./minio-binaries/mc alias set myminio http://localhost:9000 minio minio123; > Added `myminio` successfully. # ファイル操作の例 # バケット内のファイル一覧を表示 minio_test/mc# ./minio-binaries/mc ls myminio/image > [2023-11-07 21:18:54 JST] 11KiB STANDARD slide_01.jpg > [2023-11-07 21:18:54 JST] 18KiB STANDARD slide_04.jpg minio_test/mc# ./minio-binaries/mc ls myminio/csv > [2023-11-07 21:18:54 JST] 71B STANDARD example.csv # ファイルの中身を画面出力 minio_test/mc# ./minio-binaries/mc cat myminio/csv/example.csv > name,age,job > tanaka,30,engineer > suzuki,25,designer > satou,,40,manager # ファイルの一括アップロード minio_test/mc# ./minio-binaries/mc cp ../myData/init_data/image/* myminio/image/; > ...t_data/image/slide_04.jpg: 28.62 KiB / 28.62 KiB # ファイルの削除 minio_test/mc# ./minio-binaries/mc ls myminio/mail-template > [2023-11-15 11:46:25 JST] 340B STANDARD mail.txt minio_test/mc# ./minio-binaries/mc rm myminio/mail-template/mail.txt > Removed `myminio/mail-template/mail.txt`. mcコマンド一覧 MinIOクライアントに関する詳細なドキュメントが必要な場合は、公式マニュアルをご覧ください。 MinIO Client 公式マニュアルはこちら 最後にJavaのソースコードからアクセス ローカルでMinIOを使ってS3互換の開発環境を構築した後、実際のJavaアプリケーションからMinIOにアクセスする方法を紹介します。 まず、Gradleの設定を行います。 plugins { id 'java' } java { sourceCompatibility = '17' } repositories { mavenCentral() } dependencies { // https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-s3 implementation 'com.amazonaws:aws-java-sdk-s3:1.12.582' } 次に、MinIOにアクセスするためのJavaクラスを作成します。 package com.example.miniotest; import com.amazonaws.ClientConfiguration; import com.amazonaws.auth.AWSStaticCredentialsProvider; import com.amazonaws.auth.BasicAWSCredentials; import com.amazonaws.auth.EC2ContainerCredentialsProviderWrapper; import com.amazonaws.client.builder.AwsClientBuilder; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.AmazonS3ClientBuilder; import com.amazonaws.services.s3.model.GetObjectRequest; import com.amazonaws.services.s3.model.S3Object; import com.amazonaws.services.s3.model.S3ObjectSummary; import com.amazonaws.services.s3.model.ListObjectsV2Result; import com.amazonaws.regions.Regions; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.List; public class Main { public static void main(String... args) { new Main().execute(); } /** * MinIOのS3互換性テスト * バケット内のファイル一覧を取得し、内容を表示する */ private void execute() { System.out.println("--- Start ---"); // ローカルのMinIOに接続する場合と、 // AWS S3に接続する場合で切り替える。 // spring bootのプロファイルで切り替える事を想定。 boolean isLocal = true; // MinIOはAWS S3と互換性があるので // AWSのライブラリから接続する事ができる。 AmazonS3 s3Client = null; if (isLocal) { s3Client = getAmazonS3ClientForLocal(); } else { s3Client = getAmazonS3ClientForAwsS3(); } // バケット名 final String bucketName = "csv"; // バケット内のすべてのオブジェクトをリストする ListObjectsV2Result result = s3Client.listObjectsV2(bucketName); List<S3ObjectSummary> objects = result.getObjectSummaries(); // 取得できたファイル名の数だけループする for (S3ObjectSummary os : objects) { System.out.println("バケットから取得したファイル名 : " + os.getKey()); // ストリームでファイルの内容を取得する。 // もちろんファイルをダウンロードする事もできる。 try (S3Object s3object = s3Client.getObject( new GetObjectRequest(bucketName, os.getKey())); BufferedReader reader = new BufferedReader( new InputStreamReader(s3object.getObjectContent()))) { String line; while ((line = reader.readLine()) != null) { // 1行ずつファイルの中身を画面出力 System.out.println(line); } } catch (IOException e) { e.printStackTrace(); } // ファイルの切り替わりで空行を入れておく System.out.println(); } System.out.println("--- End ---"); } /** * ローカルのMinioに接続する場合はこちら * @return AmazonS3インターフェースの実装であるAmazonS3クライアントインスタンス。 */ private AmazonS3 getAmazonS3ClientForLocal() { final String id = "minio"; final String pass = "minio123"; final String endpoint = "http://127.0.0.1:9000"; return AmazonS3ClientBuilder.standard() .withCredentials( new AWSStaticCredentialsProvider( new BasicAWSCredentials(id, pass))) .withEndpointConfiguration( new AwsClientBuilder.EndpointConfiguration( endpoint, Regions.AP_NORTHEAST_1.getName())) .build(); } /** * Amazon S3クライアントを取得し、AWS S3サービスへの接続を設定します。 * このメソッドは、Amazon EC2インスタンス上での実行時にIAMロールを用いて自動的に * 認証情報を取得し、S3との接続を確立します。IAMロールにはS3へのアクセスを許可する * ポリシーが関連付けられている必要があります。 * * クライアントは以下のように構成されます: * - リージョン:Regions.AP_NORTHEAST_1(アジアパシフィック(東京)) * - 最大接続数:500 * - 接続タイムアウト:120秒 * - エラーリトライ回数:最大15回 * * 注意:このメソッドは、EC2インスタンス上で実行されることを想定しています。 * EC2以外で実行する場合は、AWS認証情報を別途提供する必要があります。 * * @return AmazonS3インターフェースの実装であるAmazonS3クライアントインスタンス。 * @see com.amazonaws.auth.EC2ContainerCredentialsProviderWrapper * @see com.amazonaws.services.s3.AmazonS3 * @see com.amazonaws.services.s3.AmazonS3ClientBuilder * @see com.amazonaws.regions.Regions */ private AmazonS3 getAmazonS3ClientForAwsS3() { return AmazonS3ClientBuilder.standard() .withCredentials(new EC2ContainerCredentialsProviderWrapper()) .withRegion(Regions.AP_NORTHEAST_1) .withClientConfiguration( new ClientConfiguration() .withMaxConnections(500) .withConnectionTimeout(120 * 1000) .withMaxErrorRetry(15)) .build(); } } 実行結果 --- Start --- バケットから取得したファイル名 : example.csv name,age,job tanaka,30,engineer suzuki,25,designer satou,40,manager --- End --- ソースコード解説 このコードの注目すべき点は、AWS SDK for JavaがMinIOとAWS S3の両方に対応していることです。 ローカルのMinIOインスタンスに接続する際にはgetAmazonS3ClientForLocalメソッドを、 AWS S3に接続する場合にはgetAmazonS3ClientForAwsS3メソッドを使用してクライアントを初期化します。 このアプローチにより、異なるバックエンド環境間で同一のSDKを利用することが可能となり、 同じインターフェースでの操作を実現します。 このように、追加コストをかけずに実際のAWS環境へのデプロイ前に気軽にアプリケーションをテストできるのはいいですよね。 このガイドが何かのお役に立てば幸いです。 最後までお読みいただき、ありがとうございました🙇‍♂ [^1]: 共通サービス開発グループメンバーによる投稿 1 [ グローバル展開も視野に入れた決済プラットフォームにドメイン駆動設計(DDD)を取り入れた ] [^2]: 共通サービス開発グループメンバーによる投稿 2 [ 入社 1 年未満メンバーだけのチームによる新システム開発をリモートモブプログラミングで成功させた話 ] [^3]: 共通サービス開発グループメンバーによる投稿 3 [ JIRA と GitHub Actions を活用した複数環境へのデプロイトレーサビリティ向上の取り組み ] [^4]: 共通サービス開発グループメンバーによる投稿 4 [ VSCode Dev Container を使った開発環境構築 ]
アバター
こんにちは!👋 KINTOテクノロジーズのグローバルプロダクト開発グループでUI/UXチームに所属しているAz, Moji, Aiです。今日はUI/UXデザインの中でダイバーシティ(diversity/多様性)とインクルーシビティ(inclusivity/包括性)の奥深い世界についてお話します! デザインにとってダイバーシティとインクルーシビティとは? Nielson Norman Group によると、インクルーシブデザインとは人種や障がいなど、多様なバックグラウンドやアビリティを持つ人々を理解した上で、それぞれが利用しやすいプロダクトを創る手法です。 では、インクルーシブデザインの具体的な例を挙げてみましょう。わかりやすい例は建築に見られます。車いす用のスロープ、点字や自転車用のレーンなど、全ての人にとって快適な空間を創ることが重要です。 日常生活におけるインクルーシブデザインの例 UI/UXデザインにおける例 インクルーシブデザインについて、なんとなくご理解いただけましたでしょうか?次は、UI/UXデザインにおける具体例を見ていきましょう。 (左から右へ) 代替テキスト, キーボードナビゲーション, Appleのアクセシビリティ HTMLやCSSに詳しい方であれば、画像の代替テキスト(alt属性)の目的について疑問に思ったことはありませんか?これは単に画像が読み込めなかったときのフォールバックだけではありません。視覚障がい者の方など、スクリーンリーダーを使ってサイト閲覧する方に画像の説明を提供するためのキーにもなります。 キーボードだけを使ってサイトをナビゲートできるようにすることも重要です。キーボードアクセシビリティは、キーボードだけを利用するユーザーの体験を向上させるだけでなく、例えばスクリーンリーダーを利用する方、弱視の方、運動障がいや認知障がいのある方、また、ショートカットや代替キーボードを好む方などにも有益です。 Appleはアクセシビリティをデザインに取り込むことに優れていて、様々な障がいを持つ方々に対応するユーザーインターフェースとエクスペリエンスを提供しています。例えば、読みやすさを向上するためのフォントサイズ調整、単語選択による音声読み上げ、障がいのある方向けに設計された音声コントロールや、その他たくさんのインクルーシブデザインが採用されています。詳しくは Apple公式サイト をご確認ください。 これらの例はUI/UXのインクルーシブデザインにおけるほんの一例です。 Web Content Accessibility Guidelines (WCAG)は、ウェブコンテンツのアクセシビリティを向上させるための原則とテクニックを定義しており、障がいを持つ方々など多方面に配慮されたものとするのに役立ちます。 さて、ここまではインクルーシブデザインの基本部分を説明してきました。 ここからは、当社のメインビジネスであるモビリティプラットフォームでどのように応用しているかについて、Mojiから説明いただきます。 Aiがインクルーシビティの詳細について説明してくれました。ここからは私が「モビリティ」の世界でインクルーシビティをどのように表現するかを深掘りします。 改めまして、 Moji です。世界中のどんな方であっても、お客様が目的の場所へ移動する手助けになるようなデザインを提供することが私の使命です。 私はデザイナーとして、我々の開発するプロダクトやソリューションが、民族、言語、年齢、性別、身体能力、文化的背景を超えた幅広いユーザーに対応できるようにする責任と能力があると考えています。 これを他の企業がどうやって実現しているかをベンチマークすることは、単に興味深いだけでなく、我々の仕事をより良く、テックプロダクトをよりインクルーシブなデザインするためのアイデアにも役立ちます。例えば Googleマップ を例に挙げてみましょう。こちらは移動する際に利用するアプリとして多くの人に日常的に利用されています。 "アクセシブル"な(使いやすい)アプリにするためのGoogleマップの標準 GoogleマップはリアルタイムのGPS情報や交通情報を提供するだけでなく、幅広いオーディエンスを対象にデザインされています。 Googleマップでは、 視覚障がい のある方のために 音声ナビシステム があります。これによって、道を曲がるタイミングや、渋滞、経路を遮る可能性がある場合などを教えてくれます。これにより音によるサポートが必要な方々がより生活しやすくなります。 Googleマップの最新アップデートでは、アプリをよりアクセシブルでインクルーシブにするための機能がいくつか追加されました。 没入型ルート案内の イマーシブビュー は、移動手段が車であっても徒歩であっても自転車であっても、経路をより詳細に表示してくれます。以前に比べてより移動しやすくなりました。 また、Googleマップは世界中で利用されているため、40以上の言語が利用可能です。これによって、アプリは世界中でアクセシブルになるだけでなく、ユーザーの母国語など好きな言語で情報を得られ、ユーザー満足度も向上します。 RTL言語に対応したグローバルアプリ開発における課題 さて、アプリデザインにおける言語と地域性への考慮について話を移します。ここからはチームメイトのAzに執筆いただきます。 グローバルにアクセシブルなアプリにするという基本的な課題に対し、特に彼女はアラビア語のような右から左 (RTL/Right to Left) へ読み書きされる言語をサポートするタスクをリードしてきました。Az、お願いします。 最後にバトンタッチされました。UI/UXチームAzです。 KINTOテクノロジーズでRTL対応をした時に気づいたことがありました。それは… Diversityを進めるためには知らなければいけない 今までに無いものを創造するのではなく「当たり前」に感じることを拾っていくことが大事だからです。 今まで意識していなかった部分や初めて知った部分がありました。 まずRTLとは"Right To Left"で右から左に読み進める言語です。 テキスト方向が変わるため、目線の移動順序も変わります。レイアウトも右から左に並ぶよう変更します。 アイコンとテキストの位置、アクションボタンの方向、バッヂの位置などネストした要素も反転します。 ただし、物理アイテムである「ヘッドセット」、ユニバーサルデザインである「位置情報」のアイコンは反転しません。 表示だけでなく入力もレイアウトの反転が必要になります。 進行方向に合わせてインジケーターの増減の方向も変わります。 フォーム系でも例外があります。 電話番号やクレジット番号などの並びに意味がある数列は反転させてはいけません また テキストでも固有名詞の"KINTO"は反転させません ここではKTCの例を紹介しましたが Apple Human Interface guideline や Google Material design に他の具体例も載っています。 この記事でも気づいた方は多いかもしれませんが、UIUXチームのメンバーは多種多様なバックグラウンドを持っています。 そのため一人では気づかない知識や着眼点、知見を増やしてくれます。 Aiは彼女の持つ建築知識から現実空間との比較でDiversityの必要性を示してくれました。 高いリサーチ能力と知識をもったMojiは馴染みが深いサービスで何が行われているか解説してくれました。 今回は別記事で登場するTimもプロジェクト進行やフロントエンドまで幅広くカバーできる頼れるメンバーです それぞれが持つ「当たり前」を知って積み重ねて、これからも誰もが心地よく使えるサービスを展開していきます。
アバター
はじめに はじめまして、データ分析部-分析G-分析プロデュースT(兼データサイエンスT)の森本和樹と申します。 普段は大阪オフィス勤務で、リテンションProj・与信Proj・中古車部・MyRouteアプリに関連する分析テーマを取り扱っております。 (詳しい業務内容はおって別テックブログに記載予定していきたいな〜と考えております。) さて、今回の記事では"QuickSight Generative BI"のプレビュー版を使ってみた内容を紹介していきたいと思います。 先月TOYOTAグループ向けAWS生成AIワークショップに参加させていただいた時に紹介があり、「これ結構使えんじゃね?」と思い試してみた結果です。 本記事で書く内容 QuickSight Generative BIの概要 Generative BIで ラーメンサブスク の売上ダッシュボード作ってみた 良かった点/今後に期待 本記事で書かない内容 QuickSightの使用方法 QuickSight Qの説明 Generative BI の利用開始方法( こちら がよくまとまっておりました) Amazon QuickSight の Generative BI 機能を発表 Generative BIとは 簡単に言うと、"QuickSight Q"に"Amazon Bedrock"のLLMを適用することでより幅広い機能が追加されたサービスです。 元々"QuickSight Q"という自然言語で質問を投げかけると、その回答をグラフで返してくれる機能がありました。 そこに"Amazon Bedrock"のLLM(大規模言語モデル)を適用することで、より自由度の高い分析を自然言語ベースで行えるようになりました。 Quicksight Q ※QuickSight Qは東京リージョン他多数のリージョンで利用可能。 参考 Generative BIでダッシュボード作ってみた それでは早速Generative BIを試していこうと思います。 今回は「 もしKINTOがラーメンのサブスクを始めたら 」という仮想テーマでダッシュボードを作っていこうと思います。 ※KINTOはモビリティサービスを手掛ける会社ですので、ラーメン事業には手を出さない。。と思います。。 目指す姿 今回はCRISPさんが公開している ダッシュボード の"セールス"セグメントを参考にし、下記2つのダッシュボードを作ることを目標におきます。 売上(年月ごと) 契約プラン構成比 前準備 前準備としてラーメンサブスクのサービス概要とサンプルデータを作成します。 サービス概要 ChatGPTにラーメンサブスクの契約プランを考えてもらいました。 思ったより練られたプランが出てきました。笑 即採用です。 サンプルデータの作成 次に以下のプロンプトでサンプルデータをChatGPTに作成してもらいました。 結果 まじでそれっぽいサンプルデータをCSVで作ってくれました。 実践 では早速先ほどのサンプルデータをQuickSightに読み込ませてグラフを作成していきたいと思います。 今回は社内のsandbox環境でバージニア北部リージョンを用いてお試ししています。 ※ 前述の通り、Generative BI利用開始方法は省略します。 1. 売上(年月ごと)グラフの作成 まずは売上(年月ごと)のグラフを作成していきたいと思います。 Generative BIは英語対応のみ(2023/12/11時点)ですので、英語のプロンプトを作成します。 2023年12月11日時点の月次売上見込みを表示 下記のプロンプトを"Build a visual"に入力。 Cumulative Sum(Yen) in 2023-12 Buildを押すと、約3秒ほどで下記のようなボードが作成されました。 想定通りの出力であることを確認後、"ADD TO ANALYSIS"をクリックし、ビジュアルとして追加しました。 年月ごとの月次売上推移グラフを作成 同様に下記のプロンプトを入力。 Cumulative Sum(Yen) per months こちらもほぼ想定通りのグラフが出力されました。 ビジュアル追加後、グラフの大きさを手動で変更した結果がこちら。 横軸が"MM月DD, YYYY HH/hh"形式となっていて見にくいので、ビジュアル変更を行います。 Generative BIはビジュアルの変更も自然言語で行えるようです。 お気づきかと思いますが、私は英語力が高いわけではないので社内AI-chatBOT(しぇるぱ)にサポートいただきます。 打ち込んでみる。 どうやらまだビジュアル編集機能は不十分な模様。 公式 を確認してもまだできることは少なそうですので手修正します。 今後に期待ですね。 都道府県ごとの月次売上ランキングテーブルの作成 次はテーブル形式のビジュアルの出力に挑戦します。 またまたしぇるぱにサポートいただいて、下記プロンプトを入力。 Please provide the monthly fee sum yen for each prefecture in a ranking format in a table in December 2023 (in3つ続いとるやないかい!) 結果 もー感動ですね。まさに欲しかったテーブルを表示してくれました。 ビジュアルに追加(グラフの大きさ等は手修正しております。) 2. 契約プラン構成比 次に契約プラン構成比を円グラフで表示したいと思います。 例に漏れずしぇるぱに翻訳してもらい下記プロンプトを入力。 total unique number of Contract ID per contract plan in pie 完璧ですね。 ついでにプランごとの月額料金の合計も表示してもらいます。 Total monthly fee for each contract plan in table ダッシュボード表示 作成したグラフをダッシュボード化して確認してみます。 折れ線グラフの時系列フォーマット以外は全てGenerative BIに作成していただきました。 結構いい感じではないでしょうか!? Exective summary ダッシュボードの内容をもとにサマリーを作成してくれる機能もあるようです。 ダッシュボード画面の右上にある"Build"ボタンから"Executive summary"をクリック。 約10秒ほどでサマリーを作成してくれました。 構成としては、ダッシュボード全体の説明、各グラフの説明となっているようです。非常に簡易的ではありますが、内容も正しそうです。 また、グラフごとの説明にリンクが埋め込まれておりました。大規模なダッシュボードとかだとサマリをクリックすると、リンクされたグラフまで飛ばしてくれるので便利ですね。 良かった点/今後に期待 良かった点 自然言語ベースの命令をすることで即座にグラフを作成してくれる。 簡易的なグラフであれば手作業で作るより早い。 カラム名を明確に指示しなくてもある程度は察してくれる。  →逆に言うと、察してもらうために適切なカラム名をつけておく必要がある。 月次の集計等も自動でおこなってくれる。 Exective Summary は資料の叩き台として使用できる。 今後に期待 グラフの微修正機能がまだ不十分。 ただ、ここは自然言語というより手で行なった方が早そう。 英語対応のみ。(2023/12/11時点) 入力する欄が短く、文章の修正がしにくい。 長い文章を入力した後、思ったグラフが表示されず文章を修正したい場合、少しやりにくかった。。 直近3ヶ月(last 3 months)などの時系列表現を汲み取ってくれない。 さいごに 今回はGenerative BIのパブリックプレビュー版を試してみました。 実業務で使えるかと言われるとまだそのレベルではないですが、今後のアップデート次第ではかなり期待感を持てるサービスだと思いました。 現状の見える化を手軽・高速に行うことができれば、ビジネス改善のサイクルもより早めて行くことができますので、今後が楽しみです。 (本筋とはそれますが、ChatGPTが作ったサンプルデータとイラストの完成度が高くてびっくりしました。) また、分析Gの説明は下記テックブログに記載しておりますので、もしご興味あれば一読ください。 KINTOテクノロジーズ 分析グループを紹介します
アバター
はじめに  こんにちは!QAチームのmmmです。  普段は主にKINTOのWEBシステム関連のQA業務に携わっています。 扱うシステムにはお客様が目にされるフロント領域、販売店様が使用されるバックオフィス領域に加え、社内業務用のシステムが複数あり、これらのシステム間では各種データが連携されています。  最近では「 KINTO Unlimited 」、「 KINTOかんたん申し込み 」などのアプリが増えましたが、新しい機能や要件が追加されると既存システムとの関わりや影響を整理しなければなりません。 そのため、システム単位での仕様はもちろんのことですが、その他にもKINTOのサービスにおける一連の業務を理解し、データの流れを掴む必要があります。  システムや新しい機能要件が増えるたびに整理することが増え、QA観点にも影響するので個人的にはQA業務の中で大事かつ大変な作業と感じています。  そこで今回はテスト設計に焦点を当て、 過去担当した案件で直面した課題から現在開発チームとやりとりする際に意識していることについてお話ししていこうと思います。 よくある課題 同じ機能の仕様が複数の資料に存在する  プロジェクトには様々な開発チームが参加していることもあり、同じ機能に対してそれぞれのチームに資料が存在することがあります。そのため下記のようなことが発生しやすいです。 資料間で内容に差異があり、正しい仕様がわからない 資料間で文言揺れがあり、コミュニケーションにすれ違いが起きる 開発側でも本来考慮すべき仕様が埋もれてしまいバグに繋がってしまう 検討中ステータスの仕様が存在する  資料を読み進めていると「確認中」や「?」など、まだ仕様が確定されていない表現で記載されていることがあります。これらはテスト設計、実施に下記のような影響があります。 テスト設計:仮のテスト観点で進めるため、テストケース数が仮決めになる(増減する可能性がある) テスト実施:未確定範囲のテストは進められない、また、仕様変更が生じた際にはケースの修正作業が発生する 各システムの状態を俯瞰できる資料がない  利用者に見えている実際のフロントエンド領域の状態表示に対して、裏側のバックオフィス領域では細かくステータスを保持していることがあるのですが、そこをぱっと見て分かるような資料が必ずしも存在するとは限りません。  たとえば、ECサイトで商品を購入する際、大体は下記のようにお客様側のステータスよりお店側の方が(実際はおそらくもっと)細かく分かれていたりします。  その両方を俯瞰的に見られる資料がない場合、システム間のデータ連携の観点が必要なため、テスト設計に際しQA側で整理する必要があります。 計算系の仕様がコードで記載されている  金額や日数計算が必要なテストがある場合、開発仕様を確認しますがコードでそのまま記載されていることがあります。この場合下記のような影響があります。 読み解くことに時間を要する テスト実施までに第三者が見て分かるように仕様をまとめておかないとQA作業が属人化してしまう 開発チームとのコミュニケーションで意識していること プロジェクトの概要を把握する  前述で挙げた課題はプロジェクトの性質上避けられないこともあるため、 まずはプロジェクトの発足の背景などを聞き、QA側でもその目的や経緯などを理解することで仕様理解の促進にも繋がり、仕様に対して過不足がないかどうかなどの疑問を持てるようになると考えています。 一通りのシナリオオペレーションの説明をお願いする  各システムの仕様書があるので資料に書いてあることは読めばわかる…という話ではありますが、 システムを理解している開発側から直接説明を受けることで下記のようなメリットがあります。 (一通り仕様を認識し、俯瞰できる資料はQA側の理解用に自作することが多いです。) 想定アクター/ユーザーの操作がわかりやすい データの流れのイメージがしやすい タイムリーに質問ができ、理解促進になる 資料の棲み分けを確認する  この機能要件や画面デザインに対して正しい仕様が記載されている資料はどれなのか、ほかにも資料が存在するが古いメモ程度のものなのか、こちらでは判断できないので単純に確認していきます。  各開発チームが担当している領域の内容が最新で正になることが多く、都度質問することが多いので開発側の負担も考えクローズドクエスチョンを意識して質問しています。 <例> 「●●の仕様については、資料Aが正しい認識でよろしいでしょうか? 資料Bにも同様の内容が記載されていましたが少し内容が異なるため確認させてください。」 制約事項を確認する  QA作業する上で現状わかっている制約事項がある場合、事前に共有をお願いすることでQA側の対応も検討しやすくなります。 計算系などの複雑な仕様は別途説明会をお願いする  様々な価格やプランが存在するため、その分計算式も複数存在します。 似たような計算式でも持ってくる値が微妙に違うこともあり、間違いを事前に防ぐため開発担当者の説明を求める上で下記を明確にすることを意識しています。 そもそもの金額の意味 計算式に使う値の意味や参照する場所 日数の数え方 テストする上で気をつけることがあるか 計算用ツールの存在  計算系はテスト実施の効率を考え計算用ツールをQA側で自作することが多いため、開発担当者と都度認識合わせを行いながら仕様をまとめ最終的にツールに反映しています。  また、今回計算系をあげましたが、理解が難しいと感じた仕様は素直に開発担当者に直接聞きに行くことが多いです。 おわりに  今回執筆依頼があった際に内容に悩んでいると、本ブログ担当も兼務している開発チームの方から「QA依頼時にQAチームがどんな情報を欲しがっているのか分かると助かる」といった旨の言葉をいただきました。  この内容にはあまり沿ってはいないですが、まずはQA業務のとっかかりであるテスト設計での課題に対する情報を発信することで、テスト以外のQA業務への認知に少しでも役に立つと良いなと思い執筆いたしました。  また、今回述べた課題に対する対応は現在すでに開発チームから配慮いただいているところもあり、QA立ち上げ当初と比較すると随分整理された作業環境になっていると実感しています。  ただ資料だけでは見えない情報を整理するのもQA業務の一つと考えているので、仕様を読むだけでなく他仕様への影響などを模索し整理する作業は引き続き頑張っていきたいと思っています。
アバター
Hello (good evening), this is part 2 of the irregular Svelte series. Click here for the previous articles What I learned from using SvelteKit and Svelte for a year *SvelteKit major release supported Comparison of Svelte and other JS frameworks - Irregular Svelte series-01 Svelte unit test - Irregular Svelte series-02 Today, I will write about Svelte unit tests. You can get the module here. We will use three Vitest + jsdom + @testing-library/svelte . Vitest This is a testing framework that uses a tool called vite. It works very fast because it uses vite. https://vitest.dev/ jsdom This is a library that uses the DOM in Node.js. You can parse HTML and call web APIs. https://github.com/jsdom/jsdom @testing-library This is a test library that supports various frameworks. It supports Svelte, React, and Vue. https://testing-library.com/docs/svelte-testing-library/intro/ Environment settings First, add the modules below. *You can use whatever package manager you want. Here, I will use yarn. yarn add vitest jsdom @testing-library/svelte @types/jest *Since we will use TS (TypeScript), add @types/jest , because we also want to add types to the test file. Of course, it is not necessary if it is written in TS. config Next, add a description for the test to vite.config.js. import { sveltekit } from '@sveltejs/kit/vite'; /** @type {import('vite').UserConfig} */ const config = { plugins: [sveltekit()], // Add the following from here test: { // Target file for test include: ['src/**/*.{test,spec}.{js,ts}'], globals: true, // test environment environment: 'jsdom' } }; export default config; jsdom is configured in environment . package.json Add the following to package.json. You can run it with yarn vitest without writing. "test": "vitest" You are now ready to test. Let's test it out I'm going to write a test with a component that has a common add and subtract button. Component side First, prepare the components you want to test. <script lang="ts"> let count:number = 0; </script> <! -- Subtract button --> <button on:click={() => (count -= 1)} aria-label="Subtract">-</button> <! -- defined count variable --> {count} <! -- Add button --> <button on:click={() => (count += 1)} aria-label="Add">+</button> Since it is necessary to read addition and subtraction respectively in testing-library, for this article,we set aria-label. The components are created. The following simple components are drawn on the screen. Press the plus button to add, and the minus button to subtract. Complete figure Test Now we are going to move to the unit test file. Depending on the number of components and personal preferences, I prefer to place them in the same hierarchy without having to move my gaze or the cursor back and forth. import { render, fireEvent, screen } from '@testing-library/svelte'; // $lib is an src/lib alias import Counter from '$lib/components/Counter.svelte'; describe('Counter.svelte', async () => {  // Initial value test('Initial counter value is 0', async () => { render(Counter); expect(screen.getByText('0')).toBeTruthy(); }); test('Subtraction process', async () => { render(Counter); // define the button const decreaseButton = screen.getByLabelText('Subtract'); // define the event await fireEvent.click(decreaseButton); const counter = await screen.findByText('-1'); expect(counter).toBeTruthy(); }); test('Addition process', async () => { render(Counter); const increaseButton = screen.getByLabelText('Add'); await fireEvent.click(increaseButton); const counter = await screen.findByText('1'); expect(counter).toBeTruthy(); }); }); Now, the test is ready. Let's break it down by test unit. test('Initial counter value is 0', async () => { render(Counter); expect(screen.getByText('0')).toBeTruthy(); }); Considering the test item Initial counter value is 0 , we first render the Counter component which is called by import Counter from '$lib/components/Counter.svelte'; . Then, we run a matcher called toBeTruthy to judge whether or not the Counter component has an initial value of 0. Basically, a matcher is a function used to evaluate tests. See the Jest official website for more details. Jest Next, about testing the subtraction process. Both the addition process and subtraction process have the same logic, so I will only explain the subtraction process. test('Subtraction process', async () => { render(Counter); // define the button const decreaseButton = screen.getByLabelText('Subtract'); // define the event with fireEvent await fireEvent.click(decreaseButton); // const counter = await screen.findByText('-1'); expect(counter).toBeTruthy(); }); The Subtraction process test is done as follows. Draw the component Define the button in the component Set click event Verify that the value decreased by 1 testing-library and async/await make testing easy, are easy to understand, and are highly compatible with Svelte. The addition process test is the same except for the value of findByText , so I will skip it. Let's run it Do the yarn test When it passes like this, a green message saying that it passed is output to the console. Let's see what happens if it fails the test. <script lang="ts"> // 0 => 1 let count:number = 1; </script> <! -- Subtract button --> <button on:click={() => (count -= 1)} aria-label="Subtract">-</button> <! -- defined count variable --> {count} <! -- Add button --> <button on:click={() => (count += 1)} aria-label="Add">+</button> In the test file, the initial value is assumed to be 0 , so if the value 1 is set, there will be an error. If there is a mistake, an error is also output as follows. Also, the details of the error are as follows. There is an error message such as, "The counter component is expected to have an initial value of 0." It's simple. You have completed the unit test. It is useful since both the configuration file and the test execution file require less description. That is all for Svelte unit tests. Next time, I will talk about Storybook with SvelteKit . Look forward to next time!
アバター
Introduction Mabuhay! It has been almost a year since my last blog, and I'm still Mary the merry of the Global Development Group at KINTO Technologies. (BTW, feel free to check out my first blog here ). Well, what has changed since last year? I can say that there are times when am fully occupied with tasks I have to accomplish, and wish to have a personal assistant. I believe they can help us track our tasks which are deemed essential but may be too time-consuming if we do it ourselves. If we are lucky to have one, it will allow us to be able to keep our focus on other bigger things that have to be done as well. This thing about personal assistant is similar to frontend’s state management. It keeps track of the changes we make or actions we take and ensures that our application is running properly as expected. State is the information that we need to drive our app, and we have to manage it throughout our application development. Unveiling the Power of State Management 💪 In one of KINTO’s back office systems, the user is allowed to download multiple data across the website. Initially, one download would only take a second or two until it finishes. However, as time went by, the data grew larger and larger until it came to a point wherein the download was already taking several seconds to a couple of minutes. At this point, nothing is being displayed during the progress and this confused the user as to what happened after he clicked the download button. To get rid of the confusion, we have decided to display a download notification component that will show the download status together with how many downloads are still in the queue. ![Download Component](/assets/blog/authors/hundanmz/downloadComponent.png =370x) State management was introduced to me during this project, and I was able to see for myself how powerful it is in front-end development. Responsive User Interface - The website contains several pages with download buttons and every time the user clicks a button, we update our download count icon and show the users how many downloads are in progress. Accuracy - The display inside the download notification component relies on the website’s download buttons. Since the state is the source of truth and we update it every time the user clicks the download button, we are able to make sure that what we show to the user is accurate. Easy debugging - The state is stored in a single location, and it allows us to debug faster. Maintenance - Reusable codes can be created in state management, and it makes our code readable and easy to maintain. Choosing Pinia over VueX ![Pinia VueX Logo](/assets/blog/authors/hundanmz/piniaVueXLogo.png =150x) As I have only become aware of state management during this project, my colleagues introduced me to Pinia and VueX. Both of these are state management libraries for Vue.js, and I am free to choose which one to use. After some time researching these 2 libraries, I have decided to use Pinia over VueX mainly due to these reasons: Modular by Design - Pinia allows us to create multiple stores and import only to components where they are needed; while VueX provides us with only one store. Although I only needed one store meant for download in this project, this doesn’t mean that this will be all that we need in the future. It will be easier to manage if in cases we need to add a different module sooner or later. Simpler API - The simple API allowed me to get started easily with state management. States can be directly updated in actions, and mutations have been removed. Official State Management Library for Vue - This is my top reason as to why I chose Pinia over VueX. Pinia is the official state management library for Vue right now. Although VueX can still be used, it is already in maintenance mode, and will no longer have new features. Exploring Alternatives to State Management Libraries If in case we decide not to use any state management libraries, there are other possible ways for us to manage the state and we have to evaluate which of these solutions fit our needs. Listed below are some of the solutions: Props and events - If we need parent-child communication, this one should be our top choice. A parent can pass the data down to its child; while a child can emit events and communicate changes back to the parent. Local Storage/Session Storage - If there is data we want to persist, we can use the browser’s local storage/session storage.  This is ideal for scenarios such as saving user preferences. Event Bus - If there are unrelated components wherein we need to facilitate communication, we can use an event bus. While this approach is discouraged, we can use it in simple scenarios. Conclusion State management plays an important role in frontend development. While our application grows bigger, chances are there will be more and more states we need to manage. Pinia is a friendly state management library and is easy to understand for a junior developer like me. Although nothing technical is discussed here in-depth, I also encountered some issues when using Pinia. How about we meet again in my next blog? 😊 References Pinia What is Vuex? | Vuex The Power of State: A Deep Dive into State Management State Management in Frontend Development: An Overview and Case Study Advantages of Pinia vs Vuex Vue.js State Management: Pinia vs. Vuex Vue.js Events API | Vue 3 Migration Guide
アバター
はじめに QAグループのokapiです。 前回の記事では「 QA業務の認知度向上 」というタイトルで、 QAが案件に参画してどのようにQA作業を行っているかを記載しました。 今回は、私が最近ネイティブアプリの案件を多く担当していることもあり、 「ネイティブアプリのQA業務の特徴」について書きたいと思います。 ネイティブアプリのQA業務について 基本的なQAの設計では、テスト範囲(テスト対象/対象外)を明確にしたテスト観点を作成し、 その観点に基づいてテストケース(前提条件・手順・期待値)を作成していきます。 しかし、ネイティブアプリの設計では上記に加え ・iOSとAndroid ・テスト対象のOSバージョンとスマートフォン端末 ・ネイティブアプリの機能 を考慮する必要があるため、機能がそれほど複雑ではないネイティブアプリでも 「テストの規模が大きくなりがちな特徴」があります。 項目 特徴 iOSとAndroid ・iOSはApple社が開発したOS ・AndroidはGoogle社が開発したOS であり、開発環境が異なるため、テストの分量も単純に倍の計算になります。 テスト対象のOSバージョンとスマートフォン端末 一般に発売されているスマートフォン端末は種類が多く、 それらすべてとOSバージョンの組み合わせを網羅したテストは現実的に不可能 ネイティブアプリの機能 携帯端末独自の機能やスペックがアプリの機能に影響するため、 それらの特性をふまえた上で、インストールされたネイティブアプリの動作を確認する必要がある ・Push通知  ーアプリがユーザにお知らせを送る機能 ・タッチスクリーン  ー画面上の領域をタッチすることで操作する機能 ・パーミッション  ーアプリが端末にアクセスする時にユーザに許可・許可しないのポップアップを表示する機能 iOSとAndroid iOSとAndroidのOSが異なるため、「テストの分量も倍」となるので、 工数を抑えたいところです。 しかし、開発チームもiOSとAndroidとBFFで分かれていることもあり、 iOSで不具合がなくても、Androidで不具合が発生する Androidで不具合がなくても、iOSで不具合が発生する APIで不具合があり、Android, iOS両方でテストが必要となる これらのパターンが各機能で発生する可能性があります。 そのため、iOSで確認済みだからAndroidでは省略、(あるいはその逆)というような進め方をすると 「品質に影響する不具合」が残存する恐れがあるため、どちらのOSでも基本実施する方針で進めています。 テスト対象のOSバージョンとスマートフォン端末 OSと端末の「全ての組み合わせのテストは不可能」であるため、 対象アプリの推奨環境(例:iOS15.0以上/Android9以上)を確認した上で、 各OSのシェア率を考慮して、メインで検証する「OS」を決定します。 そして、 メインOS  :全テスト実施 メインOS以外:表示確認+OS関連の不具合が発生した箇所 と割り当てます。 「端末」に関しては、端末依存の不具合は稀で、発生しても致命的な事象とはなりづらいので、 基本的に上記のOSに準拠した端末でテストを実施しています。 ただ例外もあり、 カメラ起動を伴う機能テストは、上記OSと端末の割り当てルールとは異なり、 持っている全ての種類の端末でテストを行います。 理由としては、これまでのネイティブアプリのQAで初回のテスト時に、いずれかの端末でカメラ起動時にアプリがクラッシュする、という不具合が割と高頻度で発生していたからです。 ネイティブアプリの機能 ネイティブアプリのQAでは、携帯端末の機能をふまえた上で アプリが仕様通りに動作するかを確認する必要があります。 しかし、仕様書には「アプリの仕様」のみ記載されており、 携帯端末側の機能までは言及されていないことが多いです。 そのため、端末の機能がアプリの挙動に影響することで不具合が発生し得るため、 「端末の機能」を理解した上でテスト設計を行うと、ユーザビリティ観点の不具合を検出できます。 項目 アプリの仕様 端末の機能 ユーザビリティ観点の よくある不具合 Push通知 ・Push通知の  -タイミング  -内容  -タップした時の遷移先 ・アプリ内のお知らせの通知バッジの  -表示タイミング  -削除タイミング ・アプリアイコンの通知バッジ  -複数溜まった時の表示  -表示タイミング  -削除タイミング ・状態の変化による仕様  -ログイン/ログアウト  -アプリフォアグラウンド/バックグラウンド/ロック画面 ・複数通知受信時にアプリアイコンの数が通知数に一致しない ・アプリアイコンの通知バッジが  -表示されない  -表示されるタイミングが遅い ・アプリアイコンの通知バッジが  -消えない  -消えるタイミングが遅い ・通知対象でログイン→ログアウトの時に通知が  -受け取れない  -通知押下でエラーとなる ・アプリフォアグラウンドの時に通知が届かない タッチスクリーン ボタンやリンクをタップした時の動作 ・ダブルタップ  -タップを素早く2回行う ・フリック  -指先で左右に弾くスワイプ ・スワイプ  -ゆっくりと左右スライド ・ピンチイン  -二本の指で同時に画面に触れて距離を狭めて縮小 ・ピンチアウト  -二本の指で同時に画面に触れて距離を広めて拡大 ・ダブルタップで  -同じ画面が2重で開く  -登録内容が2重で登録される ・フリック/スワイプ/ピンチイン/ピンチアウトの操作した時に表示崩れが発生 パーミッション ー ・Push通知の許可・許可しない ・位置情報の許可・許可しない ・カメラの許可・許可しない ・Push通知の許可設定が設定と連動しない ・位置情報の許可やカメラを許可でクラッシュ 今後の課題 ネイティブアプリのQA業務では、 「システム要件に沿った仕様」と「アプリ特有の機能」を確認しており、 アプリ開発のQAに本格的に参画していく中で、iOSの審査が厳しいということを知りました。 例えば、 「非ログインでも利用できる」形でないとリジェクトされる GooglePlayのリンクが入っているだけでもリジェクトされる などの内容です。 こういった知見もナレッジに加えていくことで、アドホックテストに観点として組み込んだ上で、 さらなる品質向上につなげていけると考えています。 さいごに 今回は、ネイティブアプリのQA業務の特徴について「テストの規模が大きくなりがち」と紹介しました。 しかし、ネイティブアプリでは、iOS,Android,APIと様々な観点でQAから多くの不具合が起票されるため、改修の対応を行う開発側の負担も高く、 Webアプリと比べて双方のコストが高い傾向にあり、現状では効率性があまり高くないと感じます。 直近で携わったアプリの開発言語はそれぞれAndroidはKotlin、iOSはSwiftでした。 プラットフォームごとのネイティブ開発には、細かなチューニングを行なえる個別最適化といったメリットがあります。 同一のソースコードで開発できるKotlin Multiplatform Mobile(KMM)やFlutterのようなクロスプラットフォームもありますが、端末の制御※など個別のOSに依存する部分は別に学ぶ必要があるなど、デメリットもあります。 ※カメラ、GPS、センサー系等 その点、ネイティブ言語は対応するOSが直接サポートしている言語なので、端末の機能の活用性に対しては自由度が高くなります。 今後は開発エンジニアの指向やアプリの開発目的も踏まえて、最適な開発手法が取られていくと予想・期待しています。 QAエンジニアの立場からも、開発手法に合わせて柔軟にQAテストの効率を上げていけるよう精進していきたいです。
アバター
Hello (or good evening), let’s start. This is the first part of our irregular Svelte series. Last time , I roughly described the process to get SvelteKit running. (It has been updated to fit SvelteKit's major update, so please read it.) This time, I will compare the characteristics of Svelte, which is based on the concept of " Write less code ," with other JS frameworks. Svelte / React / Vue.js Although React and Vue.js uses virtual DOMs and Svelte does not use DOMs, they are often compared to each other, and we will do that here. *I will use Svelte (v3) / React (v18) / Vue.js (v3). Fetching & looping Fetching and looping are often written in sets, so let’s write them together and compare them. Svelte Let's start with Svelte. Svelte has its own await/block syntax, that can be written neatly. <script> const fetchItems = async function() { const items = await fetch('URL'); return await items.json(); } </script> {#await fetchItems()} <p>Loading</p> {:then items} {#each items as item} <p>{item.name}</p> {/each} {:catch error} <p>{error.message}</p> {/await}   React There are more lines of code compared to Svelte. However, it is usually split up and is almost never left like this. In the beginning, useState is used in the definition. Perhaps this is what is typical of React. function FetchComponent() { const [error, setError] = useState(null) const [isLoaded, setIsLoaded] = useState(false) const [items, setItems] = useState([]) useEffect(() => { fetch('URL') .then(res => res.json()) .then( (result) => { setIsLoaded(true); setItems(result) }, (error) => { setIsLoaded(true); setError(error) } ) }, []) if (!isLoaded) { return <div>Error: {error.message}</div>; } else if (!isLoaded) { return <div>Loading...</div>; } else { return ( <ul> {items.map(item => ( <li key={item.id}> {item.name} </li> ))} </ul> ); } } Vue.js Writing with React feels similar to writing with Vue 3 and 2. <script setup> import { ref } from 'vue' const items = ref(null) const error = ref(null) fetch('URL') .then((res) => res.json()) .then((json) => (items.value = json)) .catch((err) => (error.value = err)) </script> <template> <div v-if="error">{{ error.message }}</div> <div v-else-if="items"> <ul v-for="(item,index) in items"> <li>Number:{{index+1}} Name:{{item.name}}</li> </ul> </div> <div v-else>Loading</div> </template> Reactive This is an essential mechanism in modern frontend applications where components are reused. Svelte In Svelte, preface with $: to make the code reactive. If you do not add $: , it will not be executed even if you change dependent values. If you are used to other frameworks, you may be confused at first, but once you use it, you'll be impressed by how clear it is. $: foo = false React Without getting into details, you generally use useState to define in React. Comparing it to Svelte, useState has the same role as $: . import {useState} from 'react' const [foo] = useState(false) Vue.js When using Vue, it changes when you generate with reactive . <script setup> import { reactive, computed } from 'vue' const state = reactive({ count: 0 }) const increment = () => { state.count++ } </script> About props I will now compare by passing a basic string. They all seemed different, but they have almost the same writing style. Svelte <script> export let name </script> <p>Hello, I'm :{name}</p> <script> import ChildComponent from './ChildComponent.svelte' </script> <ChildComponent name="Svelte" /> React const ChildComponent = (props) => { return <h1>Hello, I'm :{props.name}</h1>; } export default ChildComponent; import ChildComponent from './ChildComponent.jsx' function App() { return ( <ChildComponent name="React" /> ); } export default App Vue.js <template> <p>Hello, I'm {{name}}</p> </template> export default { props: { name: String, } } <script> import ChildComponent from './ChildComponent.vue' </script> <template> <ChildComponent name="Vue" /> </template> Import the child component and pass the value. All of them were easy to understand. General comments This was a short comparison of Svelte, React, and Vue.js. What do you think? Each one has its own merits, Svelte's focusing on " Write less code ." You will notice that it is remarkably accessible. Have a good Svelte life. And if you are new to it, please write with Svelte, it is a very fun framework.
アバター
はじめまして!グローバル開発グループ UXUI チームのモジです。 KINTOテクノロジーズでの私の主な役割はプロダクトデザインで、自分のビジネス知識とデザイン・スキルを融合できる点が気に入っています。私は、使いやすく、美しく、測定可能な結果を生み出すユーザーインターフェースの創造を目指しています。 私の究極の目的は、複雑な問題をシンプルでユーザーフレンドリーな体験に変え、ユーザーが満足できるようにすることです。 TechBlogに初めて記事を書きます! TechBlog 自体のデザイン変更プロセスについてご紹介します。楽しんでいただけると嬉しいです。 取り組み範囲と困難だったこと 昨今のデジタル社会では、変化に適応するために刷新と再開発が常に必要です。 KINTOテクノロジーズ では、TechBlogのデザイン変更を2つのフェーズ段階に分けて実施することを決定し、大きな変化を遂げました。 KINTOデザインシステムに準拠することを大前提として、各フェーズにはユーザーエクスペリエンス向上と機能性向上といった明確な目的を設定しました。 以下の画像は、TechBlogチームと協議した結果、デザインを変更した範囲を示しています。 デザイン変更の範囲 デザイン変更のプロセスでは、入り組んだ迷路を進むように様々な困難が待ち受けていました。 KINTOデザインシステムは、動的で常に進化を続けています。また、ウェブパターンについては、デスクトップビュー用の組み合わせに限られてしまっていました。このような状況においては、 新しい機能をKINTOデザインシステムに合わせる ために、綿密な計画を立て実行する必要があり、これが大きな課題のひとつとなりました。 こういった複雑さに加えて、時間的な制約と、モバイルビューとデスクトップビューという2つのプラットフォームに対してデザイン変更を行う必要性がありました。 以下の画像では、モバイルとデスクトップの両方のビューにおける現デザインの主な問題点を示しています。 モバイルビューの主な問題点 デスクトップビューの主な問題点 第1フェーズ:ユーザビリティとアクセシビリティ重視 デザイン変更プロセスの初めの段階では、主に デスクトップとモバイルの両方 でTechBlogのユーザビリティとアクセシビリティを向上させることに取り組みました。 関連する記事や情報にアクセスしやすくするための重要機能として、 検索バー を導入しました。 読者は、この機能があることで幅広いブログコンテンツをスムーズに検索することができるようになります。 モバイルビューの検索バー デスクトップビューの検索バー このフェーズでのもうひとつの大きな改善ポイントとして、 カテゴリータグ を配置しました。この機能を利用すれば、読者はテクノロジー関連のトピック全体を簡単に分類、把握できます。コンテンツを検索するプロセスが強化され、閲覧体験の向上につながります。 スクロール可能なカルーセル形式のカテゴリータグ カテゴリータグを右サイドバーに配置 このフェーズでの重要なビジュアル変更は、トップページの ブログ記事サイズ の調整でした。 デスクトップとモバイルの両方でこの変更を行いました。これにより、コンテンツの読みやすさと全体的な視覚アピールのバランスが良くなり、ユーザーインターフェースが向上しました。 デスクトップビューでのブログ記事サイズ ビフォーアフター 第2フェーズ:機能性と多言語アクセスの強化 TechBlogデザイン変更の第二フェーズでは、他にも便利な機能が統合され、全体的な機能性とユーザーエクスペリエンスの向上につながりました。 特筆すべきは、 言語切り替え が導入され、英語と日本語両方の読者に対応できるようになったことです。 この機能は、トップ・ナビゲーション・バー(モバイルビュー)のスペースの制約があるため当初は難航したものの、最終的には、読者が簡単に言語オプションを切り替えられるような形で盛り込むことができました。 モバイルビューでの言語切り替え デスクトップビューの言語切り替え このデザイン変更のフェーズでは、記事ページの インデックスの配置 をモバイルビュー用に調整し、長文のブログ内のナビゲーションを効率化しました。 モバイルビューのインデックス配置 さらに、 ソーシャルメディアボタン も配置変更したことで、共有が簡単になり、デスクトップビューでのユーザーエンゲージメント向上に寄与します。 デスクトップビューの共有ボタンの配置 存在しないページや削除されたページにつまずく可能性のあるユーザーを誘導するため、 404ページ も本フェーズの一環としてデザインしました。 また、各記事の末尾には KINTOテクノロジーズの採用セクションへの直接リンク を貼り、技術に精通した読者を優しく誘導し、キャリアの可能性を探ってもらうことができます。 モバイルビュー デスクトップビュー さらにこのフェーズでは、記事を執筆者の名前で検索できる機能を組み込みました。このために 2つのフォーマット をデザインしました: シングルオーサー(単著)フォーマット :複数の執筆者を1つのプロフィールに収容。各ライターの名前をクリックして記事検索が可能。 マルチオーサー(共著)フォーマット :執筆者の名前で記事を整理できるほか、それぞれの専用プロフィールを表示。 2つ目のフォーマットは優先順位が低かったため、開発チームは1つ目のフォーマットでまず進めました。執筆者のプロフィールを合理的なアプローチで表現することでユーザーエクスペリエンスの向上を図ります。 モバイルビュー モバイルビュー デスクトップビュー デスクトップビュー 目的 このデザイン変更の根本的な目的は、ユーザーエクスペリエンスを豊かにすることでした。 検索のしやすさ、関連コンテンツへのアクセスのしやすさ、ユーザーインターフェースの全体的な向上を目指し、微修正・追加・調節をしていきました。 モバイルビューおよびデスクトップビューでのデザイン変更前と変更後 KINTOデザインシステムが重要な役割を果たしました。このシステムに依拠してはいますが、必要な改造も行いました。いくつかのコンポーネントはスクラッチで作成したり、ファイル内でローカルな微調整をするなどして、要求を正確に満たせるよう段階的に作業していきました。 このようなアプローチをとることで、ダイナミックなデザインシステムとTech Blog特有の機能要件の両方に対しバランスよく沿うことができました。 以下の画像では、最初にTech Blogで使用できるようデザインされた フッターコンポーネント が、 KINTOデザインシステム へ組み込まれ、他のプロジェクトに適用された際にどのようになるかを示しています。 モバイルビューでのフッターコンポーネントの例 デスクトップビューでのフッターコンポーネントの例 予想される効果 期待される主な効果について、以下に概要をご説明します: 検索バーとカテゴリータグを組み込むことにより、記事の検索がしやすくなりました。検索の手間を省き、コンテンツ発見プロセスの改善につながっています。 多言語機能の導入により、言語の壁が無くなり、多様な読者(特に英語または日本語を使う方)に記事を理解してもらえるようになりました。 デザインを修正したことで、ブログ記事の見栄えと実用性が改善されると考えられます。SNS共有ボタンを配置し、404ページを工夫、記事サイズの調節も行い、機能拡充を図りました。これによりユーザーエンゲージメントの飛躍的向上が期待されます 各記事の末尾に採用情報のリンクを付けたことで、技術志向の読者がKINTOテクノロジーズの採用スペースにうまく誘導されるだろうと考えています。 これら2つのフェーズにわたるデザイン変更は現在進行中です。見栄えと機能拡充、ユーザビリティ向上をバランスよく達成したいと思っています。 完成後は、 ユーザビリティテスト プロセスを実施し読者からのフィードバックを収集します。今回の変更があらかじめ定めていたゴールを達成できたかを確認していきます。 次のステップ これらのデザイン変更は始まりにすぎず、改善プロセスは今後も続きます。 Tech Blog向けとしてローカルコンポーネントの微調整とデザインを行ったわけですが、これらがKINTOデザインシステムに統合できるかどうか、精査することになります。 承認が下りれば、他プロジェクトでも利用できるようになります。これにより今回のデザイン変更は、当ブログの枠を超えた将来的な統合に向けてポジティブな効果を及ぼしていくことと考えられます。 急速に変わるデジタル社会の中で、KINTOテクノロジーズが変化し続けていく中、今回のデザイン変更がテックブログの今後にどう影響するか、楽しみです。 参考 KINTOテクノロジーズ - TechBlog KINTOテクノロジーズ– 企業情報 KINTOテクノロジーズ- 採用情報 ニールセン・ノーマン - ユーザビリティ・テスト
アバター
はじめに こんにちは KINTO テクノロジーズで KINTO ONE(中古車) のフロントエンド開発を担当している中原です。 KINTO ONE(中古車) は KINTO ONE でのリースアップ車両を再度リース契約いただくための EC サイトとなっており、実際の在庫車両情報の確認や契約までの手続き、契約の管理などができるようになっています。 KINTO ONE(中古車)サイト 新車の納期が長期化して久しいですが、比較的短い納期で高品質な車両を利用できることや、中途解約時の解約金が 0 円と設定されている手軽さがおすすめのサービスとなっています。(2023 年 12 月現在、東京都・愛知県のみでのサービス展開となっています。) 車両画像の問題 新車と異なり中古車を扱うサイトにおいては、商品として個別の車両を扱うことになり、当然 EC サイトとしてはそれぞれの車両の画像を掲載することとなります。 KINTO ONE(中古車) では、リースアップ車を商品化するにあたり各車両の撮影を行い、その画像がバックエンドの車両管理サービスに格納されるようになっていました。 サイトの表示にあたっては、バックエンドから画像 URL を含む車両情報を取得しフロントエンドのサーバコンテナにてページとして構築し、車両画像に関してはクライアント側から車両管理サービスの画像配信パスから取得するようになっていました。 --- title: サーバ構成(概要) --- flowchart LR %%外部要素のUser U[User] %%グループとサービス subgraph GC[AWS] subgraph FE[中古車サイトフロントエンド] subgraph CF["Cloudfront"] end ECS("フロントエンドサーバ") end subgraph BE[車両管理サービス] UCAR("車両管理サーバ") end end %%サービス同士の関係 U --> |"サイトアクセス"|CF CF --> ECS ECS --> |"車両情報の取得"|UCAR U --> |"車両画像の取得"|UCAR %%グループのスタイル classDef SGC fill:none,color:#345,stroke:#345 class GC SGC ここで、車両管理サービスが配信する車両の画像はワンサイズの JPG となっていたため以下のような問題がありました。 非効率な圧縮方式 表示サイズに関係ないサイズでの配信 実際のサイトでの表示サイズに関わらず、横 1000px 超の画像を配信していた 実際にサイト性能を測定する PageSpeed Insights でも、車両画像に関する指摘が多く挙げられていました。 PageSpeed Insights の指摘 ありたい姿 まず挙げられるのは、PageSpeed Insights で指摘されたポイントの改善です。 効率的な圧縮方式で配信している 表示サイズに応じた画像サイズで配信している これらにより、ページ表示のスピード改善・クライアントのネットワーク通信量の削減ができるだけでなく、サーバ側のコストも改善されます[^1]。 また、開発・運用上の観点から次の点もありたい姿としてあげます。 追加リソース[^2]は最小限に フロントエンド側から画像の変換設定の要求ができる 費用を抑えて、クイックに対応できる リソースを追加すればそれに付随する管理工数も増えるため、できるだけ小さな構成でできることが望ましいです。 また変換設定については、デザインの変更や、新しいタイプ高解像度のデバイスの追加などにより表示する画像への要求が変わりうることを念頭に置いています。こういった時にフロントエンド側から容易に取得する画像の解像度や圧縮方式が変更できることが望ましいです。 [^1]: KINTO テクノロジーズでは主に AWS 上にサービスを構築していますが、インターネットへのデータ送出もコストがかかるポイントです [^2]: ここで言う「リソース」とは AWS のリソースだけでなく、画像変換の外部サービスなども含めた概念です。 画像変換手法の検討 車両管理サービス側で写真登録時に画像変換・配信 この方法は、事前に定めたものを作るだけならば要求を満たしていると言えますが、前節「追加リソースは最小限に」や、「フロントエンド側から画像の変換設定の要求ができる」の部分に合わないため選択しません。 外部サービスの利用 imgix をはじめ、さまざまな画像変換機能を持つ CDN がありますが、こちらも選択しませんでした。 サイトの利用状況から月額で言えば、200-300USD のプランがフィットしそうでした。また、作業として現状の画像を管理しているストレージに対する設定変更やそのための社内調整などで、そこそこの工数が発生しそうです。 外部サービス利用し監視等の工数がかからないことは良いですが、 KINTO ONE(中古車)  はまだまだ途上のサービスであり、導入効果の見積りも難しい中、金銭的・時間的コストを鑑みて選択しませんでした。 Next.js のリモート画像最適化 最も実装の工数がかからない方法としては Next.js の Image コンポーネントを用いて画像を最適化させる方法ですが、この方法も現在のサイト状況に見合わず取らないこととしました。 現状、Next.js をフレームワークとして利用し、サーバサイドレンダリングによるサイト配信を行っていますが、サーバとしては比較的小さなインスタンス構成で実行しています。しかし、1 ページあたりの画像の点数も多く、処理の負荷がピーキーになることから、最小負荷時におけるインスタンスサイズを大きくする必要がありそうでした。実際にサービス初期に同様の設定を行っていた際にサイトがダウンしてしまうこともありました。 画像変換のためだけにインスタンスサイズを大きくすることは避けたかったのでこの方法も選択しませんでした。 Lambda@Edge で自前で構築(★ 採用) Cloudfront と組み合わせでエッジ側で画像変換を行う関数を実行し、変換後の画像を配信する方法です。サイト自体は Cloudfront 経由で配信していましたので、少し設定を追加するだけで素早く導入できそうでした。費用面も画像の枚数から変換処理に関してはほぼかからず、サイズを圧縮することから転送費用も圧縮できます。実装の手間は少々かかりますが以降はサーバレスで動作してくれるので、同時実行数にさえ気をつければそこまで管理の手間も掛からなそうでさそうでしたのでこの方法で行くことにしました。 Lambda@Edge での画像変換機能追加 以下のような構成へと変更します。 --- title: サーバ構成(改修後) --- flowchart LR %%外部要素のUser U[User] %%グループとサービス subgraph GC[AWS] subgraph FE[中古車サイトフロントエンド] subgraph CF["Cloudfront"] LM["Lambda@Edge<br>リサイズ・WebP変換"] end ECS("フロントエンドサーバ") end subgraph BE[車両管理サービス] UCAR("車両管理サーバ") end end %%サービス同士の関係 U --> |"サイトアクセス"|CF CF --> ECS ECS --> |"車両情報の取得"|UCAR U --> |"車両画像の取得"|CF LM --> |"車両画像の取得"|UCAR %%グループのスタイル classDef SGC fill:none,color:#345,stroke:#345 class GC SGC 車両画像のパスへアクセスした際のビヘイビアを追加し、Lambda@Edge でリサイズ・WebP への変換を行なった結果を返却するようにしました。 Lambda@Edge での処理内容については、先例 ^3 や AWS 公式のガイド ^4 など、情報が多くあるのであまり詳しくは記載しませんが、今回の実装におけるポイントに触れておきたいと思います。 クエリパラメータでの画像変換内容指定 画像の変換設定は以下のクエリパラメータで指定できるようにしておきます。 query 説明 width リサイズ後の画像の横幅を指定 quality 画像変換時の画質を設定 これによりサイト側から表示したいサイズの画像を指定したサイズ・画質で取得できるようになります。 キャッシュ設定 上記のクエリパラメータをキャッシュキーとして設定するようにします。これを怠ると、先に生成されたサイズの画像がキャッシュされてしまい、大きなサイズの画像を要求したのに小さいサイズの画像が表示されてしまう、といったことが起きてしまいます。 next/image のカスタムローダー設定 Cloudfront 側で画像変換をできるようにしたら、ページ側でも対応する実装が必要になります。 本サービスは Next.js でサイト構築していますので、Image コンポーネントに対してカスタムローダーを設定することで細かな設定をすることなく表示されるサイズに対して最適な画像のサイズでリクエストすることができます。 なお、表示に対して最適なサイズを選択するためには sizes プロパティの設定 が重要なので注意しましょう。 この値を設定することにより、Image コンポーネントのレンダリング時に srcset プロパティを実際の表示サイズに適した値で設定してくれます。 import Image, { ImageLoaderProps } from "next/image"; // 車両画像用コンポーネント export function CarImage({ src, sizes, alt = "車両画像", className = "" }) { // カスタムローダー function optimizeLoader({ src, width, quality }: ImageLoaderProps) { return `${src}?width=${width}&quality=${quality}`; } return ( <Image className={className} src={src} alt={alt} sizes={sizes} quality={90} loader={optimizeLoader} loading="lazy" /> ); } このようなコンポーネントを作成し利用することで、サイト上の表示サイズに応じた画像サイズのパラメータでリクエストされ、リサイズ・WebP 変換された画像を表示できるようになります。 結果 今回の手法で画像最適化を行うことで、PageSpeed Insights の画像に関する指摘が解消していることが確認できました。 PageSpeed Insights の画像に関する指摘が解消されました 最後に 今回はサイトパフォーマンス改善のうち、表示画像について最適化を試みました。ですがまだまだパフォーマンスの問題は多く山積しています。 引き続きサイトパフォーマンスの改善をし、ユーザにより快適な体験をしていただけるように取り組んでいきたいです。
アバター
はじめに KINTOテクノロジーズでQAグループFEチームのリーダーをしている遠藤です。 普段、私の作業としてはKINTOテクノロジーズで開発しているKINTO Webサイトのフロントエンド部分について、複数のプロダクトやプロジェクトからQA案件を確認させてもらい、各QA担当者の作業の割り振りや管理をしています。 作業をしているとQA内部だけでなく開発側の方々とお話しする機会も多く、今回は雑談をしている時に、 「なぜQAをやるのか?」 という質問があがり、こういう場をいただいたので私なりの思いを書いてみようと思います。 開発においてQAは、不要か? 「なぜ、QAをやるのか?」をテーマにQAの役割や必要性を書く前に、 そもそもQA自体必要なのか? という点について考えてみたいと思います。 品質のセミナーや記事とかで、QA不要論があがったりすることがあります。アジャイル開発の中でチームの外にQA部隊を置くのではなく、それぞれのチームメンバーの中にQAの役割が備わっていれば、QAは不要だというのが私が聞いたお話です。 たとえばアジャイル開発チームとは別にQA部隊がある場合、以下のような懸念が考えられます。 スプリントの中で、仕様変更に柔軟に対応しようとすると、そのあとのQA工程に影響が出る可能性が高い QAが仕様を理解するまでのリードタイムが別に掛かることで、QA工程が長くなる 不具合が発生した場合、スプリントの中で対応しないためその分の手戻りが大きくなる このような点から、アジャイル開発においてはチームの中に開発からQAの役割を含んだテストまで対応できるメンバーさえいればこれらの懸念無く対応できる、というのが話の主旨かなと思っています。 ここで、QA部隊は必要なくともQAの役割自体は否定されてない点が重要だと考えています。 逆に、あくまでQA部隊が必要というお話をされている方の意見として挙げられるのが、 開発とは独立した客観的に判断するQA部隊があることで、違った視点からより品質を高められる 仕様のナレッジがQA部隊に集中しやすくプロジェクト情報を横串で得られる ナレッジを元に、並行して動いている他のプロジェクトに対しても考慮漏れや必要な情報を組織として提供できる という部分かと思います。 一方で、QAの役割をアジャイル開発チーム内に置くことの難しい点として、 開発からシステムテストまで、テストという面において、高度なスキルを持つメンバーを集めることができるのか 集められない場合にはメンバーの育成が必要になるが、適切なスキルを取得するまで時間がかかる スキルを持つメンバーにナレッジが集中しやすく、そのメンバーがチームから離脱するとQA対応が難しくなる ということが挙げられるかと思います。 他の企業のコラムなどでもQAという部やグループは置いてないが、サービス利用者のためにQA作業は行っているという記事を読んだことがあります。つまり、QA部隊を組織として作るか作らないかは開発手法だったり、組織文化を考慮して選択する。ただし、システム要件にもとづき利用者のために全体的な品質を確認するQAの役割が必要だということは、皆さん共通認識をもっているのかなと感じています。 テストだけではないQAの役割 確認・検証を行うにあたり、QAはテストをするためのテスト専門チームで、QA=テストと錯覚する方も多いのですが、QAの役割としてはテストだけではありません。その点に関して大きく3つ記述します。 (1)仕様としての正解を確認する テストを設計する際、システム要件を確認した上で不明点を開発側、業務側にお尋ねします。QAはテストを実施する点から、まずは、要件をもとに仕様の正解を確認します。この作業を通して、仕様の細かい部分に関してQAが指摘することで、要件漏れや仕様の整理につながることがあります。 KINTOのWebサイトで「審査申込の流れ」部分の画面見直しがあった場合を例にご説明します。 この場合、テストの期待結果としては「お申し込みに必要なもの」、「審査お申し込みのステップ」のデザインが、画面仕様と一致していることになります。 お申し込みに必要なものとして、通常のWebからの申し込みの場合は運転免許証画像のアップロードが必要です。ただ、KINTOのサービスは販売店様の店頭でも提供しており、店頭の場合ですとその場で運転免許証を確認できるため、画像をアップロードしなくて良い内容になっています(下記の赤枠の運転免許証の部分)。その点を開発側に確認したところ、だしわけの考慮が必要だということに気づいてもらえたということがあります。 細かい点ではありますが、想定される利用ケースや条件を考慮し、テストの期待結果に相当する正解は何か?という点をしっかり確認します。このように、曖昧な表現や漏れている部分に対して具体的にしていくことで、本来あるべき仕様の確認をします。 先述のように、QAでの仕様確認を通じて、開発側が認識していなかった要件を指摘できることがあります。 また、要件定義段階ではないものの開発工程と並行してテスト観点をまとめることで、テストを実施する前に早めに品質を高めることができます。 (2)テスト設計時における資料整理 短期間に開発する際、開発しながらドキュメントを整理することは時間的に難しい場合があります。 各仕様書があっても、一覧化できていなかったり、操作手順がまとまってなかったりというケースもあります。QAでは上記(1)で仕様の正解を確認しつつ、テスト設計でシナリオ、機能確認、表示確認について、下記のように必要な観点の洗い出しを実施します。 その際、元の情報は開発側にあるので、基本的にはその資料を流用しますが、必要に応じてQA側のテストで確認しやすいように、一覧化したり手順をまとめたりします。 QAが作成した資料を参考にすることで全体の機能を俯瞰して見ることができたり、ある手順を確認するのに役立った等、QA以外の社内関係者から嬉しい言葉を頂くことがあります。 情報としてはプロジェクト内に集約されるため、QAでまとめる資料の内容が最新とは限りませんが、あくまで現状の仕様理解を目的として整理します。また、QAでは並行して動いているプロジェクトを横串に見れている点から、仕様を整理している中で開発側に懸念事項などの情報提供をできることもあり、品質面での支援になっていると言えます。 (3)不具合分析によるフィードバック プロジェクトが完了した後、QAテストの結果を元に、不具合分析を行います。下記のようにプロジェクト毎に行うのが中心になっていますが、プロジェクトやプロダクト毎の特徴により、要件定義段階での考慮を厚くしてもらうとか、単体テストを強化してもらうなどのフィードバックを行います。 こういった内容を振り返りの場でプロジェクト関係者にフィードバックをすることで、次回のプロジェクト進行の参考にしてもらいます。 不具合分析する際に、プロダクト毎での不具合傾向やプロジェクトとしての課題などを明確にするという点を挙げていき、それについて認識を合わせます。 弱み部分だけの報告ではなく、例えば要件の詰め方を他のプロジェクトとは違った手法を取ってみたとか、単体テスト部分を工夫したという場合に、その効果が出ているという点もしっかり伝えることが大事になります。この報告は、取り組みが良い方向に向かっておりさらにその部分を強化する指針となるので、フィードバックの際には、マイナス面だけにならないよう注意しています。 このようにテストだけではなく、品質を作りこむ面でもQAの役割には意義があります。 結局、QAってなんでやるの? Webやアプリでサービスを提供する我々にとって、例えば デザインは一致しているが、ボタンの位置が画面ごとに異なる 画面遷移に時間がかかる PCでは問題ないが、スマホだと表示サイズが変わることで文字が読みにくくなる という事象があった場合、提供したいサービスの魅力を伝える以前に、使いづらい見づらいという点から利用されなくなる恐れがあります。 要件としては満たされていることの確認だけではなく、サイトの訪問者が快適に使えるように改善できる点においてQA作業を行う意義はあると思います。 また、QA業務を通して横串でシステム要件を確認できるため、ある程度の仕様情報が得られることで、想定していないプロジェクトのリスクを発見できたりする役割もあります。 KINTOテクノロジーズでは、各プロダクト毎に複数のプロジェクトが並行して動いているため、 プロジェクトのリリースタイミングによるリスクが発生しないか? 共通の仕様が変更される場合、影響があるであろう他のプロダクトがその内容を認識しているか? 一連の試験を実施することで、プロダクトをまたがるようなデータの連携を含めた機能に問題ないか? という、事前にプロジェクト側で考慮が想定されている部分においても、QAのタイミングであらためて確認を行うことで、残っているリスクを洗い出し品質の作りこみを実施しています。 このように、実際にサービスを利用されるお客様のためにQAが客観的な視点から要件を確認し、品質面の作りこみのサポートを行う必要性はあると思います。 この「お客様のために」という気持ちは私は大事だと思っています。我々のサービスは大多数の方々に利用されています。ただ、お客様は、個人としてそのサービスに向き合います。そのお客様が、ちょっとでも使いづらかったり、見づらかったりすることで、二度とサイトを開かなくなるという事態は、避けなければいけません。 なので、この「お客様のために」という気持ちが、本来伝えたいサービスの魅力を伝え、更なるお客様の獲得につながるという、好循環のスパイラルをにぎる重要な役割と考えています。 さいごに 今回、そもそもQAなんでやるのという漠然とした点から私の考えを記述しました。記事にも書いたように、QAの役割は組織ごとに異なるものでもあります。今回の内容に賛同いただける方や、私が持っていない意見をお持ちでQAに興味のある方など、ご意見ありましたらご連絡いただければと思います。 また、一緒にQAやってみたら楽しそうだなと思った方々、QAを盛り上げてもっと良くしていきたいと思っている方々、いつでも大歓迎ですので以下の採用ページからぜひ応募してください。カジュアル面談からでもOKです。 https://hrmos.co/pages/kinto-technologies/jobs?category=1783696806032474116
アバター
Hi, my name is Shida from the CIO office at KINTO Technologies (KTC). I usually work to support everyone at KTC! Aiming to be a bridge between teams and people, I place importance on communicating with everyone on a daily basis. In this article, I would like to introduce you to the community activities we are doing outside of the company. What are Community Activities? At KINTO Technologies, like-minded employees organize activities for the purpose of communicating more between each other. Many of these are frequently formed through shared interests, such as a community of individuals who appreciate one thing or the other. I myself am a member of multiple communities (maybe 21 or so...) and feel the following benefits from the expansion of communication. Benefits of Expanding Communication Opportunities Among Colleagues Deeper relationships can be built when you get to know different sides of your colleagues that don't come up in our everyday work. Provides an opportunity for a break to recharge yourself. Team members who don't typically collaborate frequently can deepen their ties. It often translates into effective collaboration in our daily work by becoming close through club activities. Stimulating communication = more opportunities to get to know each other Internal communities can contribute to cultivating corporate culture from bottom up. I also believe that effective communication is the foundation of a strong organization and can contribute to keeping a vibrant business. I might have gone a bit overboard in making it sound too grand, so let’s move on to the second half in a more casual way! Usually, we spend our days staring at the PC in the office, so physical activity is a must! Let me introduce you to some sports communities I'm in (^o^)/ Sports Communities 🏀Basketball Club🏀 \Characteristics/ Members: 25 Anyone with a passion for basketball is warmly welcomed! About 10 joiners every match, even on weekends Cheering each other and sweating together lively by passing and shooting practice. Introduce a fresh form of communication distinct from the usual. Held in a beautiful gym close to the office In super intense games, the energy is so high that the camera loses focus completely lol ⚽️Futsal Club⚽️ \Characteristics/ Members: 39 An atmosphere where both beginners and experienced members can enjoy (we even have a former J-League player joining!) It’s a great opportunity to communicate with people from other teams and have a good time together. It's okay to just join to cheer or watch them play. Anyone can casually join when they feel like. Communication beyond age and nationality (sports transcends language barriers) My memorable first shooting scene⚽️ (I lack composure in my arms, right?) Whether I scored a splendid goal after this... I leave it to your imagination, everyone(˘ω˘) Even in sudden torrential rain, the game goes on. You can still experience the vitality of youth as a working adult!✨ ⛳️ Golf Club ⛳️ \Characteristics/ Members: 21 A community that transcends team divisions and positions We practice at the driving range and play rounds together (about once a month during the season) Direct OJT from the manager, fostering camaraderie and contributing to personal growth Communication throughout the day (including training camps) A refreshing feeling of a driver shot in the midst of nature cannot be experienced in the city. (Wanting the echoing sound of striking a ball to be my alarm clock!) Several members have started playing golf since they joined the company (close-knit ladies) In the tension-filled green surroundings, we silently cheer for each other, ‘Go for it!’ . 🎾 Tennis Club 🎾 \Characteristics/ Members: 20 There are many experienced members that kindly offer advice for those who are starting out. The matches will be a real test for both newbies and seasoned players! Held after work at a tennis court close to the company. Enjoy beer after tennis! (Everyone loves alcohol). Practice scene Since half of us are beginners, the experienced members offer friendly lessons on techniques \( ˙-˙ \)(/ ˙-˙ )/ Thanks to their careful instructions, every beginner caught on quickly! Summary Did any of these activities interest you? As communities are formed organically, a new one might be emerging as we speak...! How to spend your time after work or the weekends varies from person to person. As one option, KTC offers many opportunities to enjoy sports and connect with other employees. You can make the most of your free time by refreshing yourself through exercise! We look forward to welcoming you to these communities when you join KTC 🤗
アバター
はじめに みなさまこんにちは!グローバル開発部兼テックブログ運用チームの森です。普段は Global KINTO Web のPdMや各国個人情報関連法の対応リードを行っています。(まぁつまりいろいろやってます。笑) 私事ですが、私の プロダクトエンハンスチーム が社内の組織体制変更に伴って7月より新しいレポートラインになりました。(名前も若干変わりました!) 新しいグループマネージャーは水野さんです。今までもコミュニケーションがありましたが、他のチームとの交流もあまりなかったので、これを機にマネージャーとチームリーダー陣で「リーダーズインテグレーション」を実施しました。本日はそのレポートです📝 8月に実施したのですが、私の筆が遅く、年末の記事リリースになりました 😅 リーダーズインテグレーション? インテグレーション(Integration)とは統合を意味し、リーダーとチームメンバーの意思疎通を図り、チームの結束力を高めるためのフレームワークです。 新しいリーダーを抜擢した時や、チームの関係性に課題があり、結束力を高めたい時に実施すると効果を発揮します。 参考: リーダーズインテグレーションのすゝめ 私がこのワークショップを知ったのはコーポレートITグループで実施したと伺ったのがきっかけです。どうやら前職でご経験があった様子。 「新しいリーダーを抜擢した時」とはちょっと違いますが、ちょうど私が新しいレポートラインに所属したタイミングだったのと、他のチームとあまり交流できていなかったので、「これ、ええやん…!」となってマネージャーに持ち掛けたところ、快諾いただけたので、コーポレートITのずーしみさんにファシリテーションをお願いして実施しました✨ リーダーズインテグレーションの流れ 開催日時:2023年8月29日 17:30~19:30 場所:神保町オフィス 参加者:グローバル開発部グローバルプロダクト導入グループ マネージャー1名 リーダー5名 ファシリテーター:ずーしみさん from コーポレートITグループ Time Action Time (m) 17:30 取り組み説明/ファシリテーター自己紹介 5 17:30 リーダーからご挨拶 3 17:33 (リーダーお部屋から退出) 17:35 リーダーについて知っていることを書き出す 15 17:50 リーダーについて知らないことを書き出す 15 18:05 自分たちのことでリーダーに知っておいて欲しいことを書き出す 15 18:20 リーダーのため、グループのために自分たちが出来ることを書き出す 15 18:35 (メンバーお部屋から退出、リーダー入室) 18:40 リーダーがみんなから出た意見を見て回答を考えるタイム 10 18:50 (メンバーお部屋に戻ります) 18:55 リーダからの回答タイム! 30 19:25 バッファ&フリートーク 5 20:00 懇親会 導入 まずはファシリテーターとリーダーそれぞれから、本ワークショップを導入した背景とワークショップの説明をしてもらいます。今回、水野さんからは「普段の1on1やミーティングとは異なる場としてみんなから意見をもらえると嬉しい」とのお言葉をいただきました。 そしてその後、なんとリーダーは退席します!ここからが本番です。 メンバーによる書き出しタイム リーダーについて「知っていること」「知らないこと」「知っておいてほしいこと」「リーダーのためにできること」を書きだします。プライベートの話も入るのであまり多くは書けないですが、少しだけ挙がったものを書いてみます。(水野さん、おゆるしを。) リーダーについて知っていること📝 KINTOテクノロジーズ入社当時はJapanの中古車案件担当 グローバルには1年ほど前からJoin 猫が好き🐱 運転がお好き🚗 などなど 私にとっては新しいマネージャーでしたが、他のリーダー達にとってはそうでなかったので、「へ~、そうなんだ」と思うことが多かったです。 リーダーについて知らないこと📝 なぜKINTOテクノロジーズに入社したのか これまでの経歴 開発経験 💻 評価するポイントは? などなど ここは逆に「意外とみんな同じこと思っているんだな」という印象でした。 リーダーに知っておいてほしいこと📝 もっとコミュニケーション取りたい R&D開発とかしてみたい メンバーのマネジメントに悩んでいる みんなでキャンプしたい⛺ などなど ちょうど弊社の評価時期だったこと、また、組織体制が変わったことで全員初めて評価する側になったこともあって、同じことに悩んでいることがわかりました。 リーダー・グループのためにできること📝 車両や自動車業界の知識がある 愚痴、聞きます 他の開発チームとのコネクション エンジニア向け勉強会開催できます 新しいビジネスアイデア出します などなど 各自自分ができることがポンポン挙がってきたことに良い意味で驚きました。 リーダーからの回答タイム リーダーが合流し、貼られたふせんそれぞれに回答します。とは言っても、誰が書いた?とかを聞くことはなく思っていることをお話いただく形です。マネージャーの思っていることを聞く機会なんて意外とないので、30分もあっという間に過ぎさりました。 猫アレルギーなのに猫好き(かわいそう)、トップス白、パンツは黒のセットのクローゼットがある(どこかで聞いたような…)といったプライベートな内容から、評価は期初から何が変わったか?が大事、腐らずにやっていってほしいといったメンバーに対する意見などをお伺いできました。 特に、リーダーに知っておいてほしいこと・グループのためにできることに対しては、前のめりなふせんが多かったからか、「評価や組織の悩みは共有しあおう」「コミュニケーションの課題を解消するために協力してもらいたい」「もっと任せても良いんだなとわかった」といったコメントをいただきました。なんとなく、チームがUniteされた印象で、熱い気持ちになりました。 モザイクだらけですが、こんなにたくさんのふせんが貼られました! 所感 メンバーとして参加してみて、マネージャーとの繋がりが深まったのはもちろんなんですが、各チームリーダー達が思っていることを聞けたことがとても良かったです。プロジェクトによっては普段全く関わらない方もいるため、参加者みんなが想像以上にKINTOテクノロジーズやグローバルKINTOに対して真剣に考えていることがわかりました。 参加者からの声: 自分以外のチームメンバーが抱いている課題など知れてよかった。 自分が上司に求めている事/知っている事の深さ/広さを、他のメンバと比較して客観的に見る事ができた 話しやすい雰囲気を作るために、怒ったりネガティブな感情を出さないようにしていましたが、あながち間違っていなかったのかもなという発見があった。 実際に本当にそれが反映されるかわからないので、振り返りなど数ヶ月後にやると良いかも。 敢えて伝えたいと思ってない事でも、相手にとっては意味が有る事もある。それを敢えて引き出すには、こういった場は有効 私自身としては新しく参画したグループだったので、タイミングとしては良かったですが、他の皆さんにとっては「なぜ今さら?」感もあったようで、行うタイミングは検討すべきだったかな、と反省もあります。一方で、全く意味が無かったという意見もなかったので新しいリーダーが就任するタイミングなどではさらに効果的なのかな、と感じました! さいごに 全体を通して時間配分や書き出している間の声掛けなど、ファシリテーションによって結果が大きく左右されると感じました。なかなか書き出しできないときに、「○○と思ったことってないですか?」「○○なんですね!それも新しい発見じゃないですか!」などという声掛けをいただいたり、臨機応変に時間配分を検討したり。わざわざ神保町まで来てくださったずーしみさん、ありがとうございます🙏 最後に、「リーダーズインテグレーションをやるならこちらをぜひ!」と勧められた本をご紹介させてください。ファシリテーションの力は偉大です!🥺✨ https://www.amazon.co.jp/%E3%82%B6%E3%83%BB%E3%83%95%E3%82%A1%E3%82%B7%E3%83%AA%E3%83%86%E3%83%BC%E3%82%BF%E3%83%BC-%E6%A3%AE-%E6%99%82%E5%BD%A6/dp/4478360715 長くなりましたが、懇親会でいただいたおそろしくどでかい羊肉で締めさせていただきます 🍖🤤 ごちそうさまでした🙏
アバター