TECH PLAY

KINTOテクノロジーズ

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

936

はじめに こんにちは! 先日、弊社もプレミアムスポンサーを務めた「 JSConf JP 2024 」が行われました! 今回は実際に現地参加したメンバーによるセッションレポートをお届けします! ITOYU You Don’t Know Figma Yet - FigmaをJSでハックする https://jsconf.jp/2024/talk/hiroki-tani-corey-lee/ Figmaはブラウザで開ける、だからこそdevtoolsを使ってJSで操作出来るということを知りました。 Figma公式が用意しているAPIを、 figma グローバルオブジェクトを使って操作することで、要素のCSS情報を取得したり、レイヤーを作成したり出来るそうです。 Figmaがブラウザで開けるからこそのメリットを最大限に活かせるということで、Figmaの無限の可能性を感じました。 グローバルオブジェクトを通して出来ることについては、以下のFigma公式ドキュメントを参照してみてください。 https://www.figma.com/plugin-docs/api/global-objects/ 幸せの形はどれも似ているが、不幸なプロジェクトはそれぞれの形がある https://jsconf.jp/2024/talk/mizchi/ 普段mizchiさんがパフォーマンスチューニングのコンサルをする中での経験を元に、パフォーマンス課題の発生傾向を紹介していました。 その中で「安易なアンチパターンの採用をした結果、後々爆発する」という話を聞いて、私の過去の経験を思い出しました。 ドキュメント上では非推奨とされているけど、目の前の問題を解決するためにStackOverflowで見つけたHackを採用した結果さらに厄介な問題を引き起こすという経験、 あると思います。 その場しのぎの解決策を採用するのではなく、根本的な解決策を見つけることが大切だとあらためて感じました。 nam 生成AIでコーディング試験を解いてみよう(株式会社ハイヤールー) https://jsconf.jp/2024/talk/hireroo/ このワークショップの主催は、コーディング試験サービスを提供しているHireRooさんなので、正真正銘本物のコーディング試験です。 その本物のコーディング試験を生成AIで解いてみる、という通常は試す機会のないワークショップでした。 (セッションだと思い込んで見に行ったところ、PCが必要だった模様…申し訳ないですがHireRooの方のPCで解かせていただきました。すみません…) Chat GPTで取り組んだのですが、問題文だけをそのまま渡してもなかなか思った通りのコードは返ってこず…やはり工夫が必要でした。そうウマいこといきませんね。 ちなみに実際にコーディング試験で生成AIを使うと結構わかるそうです。 LT: JavaScriptを支えるエコシステム(漫才) https://jsconf.jp/2024/talk/ecma-boys/ このセッションでは、登壇者の方のお母様が今気になっているパッケージマネージャーやバンドラーの名前を忘れてしまったそうで、お母様から聞き出した特徴をもとにそれらが何なのかを推測する、という内容でした。 「オカンが気になっているパッケージマネージャー」など、パワーワードが頻出しており大変興味深かったです。 個人的にはバンドラに関する話題で「設定ファイルがわかりやすいならwebpackではない」と断じられていた部分が心に残りました。 きーゆの LT: JavaScriptのモジュール解決の相互運用性 https://jsconf.jp/2024/talk/berlysia/ このセッションではJavaScriptのモジュール解決についてお話されていました。 つい最近もSwiperを含むコンポーネントのUT実装でCJS/ESM問題に直面し、モジュール解決の知識不足に危機感を抱いたばかりでした。 また、JestからVitestへのマイグレーションもチーム内で少し話題になったこともあり、この辺りの話はしっかり理解しておく必要性を感じました。 ちなみに、私にはとても難しく、聞くのがやっとでした🥲 早くこの手の話にうんうんできる人になりたいです。 LT: クルマのサブスクサービスをNext.jsで内製化した経験とその1年後 https://jsconf.jp/2024/talk/kinto-technologies/ 自社のセッションになります。 内製化PJは私が入社するよりはるか昔の話なので、歴史を学ぶ意味でも聴講しました。 技術スタックが担当しているプロダクトとほぼ同じなので、課題や今後の展望も自分事として受け取りました。 Ren.M LT: romajip: 日本の住所CSVデータを活用した英語住所変換ライブラリを作った話 https://jsconf.jp/2024/talk/kang-sangun/ こちらのセッションではromajipというライブラリの制作についてお話しされていました。 個人的に郵便局だけでなく、デジタル庁も日本の住所マスタを提供しているのが驚きました。 また、同名の地名などの対策などが大変そうだなと感じました(東京と大阪にある日本橋など) 私自身もライブラリを自作する機会があれば躓いたポイントやこだわりをまとめておきたいです! LINEヤフーにおけるPrerender技術の導入とその効果 https://jsconf.jp/2024/talk/masanari-hamada-tomoki-kiraku/ こちらのセッションではLINEヤフー様によるPrerender技術の導入検証ついてお話しされていました。 Prerenderとはリンクをホバーしたタイミングで遷移先のページを事前に読み込む技術のことのようです! その結果、ページ表示スピードを格段に上げ、ユーザ体験を大幅に向上させます。 LINEヤフー様では様々な検証した結果、導入には至らなかったとのことでした。(リンクの密集問題など) しかし、使い方によっては格段に読み込みスピードが早くなりそうでしたので私もこれから勉強してみたいと思いました! ノベルティ スポンサー企業のブースを回り、様々なノベルティをいただきました! 個人的にメルカリ様の「SOLD OUTキーホルダー」が嬉しかったです! 公式Tシャツとトートバッグ スポンサーノベルティ We Are Hiring! KINTOテクノロジーズでは一緒に働く仲間を探しています! まずは気軽にカジュアル面談からの対応も可能です。少しでも興味のある方は以下のリンクからご応募ください! https://hrmos.co/pages/kinto-technologies/jobs/1955878275904303141 おわりに いかがだったでしょうか! 来年のJSConf JPもぜひ現地参加できればと思います! ここまでご覧いただきありがとうございました!
アバター
Introduction Hello! My name is Ren.M I work on developing the front end of KINTO ONE (Used Vehicle) . KINTO Technologies Corporation will be serving as the premium sponsor of JSConf JP 2024 , which will be held at the KS Building Kudansakaue in Tokyo on Saturday, November 23, 2024. ■ About JSConf JP 2024 JSConf JP 2024 is a Japanese JavaScript festival organized by the Japan Node.js Association. This will be the 5th JSConf event in Japan. Sponsor Booth Yo can visit our booth and take part in our JavaScript questionnaire! Those who answer the questions can spin the gacha and receive an exclusive novelty gift! Here are pictures of some of them! Paper clips Tote bag Sponsor Workshop In the workshop, we will give a presentation on "Building Vehicle Subscription Services In-House with Next.js and Reflections One Year Later (tentative title)!" Click the link below to learn more! (in Japanese) https://jsconf.jp/2024/talk/kinto-technologies/ We Are Hiring! At KINTO Technologies we’re looking for talented people to join our team! If you’re interested, let’s start with a casual meeting. Even if you're just a bit curious, don't hesitate to apply using the link below! https://hrmos.co/pages/kinto-technologies/jobs/1955878275904303141 Conclusion If you're interested, we'd love for you to visit our booth and join our workshop! We're excited to welcome you to the venue. We will be looking forward to seeing you there!
アバター
A.K Self-introduction I'm A from the my route Development Group. I am from Latvia. In my previous job at a startup, I was working broadly as a full-stack developer. How is your team structured? Six members including myself. What was your first impression of KINTO Technologies when you joined? Were there any surprises? Even though it's part of a large group company, I found my team surprisingly easy to work with because of the friendly atmosphere. I really appreciated that there are study groups available for basically any technology I'm interested in. What is the atmosphere like in the workplace? Surprisingly, there are many foreign nationals, and they all have a high level of technical skill and are easy to talk to. How did you feel about writing a blog post? I'm not good at it. Question from M.O.: A, as a smart home user, what's the question you ask Alexa most often? Well, I definitely ask, "What's the weather today?" before heading out. I also use "What's this song?" or "Play [song name]" almost daily, since it's connected to Spotify. As a fun fact, Alexa can be used as a TTS speaker, so I enjoy playing custom messages. The most useful one for me, though simple, is a reminder that to plays the time plus a message every 5 minutes between 7:00 and 8:00 a.m. "It's already 7:35! Are you getting up or what?! "Something like that. S.D Self-introduction I am Deguchi from the Production Group. In my previous job, I worked on car navigation and map data related fields. I was also involved in natural language processing and machine learning. How is your team structured? It is a group of 5 people including myself. Each member is individually involved in different projects. What was your first impression of KINTO Technologies when you joined? Were there any surprises? Since the company's atmosphere was explained during the interview, there weren't any major surprises. What is the atmosphere at the site? While most communication happens on Slack, there's also a lot of face-to-face interaction, creating an environment that's easy to communicate in. How did you feel about writing a blog post? I like having the opportunity to share information outside the company. It allows me to review past cases and Tech Blogs and gather a variety of insights from internal team members. Question from A.K Out of all the gadgets you've collected, which do you think is the most useful? It's hard to pick just one, so let me share a few of my favorites! Raspberry Pi: An amazing product that allows you to easily challenge IoT and actually create things! It's impressive that Ubuntu (with GUI) runs properly for this price. Insta360 Flow: It's great to get this level of gimbal performance at this cost! Subject tracking is also convenient! Mitene GPS: I recommend this for small children to have. It's a useful gadget that it can be taken to places where cell phones aren't allowed. The battery life is also good. K.N Self-introduction I am Nishi from the Data Engineering Team at Analysis Group. How is your team structured? The Analytics Group consists of three teams: the Data Science Team, the Data Engineering Team, and the Data Produce Team. What was your first impression of KINTO Technologies when you joined? Were there any surprises? There are many in-house study groups! What is the atmosphere at the site? In daily morning meeting, we share our progress, issues, and consultations. Since we have three locations, Tokyo, Nagoya, and Osaka, and a mixed work system of home and office, we communicate through Slack Huddles, sharing screens as needed. How did you feel about writing a blog post? After going through past articles for reference, I felt it was a great opportunity to get to know other employees. Question from S.D: Looking back to when you joined the company, is there anything you wish you had more information about, or a system you wish had been in place? I took many business model orientation courses after joining the company, but I think having a review session about three months later would be helpful for retaining the information better. W ![W avatar](/assets/blog/authors/numami/maymember/4.png =200x) Self-introduction I'm Watanabe and I belong to the Organizational Human Resources Team in Human Resources Group. I worked as a sales manager at a human resources firm and handled human resources at a startup. How is your team structured? The Human Resources Group includes the Organizational HR Team, the Recruiting Team, and the Labor Relations and General Affairs Team. The group had a total of 13 members. What was your first impression of KINTO Technologies when you joined? Were there any surprises? There were no particular surprises. I expected the internal control system to be well-organized since it's a Toyota Group company, and it was well-structured as I had anticipated. However, I feel we have enough freedom. I'd already heard about various internal challenges both positive and negative from the interview, so there were no surprises in that point either. What is the atmosphere at the site? My impression is that everyone is positively engaged in their work. During my first month with the company, I had conversations with the managers. They were all supportive and welcoming, which helped me start comfortably. How did you feel about writing a blog post? I thought it was great how much effort goes into both internal and external communication. Given that it's a major affiliate, I expected stricter control over external communications. However, I feel there's a high level of freedom on this point, much like a venture company. Question from K.N: What kind of challenges would you like to take on at KINTO Technologies? I want to take on the challenge of creating an environment where everyone can move forward as one. K Self-introduction I'm part of the IT/IS Division. In my previous job, I worked in MS infrastructure, .NET development, and information system operations at a SIer company. How is your team structured? The IT/IS Division consists of four teams: Asset Platform, Corporate Engineering, Tech-Service, and Enterprise Technology. As a member of the Corporate Engineering team, I am mainly involved in addressing business issues and requests through system implementation, renovation, and improvement. What was your first impression of KINTO Technologies when you joined? Were there any surprises? There were no surprises. Everyone in the IT/IS Division is thinking about, "How do my work tasks provide value?" My first impression was how impressive it was that things were so well-managed. What is the atmosphere at the site? I usually work in the Muromachi office. The atmosphere makes it easy for us to consult with one another and think of each other's work as if it were our own. We regularly have 1-on-1 meetings with leaders, managers, and general managers to discuss honest opinions, impressions, requests, and concerns. As a result, it feels easy to communicate openly with others outside of these 1-on-1 meetings. How did you feel about writing a blog post? I thought it was simply a good measure, as we are actively communicating with the outside world beyond this blog. Question from W: Any interesting places (travel destinations, etc.) you have visited recently? I recently moved to a new house and visited a public bathhouse with a college friend who came to visit. The Showa-style appearance and atmosphere of the bathhouse were elegant, providing us with an extraordinary experience. I wasn't really into public bathhouses before, but I actually found it to be an enjoyable place to refresh and unwind. JK ![JK avatar](/assets/blog/authors/numami/maymember/6.png =200x) Self-introduction I am Kim from the Toyota Woven City Payment Solution Development Group. How is your team structured? It is a group of 6 members including myself. We are actually working on the Woven side, and there are other Woven members in the team besides KINTO Technologies. Our work covers a wide range, from frontend and backend development to infrastructure. What was your first impression of KINTO Technologies when you joined? Were there any surprises? It was nice to hear various details during the orientation. What is the atmosphere at the site? Basically, we set up a sprint plan once a week and work according to the target. We also make time for tech talks and document reading. Since we often work remotely, we use Slack, Meet, and other tools to stay connected with team members. How did you feel about writing a blog post? I wanted to give even a little useful information to those who read my article. Question from K: What do you value the most in your work? I think it's the same everywhere, but communication with people is the most important. Especially in development side, if there's miscommunication about functional requirements, something entirely different might be created (lol). The other is continuation. By persisting in my work, not only does my own work improve, but also the team can achieve a higher level of completion. M ![M avatar](/assets/blog/authors/numami/maymember/7.png =200x) Self-introduction I am M from Data Integration Platform Team. How is your team structured? There are two people, including myself, working on product maintenance. The product I am responsible for is connected to many systems, so I frequently need to communicate with various people. What was your first impression of KINTO Technologies when you joined? Were there any surprises? I was surprised by the proactive introduction of study groups, as well as new tools and services. What is the atmosphere at the site? It's like a calm atmosphere where conversations occur when needed. How did you feel about writing a blog post? I didn't think anything in particular. Question from JK: What were the onboarding and catch-up processes like for your work after joining the company?Please share any positives you noticed during the process! First, I had a 1-on-1 session to go over the team structure, the purpose and role of the product I'd be working on. After that, I set up the machines and development environment using the provided documentation. So far, pretty standard onboarding up to that point. Afterward, we went through a hands-on process of signing a contract for a new KINTO car to better understand the business. The hands-on materials were carefully prepared, making it easy to understand the car rental process! D ![D avatar](/assets/blog/authors/numami/maymember/8.png =200x) Self-introduction I'm D from the my route Development Group. How is your team structured? It is a group of 6 people including myself. What was your first impression of KINTO Technologies when you joined? Were there any surprises? I felt that the company offers lots of opportunities for sharing information. The atmosphere was also more relaxed than I had imagined. What is the atmosphere at the site? We often work individually in a quiet and focused manner. All the team members are kind. How did you feel about writing a blog post? I was very nervous at the thought of someone outside the company reading my article. Question from M: Have you found a favorite lunch spot? If so, let us know! Yes, an Indian restaurant on the first floor of the building. M.O Self-introduction I am Onuma from the Mobile Development Group. Previously, I worked as an Android engineer for the voice platform Voicy. I was also involved in backend development (Go), as well as frontend (Angular/TypeScript) and iOS app development. How is your team structured? The my route Android development team consists of four people, including myself. What was your first impression of KINTO Technologies when you joined? Were there any surprises? I had heard that there were many engineers from outside Japan, but there were even more than I expected. There are abundant in-house study groups, providing plenty of opportunities for learning and output. What is the atmosphere like in the workplace? Each person's area of responsibility is clearly defined within the company, which allows me to focus on my work and coding. I also believe this is an environment where we can immediately share any knowledge gained in the course of our work with one another. How did you feel about writing a blog post? I enjoy sharing knowledge about technology. Question from D: If any, what has been your biggest problem since joining the company? Adding home working schedules to Outlook to comply with remote work rules.
アバター
この記事は KINTOテクノロジーズアドベントカレンダー2024 の5日目の記事です🎅🎄 KINTOテクノロジーズ株式会社のモバイル開発グループでAndroidエンジニアをしています、大沼です。 普段はモビリティサービス「my route」アプリの開発に従事しています。 本記事では、Android Automotive OSをビルドする手順とAndroid AutomotiveアプリおよびAutoアプリなど車載向けアプリの開発方法をご紹介します。 Android Automotive OSをRaspberry Piに入れて起動する Android Automotive OSとは Android Automotive は AOSPの枠組みに含まれるAndroid ベースの車載用プラットフォームであり、プリインストールされた IVI システムの Android アプリに加えて、セカンドパーティとサードパーティの Android アプリも動作します。 詳しくは公式のドキュメントをご覧ください。→  https://developer.android.com/training/cars?hl=ja#automotive-os AOSPとは AOSPはAndroid Open Source Projectの略で、Android OSを構成するすべての要素がオープンソースで公開されています。 Android オープンソース プロジェクト Googleの開発した最新のOSは一定の非公開期間を経たのち、オープンソースとして公開されます。この公開されたOSをベースに、デバイス開発元が用途に合わせた機能追加や修正を加え、自社のスマートフォンやタブレットなど各種端末にOSを搭載します。 Android Automotive OSをビルドするために準備するもの PC *後述のビルドするためのハードウェア要件を満たしている必要があります ディスプレイ *タッチモニターがベター RaspberryPi 4B MicroSD 16GBあればいいはず MicroHDMI-HDMIケーブル ビルドするためのハードウェア要件 OS : Ubuntu 22.04 Intel Gold 6226R (16コア、32スレッド) 16 GB 以上の RAM HD: 1TB * 注意: Windows または MacOS 上でのビルドはサポートされていません。 AWS EC2で環境つくってビルドしようとしたけど無料枠で上記スペックは用意できないので諦めました。 ビルド環境の構築 ビルドに必要なツールをインストールします。 sudo apt-get install git-core gnupg flex bison build-essential zip curl zlib1g-dev libc6-dev-i386 libncurses5 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z1-dev libgl1-mesa-dev libxml2-utils xsltproc unzip fontconfig Repoとlocal_manifestの追加 Android OSは多くのソースコードの群で構成されています。 RepoはAndroid ソースコードのチェックアウトに利用します。 コンポーネントの結合は疎結合で、それぞれが独立したGitレポジトリで管理・開発がされています。 これら多くのGitレポジトリをManifestファイルと呼ばれる管理ファイルをもとに管理するのが Repo というツールになります。 ## Repo ランチャーをインストール repo init -u [https://android.googlesource.​com/platform/manifest](https://android.googlesource.com/platform/manifest) -b android-13.0.0\_r35 --depth=1 ## local_manifestの追加 git clone [https://github.com/grapeup/​aaos\_local\_manifest.git](https://github.com/grapeup/aaos_local_manifest.git) .repo/local\_manifests .repo/local_manifests/manifest_brcm_rpi4.xml の46行目 <!-- FFmpeg --> 以下にdav1dを追記 Added missing dav1d library in the local manifest by jijith700 · Pull Request #5 · grapeup/aaos_local_manifest · GitHub ## local_manifestに不足しているdav1dライブラリを追加 <!-- FFmpeg --> <project path="external/dav1d" name="raspberry-vanilla/android_external_dav1d" remote="github" revision="android-13.0" /> コンパイル . build/envsetup.sh lunch aosp_rpi4-userdebug make bootimage systemimage vendorimage -j$(nproc) イメージの書き込みとデプロイ MicroSDをクリーンします。 sudo umount /dev/sdb* sudo wipefs -a /dev/sdb* sudo wipefs -a /dev/sdb 次にMicroSDに4つのパーティションテーブルを作成しイメージ書き込みします。 MicroSDに書き込むイメージは boot.img , system.img , vendor.img の3つです。 sudo dd if=boot.img of=/dev/sdb1 bs=1M というコマンドで書き込みできると思ってトライしましたが、手順が多く難しかったので GParted というパーティション編集ソフトを使いました。 Android Automotive OSの起動 MicroSDをRaspberry Piに刺して起動します。Raspberry Piにはタッチモニターを接続しておくとマウスがなくても操作が可能なので便利です。 私は手持ちのタッチモニターがなく、泣く泣くPC用モニターに繋げています。 Android Auto や Android Automotive OS で動く車載向けアプリを開発する 次にAndroidで車載アプリを実装、デバッグする上で基礎となるところをご紹介します。 Android Autoはスマートフォンと連携して車載ディスプレイにアプリを表示するのに対し、 Android Automotive OSは車載システム自体にAndroidが組み込まれており、アプリを直接インストールできます。 今回は経路案内アプリを試しに実装しました。 以下開発環境はMacです。 サポートされるアプリのカテゴリと対応するAndroidのAPI カテゴリ 説明 対応する Android API メディア 音楽、ポッドキャスト、オーディオブック向けのアプリ MediaBrowserService を使用して、コンテンツのブラウジングや再生制御を行います。 MediaSession を使用して、再生状態やメタデータをシステムに通知します。 ナビゲーション 音声案内や視覚ガイドによるターンバイターンの道案内 CarAppLibrary の NavigationManager を使用して、ナビゲーションの開始、終了、 目的地設定、 ターンバイターンの案内などを制御します。 ポイント・オブ・インタレスト (POI) 駐車場、EV充電スポット、ガソリンスタンドなどの場所を見つけるアプリ PlaceClient を使用して、場所の検索、詳細情報の取得、 プレイスオートコンプリートなどの機能を実装します。 CarAppLibrary の PlaceListMapTemplate を使用して、POI を地図上に表示します。 メッセージング( Android Auto のみ) 音声入力によるハンズフリーメッセージの返信 CarAppLibrary の MessagingManager を使用して、メッセージの送受信、音声入力、 テンプレートメッセージの送信などを制御します。 ゲーム 駐車時のエンターテイメント用アプリ CarAppLibrary の ScreenManager を使用して、駐車時にゲーム画面を表示します。 InputManager を使用して、ゲームのコントロール入力を受け取ります。 ブラウザ & ビデオ ブラウザの統合やビデオ再生機能(AAOS特有、 駐車中に使用されることが多い) CarAppLibrary の WebTemplate を使用して、Web コンテンツを表示します。 VideoTemplate を使用して、ビデオコンテンツを再生します。 これらのテンプレートは、 駐車時にのみ使用することが推奨されます。 補足 公式ドキュメント の対応表の要点を抜粋しました。 毎年新しいカテゴリが追加されているため、まだアプリを広くリリースできない場合でも、将来的にはリリースできるようになる可能性があります。 CarAppLibrary は、Android Auto および Android Automotive OS アプリ開発のための Jetpack ライブラリです。 PlaceClient は、Google Places API を使用するクライアントです。 Desktop Head Unit (DHU) DHUとは? Android Autoの環境をデスクトップでエミュレートするツールです。 実際の車載端末を使わずに、車内体験をシミュレーションできます。 なぜDHUを使うのか? アプリが車載環境でどのように動作し、表示されるかをテストできます。 UI/UXが運転者の注意を逸らさないようにガイドラインに準拠しているかをデバッグし確認できます。 DHUを起動する DHUを起動する手順を行うために以下が必要です。 Macbook Android デバイス SDK ManagerでAndroid Auto Desktop Head Unit Emulatorをインストールする Library/Android/sdk/extras/google/auto に desktop-head-unit があることを確認する desktop-head-unit に権限を与えます chmod +x ./desktop-head-unit Android デバイスの同じポート番号にソケット接続を転送します。 adb forward tcp:5277 tcp:5277 Android デバイスでAutoの設定を開きます [アプリ] > [Android Auto] > [詳細設定] > [アプリ内のその他の設定] をタップします。 バージョンと権限情報を10回ほどタップして開発モードにします。 起動します ./desktop-head-unit --usb Hostについて Android Auto や Android Automotive対応車で作成したアプリを動かすとき、アプリは車と直接やりとりする訳ではありません。このときの接続先はAndroid デバイスに入っている Android Auto アプリです。 DHUのインストール手順で、USB接続した実機と接続する必要があるのはこのホストの役割をする、Android Autoアプリと連携する必要があるからです。 Android Auto アプリはホストと呼ばれ、全ての Auto 対応アプリはこのホストとやりとりします。 もし Android Automotive 対応の車で動かす場合は車載器に OS が入っているので、Android Automotive がホストになります。 ライブラリ CarAppLibrary は、Android Auto および Android Automotive OS アプリ開発のための Jetpack ライブラリです。 CarAppLibrary を使用して構築されたアプリは、Auto または Automotive 上で直接実行されるのではなく、ホストアプリを介して動作します。 プロジェクトレベルbuild.gradleにCarAppLibraryのバージョンを宣言します。 buildscript { ext { car_app_library_version = '1.4.0' } } dependencies { ... implementation "androidx.car.app:app:$car_app_library_version" ... } サービス、セッションの追加 CarAppServiceを継承したクラスを追加します。 ホストによってバインドされるCarAppServiceを拡張する必要があります。 インテントフィルターで、自動車アプリのカテゴリとして androidx.car.app.category.POI を宣言する必要があります。 <service android:name="com.example.places.carappservice.PlacesCarAppService" android:exported="true"> <intent-filter> <action android:name="androidx.car.app.CarAppService" /> <category android:name="androidx.car.app.category.POI" /> </intent-filter> </service> CarAppService抽象クラスは、 onBind や onUnbind などのオーバーライドはできません。ホストアプリとの適切な相互の運用はライブラリがよしなにやってくれてます。 createHostValidator と onCreateSession を実装するだけです。 createHostValidator で返すHostValidatorは、CarAppServiceがバインドされるときに参照され、ホストが信頼されていることを確認し、ホストが定義したパラメータと一致しない場合にバインドが失敗するようにします。 ALLOW_ALL_HOSTS_VALIDATOR は検証でのみ使えるHostValidatorです。 class PlacesCarAppService : CarAppService() { override fun createHostValidator(): HostValidator { return HostValidator.ALLOW_ALL_HOSTS_VALIDATOR } override fun onCreateSession(): Session { return PlacesSession() } } PlacesSessionクラスを追加します。 class PlacesSession : Session() { override fun onCreateScreen(intent: Intent): Screen { return MainScreen(carContext) } } Template 決まったテンプレートの中から選んでガイドラインに沿って実装する必要があります。 自動車向けアプリはドライバーに最適なUIでなければいけないので、UI UXが限定的になってきます。 参照元:公式のテンプレートのドキュメント また、マップを表示するテンプレートにアクセスするために使用するパーミッションを追加します。 <uses-permission android:name="androidx.car.app.MAP_TEMPLATES" /> 場所情報をリストアップする 起動したら場所のリストアップをします。 UIはComposableで実装可能です。 CarAppLibraryの Screen を継承した MainScreen を追加します。 場所の一覧とマップを表示するため、 onGetTemplate で PlaceListMapTemplate を返します。TemplateはBuilderデザインパターンで実装されています。 一覧表示するアイテムを setItemList にて渡しTemplateをビルドし返します。 一覧表示するアイテムの構築には ItemListBuilder を使います。 class MainScreen( carContext: CarContext, ) : Screen(carContext) { override fun onGetTemplate(): Template { val placesRepository = PlacesRepository() val itemListBuilder = ItemList.Builder() .setNoItemsMessage("No data") placesRepository.getPlaces() .forEach { itemListBuilder.addItem( Row.Builder() .setTitle(it.name) // リスト内の各項目は、タイトルまたはテキスト行にDistanceSpanを追加する必要があります。 .addText( SpannableString(" ").apply { setSpan( DistanceSpan.create( Distance.create(Math.random() * 100, Distance.UNIT_KILOMETERS), ), 0, 1, Spannable.SPAN_INCLUSIVE_INCLUSIVE, ) }, ) .setOnClickListener { screenManager.push(DetailScreen(carContext = carContext, placeId = it.id)) } .setMetadata( Metadata.Builder() .setPlace( Place.Builder(CarLocation.create(it.latitude, it.longitude)) .setMarker(PlaceMarker.Builder().build()) .build(), ) .build(), ).build(), ) } return PlaceListMapTemplate.Builder() .setTitle("Places") .setItemList(itemListBuilder.build()) .build() } } 場所の詳細情報を表示する PaneTemplateを使って詳細画面を実装します。 class DetailScreen(carContext: CarContext, private val placeId: Int) : Screen(carContext) { private var isFavorite = false override fun onGetTemplate(): Template { val place = PlacesRepository().getPlace(placeId) ?: return MessageTemplate.Builder("Place not found") .setHeaderAction(Action.BACK) .build() val navigateAction = Action.Builder() .setTitle("Navigate") .setIcon( CarIcon.Builder( IconCompat.createWithResource( carContext, R.drawable.baseline_navigation_24 ) ).build() ) .setOnClickListener { carContext.startCarApp(place.toIntent(CarContext.ACTION_NAVIGATE)) } .build() val actionStrip = ActionStrip.Builder() .addAction( Action.Builder() .setIcon( CarIcon.Builder( IconCompat.createWithResource( carContext, R.drawable.baseline_favorite_24 ) ).setTint( if (isFavorite) CarColor.RED else CarColor.createCustom( Color.LTGRAY, Color.DKGRAY ) ).build() ) .setOnClickListener { isFavorite = !isFavorite // 画面の状態の更新を拾えるように、`onGetTemplate`を再度呼び出すようにinvalidate()をコールする invalidate() }.build() ) .build() return PaneTemplate.Builder( Pane.Builder() .addAction(navigateAction) .addRow( Row.Builder() .setTitle("Coordinates") .addText("${place.latitude}, ${place.longitude}") .build() ).addRow( Row.Builder() .setTitle("Description") .addText(place.description) .build() ).build() ) .setTitle(place.name) .setHeaderAction(Action.BACK) .setActionStrip(actionStrip) .build() } } アプリの起動 他のアプリを起動しようとするとエラー Caused by: androidx.car.app.HostException: Remote startCarApp call failed ナビゲーションを開始しようとして(startCarAppをコールする場所)エラーが発生する可能性があります。 その場合、ナビゲーションアプリがインストールされていないことが原因です。 エミュレータ上のPlayストアで探してもらえたらナビゲーションアプリはすぐ見つかります。 アプリで得られる車両プロパティ 検証はまだしていませんが、以下が取得できるとのことです。エミュレータで設定値を変えることができるのかもしれません。 参照元 速度情報 (Vehicle Speed) 車両の現在の速度を取得できます。通常は km/h で提供され、速度制限や運転支援機能に基づいたアクションに使用されます。 燃料レベル (Fuel Level) ガソリン車であれば、タンク内の燃料残量を取得できます。これはアプリで「燃料が少ない」警告や最寄りのガソリンスタンドの提案などに使用されることがあります。 バッテリー残量 (Battery Level) 電気自動車(EV)やハイブリッド車の場合、車両バッテリーの状態をモニタリングできます。充電状況やバッテリー残量を表示するために利用されます。 ドアステータス (Door Status) 各ドア(フロント、リア、トランク、フード)の開閉状況を取得できます。ドアが開いている場合に通知したり、閉じ忘れを防ぐアラートを設定できます。 ライトの状態 (Light Status) 車両のライト(ヘッドライト、ハイビーム、フォグライトなど)のオンオフの状態を取得できます。これにより、夜間モードの切り替えやドライバーへのフィードバックが可能です。 エンジンの状態 (Engine Status) エンジンのオンオフやアイドリング状態を取得できます。アプリケーションは、エンジンがオフのときに特定の操作を制限できます。 パーキングブレーキの状態 (Parking Brake Status) パーキングブレーキがかかっているか、解除されているかの状態を取得できます。これにより、駐車中のインタラクションやアプリ機能を制御できます。 ギアの位置 (Gear Position) シフトレバーの位置(パーキング、リバース、ニュートラル、ドライブなど)を取得できます。これにより、バックカメラの自動起動やギアに基づいたインターフェースの切り替えを行うことが可能です。 タイヤの状態 (Tire Pressure) タイヤの空気圧などの情報を取得できます。これにより、低圧の警告やメンテナンスのアラートを通知できます。 外部温度 (External Temperature) 車外の温度を取得でき、天候や走行条件に基づいたインターフェースや運転者への通知に利用できます。 座席センサー (Seat Occupancy Status) 各座席の乗員の有無やシートベルトの装着状況を取得します。安全のため、シートベルト未装着の警告を表示する場合に使用されます。 ウィンドウステータス (Window Status) 各窓の開閉状況をモニタリングできます。例えば、運転終了時にウィンドウが開いたままの場合、通知を出すことができます。 HVAC(エアコン)の状態 (HVAC Status) 車両の空調システム(暖房、冷房、風量、風向)の設定や状態を取得できます。これにより、快適な車内環境をアプリで制御できます。 位置情報 (GPS Location) 車両の現在の GPS 位置情報を取得できます。これにより、ナビゲーションアプリや場所ベースのサービスが利用可能です。 ワイパーの状態 (Wiper Status) ワイパーの作動状態を取得できます。天候や視界状況に基づいたUIの調整に役立ちます。 最後に 最後まで読んでいただきありがとうございます。 Android Automotive OS 素人がクローンとビルドして起動できるくらいに、Androidのオープンソースは品質維持され、簡単でした。ですが、要求されるPCスペックは高いです。弊社エンジニアに世界には最初からAndroid Automotive OSがインストールされた基盤が売ってるよと教えてくれ、早く言ってよ〜と思いましたが、OSを起動できた時は感動しました。 AutoおよびAutomotiveアプリ開発について 自動車向けアプリの実装はどういったものか、概観を掴む目的のため大雑把な記事になってしまいましたが、手順が少なく実装できることがわかりました。 Hostアプリの概念やエミュレータ起動の手順がやや面倒なところがあります。 自動車向けアプリの開発はUIのカスタマイズ性が無いぶん、より「何ができるアプリなのか」を洗練することに醍醐味があるかもしれません。 今後、自動運転が普通に乗れる未来がくれば、運転者もゲームができたりカテゴリが増える未来が来るかもしれませんね。 おまけ 運転について幼い頃を振り返り、 弊社の先輩の記事 にインスパイアされ音楽生成AIで音楽を作ってみたのが以下ですが、エモくていい感じでした。 ここまで聴いてくれるのは同僚くらいかと思います。感想お待ちしております。 https://soundcloud.com/numami-775711983/5qclozsqk1mz
アバター
はじめに KTCデータ分析部 分析G マネージャの西口です。 未来に向けた技術開発や研究が、現実社会での課題解決にどのように貢献できるかを考えることは、イノベーションを推進する上で重要なテーマです。しかし、研究者と企業の間には「未来に必要な研究」と「現場で今すぐ使いたい技術」というズレが存在します。このため、両者が連携しづらいという課題が生じています。この記事では、この「マッチングの壁」を乗り越えるための取り組みについて、これまでの活動と今後の展望を紹介します。 (Generated by Microsoft Copilot) これまでの活動 トヨタ自動車には 未来創生センター (以下、FRC)という「未来につながる研究」を行っている部門があります。FRCとはご縁があって、KINTOテクノロジーズ(以下、KTC)のデータ分析部で抱える研究的な課題の助っ人として参加していただきました。それがこの取り組みの始まりでした。当初は、具体的なデータサイエンス課題があり、特に問題もなく新規性のある研究案件として進めることができました。教科書に出てくるデータサイエンスの課題では、予測値そのものが評価の対象となります。しかし、ビジネスの観点から見ると、予測値の信頼性やばらつきについても重要です。つまり、どれくらいの確度で予測ができるのかを知りたいということです。その後もいくつかの課題が浮上し、さらなる取り組みを続けていくことになりました。当初はそれほど苦労することもなく、それらの課題をビジネスに寄与する研究案件とでき、ご支援をいただいてきました。 マッチングの苦労 しかし、問題が出てきました。それは取り組む案件の制約事項がお互いで異なるということが明らかになってきたのです。具体的には、共に目指すのはユーザーの体験価値の向上ですが、その成果がKTC側は「製品化」であるのに対して、FRC側は「未来につながる研究」(成果物としては特許化や論文化)だということです。それらの違いが、例えばスケジュール感だったり、完成度のレベル感だったりと、協業しづらい制約となってきました。このような制約事項の中でマッチングすると、「あったら嬉しいが無くても困らない技術」を研究の対象とせざるを得ませんでした。結果、構築された技術は現場にとっては優先度が低く活用されないため、「研究部隊」と「ビジネス現場」の連携の難しさを痛感しました。 (Generated by Microsoft Copilot) アイデアソンの実施 1. アイデアソンへの期待 その解決策の1つとして、「アイデアソン」を実施しました。アイデアソンとは、短期間で課題に対する新しいアイデアを出し合い発展させるためのワークショップ形式のイベントです。このイベントを通して、FRCとKTCの双方が参加し、自由な発想でお互いの技術や研究を生かし合える方法を考える機会になるのではと考えました。また中長期的にも両者が潜在的な協力の可能性を発見し、KTCとしては技術の応用方法について新しい視点を持つこと、FRCでも次の研究の“種”に繋がっていくことを期待しました。 取り組みの目的 アイデアソンでの期待 研究サイド 未来に必要な研究 種の発見 ビジネスサイド 今すぐ使いたい技術 新たな視点 2.実施の流れ 具体的な動きとしては、FRCに紹介できそうな技術リストを作ってもらい、それをKTCでアンケートを取り、その結果をもとに2つの技術紹介をお願いしました。当日は、その2つの技術の紹介と簡単な質疑応答の後、アイデアソンを行いました。 3.実施状況 2024年9月に実施 16:00~17:30 勉強会:2つの技術紹介 技術A:レコメンデーションに関する技術 技術B:顧客心理測定に関する技術 17:40~19:00 アイデアソン(各テーブル25分) FRCから7名(オンライン1名)、KTCから11名(オンライン3名)が集まりました。アイデアソンではKTCのメンバーを3つに分け、技術Aのテーブルと技術Bのテーブル、そしてフリーディスカッションのテーブルを順に回ってもらう形を取りました。それぞれのテーブルはFRC2~3名、KTC3~4名という構成で行われました。一部のメンバーを除き、今回がほぼ初対面だったので、最初は自己紹介と業務内容の紹介がなされたあと、それをもとにそれぞれのテーブルのテーマでディスカッションが始まりました。25分はあっという間で、ちょうど盛り上がってきたところでタイムアップというような場面も多く見受けられました。そんななか、実際にマッチングできそうな案件が出てきて、FRC研究者とKTCエンジニアですぐに詳細の擦り合わせを始めています。具体的なことは言えませんが、KTCが追求する「顧客理解」と研究部門の技術がうまく噛み合うと、話が進展しそうな手応えを感じました。 4.実施後の参加メンバーからの感想と今回の反省点 実施後にKTC参加メンバーにアンケートを行いました。満足度は、5点中 4.11で、「内容に興味があれば」の条件ありの場合も含めると全員が次回も「参加したい」という意向でしたので、有意義な時間になったものと考えられます。 ただ、以下のような改善点も出てきました。 勉強会の説明の時間が長い オンラインでの説明は音声が聞き取りにくかった 勉強会の技術説明はKTCの実際のデータを適用した例を含めて欲しい。具体例をもっと増やして欲しい アイデアソンの時間をもっと増やして欲しい アイデアソンの各セッションの冒頭での自己紹介や業務説明が冗長で議論の時間を多くとれなかった これらの点を踏まえ、次回開催時はより円滑な進め方で実施したいと思います。 今後の展望 トヨタグループにはFRCだけでなく、他にも多くの研究部隊が存在します。機会があれば別の研究部隊とも意見交換を行い、マッチングのための場を作っていきたいと考えています。具体的には、ビジネス現場が求める技術や解決策をより明確に提示し、研究者が自身の研究をビジネス現場で活用できる場を設けることです。その逆も同様に、研究者の関心(テーマや課題)を企業に伝えることで、双方の理解が深まっていくと考えます。 このようにすることで、技術が実際の現場で活かされる事例が増えていき、双方にとってWin-Winの関係を築くことができると考えています。そのためには、アイデアソンやマッチングイベントの実績を重ね、よりスムーズな技術と研究の連携を実現する必要があります。これにより、未来に向けた研究の現実世界での実装サイクルが高速化し、より良い社会づくりに貢献できると信じています。 まとめ 未来につながる研究と今使いたい技術を結びつけるには、両者のニーズや期待を理解し合う場が重要です。上記のような勉強会やアイデアソン、ワークショップを通じて、研究者とビジネス側の相互理解が深まり、より実用的な連携が生まれると考えています。 その連携により、 KTCが掲げる「内製開発組織と顧客視点」 にさまざまな新しい技術が加わることで、顧客にいち早く新たな「感動」を届けられると思っています。 今後もKTCは、FRCと新たな技術の開発とその利活用の道を探っていきたいと思います。それは、私たちがモビリティプラットフォーマーのトップランナーとして一人ひとりの「移動」に「感動」をもたらすためにも大切なことだと考えているからです。 (Generated by Microsoft Copilot) <当サイトの内容、テキスト、画像等の無断転載・無断使用を固く禁じます。>
アバター
この記事は KINTOテクノロジーズアドベントカレンダー2024 の5日目の記事です🎅🎄 KINTOテクノロジーズで my route(iOS) を開発しているRyomm a.k.a 幻のbot職人 です。 まなびぃ から小ネタです。 ここではSlack CLIの話として書いていますが、内部的にはSlack CLIもSlack APIを使用していますので、Slack APIを直接使用しているケースでも当てはまるかもしれません。 背景 Slack CLIで以下のような処理を行おうとしたとき、なぜかBlock Kitのメッセージが送れないことがありました。 フォームの入力でrich_text型として値を受け取る 値をrich_text型としてDataStoreに保存 DataStoreから保存したいくつかのrich_text型のデータを取り出して結合し、整形する postMessage を使って作成したblockを送信する しかし、 parameter_validation_failed というエラーで落ちてしまいました。 ![エラー](/assets/blog/authors/ryomm/2024-12-04-2/02.png =600x) 原因 送信部分でパラメータ不正のエラーが出ており、送信しようとしていたblockを調べてみると、以下のように block_id が重複していることがわかりました。 [ { "type": "rich_text", "block_id": "xdrwH", // <- this "elements": [ /* ... */ ] }, { "type": "rich_text", "block_id": "xdrwH", // <- this "elements": [ /* ... */ ] } ] 送ろうとしているメッセージの block_id が衝突しているため、Slackにメッセージを送れないようです。 block_id block_id とは、ブロックの一意の識別子です。 公式ドキュメントには以下のように説明されています。 A unique identifier for a block. If not specified, a block_id will be generated. You can use this block_id when you receive an interaction payload to identify the source of the action. Maximum length for this field is 255 characters. block_id should be unique for each message and each iteration of a message. If a message is updated, use a new block_id. https://api.slack.com/reference/block-kit/blocks block_id を指定せずにブロックを作成した場合は、自動的に block_id が生成されます。 主にインタラクティブなやり取りをしたい場合に使用します。例えばボタンが押された際にどのブロックのボタンを押されたのか?などの特定に役立ちます。 1回のメッセージ、もしくはメッセージの反復(=一連の双方向なやり取り)の中で一意である必要があります。 また、メッセージが更新された際には新しい block_id を使用します。 今回のようにフォームでの入力の場合、受け取ったrich_textに含まれる block_id は自動生成されたものになります。 さらに、冒頭の処理では入力で受け取るrich_textは別々のメッセージとして受け取っているため、 block_id も重複している可能性があります。 実際に今回の問題は block_id が衝突していることで起こりました。 ここで一句 なぜなのか 自動生成 信じてた 衝突するよ block_id 自動生成されたblock_idはUUID的な簡単には衝突しないものだと信じていたのに、衝突したなぁ...という唖然とした気持ちが表れていますね。 これは私の推測ですが、Slack側が自動生成する block_id はブロックの内容をもとに作られていると思われます。 試しに全く同じ入力を行うと、全く同じ block_id が取得できます。 ![エラー](/assets/blog/authors/ryomm/2024-12-04-2/03.png =600x) rich_textにhogeと入力する → 毎回 RlmLN というblock_idが生成される { "type": "rich_text", "block_id": "RlmLN", "elements": [ { "type": "rich_text_section", "elements": [ { "text": "hoge", "type": "text" } ] } ] } このため、全く同じ入力がある可能性がある場合、同じくらい block_id が衝突する可能性もあると考えると良いでしょう。 解決策 さて、いくつかのブロックを結合して1つのメッセージとしてSlackに送りたいとき、メッセージ内のそれぞれのblock_idは一意にする必要があります。 インタラクティブな動作を行わない場合、 block_id を保持する必要性はあまりないので削除してしまうのが一番シンプルな解決策です。 block_id が指定されていない場合はSlack側が自動で生成してくれるため、 block_id を削除したまま送信します。 これは整形を行なっているメソッドの一部です。delete演算子でオブジェクトからblock_idプロパティを削除しています。 // client.apps.datastore.query で取得した結果のitemsが引数eventに入る // 参考: https://api.slack.com/methods/apps.datastore.query#examples function eventMessage(event) { // ... event.description.forEach((description) => { if (description.block_id) { delete description.block_id // 🐈❗️ } message.push(description) }) // ... } これで block_id の衝突を気にせずメッセージを送ることができるようになりました! ただし、インタラクティブなやり取りをしたいときには、オブジェクトから block_id を削除するのは良い方法ではないです。 その場合は、送信時にアプリ側で block_id を作成して割り当てると良いと思います。 おわりに block_id が衝突してメッセージが送れないはなしでした!
アバター
👋Introduction Hello, my name is Sasaki and I am an aspiring retrospective master. I work as a Project Manager at KINTO Technologies. In my previous job, I was a project manager and worked on agile development (Scrum and Kanban) in a team. I really like retrospectives. In my previous job, I used retrospectives to organize minimal design documents, promote CI, and even remove tension between new and senior employees. They were very helpful for both development and mental care. Introduction It's been a year since I joined the company, during which I've released several projects and facilitated retrospectives as a Project Manager. Unlike Scrum team's retrospectives conducted in the iterative development cycle, project retrospectives are for development and release processes that have definite start and end points and involve different members every time. Regarding this type of retrospectives, I found that setting its timing, perspective, and objectives is more challenging in comparison with sprint-based retrospectives. In addition, we had to be careful about operational aspects such as how to draw out honest opinions when we had not yet built relationships with team members, what tools to use in a retrospective that would fit the participating members, what framework to use, and whether to hold the retrospective in person. In this article, I'd like to discuss the approach I adopted for "project retrospectives" as a part of cross-team initiatives, the reasons behind it, as well as the specific retrospective procedures and the outcomes achieved.🙌 Table of Contents Project Retrospective Retrospective Structure Project Retrospective Design Retrospective Practice ::: message This article is useful for: Those interested in learning the issues and solutions involved in project retrospectives Those interested in learning about retrospective templates Those interested in learning how to use templates in retrospectives ::: Project Retrospective Projects at KINTO Technologies KINTO Technologies offers a variety of products for end users and the back office, including products that handle the front-line customer experience, products for dealerships that order cars, and products that support customer centers. In cases where multiple products need to be released in cooperation, such as updates to contract plans or the addition of supported brands , or when there are numerous stakeholders involved, development at KINTO Technologies proceeds in units of projects . Project Progress Each product is developed daily in a different style for each team, such as Scrum. As a project, major processes and milestones are planned, and after requirements analysis and definition are finalized, the design and development process is carried out in an agile manner. The project will proceed using what is commonly known as a hybrid development method (waterfall + scrum). Although products are iteratively developed in daily cycles, the overall development process follows a waterfall model to ensure quality and meet deadlines at each milestone. Source: What is hybrid development? Explanation of the difference from "agile type" and its promotion system About This Project Until now, when canceling KINTO ONE's cancellation fee free plan during the contract period, cancellation had to be done by phone. To improve customer usability, we will make it possible to apply for this service via the web. Apart from this, in our back-office products, we worked on a year-long project to semi-automate and improve the mid-term cancellation process, which was manually operated. As the number of online cancellations increases, the process automation becomes essential to handle a large number of cancellation requests efficiently, along with the update. The development of these two elements will be released as a single project. The project requires four months, involving a total of about 20 team members, including team leaders and planning team members (from KINTO). https://corp.kinto-jp.com/news/service_20240219/ ‍🧙‍♂️ Retrospective Structure To make the retrospective more effective, I would like to refer to the method recommended in my favorite book, "Agile Retrospectives." We'll proceed with the retrospective divided into the following five sections: 1. Set the Stage Make it easier for people to express their opinions by breaking the ice and reading out the ground rules 2. Collect Data Review the source information from the retrospective and post sticky notes on the whiteboard. 3. Generate Insights Verbalize your ideas through exercises such as brainstorming. 4. Decide What to Do (Determination of action items) Participants use dot voting to decide which actions should be prioritized. 5. Close the Retrospective Summarize action items, express thanks, and conclude the retrospective. Brief summary To briefly summarize, we create a comfortable environment for open discussion, encourage participants to share their thoughts on the whiteboard, and then identify actions and improvements for the issues raised. These will be followed on the day of the event. This structure is mainly used for creating the agenda, but this book also includes detailed tips, such as setting retrospective time according to the development period. We will refer to this book at key points as we design the retrospective. If you're interested, I recommend reading Agile Retrospectives! Agile Retrospectives (Amazon) 🏗️ Retrospective Design The content of retrospectives should vary depending on the nature of the project, the participants, and other contextual factors. I’ll try to walk you through the design process of my retrospective step by step. Confirm assumptions and constraints Goals setting Design and review of the process 1. Assumptions and Constraints First, I organize the assumptions and constraints for the retrospective. Since various teams are participating in this project, I outline the key points to prevent any delays in progress. Differences in retrospective culture among teams Some teams conduct retrospectives regularly, while others don’t Some people have experience with KPT but are unfamiliar with other methods. Differences in tool proficiency Some teams are not familiar with using whiteboards Some people don't know Miro Some people need additional permissions to access tools, such as Confluence Differences in participant locations Tokyo, Nagoya, Osaka Others This project is a fixed-term, cross-team initiative and will conclude upon completion. 💭 What I Thought Differences in retrospective culture Looking at the meeting schedules, there were clear cultural differences between teams that conducted sprint retrospectives and those that did not. Everyone seems to know about KPT, as they have conducted KPT in previous projects. Tool selection Since multiple teams participated, there were differences in the level of familiarity with the tools depending on the team. It can be uncomfortable to join a meeting without a good understanding of the tool, so I always try to ensure everyone can participate positively without getting let down by tool usage Meeting time settings I don't know about the entire company, but I feel that the meeting times are shorter compared to my previous job. Long meetings are about 30 minutes and many people feel that any meeting lasting over an hour is too lengthy. Some teams may have members who aren't fully proactive about project retrospectives and participate more out of obligation (believing that their contributions within their respective teams are enough). Taking this into consideration, I want to set the time as short as possible so that it is less likely to cause confusion. Location (Onsite/Offsite) Since some people are based in different locations, it is also important to decide whether to hold the meeting in person or online. If holding the meeting in person, it is important to ensure that online members do not feel left out. When I asked the question on the company's agile channel, everyone shared the methods they have used in the past and the points to be careful about (hybrid meetings, using Jamboards, etc. Thank you everyone!) Psychological safety Psychological anxiety is another factor to consider. Since communication isn't well established across members from different teams, it can be difficult to draw out their true feelings. Our goal was to create an environment that fosters as much psychological safety as possible. Now, how do we proceed? 2. Goals setting I'll set the goals I'd like to achieve in this retrospective as the Project Manager and facilitator. 💭 What I Thought I hoped this retrospective would drive improvements beyond organizational boundaries and enable cross-functional enhancements to the service itself. However, as I'm still in the early stages of building trust with the participants, it's challenging to expand the scope of the retrospective at this point. With that in mind, I decided to focus this retrospective on sharing project results and resolving issues within my control (project management) . Regarding the cross-sectional issues and problems that came up during the discussion, I would like to keep them as a common understanding for future improvements. I also want to help everyone get comfortable with interactive retrospectives at an organizational level, so I definitely plan to use the whiteboard. The main mission Review and share project outcomes Identify improvement tasks as project management The sub-mission Gain a common understanding between planning and development on the larger issues Introduce interactive retrospectives using whiteboards 3. Design and review of the process To achieve our goals while keeping the aforementioned constraints in mind, I'll consider how to proceed with the day's retrospective. 1. Set the stage Psychological safety Since many members will participate in the retrospective, we will proceed according to a set flow to some extent. In order to explain these and ensure psychological safety in the space, we will declare the ground rules at the beginning. Since we want to convey them little by little, we will also casually put them on the whiteboard in a visible place. Time settings According to Agile Retrospective guidelines, a release retrospective can last from one to nearly four days. However, as mentioned, even an hour feels too long for many participants, so I'd like to condense it to around 45 minutes. 2.3 Determine the time required How much time should we spend on a retrospective? It depends. -omitted- For a team doing a one-week iteration, an hour of retrospective is sufficient. For a team doing a 30 day iteration, half a day is enough. Shorter time will give lax results. (Release and project retrospectives take at least one day. In some cases, they may take four days.) Quote: Agile Retrospectives , Chapter 2. 2. Collect data Differences in retrospective culture / Tool selection Since KPT is a popular method at KINTO Technologies and we frequently use Confluence as a primary tool in our work, we'll utilize Confluence whiteboards , which eliminates preparation hassles like setting up accounts. The following two exercises are used to collect data. Some of you may not be familiar with Timeline. Here is a detailed description of each. Timeline KPT Timeline When you go into retrospectives without preparation, the focus often ends up on the most recent and memorable events. A timeline is an exercise to help you remember what happened in the past. by arranging key facts and feelings in chronological order over a specific period. Quote: What is a Timeline? https://anablava.medium.com/a-timeline-retrospective-easy-guide-6385fce0affd This time, instead of having the full timeline described, I'll casually leave a timeline written by the Project Manager in advance. Participants can then add sticky notes with any additional thoughts they have. We won't be using dot voting, either. I borrowed this idea of a pre-prepared timeline from Kin-chan of the Agile channel. Since this is a release retrospective, I'd ideally like to gather deeper emotional insights, but since we have a limited time of 45 minutes, I'll keep it simple. KPT Many people have done this before and even if some of you have never done it before, it is easy to understand, so we will use KPT for this retrospective. I think many people have come across this at some point, such as during orientation in their student days or group training at a company. It is a framework for raising Keep, Problem, and Try, and looking for ways to improve each topic. The acronym is KPT (pronounced Kept / Key-pi-ti). I call it Kept. K eep: What I have done and what I want to continue P roblem: Issues, problems, and things you want to improve T ry: What you want to challenge Points to note about KPT KPT is the most major method of retrospective, but since it begins with identifying "problems," it can easily lead to frustration or make it challenging to express minor uncertainties. In addition, personal opinions are sometimes treated as problems. When I facilitate KPT, I try to be more objective and careful with my language than usual. *This is completely personal preference, but it might be helpful to use KPT after a demonstration or presentation of results! (Because issues related to product functionality are more likely to be raised by the development team members themselves.) 4. Generate insights Ideas will be generated in the Try of KPT. Since many of the participants are busy, it is acceptable for them to write their ideas in advance. However, doing so may weaken the connection between KP and Try, so dedicated time will be set aside on the day of the retrospective to review and dive deeper into the Try content. 5. Decide what to do (determination of action items) In the Scrum team retrospective, we get commitments through dot voting, but this time, we have a limited time (45 minutes), so we will facilitate and select action items. Organizational issues outside the project scope may also be included on the agenda. While accepting the major issues at hand, we will prepare ourselves mentally to make concrete improvements to project management. 🎯Practicing retrospectives After going through the above design, I will summarize the actual retrospective I conducted. *It's a small detail, but I'll also share key considerations for those looking to introduce a new retrospective. 1. Guidance and follow-up for the retrospective meeting (Preparation) Request for collection of project results Notification on whiteboard usage and opt-out option *If possible, speak to them individually at your seat or speak up at the end of the meeting. Provide pre-use whiteboards for those who are busy and prefer to write their input in advance. 2. Setting the scene Briefly review the ground rules to create a comfortable atmosphere for open discussion. Gently remind everyone like, "Let's keep it positive—no criticizing!" Ground rules This is a safe space to share feedback. - Avoid language that may offend others - Share everything you are willing to share - Focus on improvement, not blame - Feel free to copy or add to someone else's sticky note 3. Collect data Each team presented specific results as a project. It seems that the number of man-hours has been significantly reduced because cancellations that were previously accepted by phone can now be applied for online! A. Timeline notes We asked participants to voluntarily write down on the timeline any feelings or thoughts they had at the time. It was clear from their impressions that they had difficulties even after the release. This kind of feedback is difficult to capture with the "Keep, Problem, Try" (KPT) so I'm glad we were able to obtain it. B. "Keep, Problem, Try" notes Some participants prepared their notes in advance, while others shared during the session, resulting in a diverse range of opinions. Since many of the participants were busy, we decided it is acceptable to write only "Try" and asked them to include "Try" as a set with "Keep" and "Problem." *Since there is a lot of work-related content, text has been blurred. 4. Generate insights After a brief reading of all the sticky notes, we ask participants for their impressions of the KPT so far. As they talk about their impressions, a discussion will arise, so while facilitating, I will collect any new ideas that could lead to trying them and stick them on sticky notes. 5. Determine action items We will turn what can be improved through PjM management and the tries that can be tackled in the next project into actions. *The following is an excerpt of content that can be shared during the course of work. 6. Close the retrospective Let's summarize the above, express thanks, and dismiss. Outcome of this Retrospective The following results were obtained through the retrospective. Outcome as a project Regarding the effectiveness of the project, all involved parties were able to see concrete figures showing the reduction in labor hours. Participants were able to celebrate the project release together. Improvement actions were generated for project issues. We were able to gain a common understanding of issues across organizations (e.g., how to handle design materials). Other outcomes It took quite some courage to suggest using a whiteboard, but it was readily accepted. The timeline showed the difficulties encountered after the release, and reaffirmed the importance of stable operation after the release. From the above, I was able to achieve the goals I had planned as a facilitator. 🎉 The main mission Review and share the project outcomes: Achieved Identify improvement tasks as project management: Achieved The sub-mission Achieving common understanding between planning and development regarding large-scale issues: Achieved Introduce interactive retrospective using whiteboards: Achieved For the Future When I tried it, everyone was quick to accept the whiteboard and timeline. I was also able to introduce the timeline, so I'd like to incorporate the 4Ls and similar techniques after some time. Regarding time constraints, I may have been too hesitant and could have extended it. Or, if we have retrospectives at project milestones as well as at release, we might be able to time them nicely, even with a 45-minute limit. We can also make improvements at the right time when problems arise! Thoughts In this article, I've summarized my thoughts and methods for conducting project retrospectives. I hope this can help anyone facing similar challenges with project retrospectives! Retrospectives are like the poster child of agile, embodying iterative inspection and adaptation. Hope you all enjoy your retrospectives!
アバター
この記事は KINTOテクノロジーズアドベントカレンダー2024 の4日目の記事です🎅🎄 メリークリスマス✌️🎅 KINTOテクノロジーズ(以下KTC)で my route(iOS) を開発しているRyommです…が、今回は幻のbot職人 Ryommとして、学びの道の駅プロジェクトと共同で開発した超エキサイティングなSlack bot「まなびぃ」を紹介します。 まなびぃとは 社内の勉強会やイベントを収集し、集めたデータを活用するための超エキサイティングなSlack botです。 イベント関係のすべてを内包しています。 ![まなびぃ](/assets/blog/authors/ryomm/2024-12-04/01.png =200x) まなびぃの主な役割としては、以下の2つがあります。 イベントの検索 新規イベントの登録・周知 まなびぃに新規立ち上げイベントを入力すると、然るべきチャンネルにイベントを周知します。 また、ユーザは上記のチャンネルをウォッチしたり、まなびぃに問い合わせることで社内イベントにアクセスできます。 直接の関係者じゃなくても情報を得られる まなびぃの活用に関しては別日の【学びの道の駅シリーズ】にて言及がある(はず)なので、本記事ではまなびぃ周辺の技術に関して紹介します。 まなびぃの技術 まなびぃはSlack CLIを使用して作成しています。 https://api.slack.com/automation/quickstart Slack CLIは、Slack側でDataStoreを立ててくれたりなど、インフラを構築する手間が省けるところが気軽です。 また、開発用の環境もSlack CLI側で作れるところも良いですね。 まなびぃのざっくりとした構成は以下のようになっています。 トリガー まなびぃには3つのトリガーが生えています。 機能 トリガーの種類 イベントの追加 linkトリガー イベントの削除 linkトリガー イベントの検索 eventトリガー ![リンクトリガー](/assets/blog/authors/ryomm/2024-12-04/03.png =500x) ![リンクトリガーフォーム](/assets/blog/authors/ryomm/2024-12-04/04.png =500x) ![eventトリガー](/assets/blog/authors/ryomm/2024-12-04/02.png =500x) Slackのワークフローのトリガーには4種類あります。 トリガー名 説明 linkトリガー 作成するとURLが発行され、Slack上でそのリンクが押されたら実行(Slack以外では無効) scheduledトリガー 時間で実行 eventトリガー メンションやリアクションきっかけで実行 webhookトリガー 特定のURLがPOSTリクエストを受信したときに実行 https://api.slack.com/automation/triggers まなびぃでは基本的にユーザーは検索機能を使用し、イベント運営者のみが追加・削除機能を使用する想定をしています。 そのため、うっかり間違えてイベントを追加・削除されてしまわないようにトリガーの種類を分けています。 またイベントの登録が完了すると、botを呼び出したチャンネルと登録を周知するチャンネル( #notice-new-event )の2つに通知されます。 ![通知](/assets/blog/authors/ryomm/2024-12-04/05.png =500x) こうすることで、作成したチャンネルに関わらず新規に立ち上がったイベントを知ることができます。 もちろん、興味があるキーワードでまなびぃに問い合わせることでも情報を得ることができます。 Block Kit SlackはBlock Kitというフレームワークを使ってリッチなビジュアルのメッセージを作成できます。 以下のBlock Kit Builderというツールを使って体験できるので、使ったことがない方は試してみてください。 https://api.slack.com/tools/block-kit-builder イベント情報の取得結果もBlock Kitを使用してみやすくしています。 https://api.slack.com/block-kit ![Block Kitを使ったメッセージ](/assets/blog/authors/ryomm/2024-12-04/08.png =500x) 参照ページのリンク先がSlackチャンネルへのリンクや、Confluenceページ、キックオフ時の動画など、ものによってはとても長くなりノイズとなってしまうため、「詳細」ボタンのリンクとして設定しています。 文字列だけでなくリンクを含ませたいなどの要望もあり、説明テキストのフィールドはrich_text型を採用しています。 🕺Slack bot開発Tipsのコーナー🕺 送信時にBlock Kitを使うかどうかははじめに決めておく まなびぃはstring型で少し運用してからrich_text型に変更することにしたのですが、string型とrich_text型は互換性がないためDataStoreのマイグレーションが一筋縄ではいきません。 さらに、登録済データもrich_textになったなら改行やリンクを含めたい!など諸々の事情を踏まえた判断の上、1回DataStoreのデータを吹き飛ばす荒技を行いました。超エキサイティング! 決められるなら、はじめにBlock Kitを使うかどうかを判断しておくと苦労せずに済みます。 https://api.slack.com/automation/datastores block_idの扱いに気をつける 詳細はこちらの記事へ: 【Slack CLI】block_idが衝突してSlackにメッセージを送れない Workflowはビルド時しか実行されない テストを考えたとき、UUIDを渡すようなメソッドを作成する際はidをメソッド外から渡すようにしたいです。 const addEventFunctionStep = AddEventWorkflow.addStep( AddEventFunction, { id: crypto.randomUUID(), // メソッドの呼び出し側でIDを生成したい title: formData.outputs.fields.title } ) しかし、Workflowの定義部分はビルド時のみ実行され、その後の呼び出し時にはfunctionの中のみが実行されます。 そのため、UUIDの生成など、処理のたびに実行されてほしいコードはメソッドの中に含めるようにします。 ドキュメントを見つけるのが大変すぎる 基本的にSlack APIのドキュメントがそのまま適用できることが多いです。 特に、私はtriggerのinputや、フォーム、DataStoreでどんな型が使えるのか彷徨いました。 そんなあなたにはこのドキュメントで万事解決です! https://api.slack.com/automation/types まなびぃを支える技術 まなびぃは一応インナーソースという扱いであり、開発環境もかなり整えてあるのでご紹介します。 CI/CD 【テスト】 Slack CLIはDenoで動いているため、 deno test でテストを実行できます。 name: 🧪 Slack App Test on: pull_request: types: [opened, synchronize, reopened, ready_for_review] jobs: build: runs-on: ubuntu-latest timeout-minutes: 5 steps: - uses: actions/checkout@v4 - name: Install Deno runtime uses: denoland/setup-deno@v1 with: deno-version: v1.x - name: Install Slack CLI if: steps.cache-slack.outputs.cache-hit != 'true' run: | curl -fsSL https://downloads.slack-edge.com/slack-cli/install.sh | bash - name: Test the app run: | cd app/ deno test --no-check 【デプロイ】 手元のコンソールで slack auth token コマンドを実行すると xoxp- からはじまるサービストークンが取得できます。これをGitHubのシークレットに登録しておきます。 ワークフローの定義は以下のとおりです。 name: 🏃‍➡️ Slack App Deploy on: push: branches: [ main ] workflow_dispatch: jobs: build: runs-on: ubuntu-latest timeout-minutes: 5 steps: - uses: actions/checkout@v4 - name: Install Deno runtime uses: denoland/setup-deno@v1 with: deno-version: v1.x - name: Install Slack CLI if: steps.cache-slack.outputs.cache-hit != 'true' run: | curl -fsSL https://downloads.slack-edge.com/slack-cli/install.sh | bash - name: Deploy the app env: SLACK_SERVICE_TOKEN: ${{ secrets.SLACK_SERVICE_TOKEN }} run: | cd app/ slack deploy -s --token $SLACK_SERVICE_TOKEN これで通常のアプリのコードの更新はデプロイできるようになりました。ただし、トリガーの更新とデータストアの構成変更は自動化できないため、これらのデプロイについては手元で実行する必要がある点に注意です。 Issue Template バグや機能リクエスト、質問などを受け付けられるようにテンプレートを用意しています。 正直ほぼ使われてはいないですが、OSSっぽくて気に入っています。 Project GitHub Projectを使っています。 社内のプロジェクトでは基本Jiraを使用していますが、まなびぃではConfluenceを使っていないこともあり、GitHubに寄せた方が便利なので寄せてます。(あとGitHub Projectの良さを体験して欲しかった) というわけで、全体的にGitHub上で完結するようにしてみました。 私の所属はモバイル開発GなのでSwiftやKotlinがメインで、TypeScriptを書くとなるとハードルが高く感じられる方が多いです。また、部署外にこんなプロジェクトがあるということをアピールするのが難しいためインナーソースプロジェクトとしてはまだまだ課題が多いのが現状です。 まなびぃが成長して大きくなったら、いつか誰かコントリビュートしてくれるかな…と願いながら開発環境を整えています。 おわりに まなびぃを紹介しました。 まだまだ生まれたてのまなびぃですが、KTCのカルチャーと共に成長していければと思います...!
アバター
この記事は KINTOテクノロジーズアドベントカレンダー2024 の4日目の記事です🎅🎄 はじめに こんにちは。モバイルアプリ開発グループでiOSチームのチームリーダーをやっている中口と申します。 普段の業務では、 KINTOかんたん申し込みアプリ (以下「申し込みアプリ」とします。) Prism Japan( スマホアプリ版 / 最近リリースされたばかりのWeb版 ) のiOS開発を担当しています。 本記事では、担当している申し込みアプリをSwiftUI化することになりましたので、その過程や方針について書いていきます。 こちらのブログは iOSエンジニアの方 SwiftUIのアーキテクチャに興味のある方 チームにおいてSwiftUIを導入することになった方 などに読んでもらえたら嬉しいです。 また、本記事は先日開催されました KINTOテクノロジーズ×RIZAPテクノロジーズ Mobile Tips での発表を元に執筆させていただきます。 本記事では、ソースコードなどを用いた具体的なSwiftUI化の実例などは記載しておりません。 一方で、チームとしてどのようにSwiftUI化をすることになったのか、という過程の部分を中心に書いております。 チームでのSwiftUI化に悩みがある方などの一助になれば幸いです。 ファーストリリースの時のアーキテクチャ選定 申し込みアプリは2023年9月にリリースされました。 その際に選定された主なアーキテクチャは UIKit VIPER Combine でした。 2023年の3月ごろより開発が始まった本アプリですが、2023年に新規でiOSアプリを開発する場合「UIKit」にするか「SwiftUI」にするか結構迷いどころですよね?? この時期であればSwiftUIによる開発の方が世間的にもメジャーになっている感覚がありました。 ですが申し込みアプリではUIKitを選定しました。 その理由としては、本アプリが 短納期 であったことと、メンバーに SwiftUIに明るいメンバーがいなかった ことが挙げられます。 新技術を使ってリスクを犯すより、慣れた技術を使って安定的にリリースすることを重視したためです。 ではファーストリリース後、どのような流れでSwiftUI化に至ったのか、次に書いていきます。 # SwiftUIへ移行したい:第1波 2023年のファーストリリース後、バグ改修や小規模アップデート、リファクタリングなどを粛々と進めていましたが、その中で何か新しいことに取り組んでみたいよね、という話が出ました。 いくつかの候補が上がりましたが、その中で人気が高かったのがSwiftUIでした。 2024年の3月ごろにswiftUI化1回目の波が来る チーム内にてSwiftUIを進めるかどうか議論したところ下記のような意見がありました。 ●やる理由 SwiftUIへの興味 ●やらない理由 チーム内にSwiftUIに精通したメンバーが不在 SwiftUIへの明確は必要性を感じない(その当時の時点で) チームメンバーの入れ替えなどもあり新メンバーも多く、SwiftUIに着手している人的、時間的リソースが無い 私自身がチームリーダーとしてSwiftUI化をやり切れる自身がなかった この時はやらない理由が多かった こういった理由からSwiftUI化はまだ先と判断いたしました。 SwiftUIへ移行したい:第2波 それから、約半年が経ちました。 1on1などをやっていると、SwiftUIをやってみたいという意見はまだまだ多く、改めてSwiftUI化について議論することになりました。 2024年の8月ごろにSwiftUI化2回目の波が来る 第1波とは状況も変化しておりまして、再度議論したところ下記のような意見となりました。 ●やる理由 SwiftUIへの興味が徐々に情熱に変わってきた SwiftUI有識者が加入した(社内的な組織変更により) 当時の新メンバーが中心メンバーになっていき、チーム全体として人的、時間的リソースが確保できると感じた ●やらない理由 本当にSwiftUI化に着手して大丈夫かという不安 この時はやる理由が多かった これらの状況からSwiftUI化を進めることと判断いたしました。 目的を間違えてはいけない このようにチーム一丸となってSwiftUI化を進めようとなりましたが、目的を間違えてはいけないと考えています。 (×) 技術的好奇心でSwiftUI化したい、が目的となってしまってはダメ (○) 将来のメンテナンス性をあげる  ・ デファクトスタンダードに追随する  ・ Combineによる実装をしていたが、それが複雑化してきていまっているので脱却したい (×) SwiftUI化することでアプリの質が落ちてしまってはダメ (○) これまでと同水準以上の質を担保する (×) 本来のリリースタスクを後回しにしてSwiftUI化を進めるなど、作業の優先順位を間違えてはダメ (○) 追加機能はこれまでと同じペースで対応する 上記のことはしっかりと意識しつつ、チーム内でどのようにSwiftUI化を進めるか議論を進めました。 # SwiftUI化のアーキテクチャ選定 チーム内でどのようなアーキテクチャを採用したいか議論しましたが、主な意見としては下記が挙げられました。 ライブラリは使いたくない ViewModelは使いたくない 1.ライブラリは使いたくない こちらは主に The Composable Architecture(TCA) を指すのですが、ライブラリを使用するとその「アップデートを常に気にしなくてはいけない」、「サポートが終了したらどうしよう」、などの懸念点からなるべくTCAを使いたくないという意見が多かったです。 また、社内の別プロジェクトてTCAを使っているプロジェクトがあるのですが、そこでも使用感としても、「学習コストが高い」、「ライブラリのアップデートが早すぎてついていくのが大変」、「親Reducerの依存関係が強くなりすぎる」など課題を感じていたこともあり、TCAは見送りました。 2.ViewModelは使いたくない SwiftUIのアーキテクチャにViewModelを採用するかどうかは、よく議論の対象になるかと思いますが、SwiftUIはすでにbindingの機能を有しておりMVVMを使うことでむしろSwiftUIの良さが活かしきれないのではないか、という意見が多かったです。 そのため、ViewModelを使わない方針で意見がまとまりました。 # MVアーキテクチャを採用 その結果、我々のチームは**MVアーキテクチャ**を採用することになりました。 図で示すと下記のような感じになります。 MVアーキテクチャ Viewは原則Modelのみとやりとりを行います。 またAPIで取得したデータなどはモデルを介してViewに渡すようにしています。 現時点で我々はMVアーキテクチャに対して、 シンプルになり、将来的なメンテナンス性の向上につながる(Combine脱却) ライブラリに依存しない SwiftUIの機能を最大限に発揮できる このようなメリットを感じており、上記のアーキテクチャ選定の議論で出たような内容を反映できたと考えています。 SwiftUI化の導入部分における方針 また、SwiftUI化するにあたって導入部分の方針として下記どちらにするかをチームにて議論しました。 まず個別のViewをSwiftUI化する まず画面遷移に関する部分をSwiftUI化する その結果、 「まず画面遷移に関する部分をSwiftUI化する」 という方針にてSwiftUI化を進めることになりました。 その理由としては 経験的に画面遷移にまつわる部分が後々つまずくことが多かった 遷移を管理するViewがUIKitのままだと、個別のViewをSwiftUI化したのにそれを(臨時的に)UIKitにwrapするケースが多く発生する などの理由からです。 # SwiftUI化これから ここまでSwiftUI化の過程や方針を書かせていただきましたが、申し込みアプリのSwiftUI化はまだまだ始まったばかりです。 本記事を掲載する2024年12月時点ではまだ、プロダクションコードにSwiftUIのコードは一切入っていません。 現在は、「毎朝行っている朝会の中で余った時間(20分くらい)を利用する」、「毎週1時間SwiftUIに特化したMtgを行う」など、SwiftUI化のためのコミュニケーションの時間を増やしております。 その中で一部のメンバーにより、SwiftUI化を進めるためのサンプルコードを用意してもらいそちらをベースにチームメンバー全体にレクチャーしたり、チーム内で共通認識を持つためのコーディング規約を整備し始めたところです。 今後もSwiftUI化の実装が本格化したらペアプロやモブプロなども導入していき、チーム全体としてSwiftUIのレベルを上げていきたいと考えております。
アバター
こんにちは。プラットフォームGのPlatformEngneeringチームでPlatformEngineeringの考え方をベースにツール周りの開発・運用・展開の役割(とチームリーダーのようなことをしている、最近はスクラッチ開発側も担当するようになったんでスクラムとかプログラミング言語周りにひーひー言っている) 島村 です。 この記事は KINTOテクノロジーズアドベントカレンダー2024 の4日目の記事です🎅🎄 背景 SBOM(Software Bill of Materials)というものがあります。 2024年に 経済産業省がセキュリティ対策に役立てましょう というのも言ってますし、2021年にアメリカでは標準で作ろうというお話にもなっております。とはいえ、そのために新しいSaaSとかOSSとか色々と導入するのはハードルが高い!と考えてしまうかもしれません。 KTCでは、OSSを活用してCICDのパイプラインに組み込んで、標準的にSBOMを作成して管理しています。 DevSecOpsの文脈で、SBOM作成に合わせて 脆弱性スキャン EOLの検査 も行っています。 「ミニマムスタート」と、その改善の事例としてご紹介します。 利点と欠点 何を使ってたっけ?が見えることが一番! ちょっと前だと、log4jの脆弱性対応が記憶にあるとおもいます。弊社でも使ってないよね?という調査依頼が出されました。当時は設定ファイル見たりとか暫定の回避設定を共通で入れるように周知しましたが、今なら検索すれば一発でわかります。 利点 無料 でEOL/SBOM管理が始められる!👌 有償だと Yamory(Cloudサービス) とか BlackDuck があります SBOM生成だとMicrosoftが提供している SBOM-TOOL もあります 有償ソフトウェアとかSaaSは申請とか諸々の手間が… 使っているツール群はGitHubActionsのActionとして準備されているので、使いやすい。 ローカルでも動かせるので、色々とユースケースとして考えることができそう 欠点 endoflifeなど有志に支えられているものが多いです xeol/syftともに開発が進んで頻繁にバージョンアップされていて、ファイルの不整合が起きることがたまに ツール一覧 名称 機能 概要 Syft SBOM生成 Anchore が提供しているファイルやコンテナイメージからSBOMを生成するソフトウェア。SBOMの標準形式であるCycloneDXもSPDXも対応していますが、標準だとSyft独自形式になるのでご注意を。 KTCではCycloneDXのXMLで出力しています。JSONだとバージョン変わったりすると構成がかなり変わって取込時の考慮が増えるため XEOL EOLスキャナ XEOL が提供しているEOLが含まれているかどうかを判断するスキャナ。内部構成はSyftをベースに、 endoffile.date の情報とマッチングをかけて判断している。主だった言語とOSは対応していることと、Issue上げたら結構早く修正してくれる感じがよいです。SaaSも提供していますが、今回はOSSを利用します。 Trivy 脆弱性スキャナ aqua が提供している脆弱性スキャナ。Anchoreも Grype という脆弱性スキャナを出しているので、Syftと組み合わせるならそっちが良いかと思いましたが、脆弱性検知をした際のCICD上の挙動がTrivyの方が好ましい(表示とか)と判断してこちらを。ファイル、リポジトリ、コンテナイメージ、SBOMからなどスキャンできる対象は多いので使える範囲は多いと思います。SBOMも生成できますが、XEOLの中身がSyftなので、相性を考慮して、今回は脆弱性スキャンだけ使います GitHubActions CICDツール GitHubに包含されているCICDツール。KINTOテクノロジーズではGitHubActionsを使用してアプリケーションのビルド・リリースなどを実行しています。SBOM管理では、コンテナ作成タイミングのワークフローにSBOM生成を組み込んでいます。 CMDB(内製) CMDB Configuration Management Database。構成管理のデータベースのこと。リッチな機能までは不要でしたので、KINTOテクノロジーズではCMDBを内製しています。最近はリポジトリ情報管理、EOL情報やSBOMのパッケージも取り込んで検索できるように機能追加されました。 ワークフロー概要図 パイプライン抜粋(GitHubActions) :::message コンテナビルドやPushについては、タイミングは個々で判断だと思いますので除外しています。 Trivyの脆弱性スキャンの対象をImageにしているので、この抜粋の前にビルドしている想定です。 ::: 基本的にはアプリケーションビルドではなくShipのタイミングで実施しましょう。 SBOMファイルはバージョン管理をしてもよかったんですが、最新のみで問題はないかなと考えて、上書きするようにしています。ビルドに組み込むと、実際にワークロードにあるコンテナのSBOMじゃないものになるので、注意が必要です。 パイプラインでXEOLを2回呼び出しているのは、GitHubActionへのログ表示とファイル生成のためです。モードが別のようで、一括でやってくれなかったんで、分離することになりました。 ## Trivyでの脆弱性診断 - name: Run Trivy vulnerability scanner uses: aquasecurity/trivy-action@master with: image-ref: '${{ ImageName }}:${{ IMAGETAG }}' format: 'table' exit-code: '0' ## 脆弱性があってもImageBuild/Pushをする場合はここを「0」にする ignore-unfixed: false vuln-type: 'os' ## Javaなども含みたい場合は「library」を追加する severity: 'CRITICAL,HIGH' ## SYFTでのSBOM作成 - name: Run Syft make sbom files(format cyclone-dx) uses: anchore/sbom-action@v0 with: image: '${{ ImageName }}:${{ IMAGETAG }}' format: cyclonedx artifact-name: "${{ github.event.repository.name }}-sbom.cyclonedx.xml" output-file: "${{ github.event.repository.name }}-sbom.cyclonedx.xml" upload-artifact-retention: 5 ## Artifactの有効期限 ## XEOLでのSBOMからのEOLライブラリ検知(WF中での表示)とファイル作成 - name: Run XEOL mw/sw EOL scanner from sbom file uses: noqcks/xeol-action@v1.1.1 with: sbom: "${{ github.event.repository.name }}-sbom.cyclonedx.xml" output-format: table fail-build: false - name: Run XEOL mw/sw EOL scanner from sbom file and Output file uses: noqcks/xeol-action@v1.1.1 id: xeol with: sbom: "${{ github.event.repository.name }}-sbom.cyclonedx.xml" output-format: json fail-build: false ## AWSのクレデンシャルの設定(SBOM) - name: AWSクレデンシャル uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ S3_ACCOUNT_ROLE }} aws-region: ${{ AWS_REGION }} ## SBOM/EOLを管理するTeamのS3Bucketに保存する ## イメージ名やリポジトリ名でS3の中で階層分けをするので、Cutで抽出。 - name: SBOM and EOL file sync to s3 bucket run: | ECRREPOS=`echo ${{ ImageName }} | cut -d "/" -f 2,3` echo $ECRREPOS aws s3 cp ${{ github.event.repository.name }}-sbom.cyclonedx.xml s3://${{ s3-bucket-name }}/${{ github.event.repository.name }}/$ECRREPOS/sbom-cyclonedx.xml aws s3 cp ${{ steps.xeol.outputs.report }} s3://${{ s3-bucket-name }}/${{ github.event.repository.name }}/$ECRREPOS/eol-result.json 改善されたことと今後 自分の部署で、AWS-COREのライブラリを使っているかどうかを確認した結果 自分の部署で、EOLがあるかどうかを確認した結果 KTCではCMDBへSBOM/EOLの一覧を取り込んだため、 自身のプロダクトに何のライブラリが使われているか? EOLになっているものはないか? が上記の通り、検索して確認できるようになりました。内製CMDBでは直近でEOLになるライブラリ・パッケージも出してくれるので、事前対応も容易です。 SBOM管理の第一歩は、SBOMファイルなどをJSONで出力して、jqで成形してエクセル管理でもいいと思います。 今後は、定期的にEOLを含んだプロダクトへ、チケットで対応依頼を行う運用を開始したいと考えています。 セキュリティチームとか色々と巻き込んでいくつもりです。 所感 EOL管理周りのツールは調べましたが多くはなく、SBOM管理とかソフトウェア管理、資産管理の延長として提供しているものが多い印象です。 OSSやライブラリを使った開発も多いので、EOLを定期的に見れる改善は脆弱性対策としてもかなり有用かと感じています。ライブラリも1年~2年でEOLとなって、バージョンの追従をする必要が多いと思いますし。 見えるというのは、"気付かない"・"見なかったことに"という対策には良いと思いますので、O11yと同じでまずは「みえる」を目標にしましょう。 実際には、修正依頼も含めた運用まで建付けないと、実効性はないのかもしれません。 が、「ミニマルから始める」と題して、まずは作ろう!始めよう!ということで、今回の記事を書きました。 さいごに PlatformEngneeringチームは、社内向けの横断ツールを統制して必要なものを開発しています。 Platformグループの他チームが作ったものを受け入れたり、必要なものを新規作成や既存のものをマイグレーションしたりしています。MSPチームの定例作業の自動化とか、CDKにも手を出そうとしてるので、ManagedService以外にもプログラミングも行い始めました。 こういった活動に少しでも興味を持ったり話を聞いてみたいと思った方は、お気軽にご連絡いただければと思います。 @ card
アバター
Introduction Hello, I am ahomu, a new member who joined the company in June. In this article, I asked everyone who joined the company in June and July 2024 to share their thoughts and experiences since joining. I hope this will be helpful for anyone interested in KINTO Technologies and serve as a meaningful reflection for those who contributed to it when they look back someday! hosoya ![Photo of a houseplant](/assets/blog/authors/ahomu/20241007/hosoya.jpg =300x) Self-introduction I am hosoya. I am part of the IT/IS Division, where I handle help desk support for in-house systems. How is your team structured? The team consists of five people including myself. In addition to my team, there are several other teams, each with distinct roles, and we collaborate with them based on the nature of the inquiries we receive. What was your first impression of KTC when you joined it? Were there any surprises? I was impressed by how the info sys staff is organized into dedicated teams for each role, with seamless and thorough collaboration among them Having only worked in info sys departments with one or two people before, I was amazed by how well-structured and robust the team here is. What is the atmosphere like on-site? It is a quiet environment where you can focus on your own work. However, it’s easy to talk to the people around you, and whether it’s about work or just casual chatting, the mood instantly brightens. It’s a very cheerful and lively atmosphere. How did you feel about writing a blog post? I imagine that unless you work directly with others, you might not have the opportunity to learn about what they typically do. I hope this blog provides a chance for people to gain that insight A question from someone else: Please tell me about your daily work schedule. Answer: Basically, I get to work at 9:00 a.m., and handle help desk inquiries until I leave at 6:00 p.m. In the mornings and evenings, we hold meetings to share information across the teams The tasks vary depending on the inquiries, but for the most part, I handle routine work each day. my ![Photo of a blue ocean and sky with white clouds](/assets/blog/authors/ahomu/20241007/my.jpg =300x) Self-introduction I am my, and I am in the Data Analysis Division. I am currently working as a data scientist. As a data scientist and machine learning engineer, I have been involved in a variety of work related to data. How is your team structured? It consists of four people including the manager. What was your first impression of KTC when you joined it? Were there any surprises? I was pleasantly surprised by the excellent onboarding process, the comprehensive in-house documentation, and the vibrant communication on Slack. These aspects left a strong impression on me. What is the atmosphere like on-site? The environment has a calm atmosphere, making it easy to engage in discussions about technology. How did you feel about writing a blog post? I'm glad to have had the opportunity to share some information. **A question from someone else: Please tell me something you were really glad you bought while working from home! **Answer: A Herman Miller chair. It is comfortable to sit in even for a long time, and I am very satisfied with it. yi ![Photo of two cacti in a flower pot](/assets/blog/authors/ahomu/20241007/yi.jpg =300x) Self-introduction I am yi from the Platform Development Division’s QA Group, where I do QA. How is your team structured? The team is composed of 10 members and is broadly divided into three groups: front-end, back-office, and apps, each managing their respective projects. What was your first impression of KTC when you joined it? Were there any surprises? Although it’s a newly established company, I was impressed by how well-structured its internal organization is. Before joining, I imagined things might be a bit more chaotic, but everything felt much more organized and calm than I expected. What is the atmosphere like on-site? Even when they’re busy, the team and project members are always willing to answer my questions, and the overall atmosphere is relaxed. This makes it an environment that’s easy to settle into. How did you feel about writing a blog post? I had never written for a blog like this before, so honestly, I wasn’t sure what to write. A question from someone else: What is the atmosphere in the team like? Please tell me about something you felt was good about your team recently. Answer: As I mentioned earlier, the overall atmosphere is calm. As a member of KTC’s QA staff, it feels like we each work on our assigned project tests collaboratively with our partners. Many people are handling multiple projects and everyone is busy, but despite that, it’s an environment where not only newcomers but everyone feels comfortable asking each other questions. I think that’s one of its great qualities. ahomu ![Illustration of a seabird holding an axe](/assets/blog/authors/ahomu/ahomu.png =300x) Self-introduction I am ahomu. I belong to the IT/IS Division. In terms of work experience, I have quite a bit of experience in web front-end development, but currently, I’m involved in various inter-organizational tasks. How is your team structured? When I joined the company, I planned to figure out the specifics after getting hired. At the time of writing this article, I’m working solo, attached to a division as an in-house freelancer. (。•̀ᴗ-)✧ What was your first impression of KTC when you joined it? Were there any surprises? During my casual interview and the selection process, the head of my current division and the vice president openly shared insights about the business situation and the organization's atmosphere, so nothing has come as a surprise. If I had to mention something along those lines, being part of a large company means that internal controls are stricter compared to my previous experiences with mega-ventures and startups. I find this refreshing and quite positive. What is the atmosphere like on-site? While I mentioned working solo, I still get the chance to engage with managers and team members from various departments. I can clearly sense the weight of responsibility they carry in managing the business, yet they are always willing to engage in conversation, even with a newcomer like me reaching out unexpectedly. It’s incredibly helpful. How did you feel about writing a blog post? Now that I think about it, I was truly amazed by how actively people contribute to the Tech Blog within the company. What’s particularly impressive is that information is consistently shared without anyone needing to push for it. I feel this proactive approach holds tremendous potential for growth. A question from someone else: Please tell me about any differences you found between the Nagoya and Tokyo companies in terms of culture, atmosphere, and the like. Answer: Nagoya has a small, close-knit setup with around 20 people, many of whom are actively involved in a wide range of fields. It gives the place a unique and distinctive vibe. It feels quite connected to KINTO’s business, and there seem to be many people there who interact with the parent company as well. Recently, occasional drinking parties have started taking place at the Nagoya office. Tsuzura ![Photo of a sunset showing a river running through a foreign city and the townscape on both banks](/assets/blog/authors/ahomu/20241007/tsuzura.jpg =300x) Self-introduction I am a designer in the Marketing Planning Division’s Organization Group! How is your team structured? It consists of nine directors and four designers. What was your first impression of KTC when you joined it? Were there any surprises? Since the departments and teams are divided, I initially thought there might be limited interaction between employees. However, I’ve been able to connect with designers from other departments during lunch and at informal gatherings like private drinking parties. This has allowed me to exchange information and ideas effectively, which has been incredibly helpful. What is the atmosphere like on-site? In our team, we each focus on our own projects, so there isn’t much direct involvement with one another’s work. However, when we gather at the office, we take time to chat and connect while staying productive. Overall, it feels like a well-balanced dynamic. How did you feel about writing a blog post? Extremely excited. A question from someone else: Please tell me about any delicious lunches there are near your office! Answer: I belong to the Muromachi office, and I recommend Dedesuke Saigon Kitchen ! I always opt for their Half & Half option and get pho and curry. They offer about four flavors for each, and every single one is absolutely delicious. I highly recommend trying it! Naoki Uehara ![Profile photo of a cat with its eyes closed](/assets/blog/authors/ahomu/20241007/uehara.png =300x) Self-introduction My name is Uehara. I am part of the Project Promotion Division’s KINTO FACTORY Development Group. I work as a backend engineer. In my previous job, I did news media development at long-established ISP. My favorite programming language is Rust, and my favorite editor is NeoVim. How is your team structured? Back-end development is done by six engineers. If you include the front-end engineers as well, there are around 20 people. What was your first impression of KTC when you joined it? Were there any surprises? I initially thought I might be thrown straight into the deep end with little onboarding in place, but to my surprise, the onboarding process, one-on-one support, and other resources were incredibly well-organized. This made it much easier for me to transition smoothly into the work. The company has an atmosphere that encourages trying new things, which I find incredibly stimulating and inspiring What is the atmosphere like on-site? I think it is a very friendly atmosphere. I’m the kind of person who gets bothered when there’s something I don’t understand, but the other team members always answer my questions without hesitation or frustration, and I’m incredibly grateful for that. I now have more time to focus on development work and can think more deeply about the products from an engineer’s perspective. I feel it’s a great environment for that. **How did you feel about writing a blog post? ** Actually, before I joined KINTO Technologies, I was helped out by an article on its Tech Blog. So, it is a great honor to be joining the ranks of its bloggers myself now. Personally, I make a conscious effort to share my ideas through platforms like Slack and blogs. Moving forward, I aim to contribute more useful information to the Tech Blog. **A question from someone else: Please tell me what your best-ever vacation was! And why, if you do not mind! ** Answer: I guess that has to be my honeymoon in Ise-Shima! The Mawaryanse tickets offered by Meitetsu are incredibly convenient. They are hard to get if you live in Tokyo, but I recommend buying one on Jalan with no limited express ticket attached. Jinrong Liang ![Photo of a curry, fries, and a can of Sui (gin soda)](/assets/blog/authors/ahomu/20241007/jin.jpg =300x) Self-introduction I am Jinrong Liang, and I come from Taiwan. I belong to the Mobile Development Group, which mainly develops Android apps. How is your team structured? In the development team for the products I work on, there are six Android engineers, including me. What was your first impression of KTC when you joined it? Were there any surprises? The team I’m part of is full of energy and includes many Android engineers. Engaging with others on technical topics through study sessions and similar activities has been a highly stimulating and rewarding experience for me. What is the atmosphere like on-site? Depending on the development period, it is often busy, so it felt like quite a fast-paced development team. Even so, everyone on the team wants to make good products, so we spare no effort when it comes to communicating in detail. How did you feel about writing a blog post? Writing my first entry about joining the company gave me an opportunity to reflect on how I felt when I first started and consider how I want to grow and contribute at KTC moving forward. **A question from someone else: Are there any smartphone apps that you have been interested in lately? ** Answer: The PayPay app. I have been using it for many years since the service launched, and I am deeply interested in how it functions as a super app, continuously evolving while maintaining quality as new features are introduced. Dara Lim ![Photo of a car exhibited indoors](/assets/blog/authors/ahomu/20241007/daralim.jpg =300x) Toyota FJ25 Land Cruiser - Toyota Dealership in Bogota, Colombia Self-introduction My name is Dara Lim. I belong to the KINTO Global Development Group in the Business Development Department. My title is Business Development Manager, but the work I do relates closely to working as a business analyst. In my previous job, I worked as a financial analyst and business analyst in the insurance industry. How is your team structured? My team consists of three members, and we collaborate closely with the engineering team to develop software solutions for global full-service lease businesses. What was your first impression of KTC when you joined it? Were there any surprises? I really appreciate the orientation/onboarding process and the 1-on-1 meetings. They helped me to smoothly transition into work. My team was also very supportive. What is the atmosphere like on-site? I really enjoy the Jimbocho office space and its surroundings. My team sits close to each other so we are able to have discussions readily. How did you feel about writing a blog post? Actually, before I joined the company, I was helped by many articles on KINTO Technologies' Tech Blog, so I’m glad to write my initial experience on joining the company. A question from someone else: What is the best thing you have noticed since joining KTC? Answer: I have had the experience of traveling to Latin America to visit KINTO businesses in Peru, Brazil, and Colombia. These were very valuable experiences for me to understand the car leasing business, its profitability and best of all, to meet others fellow KINTO members. I think this is the best thing I’ve experienced since joining KTC. Ikuya Tani ![Illustration of a fluffy cat](/assets/blog/authors/ahomu/20241007/tani.jpg =300x) Self-introduction I am Tani from the KINTO ONE Development Division’s New Car Subscription Development Group, where I am a front-end engineer in the Osaka Tech Lab. I have done a wide variety of front-end development work ranging from production-related stuff to service development. How is your team structured? The team consists of four people. We are developing tools for dealers and in-house use with a small number of people. What was your first impression of KTC when you joined it? Were there any surprises? Before joining the company, I imagined it might be a chaotic environment, blending the atmosphere of a large corporation with that of a startup, and lacking a fully established work structure. However, once I started, I was pleasantly surprised to find a thorough onboarding process, flexible workload adjustments, a fully flextime system, properly reflected overtime pay, a generous welfare package, and a welcoming, friendly team. It turned out to be a collection of wonderful surprises. What is the atmosphere like on-site? I believe it’s an environment with a strong sense of psychological safety, where you feel comfortable actively asking questions about anything you don’t understand. Another attractive feature is that taking part in study sessions is recommended, and in addition, in the case of my team, there is a high degree of freedom in terms of selecting technologies, and rearchitecting and refactoring are also recommended. So all in all, it feels like an environment where it will be easy to level up my skills. How did you feel about writing a blog post? I wanted to convey a detailed and vivid picture of what KINTO Technologies is like, so I dedicated myself to typing away at the keyboard with all my effort. **A question from someone else: What is your favorite possession, and why? **Answer: My Sony noise-cancelling headphones (WH-1000XM5)! Thanks to these, even someone as sensitive to sounds as me can quickly get into the zone, so I really treasure them. Closing words Thank you everyone for sharing your thoughts on our company after joining it! There are more and more new members at KINTO Technologies every day! Stay tuned for more blog entries about joining the company, featuring perspectives from people across various departments in the future! KINTO Technologies is looking for people to work with us! For more information, please see the recruitment information . https://www.kinto-technologies.com/recruit/
アバター
この記事は KINTOテクノロジーズアドベントカレンダー2024 の3日目の記事です🎅🎄 学びの道の駅の始まりから早くも一年が経過しようとしています!「学びの道の駅」がKINTOテクノロジーズの学びカルチャーを活性化する起爆剤となると信じている技術広報グループの中西です。弊社の技術広報グループでは社員のインプットからアウトプットまで人の成長における様々な点を繋げて組織カルチャーを改革すべく日々走り続けています。 エンジニアカルチャーを後押しする大きな変化 今年、弊社のエンジニアカルチャーに大きな変化が起こりました。それは、技術広報グループの立ち上げです。今までは、プロジェクトとして活動していたに過ぎませんでしたが、今年の春より正式に組織としてグループ化し、現在は兼任ではなく専任で技術広報Gの活動を本務としている方々もいます。これは、会社として社員の発信力を後押しするという大きな決断の一つになります。 そして今年は技術広報グループの立ち上げに留まらずテックブログ立ち上げ当初から計画していたインプットの領域も組織として認めて頂く事になりました。 技術広報グループの活動を自動車に例えてみる 自動車で例えるとしたら今まで力を入れてきた「アウトプット領域」はマフラーを交換したり、排気効率が良いようにエンジンの構造変更を行っていたという活動です。 「インプット領域」である「学びの道の駅」は燃料をガソリンからハイオクやニトロに変えたり、キャブレターからインジェクションになりターボにしていくようなパワーを秘めています。つまり、燃料の変革とそれをどのように効率的に噴射してエンジンにインプットするかを担う重要なチームです。 エンジンを人やチームとして考えた場合、それぞれのエンジンに必要なインプットの内容や量が異なります。ディーゼルエンジンやガソリンエンジンでは燃料のインプット方式も異なりますし、エンジンの排気量によっても効率性が異なってきます。 社内の学びを集約 前置きが長くなりましたが「学びの道の駅」ではインプットを各人に最適化して社員同士の強みを活かすような学びの仕組みを検討しております。今までの活動として勉強会の見える化、勉強会情報のシェアや拡散、勉強会開催のサポート、社内の勉強会情報の集約など、とにかく散らばっていた学びを一箇所に集約する活動に力を入れてきた一年でした。これからは「K to K」に軸足を置き、人と人とを繋げていく活動をしていきます。 「K to K」とは? 「K to K」とは「KINTOテクノロジーズ to KINTOテクノロジーズ」の略です。社員同士で学びを得たりスキルを伝え合ったりするということを目的としています。 例えば 「分析力足りないな」→分析グループに相談。 「コーチングを学びたい」→〇〇さんがコーチングが上手。 「プロジェクトマネージメント」→PdMのあの人達に聞いてみよう のような学びたいというエネルギーと 「自分の〇〇スキルをもっと活かしたい」 あの人こんなスキルもあるけど業務で活かすきっかけを探している などの教えたい、伝えたいエネルギーを繋げていくことで、社員の魅力をより活かした形で業務を活性化させることが出来ます。 「学びの道の駅」のネクストアクションは、我々が得意とする「人やチームの魅力を引き出すこと」「点と点を結びつけること」です。どのような壁が立ちはだかるのか来年以降の活動が今から楽しみです。 他の活動 インプット領域の活動として、現在展開しているPodcastの拡張版も検討しています。今は勉強会を主催している皆様にインタビューを行うという活動が中心になっていますが、K to K同様に、社内に伝達していきたいことがたくさんあります。これらをPodcast形式にして社員の学びに繋げたり、社内に限らないアウトプットの場にもしていきたいと考えています。 またUdemy Businessも取り組みとして行っているので、動画コンテンツでどのように効果的に学習を行うのかなども企画していきたいと考えています。 まとめ テックブログやイベント開催、登壇などと並ぶ、次の大きな柱として今後の「学びの道の駅」の活動の幅を様々に展開していきたいと思います。インプット領域をどんどん拡張していく事で、最終的には事業領域での幅を広げ、社員一人ひとりがより成長でき、個性を活かして活躍できるような環境を目指していきたいと思います。 来年の活動も積極的に発信していきますので、皆様お楽しみに!
アバター
こんにちは!KINTOテクノロジーズ生成AI活用プロジェクトの顧です。 みなさんの会社はどんな方法でAWS上のリソースを操作しますか? Terraform、AWS CLI、あるいはAWSコンソール上で手動など、さまざまなな手段がありますね。 今回、生成AIの力を利用し、slack上で自然言語の操作命令を入力することで、バックエンドのAgents for Amazon Bedrock(以下Bedrock)と連携しながらAWSのリソース操作をする仕組みを作成してみました。 全体構成 全体構成は以下の図のようになっています。 全体構成 使用するイメージ ユーザはSlack上で自然言語で入力し、バックエンドのBedrockは入力に基づき、S3上でバケットを作成したり、削除したりします。 使用するイメージ 作成手順 作成手順は、以下の3ステップとなります。 Bedrock上でAgentを作成 AWS Chatbotを作成 Slackを設定 以下、詳しく作成手順を説明します。 みなさん、その手順に沿って同じことができるようになるので、やってみてくださいね。 Bedrock上でAgentを作成 マネジメントコンソールでBedrockの管理画面を開きます 左メニューの「エージェント」をクリックします 「エージェントを作成」をクリックします エージェント名を入力して「作成」をクリックします エージェントビルダーの画面に遷移します Claude 3 Sonnetモデルを選択します。(好きなモデルを選択すればいいです) 右上の「保存して終了」をクリックします 右側に表示される「準備」をクリックします 上に「正常に準備されました」と表示されます アクショングループを追加します アクショングループ項目の右上の「追加」をクリックします アクショングループを設定します ・アクショングループ名を入力します ・アクショングループタイプを「関数の詳細で定義」を選択します ・ 「Lambda 関数の定義方法を選択してください」のところ、「新しいLambda関数をすばやく作成する-推奨」を選択します ・アクショングループの呼び出しは、おすすめの「新しい Lambda 関数をすばやく作成する - 推奨」を選択します アクショングループ関数を作成します ・名前がdelete-ai-agent-gu-functionとcreate-ai-agent-gu-functionのアクショングループ関数を追加します ・ 「説明-オプション」にそれぞれ「delete S3 bucket posted bucket name」と「create S3 bucket posted bucket name」を記入 ・パラメータとして、名前はbucket_name、説明はS3バケット名、タイプはString、必須はTrueにします。 エージェント向けの指示を作成します エージェントの編集画面を開き、「エージェント向けの指示」に以下の指示を入力します あなたはS3バケットを操作するエージェントです。いくつかの関数を使い分け、ユーザーの要求のもとにS3バケットを作成か削除をしてください。 タスク1: もし、例えば「バケット名がtest-guのS3バケットを作成してください」というように、S3バケットの作成を要求されたら、create-ai-agent-gu-functionというLambda関数を実行してください。 タスク2: もし、例えば「バケット名がtest-guのS3バケットを削除してください」というように、S3バケットの削除を要求されたら、delete-ai-agent-gu-functionというLambda関数を実行してください。 Lambdaを作成 Lambdaの画面コンソールにアクセスします 新しいLambda関数を作る設定にしたため、dummyのlambda関数を作成されています dummy_lambda.pyにS3の作成と削除コードを加えます import json import boto3 AWS_REGION = "ap-northeast-1" s3Client = boto3.client("s3",region_name=AWS_REGION) location = {"LocationConstraint":AWS_REGION} def lambda_handler(event, context): agent = event["agent"] actionGroup = event["actionGroup"] function = event["function"] parameters = event.get("parameters", []) # Execute your business logic here. For more information, # refer to: https://docs.aws.amazon.com/bedrock/latest/userguide/agents-lambda.html bucket_name = next(item for item in parameters if item["name"] == "bucket_name")["value"] if function == 'delete-ai-agent-gu-function': bucket_instance=s3Client.delete_bucket(Bucket=bucket_name) responseBody = { "TEXT": { "body": f"Instance Deleted: {str(bucket_instance)}" } } elif function == 'create-ai-agent-gu-function': bucket_instance=s3Client.create_bucket(Bucket=bucket_name, CreateBucketConfiguration=location) responseBody = { "TEXT": { "body": f"Instance Created: {str(bucket_instance)}" } } action_response = { "actionGroup": actionGroup, "function": function, "functionResponse": { "responseBody": responseBody }, } function_response = {"response": action_response, "messageVersion": event["messageVersion"]} print(f"Response: {function_response}") return function_response dictionaryのeventからfunctionを取得し、前のステップの定義されたアクショングループ関数のcreate-ai-agent-gu-functionとdelete-ai-agent-gu-functionにより、処理を振り分けます lambdaにS3のバケット操作権限を付与します 以下の権限を実行ロールに付与します。 左側の「Deploy(Ctrl+Shift+U)」をクリックします エージェント画面に戻り、画面上部の「エイリアスを作成」をクリックします 「エイリアス名」を入力し「エイリアスを作成」をクリックします エイリアスが作成されます これでagentの作成は完了しました。 AWS Chatbotを作成する AWSコンソールでChatbotの管理画面を開きます 「新しいクライアントを設定」をクリックします チャットクライアントを「slack」に設定し、「設定」をクリックします AWS Chatbotによるslackワークスペースへのアクセスを許可します chatbotの管理画面に戻り、「新しいチャンネルを設定」をクリックします 設定名とチャンネルIDを入力します アクセス許可では以下のように設定します ・ロール名を入力 ・チャネルガードレールポリシーにAmazonBedrockFullAccessを追加 (本番環境なら最小権限に絞ってください) 右下の設定をクリックします 追加された設定(こちらがktc-gu-test)のリンクをクリックします チャネルロールのリンクをクリックします 許可ポリシーの「許可を追加」をクリックし、「ポリシーをアタッチ」を選択します 「AmazonBedrockFullAccess」を検索と追加し、「許可を追加」をクリックします これでAWS Chatbotの作成は完了です。 Slackを設定します 最後にSlackの設定をします。 Slack上のチャンネルに、以下のメッセージを送信します。 @aws connector add {コネクター名} {Bedrock agentのエージェント ARN} {Bedrock agentのエイリアスID} 接続ができたら、以下のメッセージが表示されます。 これでSlackの設定は完了です。 これで動作確認をしましょう。 動作確認:SlackからS3の操作命令を入力します @aws ask {コネクター名} {プロンプト}のように操作命令を入力してください S3の作成と削除ができました! まとめ 今回、AWSの生成AIエージェントサービスAgents for Bedrockを利用して、Slack上の自然言語の入力だけで、S3の作成と削除操作ができました。 これでいろいろなオペレーションが自然言語の入力でできるようになりました。 それでは、また次回お会いしましょう!
アバター
この記事は KINTOテクノロジーズアドベントカレンダー2024 の3日目の記事です🎅🎄 KINTOテクノロジーズ(以下KTC)でFlutterアプリケーション開発を担当しているSomiです。 Flutterは、プラットフォームに依存せず多様なUIを構築できる魅力的なフレームワークです。特に、CustomPaintは基本ウィジェットだけでは実現が難しい繊細なデザインを簡単に表現できます。 最近、QRコード認識画面を実装する際に、認識エリアの枠線を作成する課題がありました。既存のライブラリを使用しようとしましたが、希望する曲線デザインを実現するには限界がありました。そのため、 CustomPaintとPath を活用して直接枠線を描き、課題を解決しました。 この記事では、CustomPaintとPathを使ってQRコード認識画面の枠線をどのように完成させたのか、その手順を詳しく説明します。 枠線デザインの目標 今回実装した枠線は、QRコード認識エリアの四隅を囲む曲線状の半透明な白い枠線です。 CustomPainterクラス を活用し、Canvas上にPathで経路を定義し、曲線と直線を組み合わせて枠線を描きました。 CustomPainterを使用した枠線描画の準備 まず、枠線を描画するためのクラスである _OverlayPainter を定義します。このクラスはCustomPainterを拡張し、Canvasに枠線を描画する役割を担います。 以下は、既に定義された _OverlayPainter を用いて枠線を描画するサンプルコードです。この後、コードの具体的な実装内容について詳しく解説します。 class QrScanPageContent extends StatelessWidget { const QrScanPageContent({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text("QR Code Scanner"), // 画面タイトル ), body: CustomPaint( size: Size.infinite, // 画面全体のサイズに合わせて描画 painter: _OverlayPainter( squareSize: 200.0, // 枠線エリアのサイズ borderRadius: 20.0, // 枠線の角の丸み borderThickness: 8.0, // 枠線の太さ ), ), ); } } 背景と認識エリアの設定 先ほどお話しした _OverlayPainter を具体的に作成します。まず、背景色と QR コード認識領域を描画します。背景は drawRect メソッドを使用して半透明の長方形として描画し、QR コード認識領域は drawRRect メソッドを使用して角丸の長方形として描画します。また、それぞれの描画には Paint クラスでスタイル(色や透明度)を設定しています。次のセクションでは、本格的に枠線を描画する方法を解説します。 class _OverlayPainter extends CustomPainter { final double squareSize; final double borderRadius; final double borderThickness; _OverlayPainter({ required this.squareSize, required this.borderRadius, required this.borderThickness, }); @override void paint(Canvas canvas, Size size) { final centerX = size.width / 2; final centerY = size.height / 2; // 背景を描画 final backgroundPaint = Paint()..color = Colors.grey.withOpacity(0.5); canvas.drawRect( Rect.fromLTWH(0, 0, size.width, size.height), backgroundPaint); // 認識エリアを描画 final rect = RRect.fromRectAndRadius( Rect.fromCenter( center: Offset(centerX, centerY), width: squareSize, height: squareSize, ), Radius.circular(borderRadius), ); final innerPaint = Paint()..color = Colors.lightBlue.withOpacity(0.1); canvas.drawRRect(rect, innerPaint); //ここで枠のスタイルおよび枠を描きます。 } @override bool shouldRepaint(covariant CustomPainter oldDelegate) => false; } shouldRepaintメソッドは、このCustomPainterが再描画を必要とするかどうかを判断します。今回の例では、背景の色や認識エリアのサイズが固定されているため、再描画の必要がありません。そのため、このメソッドは常に false を返します。ただし、動的に描画する場合や、サイズや形状が変更される場合は、このメソッドを true にする必要があります。 枠線スタイルの設定 次に、枠線を描画する準備として、線のスタイルを設定します。枠線を描画する前に、Paintオブジェクトを使用してスタイルを定義します。Paintクラスは線の色、太さ、形状などを設定するためのツールを提供します。 ここでは、枠線を半透明の白色に設定し、線の形状を丸く定義します。枠線を半透明の白色に設定することで、視覚的に重要な認識エリアが一目で分かるようにしました。 final borderPaint = Paint() ..color = Colors.white.withOpacity(0.5) // 枠線の色と透明度を 設定 ..style = PaintingStyle.stroke // 外枠スタイルを設定 ..strokeWidth = borderThickness // 線の太さ ..strokeCap = StrokeCap.round; // 線の端を丸く設定 座標とサイズの計算 枠線を描画するために、まず各コーナーの座標とサイズを計算する必要があります。これにより、各コーナーの始点と終点を正確に定義できます。 以下は計算例です: const double cornerLength = 55; // 各コーナーの長さ double halfSquareSize = squareSize / 2; // 認識エリアの半分のサイズ double left = centerX - halfSquareSize; // 左側の境界 double right = centerX + halfSquareSize; // 右側の境界 double top = centerY - halfSquareSize; // 上側の境界 double bottom = centerY + halfSquareSize; // 下側の境界 座標系 : FlutterのCanvas座標系では、左上が(0, 0)です。そのため、上側は centerY - halfSquareSize で計算され、下側は centerY + halfSquareSize で定義されます。 cornerLength : 各コーナーで直線を描く長さを定義します。 halfSquareSize : QRコード認識エリアの半分のサイズを計算します。 left, right, top, bottom : 中心座標を基準に認識エリアの境界座標を定義します。 上記の式を図に表すと、以下のような位置関係になります。 枠線の描画 まず、左上コーナーから描き始めます。 左上コーナーを描くために Path クラスを使用して経路を定義します。 Path は直線、曲線、弧などのさまざまな形状を指定し、それをCanvasに描画できる便利なクラスです。 1. 右から左に直線を描く 始点をコーナーの上端に移動し、左方向に直線を描きます。 Path topLeftPath = Path(); // 新しい経路を定義 topLeftPath.moveTo(left + cornerLength, top); topLeftPath.lineTo(left + borderRadius, top); 上記のコードで、以下のような直線が描画されます。 2. コーナーの曲線を描く 直線の終点から曲線を追加します。このとき、arcToPointメソッドを使用して、始点から指定された終点まで曲線を描きます。 これにより、直線から曲線への自然な接続を作成できます。以下のコードでは、Offsetで曲線の終点を、Radiusで曲線の半径を設定し、QRコードエリアの丸みを帯びたコーナーを実現します。 topLeftPath.arcToPoint( Offset(left, top + borderRadius), // 曲線の終点 radius: Radius.circular(borderRadius), // 曲線の半径 clockwise: false, // 反時計回りに曲線を描く ); 上記のコードで、以下のように角が丸くなった曲線が描画されます。 3. 縦方向の直線を描く 曲線の終点から下方向に直線を追加します。 topLeftPath.lineTo(left, top + cornerLength); 上記のコードで、以下のように縦方向の直線が追加されます。 4. 経路をCanvasに描く Pathで定義した経路を、borderPaintを使ってCanvasに描画します。 canvas.drawPath(topLeftPath, borderPaint); 残りのコーナーの処理 以下は、左上コーナーに続いて、残りの3つのコーナーを描画するコード例です: // 左下コーナー final bottomLeftPath = Path() ..moveTo(left + cornerLength, bottom) ..lineTo(left + borderRadius, bottom) ..arcToPoint( Offset(left, bottom - borderRadius), radius: Radius.circular(borderRadius), clockwise: true, ) ..lineTo(left, bottom - cornerLength); canvas.drawPath(bottomLeftPath, borderPaint); // 右下コーナー final bottomRightPath = Path() ..moveTo(right - cornerLength, bottom) ..lineTo(right - borderRadius, bottom) ..arcToPoint( Offset(right, bottom - borderRadius), radius: Radius.circular(borderRadius), clockwise: false, ) ..lineTo(right, bottom - cornerLength); canvas.drawPath(bottomRightPath, borderPaint); // 右上コーナー final topRightPath = Path() ..moveTo(right - cornerLength, top) ..lineTo(right - borderRadius, top) ..arcToPoint( Offset(right, top + borderRadius), radius: Radius.circular(borderRadius), clockwise: true, ) ..lineTo(right, top + cornerLength); canvas.drawPath(topRightPath, borderPaint); まとめ CustomPaintとPathクラスを活用することで、QRコードの枠線のような精密なデザインだけでなく、さらに複雑なUIデザインを実現できます。QRコード認識画面の枠線を自分で実装することで、Flutterの柔軟性と強力なCanvas機能を再確認できました。 なお、CustomPainterを使用する際には、描画ロジックが複雑になるほどパフォーマンスに影響を与える可能性があります。再描画の頻度が高い場合は処理を最適化するか、他の既存ウィジェットを活用することも検討してください。 この記事が、CustomPaintやPathを活用したUIデザインの実装に役立つ参考になれば幸いです。
アバター
この記事は KINTOテクノロジーズアドベントカレンダー2024 の2日目の記事です🎅🎄 はじめに こんにちは!KTCでAndroidエンジニアをしている 長谷川 です! 本記事ではAndroid開発において、Applicationクラスでやりがちなミスとその対処法の一例を紹介します。 Applicationクラスとは Androidにおける Applicationクラス とは公式ドキュメントを参考に、以下の説明ができそうです。 「Base class for maintaining global application state. It is instantiated before any other class for your application/package is created.」 つまりグローバルで状態を管理できること、他のどのクラスよりも先にインスタンス化されるということです。 プロジェクトによって色々な実装をしているケースがあると思いますが、一般的には以下のようにアプリ内で使用するライブラリの初期化をしたり、DIの設定を行うことが多いと思います。 class MyApplication: Application() { override fun onCreate() { super.onCreate() // ライブラリ初期化 // DIの設定 } } もしここでアプリケーション起動時にサーバーからデータが欲しくて、API通信をした場合どうなるでしょうか? class MyApplication: Application() { override fun onCreate() { super.onCreate() // ライブラリ初期化 // DIの設定 // APIコール } } 少なくとも私はこのようなコードを何回か見たことがあります。 このコードはすぐには問題にならないですが、将来的に問題を引き起こす可能性があります。 本記事ではどのような場合に、このコードが問題になりうるか、説明します。 4つのアプリコンポーネントとApplicationクラスの関係 ApplicationクラスでAPIコールを行うと何が問題になるかを説明するためには、 Androidの4つのアプリコンポーネント についての理解が必要です。 下記の画像は4つのアプリコンポーネントと、それぞれのコンポーネントでよく使用される機能を表しています。 Activityは主にアプリの画面の責務を持ち、最も使用されると思います。 また通知の機能を持つアプリはServiceを使用することが多いと思います。加えてWidgetの機能を持つアプリではBroadcast Receiverを利用することになると思います。Content Providerを使ったことがある方は少ないかもしれないですが、自アプリのデータを他アプリに公開したい場合などに使用できます。 注意して欲しいことは、これらのコンポーネントのどれかが動いている場合、Applicationクラスがインスタンス化されているということです。特にActivity以外のコンポーネントはユーザーが明示的にアプリを開いていないことがあります。 例えば、Widgetを持つアプリの場合、端末の再起動などでウィジェットが作成されますが、この時にApplicationクラスはインスタンス化される可能性があります。 もしApplicationクラスにAPIコールが記述されている場合、このタイミングでユーザーはアプリを開いていなくても(そしてほとんどの場合、開発者も意図しないタイミングで)APIコールが行われてしまいます。 通知の機能を持つアプリの場合、push通知が届くタイミングでApplicationクラスがインスタンス化される可能性があります。 もし複数のユーザーにまとめてpush通知を送信した場合、ほぼ同タイミングでAPIコールを行ってしまい、ある意味DDoS攻撃のような状態になるリスクがあります。 特にこの問題はユーザー数の増加など後になって発覚することもあり、知識として知っておくことが大切です。 最初にAPIコールしたい場合どうする? 対処方法はたくさんあると思うので、正解はありませんが一例を紹介します。 データは必要な時に必要な分だけ取得するべきなので、4つのコンポーネント内でそれぞれ取得しましょう。 その際に取得したデータを4つのコンポーネント内で使いまわしたい場合は、永続化をしたり、データをApplicationに保持させたり、DIでライフサイクルスコープをSingletonに設定したクラスに保持させておくことが可能です。 おわりに お疲れ様でした。短い記事ですが、今回はApplicationクラスのライフサイクルと気をつけたい実装について解説しました。 本記事ではApplicationクラスに記述されたAPIコールを例に説明しましたが、例えばアプリ起動のイベントなどをApplicationクラスで送信することもよくある間違いの1つかなと思います。 上記で説明した通り、Applicationクラスのインスタンス化は必ずしもユーザーが明示的にアプリを起動したタイミングとは一致しないためです。 ユーザーがアプリを起動したイベントであれば、Activityに記述するべきです。もしマルチアクティビティを採用しているアプリだとしても、アプリの入り口の導線を正しく把握しましょう。 本記事がどなたかの助けになれば幸いです。 ※Android ロボットは、Google が作成および提供している作品から複製または変更したものであり、 クリエイティブ・コモンズ 表示 3.0 ライセンスに記載された条件に従って使用しています。
アバター
Introduction Hello, I am Ueyama, a new member who joined the company in April. In this article, I've compiled the reflections and thoughts of everyone who started with me in April 2024. I hope that it will be useful for everyone who is interested in KINTO Technologies, and for everyone who took part in this article if they look back at it someday. 🌸 Matsuno ![Golf](/assets/blog/authors/K.Ueyama/Newcomers/golf.jpg =250x) Self-introduction Nice to meet you, everyone! I am Matsuno, a new member who joined the company in April 2024! I belong to the MSP Team in the Platform Development Division’s Platform Group. In my previous job, I was responsible for maintaining and operating systems built on AWS. How is your team structured? The MSP Team I belong to consists of four people. I am mainly responsible for routine work we have taken over from other teams. What was your first impression of KTC when you joined it? Were there any surprises? I got the impression that there are lots people who seem to be outstanding, including the people who joined when I did. Also, finding there were lots of frank people here was a surprise in a good sense. What is the atmosphere like on-site? Basically, the atmosphere makes it easy to ask questions and consult people anytime. In addition, when people are working, they concentrate silently on what they are doing, and when they are chatting, they are very friendly. So in that sense, it is nice and balanced. How did you feel about writing a blog post? I already knew about the Tech Blog and was interested in it as well, so I thought it was a perfect opportunity! m ![Sea](/assets/blog/authors/K.Ueyama/Newcomers/sea.jpg =250x) Self-introduction I am m from the Creative Office. In my previous job, I was a UI/UX designer at an SES IT company. How is your team structured? There are 10 directors and designers. What was your first impression of KTC when you joined it? Were there any surprises? I was struck by how clean the office was, and how comfortable, too, since it even has a free drink server. What is the atmosphere like on-site? The age group is mostly 30s to 40s, and everyone is extremely knowledgeable and experienced. The office is often surprisingly bustling. How did you feel about writing a blog post? I think it is good that there is a forum where we can share our own thoughts and knowledge! Rassel ![Castle](/assets/blog/authors/K.Ueyama/Newcomers/castle.png =250x) Self-introduction I am Rassel from Bangladesh, and I joined the company in April 2024. I am an iOS developer in the Prism Team in the Platform Development Division’s Mobile App Development Group. How is your team structured? The team consists of around 14 people, and includes engineers, designers, and POs. What was your first impression of KTC when you joined it? Were there any surprises? I am interested in mobility services. I was very impressed by KTC’s mission of leading Toyota’s mobility services. There was nothing in particular that was a surprise for me. What is the atmosphere like on-site? The people are kind and helpful. There are no barriers to using the latest technology. It is also easy to talk about technical problems. How did you feel about writing a blog post? This is the first time I have written a blog post in this context, but I think it is a really cool and fun idea. Ueyama ![Pasta](/assets/blog/authors/K.Ueyama/Newcomers/pasta.jpg =250x) Self-introduction I am Ueyama from the Work System Group. In my previous job, I did system development at an SIer. How is your team structured? Our team includes seven engineers. What was your first impression of KTC when you joined it? Were there any surprises? I was able to talk to the same team members as in my consultation and interview, so I did not feel all that surprised by anything. What is the atmosphere like on-site? It is an environment where everyone is really kind and easy to talk to. How did you feel about writing a blog post? The format of managing self-introduction articles on GitHub and publishing them with pull requests was a surprise. R ![Catandfish](/assets/blog/authors/K.Ueyama/Newcomers/catfish.jpg =250x) Self-introduction I am R, and I belong to the Member Platform Team in the Development Division’s Common Services Development Group. The ratio of front-end to back-end development is around 6:4. How is your team structured? There is one product manager (PdM) and four engineers. What was your first impression of KTC when you joined it? Were there any surprises? Seeing up close outstanding people who are involved in multiple projects, events, and so on both inside and outside the company, I got the impression that it is a very free environment. Before I joined KTC, I had attended a study group held by it, and although most of the people taking part were young, I got to know a bit about its atmosphere beforehand. So, There was nothing in particular that was a surprise for me. What is the atmosphere like on-site? The back-end work is done in silence, and with the front-end work, things sometimes get very lively, with everyone talking about their views, impressions, and so on about a screen with it being implemented on. How did you feel about writing a blog post? I didn't have any worries when reading it, but when it came to writing it myself, I was troubled because I didn't know what to say. It looks like I need to hone my verbalization and communication skills. kasai ![Chick illustration](/assets/blog/authors/K.Ueyama/Newcomers/chickicon.png =250x) Self-introduction I am kasai from the SRE Team in the Platform Development Division’s Platform Group. I was an SRE in my previous job as well. How is your team structured? There are lots of people in the group, but the SRE Team consists of just two! An article about the team is going to be posted on the blog at a later date, so stay tuned for that! What was your first impression of KTC when you joined it? Were there any surprises? I got to thoroughly talk things over and get on the same page as the company in my consultation, interview, and so on, so I did not get any surprises! What is the atmosphere like on-site? Very friendly indeed! How did you feel about writing a blog post? At last...my time...has come! https://blog.kinto-technologies.com/posts/2022-12-03-ktc_club_introduction/ Closing words Thank you everyone for sharing your thoughts on our company after joining it! There are more and more new members at KINTO Technologies every day! Please look forward to more company-joining blog entries by various people from various departments in the future, too. 🍻 KINTO Technologies is looking for people to work with us! For more information, please see the recruitment information . https://www.kinto-technologies.com/recruit/
アバター
この記事は KINTOテクノロジーズアドベントカレンダー2024 の2日目の記事です🎅🎄 はじめに こんにちは! 新車サブスク開発G、Osaka Tech Lab 所属の high-g( @high_g_engineer )です。 最近は、type-challenges という TypeScript の型パズル問題集を業務前に取り組むことを日課にしています。 本記事では、TypeScript の型システムの中でも少し癖のある infer の Tips をいくつか紹介します。 まずは、infer の解説の前に、infer を利用する上で必須の Conditional Types について説明します。 Conditional Types とは Conditional Types は、条件型、型の条件分岐とも言われ、型レベルで条件分岐を可能にする型システムの機能です。 以下のように記述します。 type ConditionalTest<A> = A extends 'a' ? true : false 上記の右辺は、以下のような意味になります。 型 A が リテラル型 'a' に代入可能な場合、true 型となる 型 A が上記以外の場合、false 型となる 一般的なプログラミング言語の三項演算子と同じような挙動ですね。 ちなみに、ここでの extends キーワードは、一般的なオブジェクト指向プログラミングにおける継承とは異なる意味を持ちます。 この場合の extends は型の互換性(assignability)を確認するキーワードになります。 infer とは inferとは、「推論する」を意味し、Conditional Types 内でのみ利用できるキーワードで、TypeScript 2.8 から導入されました。 以下のように記述します。 type InferTest<T> = T extends (infer U)[] ? U : never 右辺では、Conditional Types を利用し、extends の右側で取得したい型を infer ◯ で記述します。 上記の型の場合、型 T が「任意の要素型の配列」であれば、その要素の型を返すという意味になります。 (※ここでの never は、条件に合致しない場合に返される型です) (infer U)[] は、任意の要素型の配列を表す型なので、string[]、number[]、boolean[] などあらゆる配列型が該当します。 なので、型 T が number[] だった場合、型の解決は以下のようになります。 type Result = InferTest<number[]> // number あくまでここに示したのは一例で、これ以外にも infer の利用方法は多数存在します。 infer を利用した関数型の操作 戻り値の型を取得する場合 const foo = (): string => 'Hello, TS!!' type MyReturnType<T> = T extends (...args: any[]) => infer R ? R : never type FunctionReturn = MyReturnType<typeof foo> // string 先程と同じ要領で Conditional Types を記述し、extends の右側で、取得したい型を記述します。 今回は、戻り値の型を取得したいので、extends の右側に関数の型を記述し、戻り値の部分に infer を記述して完了です。 これは TypeScript の組み込みユーティリティ型 ReturnType<T> と同じ挙動になります。 引数の型を取得する場合 const foo = (arg1: string, arg2: number): void => {} type MyParameters<T> = T extends (...args: infer Arg) => any ? Arg : never type FunctionParamsType = MyParameters<typeof foo> // [arg1: string, arg2: number] 引数はタプル型になるため、残余引数(スプレッド構文)を利用することで、引数が任意の数の場合でも対応できるようになります。 Conditional Types + 取得したい型 + infer を記述することで型を抽出できます。 これは TypeScript の組み込みユーティリティ型 Parameters<T> と同じ挙動になります。 infer を利用した配列型(タプル型)の操作 末尾の要素を取得したい場合 タプル型の先頭要素の型を取得する場合、以下のような型定義で解決します。 type Tuple = [number, '1', 100] type GetType = Tuple[0] // number しかし、タプル型の末尾の要素の型を取得したい場合、 Tuple[length-1] の様な記述は TypeScript では出来ません。 この解決方法として、ベストなのが infer です。以下のような型定義になります。 type ArrayLast<T> = T extends [...infer _, infer Last] ? Last : never [...infer _, infer Last] で、型 T が配列型またはタプル型の場合に、末尾の要素の型を Last として抽出します。 type Test1 = ArrayLast<[1, 2, 3]> // 3 type Test2 = ArrayLast<[string, number, boolean]> // boolean type Test3 = ArrayLast<[]> // never infer を利用したリテラル型の操作 リテラル型の先頭の文字の型を取得する場合 type LiteralFirst<T extends string> = T extends `${infer First}${string}` ? First : never ${infer First}${string} は、文字列の先頭の文字を First として抽出し、残りの部分を string として扱います。 リテラル型の先頭を大文字にして取得する場合 type FirstToUpper<T extends string> = T extends `${infer First}${infer Rest}` ? `${Uppercase<First>}${Rest}` : never 上記は先程と同じ様に、先頭とそれ以外に分けて文字列を処理し、 Uppercase<First> でユーティリティ型を使用して、先頭の文字を大文字に変換し、残りの文字列と結合します。文字列が空の場合は never 型を返します。 リテラル型の先頭と末尾から空白文字、改行文字などを取り除く場合 type Space = ' ' | '\n' | '\t' type Trim<S extends string> = S extends `${Space}${infer T}` | `${infer T}${Space}` ? Trim<T> : S; Space という空白文字、改行文字を格納した型を作成し、Conditional Types の条件に当てはまる場合、型 Trim を再帰的に適用することで、文字列の先頭と末尾の空白文字を取り除くことができます。 まとめ これらの例のように、infer を利用することで、ある型から欲しい部分を抜き出せるため、型を表現する際の自由度が格段に上がります。 少し癖があるため、慣れるまでに時間がかかりますが、非常に便利な機能です。 型を利用することで堅牢な開発が実現できますが、型を正しく表現しきれないと以下のようなリスクが生じます。 不要な型定義によるコード可読性の低下 不必要に複雑な型定義によるメンテナンスコストの増大 型安全性の低下 infer をはじめとした TypeScript の型システムを適切に活用することで、簡潔かつ明確な型表現を実現し、開発生産性と品質向上を常に心がけられるようになっていきましょう。
アバター
この記事は KINTOテクノロジーズアドベントカレンダー2024 の2日目の記事です🎅🎄 はじめに(活動の背景紹介) こんにちは。学びの道の駅チームの「きんちゃん」です。普段はコーポレートエンジニアとして「全社で利用するITシステムの維持管理」を行っています。 最近は「生成AI活用プロジェクト」や、「技術広報グループ」という組織にも所属し、色々と活動しています。 さて、 以前のテックブログ で「学びの道の駅」の成り立ちについてご紹介しました。 その中に「社内Podcast」の活動について記載していました。今回の記事では、このPodcastへの取り組みについて詳しくご紹介します。 このPodcastの取り組みは、学びの道の駅メンバーであるHOKAさんのこんな想いから始まりました。 社内の色々な取り組みを、Podcastで発信していきたい! とてもシンプルなモチベーションだったことに加えて、基本的に「Noを言わないメンバー」が集まっていたこともあり、学びの道の駅チームの活動として取り組んでみることになりました。 もちろん、学びの道の駅チームの取り組みなので、「学びのための情報発信」とうまく組み合わせる必要があります。 あれこれ議論の上で、以下の形にまとまりました。 社内で勉強会を主催・運営・参加している人にインタビューをする。その内容を配信する ねらいは、以下の通りです。 「社内に多くの勉強会があるけど、どんな人がどんな想いで開催しているんだろう?」という疑問に答えられる 実際に参加した人のナマの声を聞いて、価値を感じてもらえる もし興味を持ってくれる人がいたら、勉強会参加のきっかけにできる 色々な勉強会の存在を見える化(聴こえる化)していくと、社内に「学びの文化」が根付いていく 「Podcastって何だっけ?」 Podcastをやろう!と決まったものの、「何をどうやるとPodcastになるんだっけ?」という疑問が出てきます。 インターネットラジオの形で公開するもの?(社外の人も聴くのかな?) 専用のアプリで配信しなければならないもの?(配信する側も聴く側も準備の手間が…) 設備とか、どういうものが必要なんだっけ? 考えれば考えるほど色々な壁が出てきます。 とは言え、我々はシンプルに「社内の情報を社内に届ける」ことを価値としたいので、「まずは出来る仕組みでプロトタイプを作って手触り感を試す」「その後のフィードバックを受け、カイゼンしていく」という「アジャイルなマインド」で進めることとしました。 さぁ、最初のインタビューだ! そうと決まれば、インタビューすべき勉強会の選定です! ちょうど良いタイミングで、社内で「合同勉強会」という大型の勉強会が開催される予定があったため、初回はその勉強会へと参加し、運営チームの皆さんへインタビューを実施する事となりました。 しかし、参加当日にバタバタしてしまい、当日の録音はできず…。 結果、代替案として「後日、運営メンバーの皆さまに集まってもらい、インタビューする形式」を取る事としました。(実は、この代替案が今後のPodcastのカタになっていくのでした) 実際のインタビューの場はとても盛り上がり、無事に収録が完了できました。 しかし、そこで新たな難関が! 実は、「どのようにPodcastコンテンツを作るか?」「どうやって配信するか?」をまったく決めないまま、ここまで来ていたのです。 チーム内で議論しながら試行錯誤の結果、以下のような形に落ち着きました 録音したデータの加工 Clipchamp(Microsoft365ファミリー製品)を利用し、音声メインの動画ファイルとして仕上げる 配信方法 社内のSharepointにファイルを置いて、それを皆さんにPCやスマホ上で開いて再生してもらう 最終的なPodcast公開フローは、 コンテンツを完成させる 学びの道の駅チーム内レビューを実施 インタビュイーのレビューを実施 上長レビューを実施(初回実施した上で、大きな懸念がなければ2回目以降は我々に判断を移譲していただく) 社内アナウンス(=公開) となりました。あくまでも社内向けコンテンツという事を前提に、シンプルなフローを整備しました。 その後、すべてのチェックが通った上で、晴れて社内に公開できました! ![](/assets/blog/authors/ktc-taku-yajima/2024-12-02/started-a-podcast001.png =700x) その後のPodcast 初回のPodcast公開で自信を付けた我々は、2回目、3回目の企画を進めていきます。 インタビューを繰り返すたびに、我々の中に知見が貯まっていき、一定のカタ化ができるようになりました。 企画のカタ 社内の勉強会や、情報発信の活動の情報を集める 学びの道の駅チームから運営メンバーへアプローチをして、インタビューを実施する インタビューした結果をPodcast化する 運営チーム、インタビュイーのレビューを経た後に、公開(社内アナウンス)する 録音・編集・配信のカタ インタビューはZoomで行う(メンバーがそもそも多拠点に散らばっているため) マイクは各人のPCマイク、会議室のマイクを利用する。音質はいったん妥協する Zoomの録画データを音源とする 音源データはClipchampを利用して編集・加工する 音源データを編集後、社内のストレージ(MS SharePoint)に保存する 視聴者はMS Stream経由で配信を聴く このカタ化ができたことで、スムーズに仕組みが回るようになり、現在までで11本のコンテンツを配信できました。 今後について このPodcast配信活動を続ける中で、我々の中に「もっとこういう拡がりを作っていきたい」という気持ちが湧いてくるようになりました。 勉強会以外にも、色々な形で社内活動をされている方々にインタビューしたい マネジメント層の方々にインタビューして、普段考えている事を社内の皆さんに聞いてもらいたい 社内に限らないアウトプットをしていきたい 来年以降も、学びの道の駅チームは積極的に情報発信していきますので、皆様お楽しみに!
アバター
こんにちは。 DBRE チーム所属の @hoshino です DBRE(Database Reliability Engineering)チームでは、横断組織としてデータベースに関する課題解決や、組織のアジリティとガバナンスのバランスを取るためのプラットフォーム開発などを行なっております。DBRE は比較的新しい概念で、DBRE という組織がある会社も少なく、あったとしても取り組んでいる内容や考え方が異なるような、発展途上の非常に面白い領域です。 弊社における DBRE チーム発足の背景やチームの役割については「 KTC における DBRE の必要性 」というテックブログをご覧ください。 この記事では、Amazon Aurora MySQL 2からAmazon Aurora MySQL 3への移行の際に mysqldump コマンドで発生したエラーメッセージなしで処理が終了する現象についてご紹介します。少しでも参考になれば幸いです。 エラーの原因 まずはエラーの原因について説明します。今回のエラーメッセージなしで処理が終了する現象は、Amazon Aurora MySQL 2のデータベースのトリガーに設定された照合順序が、MySQL 5系では未対応の utf8mb4_0900_ai_ci だったため、mysqldump がそれを認識できなかったことが原因で発生しました。 原因が判明するまでの調査過程と解決方法を、以下で詳しく説明させていただきます。 発生した現象 Aurora MySQL 2からデータをエクスポートするために、mysqldump コマンドを直接実行しました際に、エラーメッセージが表示されないまま終了してしまう現象が発生しました。 コマンドの実行後に exit code を確認したところ、2( Internal Error )が返されました。エラーが発生していることはわかりましたが、具体的な原因を特定できない状況です。 $ mysqldump --defaults-extra-file=/tmp/sample.cnf > sample.sql $ echo $? 2 原因調査 問題の原因を特定するために、以下を実施しました。 まず、別バージョンの mysqldump コマンドを実行した場合の挙動を確認しました。 今回、Aurora MySQL 2に対してMySQL 5.7系の mysqldump コマンドを使用しています。 $ mysqldump --version mysqldump Ver 10.13 Distrib 5.7.40, for linux-glibc2.12 (x86_64) 試しにMySQL 8系の mysqldump コマンドでエクスポートを試みました。 $ mysqldump80 --version mysqldump Ver 8.0.31 for Linux on x86_64 (MySQL Community Server - GPL) $ mysqldump80 --defaults-extra-file=/tmp/sample.cnf > sample.sql $ echo $? 0 結果は成功でした。このことから、MySQL のバージョン差異がエラーの原因である可能性が浮上しました。 さらに、mysqldump コマンド自体が内部でエラーを起こしている可能性を考え、さまざまなオプションを試してエラーメッセージの有無を確認しました。その結果、 --skip-triggers オプションを付与するとエラーが発生しないことが判明しました。 $ mysqldump --defaults-extra-file=/tmp/sample.cnf --skip-triggers > sample.sql $ echo $? 0 この結果から、トリガーに関連する部分でエラーが起きていると推測されます。そこで、トリガーの設定を確認しました。 mysql> SHOW TRIGGERS FROM sample_database \G *************************** 1. row *************************** Trigger: sample_trigger Event: UPDATE Table: sample_table Statement: BEGIN SET NEW.`lock_version` = OLD.`lock_version` + 1; END Timing: BEFORE Created: 2024-10-04 01:06:38.17 sql_mode: STRICT_TRANS_TABLES Definer: sample-user@% character_set_client: utf8mb4 collation_connection: utf8mb4_general_ci Database Collation: utf8mb4_0900_ai_ci *************************** 2. row *************************** (以下省略) ここで、データベースの照合順序(Collation)が utf8mb4_0900_ai_ci になっていることに気付きました。これは MySQL 5系では認識されない照合順序です。 エラーが発生していたテーブルのトリガー定義を utf8mb4_general_ci に修正し、再度 mysqldump コマンドを実行しました。 mysql> SHOW TRIGGERS FROM kinto_terms_tool \G *************************** 1. row *************************** Trigger: sample_trigger Event: UPDATE Table: sample_table Statement: BEGIN SET NEW.`lock_version` = OLD.`lock_version` + 1; END Timing: BEFORE Created: 2024-10-04 01:06:38.17 sql_mode: STRICT_TRANS_TABLES Definer: sample-user@% character_set_client: utf8mb4 collation_connection: utf8mb4_general_ci Database Collation: utf8mb4_general_ci *************************** 2. row *************************** (以下省略) $ mysqldump --defaults-extra-file=/tmp/sample.cnf > sample.sql $ echo $? 0 mysqldump が成功しました。MySQL 8系のコマンドで成功していた理由も、この照合順序の違いで説明できます。 この調査により、トリガーに設定されていたデータベースの照合順序が MySQL 5系では存在しない utf8mb4_0900_ai_ci だったため、mysqldump が失敗していたことが判明しました。 Amazon Aurora MySQL 2 と MySQL 5.7 の関係について Amazon Aurora MySQL 2は MySQL 5.7 をベースに構築されていますが、完全に同一というわけではありません。AWS は Aurora に独自の拡張機能を実装しており、その中には MySQL 8.0 の一部機能(今回問題となった utf8mb4_0900_ai_ci 照合順序など)も含まれています。 MySQL 5.7 にて utf8mb4_0900_ai_ci を照合順序に指定しようとすると、以下のエラーが発生します。 mysql> ALTER DATABASE sample_database CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci; ERROR 1273 (HY000): Unknown collation: 'utf8mb4_0900_ai_ci' 一方、Aurora MySQL 2では同じコマンドが正常に実行されます。 mysql> ALTER DATABASE sample_database CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci; Query OK, 1 row affected (0.03 sec) mysql> SHOW CREATE DATABASE sample_database; +------------------+---------------------------------------------------------------------------------------------------------+ | Database | Create Database | +------------------+---------------------------------------------------------------------------------------------------------+ | sample_database | CREATE DATABASE `sample_database` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci */ | +------------------+---------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec) 追加の調査 エラーの原因がトリガーのみなのか検証するために、他の MySQL のオブジェクトも調査します。 Aurora MySQL 2の環境でビュー(VIEW)の照合順序(Collation)を utf8mb4_0900_ai_ci で作成し、そのダンプ時の挙動を確認しました。 CREATE VIEW customer_view AS SELECT customer_name COLLATE utf8mb4_0900_ai_ci AS sorted_name, address FROM customers; mysqldump コマンドを実行すると、エラーなく成功します。 $ mysqldump --defaults-extra-file=/tmp/sample.cnf > sample.sql $ echo $? 0 次に、Aurora MySQL 2の環境でストアドプロシージャ(PROCEDURE)の場合も同様に確認しました。 DELIMITER // CREATE PROCEDURE sample_procedure() BEGIN DECLARE customer_name VARCHAR(255); -- 照合順序を指定した文字列操作 SET customer_name = (SELECT name COLLATE utf8mb4_0900_ai_ci FROM customers WHERE id = 1); -- 照合順序を使用した比較 IF customer_name COLLATE utf8mb4_0900_ai_ci = 'sample' THEN SELECT 'Match found!'; ELSE SELECT 'No match.'; END IF; END // DELIMITER ; こちらも問題なくダンプが成功します。 $ mysqldump --defaults-extra-file=/tmp/sample.cnf > sample.sql $ echo $? 0 Aurora MySQL 2では、MySQL 5系には存在しない照合順序(Collation) utf8mb4_0900_ai_ci を使用できます。 しかし、mysqldump コマンドが MySQL 5系 ベースの場合、この照合順序を認識できず、特にトリガーに関連する部分でエラーが発生することがわかりました。 ビューやストアドプロシージャでは問題が生じないことから、トリガーにおける照合順序の扱いが原因であると推測されます。 解決方法 今回の問題は、トリガーに設定されていたデータベースの照合順序がMySQL 5系では未対応の utf8mb4_0900_ai_ci であったために発生していました。 エラーへの対応としてはデータベースの照合順序(Collation)を utf8mb4_general_ci に変更し、トリガーを再設定しました。これにより、MySQL 5.7系の mysqldump コマンドでも照合順序を正しく認識できるようになり、エクスポートが正常に行えるようになりました。 ALTER DATABASE sample_database CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; -- 必要に応じてトリガーを再作成 別の解決策として、MySQL 8.0系の mysqldump コマンドを使用する方法もあります。MySQL 8.0 系のクライアントは utf8mb4_0900_ai_ci を認識できるため、データベースの照合順序を変更せずにエクスポートが可能です。 $ mysqldump80 --defaults-extra-file=/tmp/sample.cnf > sample.sql $ echo $? 0 環境や他の依存関係の制約からクライアントのバージョンを簡単に変更できない場合もあります。 おわりに 今回の事例では、mysqldump コマンドがエラーメッセージを表示しないまま終了し、exit code を確認することで初めてエラーが発生していることに気付きました。このようなエラーメッセージなしで処理が終了する現象は、気付かないまま不完全なデータをエクスポート・インポートしてしまうリスクがあります。そのため、データベースのバックアップや移行をする際には、exit code を確認するなど、処理結果をチェックすることが重要です。 Aurora MySQL 2系はすでに EOL(End of Life)を迎えており、サポートが終了しています。まだ稼働している環境があり、移行を検討していることがあればお気をつけください。
アバター
Introducing the Team and Its Work Our team is the Woven Payment Solution Development Group. However, before I tell you about our team, I need you to know a bit about Woven City . Woven City is both a test course for mobility and a city for conducting demonstration experiments, where Toyota Motor Corporation is developing technologies with the aim of “mass-producing happiness.” The development of Woven City is led by Woven Planet Holdings, a member of the Toyota Group. Our team is working with members of Woven Planet’s Payment Solution team and other teams to develop payment services to be used in Woven City. KINTO Technologies and Woven Planet are separate companies, but when it comes to the development work, we are working as one team without particularly being conscious of that. Woven City is a mobility test course for inventing the commonplace things of the future, and we are also required to develop features that will contribute to that. In Woven City, all the residents and other people involved are either inventors who create new value in some form or other, or people who create inventions together with them. That means those inventors must be provided with the features and data that they need to create better products, services, and the like. This is a big difference between general payment services and the ones we make. For example, for how a given service accepts payments from users, we are thinking about UX aspects such as making it easier to consider things like whether the best option is prepaid, postpaid, recurring payment, or some other method. We are also looking at the data provision aspects, and thinking about providing not just the payment information but that combined with other Woven City data, in a form that will enable things to be considered from multiple angles. Of course, these kinds of data are not only provided to inventors, but also used to kaizen the system that is Woven City itself. (Of course, we never obtain people’s personal information without their consent.) How We Work The Payment Solution team, including the members from Woven Planet, is doing the development work remotely from home. However, we come to the office once a week on Wednesday, giving us an opportunity to communicate directly with each other. We use Google Meet and Slack for our communication tools. In Woven Planet, the basic premise is that communication is in English, so we converse in that, especially if there are non-Japanese speakers present. Also, on Slack and in documents, communication is done in English even when it is between Japanese people. We also use English for postings that are like talking to ourselves, so if we write about something we are concerned about, it sometimes leads to getting advice from other teams or sparks a discussion. Besides that, other teams also sometimes consult us, and sometimes, that can lead straight into starting up an oral chat via Huddle, for example. So, there is lively communication even though we are working remotely. When we come to the office, we enjoy the stimulation you can get from actually meeting people in person, such as discussing things face-to-face and eating the company food together if our lunchtimes coincide. Our development work also gives us opportunities to visit the planned site for building Woven City. Woven City itself is currently under construction, so it looks different depending on when we visit, and although there are still many vacant areas, it is a useful experience for expanding our mental image of it actually being used. Technologies We Are Using Programming language Kotlin Our team’s scope is server-side applications, and we use Kotlin to develop them. A major reason why we chose Kotlin is its high interoperability with Java. There are already a great many Java engineers in KINTO Technologies and the group, and we are hoping this will induce them to join our team quickly. I myself have experience of using Java in the past, and had a go at building simple web applications with Kotlin several times as part of introducing it. Through this, I became able to code in it about as smoothly as in Java and with no real problems just by referring to the official documentation a bit. Some of the members have experience of server-side development in other languages like Go, C#, and Ruby but none in terms of Java itself, but they can all use Kotlin with no real problems now, too. Initially, we used Kotlin as a better version of Java, but now, we are starting to forget about Java and consciously use Kotlin for its own merits. Additionally, we use Gradle for project management and write the configuration files in Kotlin Script. The main libraries we are using Ktor, Koin, Exposed, Kotest, MockK, etc. Our services consist of several application services, many of which are web services with a REST API. You can use Spring MVC and Spring Boot with Kotlin as well, but we chose Ktor instead. We chose not to use Spring because we wanted to avoid code that is heavily annotated and feels like magic. However, we still wanted to use a dependency injection mechanism for testing and dependency management, so we adopted Koin as our DI library. Koin also has an annotation-based configuration method like Spring, but it has a DSL-based configuration method as well, and we are using that one. Although it requires knowledge of Koin and of DSL itself, DSL can be incorporated into normal Kotlin code more naturally than annotations, so I feel you can express your intentions clearly in it. In addition, we use various FOSS libraries, such as Exposed for ORM and Kotest and MockK for testing. Ktor official website Koin official website Exposed GitHub repository Kotest official website MockK official website This is more of a personal interest than a team one, but since Ktor also works in GraalVM , I would like to try doing a native build with GraalVM if I get the chance. Reference: https://ktor.io/docs/graalvm.html#prepare-for-graalvm Application Infrastructure Kubernetes The applications we are developing are deployed on Kubernetes, and for the services we are developing ourselves, we write the configuration files ourselves in YAML. Another team is in charge of the development and operation of the Kubernetes environment as a whole, but this team has also prepared a CD mechanism. Basically, if we turn the new configuration data into PRs then review and merge them on GitHub, everything right up to deploying the apps gets done automatically. The team also responds to requests from us about configuration, architecture, and so on, so they are always a tremendous help. How We Do Development Because of the project’s unprecedented nature of creating a city that functions as a test course, there are many unknowns not just in the parts that our team is working on but in the whole thing, too. So, using as a foothold the features that will be required as a matter of course, we are coming up with rough hypotheses and development plans, and are learning about our own services ourselves as we create them, and about Woven City, too. Specifically, the process we are following is to set a big theme for each quarter, add or update features as needed for that, then check them by running small demos in the office. For this reason, we adopt an agile development method, we do the development iteratively with two weeks as the timeboxes, while managing the backlog with Jira. We are not following strict Scrum practices, but are seeking to adapt to the facts that come to light and changes in requirements that arise along the way as we develop things. Conclusion What is difficult about this project is that, at this point in time, the real test course that is Woven City still does not exist, and of course, the users are only potential ones, too. This goes for all teams and not just ours. It often happens that another team wants to use a feature that is still in development, but it is still unstable. On the other hand, you could also say that since there are no general users, it does not matter (at least now) if things are unstable to a certain extent. While being in this unstable state can be taken as grounds for not using each other’s creations, it can also be relished as an opportunity to improve them by respectfully but frankly pointing out their defects, all in the spirit of forging and honing them together through use. We definitely want people who think in the latter way to take part in our project.
アバター