「厳密な」テスト駆動開発サンプルと現場でのテストの書き方紹介

こんにちは! クロスマートバックエンドエンジニアの小久保です!
突然ですが、みなさん、テスト書いてますか?

やろうやろうとは思ってるんだけど、時間もないし敬遠してる。。。!
そもそもあれって現場でほんとにやれんの?

なーんて思ってる方、朗報です!

今回は簡単なプログラムを「厳密な」テスト駆動開発を使って開発する様子を見せちゃいます!

ガチンコのテスト駆動開発を体験し、そのエッセンスを持ち帰っちゃってください!

また、最後に、現場ではどんな風にテストを書いてるの? みたいなお話もしちゃいますね。

奥深きTDD(Test Driven Development)の世界の第一歩をここから始めていきましょう!

  • 「厳密な」テスト駆動開発を使って作るプログラム
  • テスト駆動開発のルール
  • 環境構築
  • Red - 失敗するテストを書く
  • Green - 最速で雑にテストを通す
  • Refactor - テストOKを維持したままリファクタ
  • 2週目 Red - 失敗するテストを書く
  • 2週目 Green - 最速で雑にテストを通す
  • 2週目 Refactor - テストOKを維持したままリファクタ
  • 大事なポイントまとめ
    • テストから書くことでクライアントの使い勝手をはじめから意識できる
    • 1テスト1アサーションを心がけ ドキュメントとしてテストコードを書く
    • テストコードを動くドキュメントのように書く
  • 続きを書いてみよう
  • 最後に - 現場ではどんな風にテストを書いているの?
  • まとめ
続きを読む

クロスマートエンジニアメンバーにeNPS調査してみた

はじめに

はじめましてこんにちは!😄

クロスマート株式会社でプロダクトマネージャー(以下、PM)を務めております神山です。

クロスマート歴は1年10ヶ月でして、入社して1年はCSMGR、その後4ヶ月産育休をいただきPMとして復帰しました。プロダクトチームにjoinするのは長い社会人歴でも実は初めてで、まだ6ヶ月の新米PMです🥚

今回Tech Blogの担当になりまして、そんなテクいことを語れるスキルもないので

【😄クロスマートエンジニア組織ってぶっちゃけどうなの??😄】

といった内容を一緒に働くエンジニアさんにeNPSアンケート*1を実施いたしましたのでご紹介させていただきます🥳

 

日本企業のeNPSスコアとクロスマートエンジニアのeNPSスコア

eNPSスコアというのは、自分の職場が普通に良い〜🎶と思っていても加算対象にはならないので基本はマイナスのスコアになります。

株式会社ビービットの調査によれば、日本のeNPS平均スコアは「-61.1」です。かなり低く感じるかもしれませんが、自分の職場を他人に勧めるのはハードルが高く、真ん中の5や6を選んでも批判者に含まれるため、eNPSはほかの調査に比べても低い点数が出やすい傾向にあります。

参照:eNPSとは? 平均や調査方法、社員の本音が見える質問、計算式、分析方法を紹介|SmartCompany(スマカン)

業界別eNPS

参照:『eNPSは何によって上がるのか ー16業界eNPS調査結果』株式会社ビービット

 

そんな中、クロスマートエンジニアeNPSスコアはなんと53.3でした。

図にするとこんな感じ

 

なぜそんなにオススメできるのか

エンジニアが「転職したい」と思っている理由には以下があるようです。

転職を決めた理由

参照:エンジニアが転職を決めた理由、第1位は「収入アップのため」 | レバレジーズ株式会社

今回のeNPSアンケートではこれらの理由に沿った質問もしてみました❗️

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

Q1.『クロスマートが関わる業界において、将来性を高く感じますか?』

4.60(/5点満点)

 

Q2.『自分の仕事とキャリア目標を達成するために、組織がサポートしていますか?』

4.07(/5点満点)

 

Q3.『仕事について学び、成長する機会がありますか?』
『新しい技術が導入されていると感じますか?』
『同僚やチームメンバーとの知識共有がスキルアップに寄与していると感じますか?』

4.44(/5点満点)

 

Q4.『休日出勤や残業が少ない環境であると感じますか?』

4.47(/5点満点)

 

Q5.『同僚との協力や連携について満足していますか?』
『働いているチームや部署の雰囲気について満足していますか?』

4.63(/5点満点)

 

Q6.『昇進の機会について充実感を感じていますか?』

3.47(/5点満点)

 

Q7.『雇用形態における柔軟性や調整の余地について満足していますか?』

4.73(/5点満点)

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

会社の将来性も感じられて、スキルアップやキャリアアップも叶えられ、チームの雰囲気もよくライフワークバランスも取れる素敵な職場です!!✨

 

エンジニアさんの生の声🎤

チームの雰囲気について

性善説に基づきながら一定自律した牧歌的な組織だなと感じる。

・他者・他部署リスペクトが高いよい組織。

・優しさあふれる環境なので、ゆるく働いているかと思いきやコミット力がすごい人が多く非常に勉強になる。

・社員同士がとても仲が良く、社の雰囲気がとてもいいと感じる。

・フルリモートながら、組織の雰囲気が間違いなく良い!

・悪い人がいない。何かやりたい時に相談したら、まず否定されないしやってみよう!ってポジティブなとこが好き

働き方について

・子供がいても柔軟に働けるのでとてもありがたいです!

・のびのびと働かせていただいている。

・無理な残業などがなく、趣味や家族との時間がきちんと確保できる。

開発について

・新しい技術を積極的に取り入れようという姿勢が感じられる。

・開発のスピード感がある。

・爆速でPDCAサイクル回すの楽しすぎる。

・賞賛文化がしっかり根付いているため部署を飛び越えてみんなが見てくれて褒めてくれるのが嬉しい!

会社について

・社会的にも意味あるプロダクトを提供している。

・スタートアップ企業なので当然にあるリスクや、またコミュニケーションが活発である事から、チームフィットの観点で弊社を勧める相手は選ぶ必要があると考えられます。

・会社としての仕組みが非常に良いため、合う人にはとことん合いそうな環境。

・明らかに働きやすい。何社か経験したが、異色の働きやすさ。自走できるタイプならば天国だろう。

・エンジニアとして働いているが、セールス、マーケ、IS、CSの仕事っぷりが自然に情報として入ってきて、非常に勉強になる。起業やサイドビジネスに活かせる。

・会社の雰囲気等はかなり良く、こんな会社他にあるの?っと思えるぐらいなのですがやはりベンチャーだったり等自己責任な部分もある。

おわりに

だいぶ手前味噌なeNPS結果になってしまいましたが、この良い雰囲気を継続できるようなプロダクトマネジメントを行なっていきます🥳

クロスマートではエンジニアやBizDevなど広く一緒に働く仲間を募集中です。

この雰囲気で働いてみたいアナタ!組織も事業も急拡大していて、やること満載なので興味がある場合は是非こちらをご覧ください☺️

*1:eNPSとは「Employee Net Promoter Score(エンプロイー・ネット・プロモーター・スコア)」の略称であり、「親しい知人や友人にあなたの職場をどれくらい勧めたいか」を尋ね、「職場の推奨度」を数値化したもの

クロスオーダー請求書で実際に使っているpandasのご紹介


2023年8月よりクロスマートのバックエンドエンジニアとして入社しました中松です。
フルリモートで大阪から参画させていただいてます。
オフィスに一度も行かないまま入社したのが衝撃的でした!
違う業界からのジョブチェンジになるので、Python以外の実務経験はほぼなく、
しかも息子がまだ0歳という状態からクロスマートで働かせていただいており、
チャンスやご縁をくださった方々には感謝です。
小さなお子さんがいらっしゃる方も多く、非常に家族を大切にしていらっしゃる方が多いのがとても印象的です。

今更だけどpandasすごい

Python歴はそこそこあるもののpandasを知りませんでした(恥)
csv(表データ)をゴニョゴニョする上でこんなに便利なライブラリがあったとは!

まず、pandasで扱うDataFrame型にcsvのデータを読み込みます。

import pandas as pd

df = pd.read_csv("sample.csv")

これだけ!短い!

請求書の機能を作成する際に実際に使った便利pandasを紹介!

クロスオーダー請求書では外部のシステムから出力されたcsvデータを読み込んで請求書を作成しています。

請求書番号 合計金額 取引先コード 商品名 個数 明細金額
1000001 4000 A111 豚肉 1 1000
1000001 4000 A111 鶏肉 2 1600
1000001 4000 A111 牛肉 1 1400

このようなデータを使っています。(実際のデータはもっと項目数が多いです)
これで1枚の請求書が出来上がります。

① 請求書のデータが2つに分かれている

合算.csv

請求書番号 合計金額 取引先コード
1000001 4000 A111

明細.csv

取引先コード 商品名 個数 明細金額
A111 豚肉 1 1000
A111 鶏肉 2 1600
A111 牛肉 1 1400

これでは既存のシステムに取り込めないため、マージすることにしました。

df_total = pd.read_csv("合算.csv")
df_detail = pd.read_csv("明細.csv")
df = pd.merge(df_detail, df_total, left_on="取引先コード", right_on="取引先コード", suffixes=(None, "_y"), how="left", indicator=True)

これだけ!
マージするキーを指定してますが、同じ場合省略しても良いです。

請求書番号 合計金額 取引先コード 商品名 個数 明細金額 _merge
1000001 4000 A111 豚肉 1 1000 both
1000001 4000 A111 鶏肉 2 1600 both
1000001 4000 A111 牛肉 1 1400 both

indicatorをTrueにしておくだけで、どちらのデータに存在しているかの情報を付与してくれます。
こちらも大変便利です!

② 請求書のデータを置換したい

請求書のデータの一部を置換したい要望があがりました。
今回使用しているデータで取引先コードを1234に変更したいとします。

df["取引先コード"].replace({"A111": "1234"}, inplace=True)

これだけで該当するデータを置換してくれます!

どちらもすごく短いコードで簡単にかけるので驚きでした。。
pandasのよりパフォーマンスが上がったバージョンとして、
polarsというモジュールもあります。
よりたくさんのデータを処理する場合、polarsを使用していきたいですね。

最後に

クロスマートは事業拡大中のため、絶賛エンジニアを募集しています。
ご興味がある方は、是非こちらを御覧ください!

xorder.notion.site

コードレビューを依頼するときに意識している2つのこと

こんにちは!
2023年10月よりクロスマートでバックエンドエンジニアとして参画している石垣です。

クロスマートに入社して早3ヶ月、爆速で過ぎていった毎日・・・
サービス・仕様理解の最中だったため、レビュイーに徹することが多かった私ですが、
今回は、この3ヶ月間、コードレビューを依頼する際に特に意識していたことについてご紹介したいと思います!

1. できるだけ詳細な概要を記載する

私は常々思うのです、コードレビューをしていただきありがとうございます!と。
それと同時に、レビューにかける時間を減らしてレビュアーの開発時間を確保してあげたい!と。
レビュアーが必要な情報を素早くキャッチし、効率的にレビューを行えるようサポートすることが、レビュイーとしての役割だと思います。
そのため、レビュアーが必要な情報を迅速に理解できるよう、詳細かつ明確な概要を提供できるように意識していました。

まず、詳細で分かりやすい概要を記載できるように所属チームのプルリクテンプレート*1を変更しました。

私が所属しているチームのテンプレートは以下になります。

## 概要

## 変更点
-

## テスト内容

## レビュワーに確認してほしいこと

## 関連URL・issue

 

実際に「注文一覧を取得するAPI」を実装したと仮定して、このテンプレートに沿って概要を記載してみます。

  • 概要
    PRの関連性がすぐに理解できるよう、関連するURLを明記します。
    これにより、レビュワーはPRの背景や目的を迅速に把握することができます。
    クロスマートではJIRAでチケット管理をしているため、いつもはJIRAのURLを貼っています。

  • 変更点
    誰が何をするための変更であるのかを明記します。
    簡潔に伝えるため、箇条書きで変更点を記載していくのがおすすめです!
    APIを作成した場合は、概要がドキュメントの役割を果たすようにエンドポイントやパラメーターを書くとより親切に思います。
    変更点を書き出していくと、実装した内容が要件を網羅したものになっていないことに気づくことも。

  • テスト内容
    テストの詳細な手順と内容を記載します。
    レビュワーが同じ手順でテストを行えるように記載し、レビュワーが同じ条件の元でテストを行い、一貫性のある結果を得られるようにします。

  • レビュワーに確認してほしいこと
    例えば、アーキテクチャの観点からアドバイスが欲しい、テスト内容は網羅されたものになっているかなどを書くことが多いです。

  • 関連URL・issue
    実装する上で参考にしたドキュメントや、関連するPRリンクなどを貼ります。

できるだけ簡潔に、不要な情報は書かない。
これを念頭に置いて記載しています。

2. 開発時に迷ったところはあらかじめ申告

  • ペアプロをお願いするほどではない軽微なもの(変数名など)
  • 期待した動作をしているがなんか自信がないもの
    ドキュメントや参考記事に書いてあったけどもっといい書き方がありそう、など

上記に当てはまる場合、私は無邪気に「自信がないです!」と自己申告しています。

実際に私が申告したものがこちら。

私はDRF歴が3ヶ月であるため、はっきり言って自信があまりありません。
この時はドキュメントを確認したり、ChatGPTに質問を投げてみたりして実装しました。
しかし、周りくどい書き方になっているのに違和感を感じたため例に倣って自己申告。
この書き方でも間違ってないけどこっちの書き方はどう?と実際にアドバイスをいただくことができました。

コードレビューはコードの品質を保つために行うものであると同時に学びのチャンスだとも捉えています。
一緒に働く先輩エンジニアからスキルを盗む絶好のチャンスです。
分からないことがあるのは、それだけ成長できるチャンスがあるということ。
ポジティブマインドでレビューをいつもお願いしています!

最後に

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

クロスマートではPM、エンジニア、BizDevなど広く一緒に働く仲間を募集中です。
ご興味がある方は、是非こちらを御覧ください!

xorder.notion.site

 

*1:※テンプレートの設定方法はこちら

非公式GUIアプリをひっそり作って社内公開してる話



メリークリスマス(こんにちは)
2023年10月よりクロスマートでバックエンドエンジニアとして参画している宮崎です。

今回はクリスマスにぴったりのElectron+Sveltekit+Skeleton+TypeScriptでデスクトップアプリを作った際の話をさせていただこうかと思います。
アーキテクト選定理由、環境構築、ポイントや詰まった箇所など冗長かつ乱文となっていますがご容赦いただければ幸甚です。

What for? (背景)

クロスマートでは
お客様の課題を解決するために、日々様々なサポートを行っています。
しかし、現在の本体プロダクトでは解決が難しいケースもあり、手作業でデータの調整を必要とする場面がどうしても出てきます。
その作業を行っているメンバーの負担を少しでも楽にできないかと考え、非公式アプリを日々作成しています。

使ってみたい技術スタックを試して形にでき、メンバーに感謝される is 最高

Why this?(選定理由)

Electron、Eel、Tauri、Flutterなどの様々なフレームワークを検討しましたが
以下の理由からElectron+Sveltekit+Skeleton+TypeScriptという結論に落ち着きました。

バックエンド(というかGUIフレームワーク)
  • Electron:
    Web技術が使える -> HTML, CSS, JavaScript大好き
    FileAPIが独自拡張されてる
    -> FileAPIの拡張でパスが取れるの革命だと思うんですよね…(唯一無二)

  • Eel: どうせなら…Tauri?というお気持ち
  • Tauri: 最後まで迷ったが、ファイルが絡むので…
  • Flutter: Dartでフロント書く気力が沸かなかった…CSS Love
  • flex, pyside... : 独自UI書く気力が…
フロントエンド
  • ネイティブのみ: 流石に味気ない
  • Vue: 色々触ったので今回は趣味ということもあり候補外
  • React: JSXが苦手なので最終手段(触らなければとは常々…)
  • Astro: 忘れてた。多分次使います
  • Svelte: 物理的に最短で記述できる!にちょっと興味が!

コンポーネントライブラリは当初利用予定がなく、CSSフレームワークのTailwind CSSを利用予定でしたが…
良さそうなライブラリ(Skeleton)を見つけてしまい勢いで採用 www.skeleton.dev

…と言った感じで非公式かつ業務外ならではの好み気分を重視して選定しています。


ちょっと前置きが長くなってしまいましたが、
ここまで読んでくれているような方が気になっているであろう環境構築は以下になります。

環境構築

SvelteKit + Skeletonのインストール

mkdir desktop-app
cd desktop-app

npm create skeleton-app@latest
# 対話式で色々聞かれるので、好みで。
# template: Bare Bones
# theme: Skeleton
# other packages: none
# TypeScript: Yes, using TypeScript syntax
# like setup: Add ESLint for code linting?, Add Prettier for code formatting?

# とりあえず一旦必要なファイルをインストール
npm i

# Electronなので追加(SSGで出力)
npm i -D @sveltejs/adapter-static

# Prettierのデフォルト戦争でTabになっているのでSpaceに変更
vi .prettierrc
> "useTabs": false,

prettier --write .
npm create svelte@latest
npm i -D @skeletonlabs/skeleton
...

最初はSveltekit入れてからSkeletonを組み込む手順で構築してましたが、
Sveltekit初体験ということもありディレクトリ構造など迷うポイントが多かったので素直にSkeleton側で用意してくれているCLIで構築しました。

Electronの組み込み

npm i -D electron concurrently

# 設定を保存するのに便利で使いやすいので比較的おすすめです。使わないなら必要ない
npm i electron-store

# mac用にしか吐き出さないので、zipとdmgのみ
npm i -D @electron-forge/cli @electron-forge/maker-zip @electron-forge/maker-dmg

有名なので知ってる人も多いと思いますが concurrently は、便利ですのでおすすめです。

パッケージの設定云々

多分一番躓く人が多いんじゃないかと思う各種設定ファイルを参考程度に抜粋+説明しておきます。

ディレクトリ構造
├── README.md
├── forge.config.cjs
├── package-lock.json
├── package.json
├── postcss.config.cjs
├── src
│   ├── app.d.ts
│   ├── app.html
│   ├── app.postcss
│   ├── electron.cts -> Electron: main
│   ├── global.d.ts -> Electron: Typeとか
│   ├── lib
│   │   └── index.ts
│   ├── preload.cts -> Electron: Rendererとの通信用
│   └── routes
│       ├── +layout.server.ts
│       ├── +layout.svelte
│       └── +page.svelte
├── static
├── svelte.config.js
├── tailwind.config.ts
├── tsconfig.electron.json -> Electron: Electron用のTSビルド設定
├── tsconfig.json
└── vite.config.ts

ある程度抜粋していますが、Electron関係のファイルも src にまとめて作っています。

Package.json
"main": "dist/electron.cjs",
"productName": "デスクトップなアプリ名",
"type": "module",
"scripts": {
  "tcs": "tsc -p tsconfig.electron.json",
  "dev:svelte": "vite dev",
  "dev:electron": "tsc -p tsconfig.electron.json && electron .",
  "dev": "concurrently -n=svelte,electron -c='#ff3e00',blue \"npm run dev:svelte\" \"npm run dev:electron\"",
  "build": "vite build",
  "preview": "vite preview",
  "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
  "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
  "lint": "prettier --check . && eslint .",
  "format": "prettier --write .",
  "make": "tsc -p tsconfig.electron.json && vite build && electron-forge make --arch=universal"
},

npm run dev:svelte
Sveltekitの起動、ブラウザで確認したい場合はこちら

npm run dev
Electronも絡めたい場合はこちら、concurrentlyでElectronとSveltekitの起動を同時に行う

npm run make
パッケージング、--arch=universal については後述

"main": "dist/electron.cjs",
Electronのエントリーポイントを指定
Electronはtsファイルを直接読み込めないためTSビルド成果物を読み込むように変更

"productName": "デスクトップなアプリ名",
アプリ名って大事ですよね…ネーミングセンス欲しい

"type": "module",
宗教戦争が起きるので、黙秘

"tcs": "tsc -p tsconfig.electron.json",
Sveltekit自体にTypeScriptを使っている関係上、ElectronのTSビルドで色々不都合が生じます。
(ElectronはデフォルトでCommonJSを使っているため、ES Moduleとの共存の部分で)
難しいことを考えず、Electron用のファイルを用意して読み込ませれば解決。

  "preview": "vite preview",
  "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
  "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
  "lint": "prettier --check . && eslint .",
  "format": "prettier --write .",

この辺は自分的には不要でしたが、消す理由もなかったので残してます。

tsconfig.electron.json
{
  "files": [
    "src/electron.cts",
    "src/preload.cts",
  ],
  "compilerOptions": {
    "module": "commonjs",
    "target": "ES2022",
    "outDir": "./dist",
    "allowJs": true,
    "checkJs": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "skipLibCheck": true,
    "strict": true,
  }
}

デフォルトの設定を"type": "module"にしているので、Electron関係のtsファイルは明示的に.ctsにする必要があります。

svelte.config.js
import adapter from '@sveltejs/adapter-static';
...
  kit: {
    adapter: adapter({
      pages: 'dist/view',
      assets: 'dist/view',
      fallback: undefined,
      precompress: false,
      strict: true
    })
  }

pages: 'dist/view',
assets: 'dist/view',
Svelteをビルドした時(SSG)の出力先変更、意外と大事。
ちなみに 'dist/' 配下にしないとElectronが読み込めないので注意。

src/routes/+layout.ts or src/routes/+layout.server.ts
export const prerender = true;

1行だけですけど、めちゃくちゃ大事です。
+layout.svelte じゃなくて +layout.ts を別途作ってあげる必要があります。
.tsです。
.svelte じゃありません。 .tsです。
もう一度言います、 .tsです。

じゃないと延々と

@sveltejs/adapter-static: all routes must be fully prerenderable, but found the following routes that are dynamic:

と言われます。(言われました)

forge.config.cjs
module.exports = {
  packagerConfig: {
    asar: true,
    icon: './static/icon/icon.icns',
  },
  rebuildConfig: {},
  makers: [
    {
      name: '@electron-forge/maker-zip',
      platforms: ['darwin'],
    },
    {
      name: '@electron-forge/maker-dmg',
      config: {
        background: './static/icon/app-background.png',
        icon: './static/icon/icon.icns',
      },
    },
  ],
};

background: './static/icon/app-background.png',
正直これ、別に必要ないです。
作ったアプリをapplicationフォルダに移す際に表されるウィンドウの背景設定。

icon: './static/icon/icon.icns',
作ろう!作るべき!Figmaとかで簡単に作れます!
Figmaで作ったのをpngでエクスポートして、icns変換してくれるWEBサイトを利用すればあっという間に完成!
ちなみに、size: 400px*400px Radius: 80px を無責任におすすめしておきます!

src/electron.cts
const dev = !app.isPackaged
...
if (dev) {
    const promise = main.loadURL('http://localhost:5173/')
    main.webContents.openDevTools()
} else {
    const promise = main.loadFile("dist/view/index.html")
}

const dev = !app.isPackaged
Electronの起動時にパッケージ化されているかどうかを判定しています。
npm run dev で起動する場合は const dev = true になります。
npm run make で作成したパッケージを起動する場合は const dev = false になります。

起動時に cross-env DEV_ENV=true を書き
const isDevEnvironment = process.env.DEV_ENV === 'true' とかでも問題ないです。
が、上記のようにパッケージ判定で賄えます!便利

const promise = main.loadFile("dist/view/index.html")
ここがSSG化したファイルを見に行く場所になりますので変更したい場合は svelte.config.js も合わせて修正してください。
ちなみにpreloadは preload: path.join(__dirname, "preload.cjs"), のように書いてます。

最大の落とし穴について

Macはインターネットからダウンロードしたり、メールの添付ファイルとして受け取ったり、App Store以外の他のソースから取得したりするファイルやアプリにcom.apple.quarantineという拡張属性を必ず付与します。

Arm64でビルドしたアプリに対してはセキュリティ解除しなければインストール画面にすら辿り着けないようになっており、それなりの知識(そういうものと認識)が必要となります。
Apple Developer Programに加入して野良アプリから昇格させるという手もありますが有料($99/年)です。

そのため、自分のおすすめは electron-forge make --arch=universal になります。
universalですと警告は出ますが一応インストールを実行させてくれるので難易度はかなり低くなります。

まとめ

ここまでくれば、
Sveltekitで作ったものを読み込んで表示するElectron製のデスクトップアプリの作成環境が出来上がっているかと思います。

あとは各々好きな機能を実装し、良きクリスマスをお楽しみください。
メリークリスマス🎄(最後まで見ていただいてありがとうございました)

最後に

お決まりですが、クロスマートではバックエンド・フロントエンドエンジニアの方、さらにはBizDevなど一緒に働ける方を広く募集しています。
ご興味がある方は、是非こちらを御覧ください!一緒にクロスマート非公式アプリを量産しましょう。 xorder.notion.site

プロジェクトで活きた!効果的なUXリサーチ

こんにちは。

3ヶ月ぶりの投稿になります、UI/UXデザイナー大島です。 今回はプロジェクトの仕様策定にUXリサーチが効果的に効いた事例をお話できればと思います。

UXリサーチとは、ユーザーの行動やその行動に至る心理、感情を調査することです。 UX を向上させるためにはユーザーを知ることが欠かせませんが、そのための活動が UXリサーチなのです。 UXリサーチの手法には、インタビューや製品・サービスを使ったテストなどさまざまな方法があり、目的によって使い分けます。

UXリサーチとは?メリットや必要とされるケースをわかりやすく解説|スパイスファクトリー株式会社

仕様策定とUXリサーチの絡め方

扱う案件の性質上、具体的な内容は伏せさせていただくので、ニュアンスが伝わるような挿絵を使ってお話させていただきます🙏

担当するプロジェクトは端的に言うと競合でも実装していない新しい機能の開発になります。

PJ参加当初は前例がない機能をデザインするという点で難易度も高く、形にするまでの苦労がありました。まずは初期の仕様をすべて組み込んだデザインを用意し、話し合ったのち修正するというサイクルをこなし、実装に移ろうか?という段階にさしかかりました。

しかし、機能的に使いやすいのか?顧客のニーズにはまるのか?とユーザー視点に思いを馳せたときに、常に引っかりがあり、「開発の前に、UXリサーチで良し悪しを確かめさせてください!!!」と提案することに決めました。

UXリサーチを行う間は開発を止めてしまうので、ちょっとドキドキしながらの提案でしたが、PM杉原が驚くほどのスピードで顧客に取り次ぎを行い、テンポよく5社以上のターゲットにインタビューを実施することができました。

 

モックを駆使してユーザビリティテスト(UT)を中心にしたインタビューを複数回行い、分析作業を進めました。回答に散らばるキーワードを俯瞰してみると、そこには確かな「ニーズ」が現れていました。

ニーズにフォーカスした新たなデザインを用意し、2巡目のユーザビリティテストを実施したことで、「これ、いけるぞ!」と自信を持てる機能に落とし込めた感覚がありました。

そして、満を持してエンジニアにバトンを渡すことができました。実際に好意的なコメントを頂き、非常にやりがいを感じた瞬間でした。

このスピードを叶える「現場」というValue

弊社のValueのひとつに「現場」というものがあり、「現場に行く、現場を見る、現場を理解する。どれだけサービスが大きくなっても、現場にいる一人ひとりのお客様と向き合い、業務の解像度を上げ続けよう。職種を超え、徹底した現場主義を貫く。」という内容になっています。

顧客と良好な関係を築き、しっかりと連携できているからこそのインタビュー実現スピードだったので、Valueの価値をしっかり体験できた瞬間でした。

最後に

入社間もないタイミングで導入したUXリサーチでしたが、終始よい流れで進行できた実感があります。風通しの良い組織でのびのびと専門性を発揮できるクロスマートに興味が湧きましたら、ご興味がある方は、是非こちらを御覧ください!

「SUQL」による構造化・非構造化データ融合の可能性

こんにちは、新卒入社してもう年末が迫ってきており焦っている田村慎です。
いきなりですが、今年からデータベース、SQLを学び始め、日々業務で使っております。そして、学生の間は非構造化データを扱う研究領域でした。これらを踏まえて構造化データ、非構造化データを扱う経験がある自分にとって非常に魅力的な研究、論文を見つけましたので、今回取り上げさせていただきます。

今回取り上げさせて頂いた論文

「SUQL: Conversational Search over Structured and Unstructured Data with Large Language Models」

目次

研究背景

昨今、ビッグデータに基づく日常生活では、情報が様々な形で存在し、飛び交っています。例えば、レストランのデータベースには、レストラン名、料理の種類、お店の評価ポイントなどの「構造化データ」と、人気の料理やレストラン利用者のレビューなどの「非構造化データ」が含まれています。これらのような構造化データと非構造化データを含むデータから、ユーザーが求める情報を適切に抽出する技術は、様々な領域や分野で求められています。

まず,構造化されたデータに対してのアプローチ

構造化データは通常、リレーショナルデータベース(RDBMS)に格納されます。このRDBMSで使用される標準的な言語としてSQL(Structured Query Language)が存在します。SQLを使用することで、データの検索、更新、削除、挿入などの操作が可能です。これにより、データベース内の情報を効率的に管理できます。SQLは直感的であり、異なるデータベースシステムで使用が可能なため、広く利用されています。データベース関連のタスクにおいて不可欠なツールです。

今回提案されている「SUQL」に関して

今回の論文により提案されている「SUQL(Structured and Unstructured Query Language)」は、LLM(大規模言語モデル)を使用し、SQLを拡張させた新しい言語です。SUQLでは、構造化データと非構造化データの両方を含むデータに対しても、SQLのように対話型のインターフェースを用いて扱うことが可能になります。この新しい言語は、自由形式のテキストを含むクエリを処理するために特別に設計されたプリミティブをSQLに追加することで、より表現力豊かで柔軟なデータ検索と分析を実現します。これにより、ユーザーは自然言語のような形式で質問を行い、構造化されたデータベースの情報と非構造化されたテキスト情報の両方から、より的確な回答を得ることができるようになります。

SUQLの実験例

今回の論文内では上の説明で例として上げている、レストランのデータに対してSUQLを使用して実験を行っております。

構造化データ部分:レストラン名、料理の種類、評価ポイント、など
非構造化データ部分:人気の料理、レストラン利用者のレビュー、など

表1.レストランデータセットの例

上記のデータに対して「イタリアンレストランでロマンチックな雰囲気のある店は?」のような複雑なユーザーの質問をLLMを元に開発された新しいセマンティックパーシングプロセス(意味的構文解析)を用いてユーザー質問を理解し、適切なSUQLのクエリへと変換を行います。従来のSQLと同じようにこの変換され発行されたクエリを使用し、DBから適切な情報の取得を行います。
これにより、構造化データと非構造化データの両方を効率的に検索し、組み合わせることが可能になります。

図1.本アプローチのフロー

実験結果

「SUQL」では、従来の方法と比較して大幅に性能が向上しています。特に、レストランに関するデータセットを使用した実験では、ユーザーが必要とする要件を適切に探し出すことの成功率が従来の手法では最大で65.0%だったのに対し、本手法では89.3%を達成することができました。このように、「SUQL」を用いることで複雑な質問に対しても高い精度で回答できることが示され、実用性が確認されています。

表2.検索精度の測定結果

まとめ

この研究は、構造化データと非構造化データを組み合わせて扱う新たな会話型インターフェースの言語の開発に成功しました。

まだ、全ての人間にとって使いやすい形式というわけではありませんが、今後の応用範囲が非常に広い研究として日常生活でより複雑な情報を簡単にアクセスできるようになることを期待して、更なる発展、研究を追っていきたいと思います。

最後に

最後まで読んでいただき、ありがとうございます。
クロスマートではバックエンド、フロントエンドエンジニアの方、さらにはBizDevなど一緒に働ける方を募集しています。
ご興味がある方は、是非こちらを御覧ください!

 

PM視点で「ナイスガイ/ナイスガール」の大切さについて考えてみた

1. 前段

ご覧いただきありがとうございます。クロスマート株式会社でプロダクトマネージャー(以下、PM)を務めております森(@monroo12)です。

PMとして公開されている記事で、会社のバリューである「現場」「共に」についてはプロダクトマネージャー視点で大事にしていることを書かせていただきました。

弊社にはあと一つ「ナイスガイ/ナイスガール」というバリューがあるので、そのバリューについてもPM視点でどのように開発体験に影響を与えているか?を考えてみました。

 

想定読者

  • クロスマートに少しでも興味があるかた
  • PMってなんなのさ?って思っているかた
  • 優しいまなざしで記事を見てくださる方

 

今回の流れ(目次)

 

2. プロダクトマネジメントに必要なソフトスキルと「ナイスガイ・ナイスガール」の共通点

プロダクトマネージャーに必要なソフトスキルとは?

ChatGPTに聞いてみました。

1.コミュニケーション能力
チームメンバー、ステークホルダー、エンジニア、デザイナーなど、さまざまなバックグラウンドを持つ人々と効果的にコミュニケートできる能力が重要です。明確かつ的確な情報の伝達が、プロダクトの成功に直結します。

2.リーダーシップ・優れた意思決定力
チームを引っ張り、方向を示し、目標に向かって進むことができるリーダーシップスキルが必要です。時には困難な決定を下すことも求められます。データを分析し、情報をもとに適切な意思決定を行うスキルが必要です。不確実性の中で意思決定を行う能力も重要です。

3.チームワーク
プロダクトマネージャーは多くの場合、クロスファンクショナルなチームと協力して仕事を進めます。チームとの協力関係を築き、効果的なチームワークを促進するスキルが重要です。

4.問題解決能力
プロダクトマネージャーは、予期せぬ問題に遭遇することがあります。そうした状況で冷静に対処し、効果的な解決策を見つける能力が求められます。

5.ユーザーエクスペリエンスの理解
ユーザーの視点を理解し、プロダクトをユーザーフォーカスでデザインする能力が求められます。ユーザビリティやユーザーエクスペリエンスに関する知識が役立ちます。

6.柔軟性と適応性
プロダクトの要件や市場の変化に柔軟に対応し、新しい情報に基づいて計画を修正する柔軟性が求められます。

他にも挙げられると思いますが、このようなスキルがあげられるようです。
※今回ピックアップするのは1~3のスキルを見てみようと思います。

 

 

弊社のバリューである「ナイスガイ・ナイスガール」とは?

素直で誠実主体的に行動するチームに貢献する。家族を大切にする。オープンである。誇りをもって仕事を楽しむ。一人ひとりが、仲間やお客様から信頼を得られる人間であろう。

ざっと見てみるだけでもプロダクトマネージャーに必要なソフトスキルと、バリュー「ナイスガイ/ナイスガール」にはいくつか共通点がありそうです。

 

3. 1つ目のソフトスキル「コミュニケーション能力」

プロダクトマネジメントにおける「コミュニケーション能力とは」

プロダクトマネジメントを行うにあたって、プロダクトマネージャーは異なるステークホルダーとの円滑な情報伝達や効果的な対話を通じて、プロダクトの開発や運用に関する理解と協力を促進することが必要になります。

そのためには

1.ステークホルダーとのクリアなコミュニケーション
2.顧客やチームからのフィードバックの受け入れと提供
3.タイムリーで適切な情報共有

が必要と言われています。

その際に、ナイスガイ/ナイスガールに必要な以下の点が生きてくると考えています。

 

ナイスガイ/ナイスガールの「素直で誠実」「オープンである」の精神

前述のとおり、「ナイスガイ/ナイスガール」の定義には「素直で誠実」であり「オープンである」精神が必要としています。

ステークホルダーに対して、素直で誠実に、オープンにコミュニケーションを取る事ができる。」
「顧客やチームからのフィードバックを素直に受け入れることができる。」
常日頃オープンであることで適切な情報共有を行うことができる。」

といったことが成立しているな、と感じます。

 

例えば具体的な現場のやりとりは??

2週間1スプリントのスクラム開発を行っていることは、他の記事でも書いているのですが、毎回行っているKPTで、KEEPだけじゃなくPROBLEMもこれでもかと言うほど素直に出てきます。

うまく言ったときはうまく言った理由を、うまく行かなかったときは反省と改善を素直かつオープンにシェアすることで開発組織が回っていて、それを促すためにPM自身が素直かつオープンなコミュニケーションを心がけています。

ほぼ網掛けになってしまいましたがKEEPの一覧

進捗悪いです、なども素直に言い合うPROBLEM

 

4. 2つ目のソフトスキル「リーダーシップ・意思決定力」

プロジェクトの主体的な推進と方針の明確化

プロダクトマネージャーには、プロダクトの成功に向けて方向を示し、チームを先導する力が必要であると言われています。

具体的には

1.ビジョンとゴールの設定と率先した導き
2.迅速かつ効果的な判断
3.モチベーションとエンゲージメントを大事にしたチームビルディング

といった行動を自ら先導し、示していかないといけません。

 

ナイスガイ・ナイスガールの「主体的に行動する」姿勢

ここで重要なのが、ただ言うだけでなく自らが行動、先導しチームに向かうべき方向性を示していくことだと考えています。

「ナイスガイ/ナイスガール」の一文にも、「主体的に行動する」「チームに貢献する」とあります。

チームのことを第一に考え自ら主体的に行動できる「ナイスガイ/ナイスガール」な行動・姿勢がクロスマートのプロダクトマネージャーに求められています。

 

言ったからにはやる、現場での主体的な行動の例

ここ最近「やろうかー」から実施された例をいくつか記載できればと思います。

  • フルリモートのフロントエンドエンジニアから「コミュニケーション向上にgatherというツールを使ってみたいです」という申し入れたあった
    • 翌日には体験版を導入し、1ヶ月後に振り返りを実施。有用性があったので本格導入が決まった。
  • バックエンドエンジニアから「パフォーマンスのモニタリングにツール導入したい」と言われ開発メンバーで検討した後即時導入を決定し、提案したエンジニアにより導入とモニタリングが行われている。

など、現場メンバーからの声が上がったものは当人が完全に主体的に行動し実行まで移す文化が成立しているかなと思います。もちろん少しでも進みが遅い場合にはPMが積極的に介入して実行していきます。

 

5. 3つ目のソフトスキル「チームワーク」

クロススキルなチーム全体の協力関係

プロダクトマネージャーは異なるスキルやバックグラウンドを持つメンバーからなるチームをリードし、共通の目標に向かって協力する必要があります。

VPoPの杉原も「ビジネスサイドを共犯にする」「ビジネス⇔開発陣の翻訳をし、橋渡しを行う」とよく言っています。

プロダクトマネジメントにおけるチームワークには以下が必要だと一般的には言われているようです。

1.クロス機能型のチーム構築
2.相互補完性
3.チームによる柔軟性と適応力

これらの要素が組み合わさり、チームワークが強化されると、プロダクトマネジメントがより効果的かつ効率的にワークし健全な開発チームとなることが考えられます。

 

ナイスガイ・ナイスガールの「チームに貢献する」心構え

耳タコになってきているかもしれませんが、ここでも「ナイスガイ/ナイスガール」の要素が大事になってきています。

「チームに貢献する」「一人ひとりが、仲間やお客様から信頼を得られる」そんな行動指針を掲げているからこそ、バックグラウンドやスキルセットの違うクロス機能な開発チームがチームとして機能し、スピーディな機能開発が実行できていると感じています。

チームワークを意識するポイントが日々どれくらいあるか?

  • プロダクトの調査依頼について
    • 日々の不具合やお客様の問い合わせに対応するため開発チームから持ち回りで調査対応担当という形で通常業務に+αで対応してもらっています。
    • ただ、担当週でないエンジニアも積極的すぎる程に調査に積極的に関わってくれています

調査依頼投稿には何人ものメンバーが集ってくる
  • チームクロスマートスタンプも積極的に使われています。

チーム力を感じると積極的に押されるスタンプ

スタンプで検索しても約800ものメッセージに

 

6. まとめ

バリューである「ナイスガイ・ナイスガール」バリューと、プロダクトマネージャーに必要なソフトスキルには一致するところがたくさんあった。

たくさんある、プロダクトマネージャに必要なソフトスキルの中から今回は「コミュニケーション能力」「リーダーシップと意思決定力」「チームワーク」について抜粋してバリューである『ナイスガイ/ナイスガール』との一致点について書かせていただきました。

素直で誠実主体的に行動するチームに貢献する。家族を大切にする。オープンである。誇りをもって仕事を楽しむ。一人ひとりが、仲間やお客様から信頼を得られる人間であろう。

思いっきり手前味噌ですが、改めて読み直してみても、プロダクトマネージャー、ひいてはビジネスマンとして重要なキーワードが散りばめられているなぁと思います。

バリューというただの言葉にならないよう、しっかりと意識、行動し強い開発組織を作っていきます。

 

最後に

最後にお決まりすぎますが、クロスマートはPMはもちろんエンジニアやBizDevなど広く一緒に働く仲間を募集中です。

我こそは最高のナイスガイ/ナイスガールであると自負されている皆様!

組織も事業も急拡大していて、やること満載なので興味がある場合は是非こちらをごらんください

xorder.notion.site

PMの募集はこちら

herp.careers

 

DjangoのマイグレーションとMySQL 5.6~でのオンラインDDLの副作用について

まえがき

こんにちは。バックエンドエンジニアの@mobojisan と申します。

この時期は本当にカンファレンスが多いですね!

個人用GitHub上にSSGを利用したブログ基盤があるのですが、それが使いにくかったので、今流行りのsupabaseでブログ基盤をおっ立て、カンファレンスに参加した時の感想記事でも載っけようかと画策していました。

しかし、作業がカンファレンスの開催スピードにとても追いつかず、カンファレンスのメモが無情にもnotion上に溜まっていきます。

もはやメモをブログとして世に出す頃には来年のカンファレンスが開催されているんじゃないか…?と思いながら、また先週もカンファレンスに参加してメモを積み上げています。

とはいえ、直接の原因は池袋ハロウィンへ参加するにあたって、準備に時間を持って行かれたからなのですが。

閑話休題

今回はMySQLを使用している際に、オンラインDDLを用いたマイグレーションDjangoマイグレーションファイルで管理している際に起こりうる問題・その対策について書きます。

ちょっと待った。オンラインDDLって何よ?

安心してください。僕もわかりませんでしたよ。(過去形)

オンラインDDLと言われてピンとくる方は、次の章まで読み飛ばしていただけますと。

DDLについて

DDLは、Data Definition Languageの略で、データ定義言語とも略されます。

基本的には、データベース新規作成にかかわる命令がDDLにあたり、具体的にはテーブル新規作成・削除で使うCREATE・DROPや、インデックスの作成、そしてカラム名の変更のALTERなどが含まれます。

ちなみにCRUDのC以外に関わるSELECTやUPDATEなど、データベースの操作を行う命令はDMLData Manipulation Languageの略でデータ操作言語と呼ばれます。

この伏線はすぐ後で回収するので覚えておいてね。

オンラインDDL

MySQL 5.6から新たに入った機能の一つです。

Alter Table実行中にDMLの操作ができるということを意味します。

オンラインDDLがないMySQL 5.5以前では、

Alter Table操作中にはそのテーブルへの更新がブロックされ、多くのセッションが待機してしまうため

本番稼働中のMySQLに対しての実行は非常に悩ましいものでした。

といったことが実務上の課題として挙げられていたようです。

詳しくは、引用元である以下をご覧ください。

第30回 InnoDBオンラインDDLについて | gihyo.jp

具体的には、以下のような組み合わせでYesであればオンラインDDLに対応しています。

基本的な操作はだいたいカバーされていそうですね。

操作 in-placeで テーブルの再構築 並行DMLを許可 メタデータのみ変更
二次インデックスの作成または追加 Yes No Yes No
インデックスの削除 Yes No Yes Yes
インデックスの名前変更 Yes No Yes Yes
FULLTEXT インデックスの追加 Yes* No* No No
SPATIAL インデックスの追加 Yes No No No
インデックスの種類変更 Yes No Yes Yes

MySQL :: MySQL 5.7 Reference Manual :: 14.13.1 Online DDL Operations

オンラインDDL実行で起こりかけた問題

ロックを取得する

オンラインDDLによって、DMLDDLを同時に実行させることが可能になるのですが、開始時・終了時にわずかな時間ロックを必要とします。

端的に言えば、

  1. DDLを実行しようとする際に、すでに

  2. ほかのトランザクションなどが走っていると、

  3. 〜テーブルへのほかのすべてのDMLがwaitし、

つまってしまうのです。

これが頻繁にアクセスされるテーブルに発生した場合、サービスが実質的に停止することになります。

SaaSのような多数のユーザーが同時に操作する環境では、つぎつぎと後続のDMLが流れ込んでくることが容易に想像できます。

そうでなくともビジネスで使われるようなソフトウェアにおいては致命的ですね。

じゃあどうすればいいのさ

DDLを流す時にメンテを入れる

安全かつ確実なのは、テーブル、とくに頻繁にアクセスされるテーブルについてDDLを流すことがわかっている場合、メンテを入れることです。

メンテを入れられるのであれば、DMLが走る心配がないのでオンラインDDLに付随する副作用である、後続DMLのブロックを気にする必要がありません。

とはいえ、ビジネスユースのアプリケーション、まして外食産業のインフラを目指す弊社サービス、できる限りメンテは減らしたいものです。

そのため、このケースに関しては別の方法を取りました。

TO値を設定する

MySQLにはlock_wait_timeoutという設定値があり、これによりメタデータロックを行うDDLの実行のタイムアウト値を設定することができます。

デフォルトの値は31536000、なんと1年になっています。

デフォルトでは1年間テーブルを占有されるのです。そんなにいる?

これは単位がs(秒)のため、標準的なテーブルの場合、ある程度でタイムアウト(TO)によって止めてしまうことで、オンラインDDL中に後続のDMLが詰まるのを防ぐことができます。

それがlock_wait_timeoutにあたるわけです。

そのため、長すぎるDDLがほかのDMLをブロックし、サービスを止めてしまう前に、TOによってテーブルのロックを強制的に解除するような設定を入れることにしました。

この設定により、このケースに関してメンテなく進めることができました。

あとがき

いかがでしたでしょうか?

話は変わりますが、弊社クロスマートでは新卒中途問わず、ポジションはさまざまにエンジニアを募集しております。

少しでもご興味持っていただけましたら、カジュアルに記事にスターを入れ、 そしてカジュアルに面談を申し込んでいただけますと、書いているこちらにもとても励みになります。

対戦よろしくお願いします。

xorder.notion.site

エンジニアチームの目標設定で自分なりの色をつけた話

エンジニアマネージャー(EM)の山田です。
今回は弊社エンジニアチームの目標設定について語ります。

自分。色を出していいっすか?

少し前にひょんな事からエンジニアマネージャーに就任した山田は悩みました。

チーム目標設定を設定するタイミングが来たのです。アレでもないコレでもない…と悩みに悩みました。

 

これまで僕らに掲げられていた*1目標は所謂「プロダクトの目標」でした。
エンジニアもプロダクトの開発に関わるメンバーです。よってこの目標が設定される事は何も間違ってはいないのですが…
「エンジニアにフォーカスされた目標」ではなかった事から、少々モヤモヤとしながらも毎日の開発を行っていました。

今回、現場エンジニアからマネージメントに役割を移して、チーム目標設定をする機会を得たので、この思いをぶつける事にしました。


そして壁にぶつかりました。
「エンジニアチームの目標に我が多く入った意見を押し出しても良いものか…?自分のエゴを押し付けているのではないか?」
と…。

 

そんな事を思って長きに渡り各所で 自分探し 相談を行った結果、1つの答えにたどり着きました。

「自分の色を表現してもいいじゃないか」

結論:攻撃力を上げる

これまでは当たり障りのない…と言うと言葉が悪いですが、「守りの開発」が評価されるような目標が設定され、評価される事が多かったです。

決して「攻めの開発」が評価されなかったわけではありませんでした。
しかし、評価する側の人全員が開発の事情に深く関わっているというものでもありません。
そのような中では守りの開発の方が数字化が容易*2でした。評価する側の視点に立つと結果を評価しやすい目標だった。とも言えます。

 

しかし、我々のようなベンチャー企業は守ってばかりでは無く、攻める必要があります。
攻めきる為の攻撃力とは即ちモノを作る事。そのための手を動かす力。行動力…。*3

作ってなんぼ」が評価される開発組織にしよう!…と。

具体的にそれを達成する為の目標は複数個掲げてはいます。
その中で最も重要なのは「粒の小さい結果でも良いので、日々継続的に出せるようにする」ということです。

 

"実装する内容を検討に検討を重ねて、時間をたっぷり掛けた巨大な修正"と
"相談や提案を都度素早く取り入れて、短時間で行った数行の修正"。

業界や慣習により様々な意見があると思いますが、
「ユーザーは1秒でも早く何らかの形で価値を得たいし、それに答える事でプロダクトの価値が上がり、会社の価値も上がる」
のであるならば、"後者の方が良い開発体制である"
…と判断しました。

Q. 今までの目標は良くなかったのか?

結論から言うとNo。良かったと思います。

目標は会社やプロダクトが置かれた状況。やるべきこと。目指すべき未来。が反映され設定されます。

当時は開発リソースの余裕もなく、守りの開発を行うのが当たり前でエンジニアに対して守りの作業をする割合が多かったです。
当時の目標には当時の状況が反映されていたに過ぎません。

現にプロダクトは存続し続け、ユーザーに対してその価値を提供し続けています。
この成果を持ってして良くなかったとは全く思わないです。

そして今。攻めの開発に転じる事でクロスマートは新しい一歩を踏み出そうとしています。

最後に

今、攻めに攻めているイケイケな企業。クロスマートは攻めた開発をしたいエンジニアを募集しています!
ご興味がある方は、是非こちらを御覧ください!

xorder.notion.site

*1:この時の山田はまだ現場のエンジニアで最前線にいました

*2:多くは既に顕在化している問題を計測し、具体的アクションを行う事になる。結果として行動に対する成果が可視化しやすい

*3:この山田が最も好きな事の一つは、無茶な事を言った後の語尾に「まあ、死なないし」とポジティブに付け加える事です

プロダクトチームで新しい取り組みをするときにどうしているか



ご覧いただきありがとうございます。
クロスマート株式会社で執行役員VPoPを務めている杉原(@sugihara_xmart)です。

2023年9月1日より執行役員に就任しました(左側)

プロダクト領域の管掌でマルチプロダクトの企画・推進なのでそのあたりの思いを記載しようかなと思っていたのですが、既に弊社広報の手によって素敵なnoteにまとめていただいておりました。

 

顧客にも「このプロダクトは自分が育てた」と感じてほしい。VPoPが語るクロスマートのプロダクト構想|クロスマート株式会社

 

今回は未来プロダクトチームの仲間になってくださる候補の方へのメッセージも兼ねてプロダクトチームで新しい取り組みをする際の流れを、最近チームに導入した「GatherTown (ギャザータウン)」を例に取り上げてみようと思います。

 

そもそも「GatherTown」とはなにか

2020年アメリシリコンバレー発祥の2Dメタバースオフィスツール。
世界累計ユーザー数は1,600万人。最大10名まで無料利用が可能。
主に欧米圏、アジア圏(主に韓国)で絶大な人気を誇る。

公式サイト:https://www.gather.town/

参考:https://prtimes.jp/main/html/searchrlp/company_id/46230

 

杉原の言葉で説明するのであれば、リモートでも気軽にコミュニケーションが可能なバーチャルオフィス、といった感じです。普段は Gather と呼んでいるので以後その表記で記載します。

 

実際のGatherの様子です。ドット絵がかわいい

どのような経緯で導入検討に至ったか

プロダクトチームで毎週持ち回りで実施している「10分勉強会」で自身が副業の話をした際に、副業先にこの「Gather」が導入されていることを話しました。

 

プロダクトチームでは2022年3月に10分勉強会を始め、なんだかんだ1年半ほど続いています。

note.com

そのときの10分勉強会の様子。いつもコメントの流速が早めです

そのとき、エンジニアの1人がとてもGatherの導入に興味を示しており、またフルリモートでの開発体制が根付きながらも徐々にプロダクトチームが大きくなりつつあったクロスマートとめちゃめちゃ相性いいのでは!?

との思いから、まずはトライアルでの運用を開始しました。

熱量の高い人によるトライアル運用

その日のうちに勢いでトライアルを開始

Gather以外にも、良さそうなものはまずライトに試して運用しよう、ということは比較的多いです。
クロスマートはtimes(分報)文化が比較的根づいているので、誰かが気軽に呟いた内容を拾ってトライアルの旗振りをすることもあります。

 

なお、Gatherのトライアルのときは、熱量が高いうちに、とかなり勢いドリブンで導入したところ、あとから座席数変えたりするのにアーリーアダプターなメンバーをやや振り回してしまったので、最低限の運用ルールは考えて導入したほうがよいかも、と振り返っていますw

 

トライアル期間の振り返りの実施

30日間のトライアル期間だったのでトライアル終了の約1週間前にKPTによる振り返りを実施しました。

勢いドリブンで来たけどちゃんと振り返りはします

このとき「TRYに一つ以上「これがあるとよりうまくいくであろうガイドラインを書くというルールでKPTを実施しました。

KEEP

PROBLEM

TRY

結果として以下のような形になりました。

  • GOOD
    • ちょっと相談しやすい(Slackよりもよい)
    • 出社感ある、一体感、人と会ってる感
    • 出社確認、MTG確認ができるのがいい
  • MOTTO&TRY
    • Slackとの棲み分け、通知
    • ログインルール
    • Gatherを利用するタイミング(会議など)

運用ガイドラインを設ければ、一定恩恵を得られそうとの判断から
期間を決めて正式導入することを決め、稟議を上げました。
※ちょうど 福岡・長野といった遠方のプロダクトチームメンバーの入社が決まっていたことも導入の後押しになりました。

稟議申請

ここから稟議申請をあげるのですが、弊社の特徴としてめちゃくちゃ稟議申請からの承認が早いです

30分で承認。これは極端すぎる例だが...

もちろん、トライアル期間中に代表に頭出しをしていたこともあるとは思いますが、

新規のサービス導入に関して、仕事の生産性に繋がりそうなものは積極的に導入しようというスタンスがあり、これは組織風土として非常に気に入っている点です。

 

もちろん導入したものがきちんとワークせず、賞味期限の切れた仕組みやツールがはびこるのはよろしくないですが、そうならないよう定期的に棚卸しも(今のところは)できてるんじゃないかなあ、と思っています。

ガイドラインを設けての運用

EM山田さんが作成くださった運用ルール。これに則りつつ活用しています

まとめ

このような形で、プロダクトチームで新しいツールや取り組みが始まる場合は多くの場合以下のような形で導入・運用されるケースが多いです。

  1. 誰かが、良さそうなサービスや仕組みを見つけてきてtimesに呟いたり、技術定例やDS(朝会)で提案する
  2. 良さそうなものでトライアルがあれば、熱量ドリブンで導入してみる
  3. 振り返りをし、今の自分達に合うか、見送るべきかを判断する
  4. 期間を決めて正式導入、運用する
  5. ガイドラインを設けて運用開始
  6. 事前に定めた期間まで来たら振り返りの実施...

特にツールは、ツールを入れただけで解決しないことが多いので、

どのように運用していくかはセットで考えるべきではありますが、

世にある良いものを活用しながら生産性高く働ける環境づくりは今後も意識していきたいと思っております。

さいごに

いつものやつですが、クロスマートではPM、エンジニア、BizDevなど広く一緒に働く仲間を募集中です。組織も事業も急拡大していて、やること満載です。ご興味がある方は、是非こちらを御覧ください!

 

xorder.notion.site

 

 

22歳のエンジニアが、フロントエンジニアの面接に開発メンバーの一人として参加するようになってみての所感

はじめに

お久しぶりです! クロスマート株式会社では主にフロントエンドのタスクを勉強させていただきつつ、スクラムマスター的なことをざっくり担当しております。ナイスガイの福留です。

高卒後五年目、クロスマート歴も一年を超え、新しいことに挑戦する機会が増えてきました。

本日は、その中から特に新鮮味を持って行わせていただいている、企業の開発メンバーとして面接に参加するという経験について記事を書かせていただこうかと思います。

ぜひ最後まで読んでいっていただけると幸いです!

また以下から弊社のエンジニアチームによって投稿している記事一覧が閲覧可能です。

xmart-techblog.hatenablog.com xmart-techblog.hatenablog.com

Click!! Me!!

この記事について

この記事では、私が開発メンバーの一人として面接に参加している上で考えたことや、 (私自身ジュニアなのかミドルなのかよくわからないスキル感ではあることを自覚した上で)生意気にもスキルを評価させていただく上での観点についての現時点での思いを書きます他、 面接官として、会社に必要な人材とはどのような人物像というのをこの記事を執筆しながら考えていければ良いなと思っております。

また転職活動時に個人的にQiitaにて執筆した、20歳のエンジニアが15社(くらい)カジュアル面談受けてみての所感のアンサー記事に出来ればエモいなぁと思ってます。 頑張ります。

対象とする読者

  • 私と同じように、若手エンジニアの立場から面接官を担当することになった方
  • スタートアップの面接を受ける、ジュニア〜ミドルクラスのエンジニアの候補者の方

書くこと

  • 若手エンジニアが面接官として参加する背景
  • 面接官としての役割とその重要性について、考えたこと
  • 実際の面接での経験談や学び

書かないこと

  • (当然ですが、)企業、個人の特定につながりかねない情報
  • 候補者の方の情報の全て

面接に参加するようになってみて

どんな立場から候補者を見るべきか

弊社では、二次面接においては開発メンバーの2 ~ 3人ほどで面接を行うことが多いです。

フロントエンジニアやフルスタックの候補者の方の面接において、私は以下のような観点から候補者の方を評価することを組織に求められているように感じます。

  • フロント技術において、スキル感は妥当であるか(オーバースペックでは無いか? メンバーと比較し、ざっくり、どの程度のレベルであると推測されるか)
  • チームメンバーとして、コミュニケーションを円滑に行えそうであるか

また、若手の正社員エンジニアという立場から候補者の方を見させていただく上で、候補者の方のニーズに沿った経験が出来そうであるか、という事も重要だと思っています。

定着率のためという言葉が記事としては適切なのかもしれませんが、個人的には、どちらかというと、「楽しく働けている。良い経験を積めている」と感じて欲しい気持ちが大きいです。

数字とか組織とか抜きにミスマッチって悲しいじゃないですか。ですよね?

面接官をやるようになった背景

シリーズBの資金調達を終えたグロース期のフェーズで、私が入社するまではフロントエンドは業務委託のエンジニアの方や、主にサーバーサイドのエンジニアの方がフルスタックに開発を行っていました。

(シード 〜 アーリー期ではフルスタックの強い方が主になり、ザクザク作っていかれてたようです。)

フロントエンドの一人目正社員エンジニアとして採用いただき、その後も正社員としてはフロントエンド専従は自分一人です。

ある程度自走して開発を行えると評価いただき、新規プロダクトの開発ではフロントエンドの開発を一人で任せていただき(リリースにはレビューを必須としているので、レビューや検証では業務委託の熟練のエンジニアの方々に見ていただいていました)、無事第一フェーズのリリースまで完了出来ました。

そういった背景から、正社員フロントエンジニアの候補者の方の面接において、技術面の評価という形で開発メンバーの一人として面接に参加しています。

そもそも面接官とは何か

面接官という言葉について、上に挙げたQiitaの記事を執筆した当初(候補者の目線のみ)と今(面接官を何度か経験した現状)では、正直、認識が大きく変わっています。

この章では、自分の中で面接官という言葉がどのように認識が変化したかを書きます。

一番大きな違いとして、以前までは「面接官は技術力の高さ・自走力やアウトプット能力、コミュニケーション能力が高いかどうかを評価するもの」と考えていました。

しかし、自らが面接官としての経験を積む中で、この認識には大きな変化が生まれました。

具体的には、単に候補者の方の技術的な知識や経験、能力を評価するのではなく、「その人が私たちの企業の現時点のフェーズにとってどれほど貴重な人材なのか」や、「チームや文化にどれほどマッチしているのか」という観点から、候補者の方とお話しさせていただく必要があると考えるようになりました。

技術の進化や業界の変動は速く、特定の開発文化やチーム編成での「これが正解」というものは存在しないと思います。

さらに、各企業やチームの背景、文化、技術スタックはそれぞれで異なります。

弊社の開発チームも特別ベストプラクティスを持っているわけではありません。私たちのアーキテクチャや技術選定も、私たちのニーズや状況に応じて選ばれています。だからこそ、技術の「高さ」に基づく一方的な評価は、実際は不可能であると感じます。

コミュニケーションの取り方やアウトプットへの態度、開発への姿勢も同様に、企業のフェーズによって、組織から求められる能力は違います。

よって、面接官というのは候補者に対して上下関係のあるものではなく、「対等な立場から、現時点での企業とマッチするかどうかを確認する役割」であると考えます

面接官として私が面接に参加する上で、会社から求められることは何か

この章では、現時点での会社のフェーズに対し、一人目正社員フロントエンジニアとして私が面接に参加する上で、会社からどのような振る舞いを求められているかについて考えたことを書きます。

割とセンシティブな話題な気がしますが、若手エンジニアの立場で、面接官として候補者の方とお話しする立場で面接に参加するにあたり、自分が会社から何を求められているかを考え続ける必要があるのでは無いでしょうか。

記事のターゲットとしている、「私と同じように若手エンジニアの立場から面接官を担当することになった方」に向けた章です。

"会社の求める人材"

会社の求める人材とはどのような方なのかについてです。

一概に「どの企業もこういった人材が欲しい」という人物像では抽象的すぎるので、グロース期である弊社がどのような人と一緒に働きたいと考えているのか、という疑問を自分に対して投げかけてみます。

まず、グロース期に会社が求めるエンジニアというのは以下のような人物像と考えています。

  • 自分で課題を発見し、解決策を提案し、実行に移せる主体性
  • 新しいメンバーやチームのリーダーとして行動できる能力
  • 誤解を防ぎ、プロジェクトを円滑に進めることができるコミュニケーション能力
  • 他のメンバーと協力し、チーム全体としての成果を出すことを重視する姿勢
  • 企業のビジョンや目標(コアバリュー)に共感し、それを技術的な側面からサポートできる思考や姿勢

  • 新しい技術やツール、業界のトレンドをキャッチアップし、自ら学ぶ意欲

  • ユーザーのニーズやフィードバックを理解し、それを元に製品やサービスの改善に取り組む姿勢

会社に所属するプレイヤーとして、周囲と協調し仕事を進める能力メンバーの一人として、チーム全体の能力を底上げする自己改善意欲ユーザーに寄り添う事の出来る姿勢の3つに重点があると考えます。

成長期であるため、採用後も人員が増えていくことが予想される点においての協調性、チームや文化作りにおいて周囲に良い影響をもたらす自己学習の習慣、売り上げを伸ばしていく上で顧客に向き合う姿勢はグロース期の企業にとっては重要であると考え、以上のような観点で候補者の方が会社にとってどのような存在となるのかを、若輩の立場ではありますが見定めていくために邁進することが、私のような若手エンジニアが面接官を担当する上で、義務なのではないかと思います。

"フロントエンジニアとしての評価基準"

先に挙げたように、候補者の方とお話しする上で重要となるのは、「候補者の方のスキルや能力がどれだけ高いか」ではなく、「候補者の方のスキルや能力が現段階の自社の求める人物像と比較し、どれだけマッチするか」であると考えています。

よって、フロントエンジニアとしての評価基準としては、現在の自社の成長フェーズと照らし合わせ、以下のような基準で候補者の方を見定める事が私に求められていると考えています。

自社のフロント技術と被る・近しい技術に対する知識や経験がどの程度あるか

例えば自社ではフロント開発にvueを採用しています。

コンポーネント単位で画面開発を行い、CSSフレームワークを使用しデザイナーの作成したfigmaのレイアウトを実現し、データストアライブラリを使用し状態管理を行っています。

TypeScriptを用いて型による可読性を担保し、多数の画面はSPAとして実装しています。

それらの知識をベースに、候補者の方に技術的な知見、経験についての質問を行い、スムーズなオンボーディングが可能であるか、あるいは勉強期間を設ける必要があるのか、設けることになればどの程度勉強期間を取る必要がありそうか、といった点を客観的に評価することが重要です。

自走力(主体的に開発をある程度進められるという意味)

自己管理能力や、フィードバックの受け入れ姿勢について、技術選定を論理的な理由で行ってきたか、等です。

職歴書をベースに、候補者の方の経験に対する質問や、考え方を質問しタスク進行の能力を評価しています。

自走力(技術研鑽の意味)

メンバーの一人として、チーム全体の能力を底上げする自己改善意欲と被る部分で、他のメンバーのモチベーションに良い影響を与えたり、その後入社するメンバーのロールモデルとなるほか、業務の効率化や新技術の導入を行う際に、自己的に技術研鑽をおこなっているエンジニアがチーム内で大きな割合を占めることは適応能力の面でアドバンテージとなります。

特にフロントエンドは技術の進化が早く、安定版のバージョンが数年後には非推奨となったり、サポートが終了することが多々あります。

そういった変化に対応していく能力は、弊社での評価基準として重要なものと考えています。

軟技能(コミュニケーション能力、問題解決能力等)

他のメンバーと円滑なコミュニケーションを取れることや、人間関係・プロジェクトでの問題を解決する能力は、チーム開発を行う上でとても重要と考えます。

チームとの会話の雰囲気のフィット等も含みます。

一時間未満の短い時間で、しっかりと評価する事が自分に出来るとは思いませんが、過去の経験を質問したり、面接中でのコミュニケーションの取り方からなるべくこの辺りを汲み取れればと思っています。

弊社はコミュニケーションコストの削減については一層重きを置いているため、他の項目も重要ですが、軟技能の評価は私も特に重視しています。

参考書籍

Scaling Teams 開発チーム 組織と人の成長戦略 (Compass Booksシリーズ)

小さな会社がITエンジニアの採用で成功する本 自社にピッタリの人材がみつかる

最後に

最後まで読んでいただいて、ありがとうございました!

弊社ではバックエンド、フロントエンドエンジニアの方を募集しています。

社員を第一に考える、とても働きやすくチャレンジしやすい・スキルを上げながら働くことの出来る会社です。

クロスマート株式会社について気になった方がいらっしゃいましたら、以下のリンクから「話を聞きに行きたい」をお願いします!

https://xorder.notion.site/730a1e5f5d2f40a186dc84fa108be1a6

データ型検証ライブラリ Pydantic v2の紹介

みなさん、こんにちは。 ニカチョーのバックエンドエンジニア武じい(@pouhiroshi) です。
ニカチョーというのは、開発部二課の課長のことです。

弊社の開発部(プロダクトチーム)はマルチプロダクトを推進すべく、最近3チームに分かれるという変化がありました。
そのうちのDev2チームのリーダーをやることになりました。部は課からできてますよね。だからDev2は二課かな。そのリーダーなので課長かな?つまりニカチョー?
これまで役職がついたことがないので、ニカチョー頑張っていきたい所存です。(特に何か変わるわけではないのですが、気分的なアレです)

さて、今回はPythonのライブラリPydanticのバージョン2についての紹介です。

Pydanticとは?

Pydanticとは、Pythonで利用できるデータ型の検証ライブラリで、Webシステムの入力チェック(バリデーション)を簡単、シンプルに実装することができます。
FastAPIというWebシステムフレームワークで公式にサポートされており、弊社の請求書サービスでもFastAPI x Pydantic(ただしversion1)の組み合わせで利用しています。

xmart.co.jp


FastAPIだけではなく、他のFW(Djangoなど)や普通のPythonプログラムを使うというだけでも利用可能です。
FastAPIを使っていなくても、Pydanticは便利です – Attsun Blog

「FastAPIを使っていなくても、Pydanticは便利です」

ごちゃりがちなバリデーション関係をすっきり実装できる便利なライブラリですので、興味のある方はぜひ触っていただけるとPydanticの良さをわかっていただけると思います。

また、Pydanticはスキーマ駆動開発に相性の良いライブラリだと日頃から感じています。この辺の話はまた別の機会にしたいと思います。
(↓とてもわかりやすくまとめていただいている記事がありました。)
スキーマ駆動開発ってなに?便利なの?って方へ。

Pydantic version2がリリース

さて、本題です。
最近、Pydantic version2(以下v2)がリリースされ、FastAPIも正式にv2対応されたとのアナウンスがありました。
Pydantic v2を使うメリットは第一には速度。
v1に比べて22.5倍の速度が出たそうです。スピードこそパワー!! これだけでもv2を使うメリットがありますね!

パフォーマンスアップ

https://slides.com/samuelcolvin/how-pydantic-v2-leverages-rust-s-superpowers#/13/0/0

あとは v1からv2へのマイグレーション(変換)ツール bump-pydanticが用意されていること。
https://docs.pydantic.dev/latest/migration/#code-transformation-tool

マイグレーションツール

メジャーバージョンアップの対応が困難すぎて、バージョンアップを諦める、というようなことはよくあることですが、
Pydanticはその点、安心・親切ですね!

あとは、諸々の便利な新機能が登場しています。紹介しきれない機能がたくさんあるのですが、今回はPydantic作者の Samuel Colvinさん2023 PyCON USで発表された Pydantic v2の新機能に沿って、ご紹介していきたいと思います。
(そして、請求書サービスのPydanticバージョンアップの予備知識としても活用していきたいと思います!)
slides.com

PydanticはFastAPIのおかげで成長したとおっしゃっていて、仲の良さが伺えますね。

ありがとうセバスチャン(FastAPI作者)


それでは、紹介する新機能一覧です。たくさんありますが、どうぞお付き合いください。

新機能1 ストリクトモード 別名ペダントモード

https://slides.com/samuelcolvin/how-pydantic-v2-leverages-rust-s-superpowers#/14

ストリクト(厳正)モード

以前は整数の定義をしたフィールドに文字列の整数値(例えば"42" Samuelさん、42歳なのですかね笑)を与えても、バリデーションエラーにならずに自動でintに変換してくれていました
ただ、明示的にエラーにしたい場合もあるので、その場合は型をpydantic.StrictIntを使うという手間がありました。

v2ではその代わりに、model_configにstrict=True をすることで、厳密なチェックが行われるようになりました。
厳しい型チェックを望むエンジニア諸氏にはありがたい機能になりそうです。

新機能2 組み込みのJSON解析

https://slides.com/samuelcolvin/how-pydantic-v2-leverages-rust-s-superpowers#/15

以前は、json文字列をModelインスタンスへ変換する場合、BaseModel.parse_rawやjson.loadsでdictに変換したのち、Modelをインスタンス化するなどの必要がありました。

user = User.__pydantic_model__.parse_raw('{"id": 123, "name": "James"}')
print(user)
# id=123 name='James'
Otherwise, if you want to keep the dataclass:

json_raw = '{"id": 123, "name": "James"}'
user_dict = json.loads(json_raw)
user = User(**user_dict)

これが、v2ではmodel_validate_jsonで、jsonからmodelへの変換が一発で可能になりました。

user = User.model_validate_json('{"id": 123, "name": "James"}')
print(user)
# id=123 name='James' 

また、カスタムエラーを実装することも可能になりました。
https://docs.pydantic.dev/latest/errors/errors/#custom-errors

PydanticCustomErrorにメッセージなどを自分で設定し、raiseすれば自分好みのエラーを発生させることができます。

from pydantic_core import PydanticCustomError
from pydantic import BaseModel, ValidationError, field_validator

class Model(BaseModel):
    foo: str
    @field_validator('foo')
    def value_must_equal_bar(cls, v):
        if v != 'bar':
            raise PydanticCustomError(
                'not_a_bar',
                'value is not "bar", got "{wrong_value}"',
                dict(wrong_value=v),
            )
        return v

try:
    Model(foo='ber')
except ValidationError as e:
    print(e)
    """
    1 validation error for Model
    foo
      value is not "bar", got "ber" [type=not_a_bar, input_value='ber', input_type=str]
    """

また、カスタムエラーメッセージを作ることも可能となりました。
https://docs.pydantic.dev/latest/errors/errors/#customize-error-messages


エラーの箇所を行番号で知ることもできる便利機能も予定しているようです。

新機能3 ラップバリデータ 別名:たまねぎ

Pydanticのwrap validatorは、既存のバリデーターを別のバリデーターでラップするものです。これにより、ロジックをバリデーションの前や後に入れたり、新しいエラーを発生させたりデフォルト値を返したり
自由にバリデーターの振る舞いを変えることができます。mode="wrap"でバリデータを定義し、引数でValidatorHandlerを受け取るようにします。
これにより、通常のバリデーションを通過させつつ、別のロジックを組み込むことが可能です。

https://docs.pydantic.dev/latest/api/functional_validators/#pydantic.functional_validators.WrapValidator

from pydantic import BaseModel, field_validator
 
class Model(BaseModel):
    x: int
 
    @field_validator('x', mode='wrap')
    def validate_x(cls, v, handler):
        if v == 'one':
            return 1
        try:
            return handler(v)
        except ValueError:
            return -999
 
print(Model(x='one'))
#> x=1
print(Model(x=2))
#> x=2
print(Model(x='three'))
#> x=-999

新機能4 RecursiveModelの検証

Pydantic v1では、RecursiveModelを継承したモデルのフィールドにRecursiveModelを指定すると、無限ループが発生していました。
Pydantic v2では、このような無限ループを検知し、バリデーションエラーを発生させるようになりました。

from __future__ import annotations
from pydantic import BaseModel, Field, ValidationError

class Branch(BaseModel):
    length: float
    branches: list[Branch] = Field(default_factory=list)

print(Branch(length=1, branches=[{'length': 2}]))
#> length=1.0 branches=[Branch(length=2.0, branches=[])]

b = {'length': 1, 'branches': []}
b['branches'].append(b)

try:
    Branch.model_validate(b)
except ValidationError as e:
    print(e)
    """
    1 validation error for Branch
    branches.0
      Recursion error - cyclic reference detected 
        [type=recursion_loop, 
         input_value={'length': 1, 'branches': [{...}]}, 
         input_type=dict]
    """

新機能5 エイリアスパス

validation_aliasPydantic は、 AliasPathを使用する際の利便性のために AliasPathそしてAliasChoicesという2 つの特別な型を提供します。
AliasPathエイリアスを使用してフィールドへのパスを指定するために使用されます。例えば

from pydantic import BaseModel, Field, AliasPath

class User(BaseModel):
    first_name: str = Field(validation_alias=AliasPath('names', 0))
    last_name: str = Field(validation_alias=AliasPath('names', 1))

user = User.model_validate({'names': ['John', 'Doe']})  
print(user)
#> first_name='John' last_name='Doe'

この'first_name'フィールドでは、エイリアス'names'とインデックスを使用して0(名)へのパスを指定しています。この'last_name'フィールドでは、エイリアス'names'とインデックスを使用して1(姓)へのパスを指定しています。
AliasChoicesエイリアスの選択を指定するために使用されます。例えば:

from pydantic import BaseModel, Field, AliasChoices

class User(BaseModel):
    first_name: str = Field(validation_alias=AliasChoices('first_name', 'fname'))
    last_name: str = Field(validation_alias=AliasChoices('last_name', 'lname'))

user = User.model_validate({'fname': 'John', 'lname': 'Doe'})  
print(user)
#> first_name='John' last_name='Doe'
user = User.model_validate({'first_name': 'John', 'lname': 'Doe'})  
print(user)
#> first_name='John' last_name='Doe'

新機能6 ジェネリック

内部で型変数を使用してAnnotated、型に再利用可能な変更を加えることができます。
Modelの型定義に別の型定義を入れて、再利用できるようにする、、、?
(ちょっと理解できなかったので、サンプルコードだけ載せておきます)

from typing import Generic, TypeVar
from pydantic import BaseModel

DataT = TypeVar('DataT')

class Response(BaseModel, Generic[DataT]):
    error: int | None = None
    data: DataT | None = None

class Profile(BaseModel):
    name: str
    email: str

def my_profile_view(id: int) -> Response[Profile]:
    if id == 42:
        return Response[Profile](data={'name': 'John', 'email': 'john@example.com'})
    else:
        return Response[Profile](error=404)

print(my_profile_view(42))
#> error=None data=Profile(name='John', email='john@example.com')
Favorite = tuple[int, str]

def my_favorites_view() -> Response[list[Favorite]]:
    return Response[list[Favorite]](data=[(1, 'a'), (2, 'b')])

新機能7 シリアライゼーション

Pydantic では、「シリアライズ」と「ダンプ」という用語を同じ意味で使用します。どちらも、モデルを辞書または JSON エンコード文字列に変換するプロセスを指します。
以下のように、Modelが入れ子になったデータも model.dump()を使って、型を気にすることなくdict型へシリアライズできます。

from pydantic import BaseModel

class User(BaseModel):
    name: str
    age: int

class Profile(BaseModel):
    account_id: int
    user: User

user = User(name='Alice', age=1)
print(Profile(account_id=1, user=user).model_dump())
#> {'account_id': 1, 'user': {'name': 'Alice', 'age': 1}}

class AuthUser(User):
    password: str

auth_user = AuthUser(name='Bob', age=2, password='very secret')
print(Profile(account_id=2, user=auth_user).model_dump())
#> {'account_id': 2, 'user': {'name': 'Bob', 'age': 2}}

model_dump_json()や、カスタムシリアライザーなども用意され、自由なシリアライズが可能になっています。
https://docs.pydantic.dev/2.3/usage/serialization/#custom-serializers

色々なシリアライザーが増えました

新機能8(というか変更)BaseModelは必須ではなくなりました(AnalyzedTypeを使えば。)

基本的にpydanticで定義するモデルはBaseModelを継承するのが必須でしたが、必須ではなくなりました。
BaseModelを継承しなくても、代わりにAnalyzedTypeを利用することで検証が可能になりました。
Pydanticは使いたいけど、BaseModelを継承してまで使うかというとちょっと・・というケースにも対応できるようになりました。

from dataclasses import dataclass
from pydantic import AnalyzedType

@dataclass
class Foo:
    a: int
    b: int

@dataclass
class Bar:
    c: int
    d: int

x = AnalyzedType(Foo | Bar)
d = x.validate_json('{"a": 1, "b": 2}')

print(d)
#> Foo(a=1, b=2)

print(x.dump_json(d))
#> b'{"a":1,"b":2}'

終わりに

Pydantic v2の新機能をご紹介しましたが、いかがだったでしょうか。
Pydanticはすでにversion2.3まで進んでおり、今回紹介した以外にも良い改善がたくさん反映されています。
詳しくはブログや、Pydantic公式ドキュメントを参照されると良いと思います。

https://docs.pydantic.dev/latest/blog/pydantic-v2-final/
https://docs.pydantic.dev/latest/

弊社サービスも、このような便利で性能の良いライブラリをアンテナ高くキャッチアップし、サービスの質を向上させていきたいと考えています。

これからもプロダクトチームは定期的にテックブログ記事を執筆していきます。気になる方はぜひ購読ボタンを押していってください!


また、クロスマートではPM、エンジニア、BizDevなど広く一緒に働く仲間を募集中です。
ご興味がある方は、是非こちらを御覧ください!

xorder.notion.site


お読みいただきありがとうございました!

フルリモート子持ちエンジニアが体得すべき筋トレ習慣と継続のコツ

どうもこんにちは。バックエンドエンジニアの小久保です。

今回はリモートで仕事しているエンジニアが
長きに渡ってその技術を発揮し続けるためにはどうするか的なお話をします。

 

単刀直入に言います。

 

筋トレしてください。

 

特に、「フルリモート」かつ「フルフレックスタイム制」のエンジニアが
安定した成果を出し続けるためには、運動習慣が不可欠です。

 

筋トレと言うと

 

「はいはい出ましたよ。脳筋脳筋。筋肉が何でも解決するとか無根拠に言うんでしょう? 聞き飽きたが?」

 

と嫌悪する方もいらっしゃると思うのです。

 

ちょっと待ってください。本当にそうでしょうか?

 

イーロン・マスクマーク・ザッカーバーグバラク・オバマホリエモンなど、
多数の著名な方々が日常に運動を取り入れています。

果たして彼らが理由もなしに運動習慣を取り入れるでしょうか?

 

本記事では、2年半に渡り 週3日の筋トレを欠かさず続けてきた
フルリモートフルフレックスなエンジニアが、
筋トレするメリット、習慣化のコツを丁寧にお伝えします。

 

参考文献

 

私のスペック

まずは小久保の基本スペックから。

  • 38歳。妻、6歳・3歳の娘と同居
  • バックエンドエンジニア。Web系7年目
  • 札幌からフルリモート。火曜~金曜はフルフレックス
  • 中学は野球部(9番ライト)。大学は人形劇サークル

バリバリのアスリートではないが、運動嫌いというほどではない。

極めて平均的な運動神経の持ち主です。

 

運動しなさすぎて やばすぎ問題

まず、フルリモートエンジニアの生活にはたくさんの問題があります。

具体的には下記です。

  • 圧倒的運動不足
  • 運動しないから良質な睡眠が得られず疲労が溜まりやすい
  • よく眠れないから生活リズムを崩しやすい

この3つは放置すると生産性を落とすレベルで体調を崩します。

 

仕事はパソコンで完結するし、誰か人と会うと言ってもZoomでつなぐだけ。

まったく移動がありません。

通勤すらないので、ひどいときになると一日500歩ぐらいしか歩かないこともあります。

 

おまけに、少し夜まで作業しようもんなら、就寝直前までブルーライトを浴びまくり。

小難しいプログラミングのことをあーでもないこーでもないと考え続けりゃ交感神経優位になって、目はランラン。

全く動いていないので肉体的疲労はほとんどない。

 

夜まっっっっっっっったく眠れません。

 

正社員エンジニアの場合はこの生活を数年、長い場合は数十年繰り返すわけです。

 

確かに楽です。天国のような待遇です。

 

でも考えてみてください。長期視点で考えてください。

 

やばくないですか?

 

筋力が落ちて早期に寝たきり予備軍になる確率大です。

身体から来る不調でメンタルも崩しやすくなります。

 

突然ですが、ゲームで考えてみてください。

あなたはパワプロで故障率が80%ぐらいになっているのに練習をするでしょうか。

ときメモで、爆弾がついてるのに他の女の子とデートに行くでしょうか?

 

問題を先送りにしてはいけません。

 

バッチの性能が〜とか技術的負債が〜とか言ってる場合じゃないです。

もっと身近な問題が眼前3センチ、息遣いが聞こえるほどに迫っています。

 

自分自身のコンディションがまともじゃなければ
エンジニアリングもクソもありません。

 

まずは長期的にこの天国のような待遇を維持する活躍するための生活習慣を考えましょう。

 

筋トレが業務に及ぼす影響

私の一般的なスケジュールは下記です。

  • 8:00~ 始業
  • 12:00~12:10 昼飯
  • 12:10~13:00 ジム
  • 17:00から19:00ぐらいに終業

昼休みにジムに行ってます。これが大変良い。

 

後述しますが、自転車で5分の24時間ジムを契約し、主にBIG3(ベンチプレス、スクワット、デッドリフト)を鍛えています。

 

レーニング中は無心となるため、業務のゴチャゴチャした不安ごとが吹っ飛ぶのが最高です。

 

スタンフォード大学の研究では、ウォーキングは創造性を60%も伸ばすことができると言う研究結果が出ています。

これは体感とも合致していて、めちゃくちゃにトレーニングした後というのは良い設計が浮かびやすいです。

 

死ぬほど詰まっていて、もうこれ技術的に不可能じゃね? と思ったとき。

ベンチプレスに向き合い、無心でバーベルを上げ下げする。

その帰り道で「あ、あのやり方試してみるか」と思ったことは1度や2度ではありません。

 

さらに、テストステロン効果で根拠なき自信が生まれるのもたまりません。

目に見えて体格もでかくなっていくので、対面での自信が以前より格段にマシになりました。

 

ベンチプレス20kgの小久保と、ベンチプレス95kgの小久保とどちらの言うことに説得力があるでしょうか。

 

筋肉は錯覚資産になりえます。他人に対してだけでなく、自分を信じこませる作用があります。

すなわち自信につながります。

 

たかが自信。そんなことより良い設計を考える時間を作ったほうが。。。と思う人もいるかもしれません。

いいえ、自信があるということは思った以上に価値があります。

 

カリフォルニア大学の研究によると、自信は才能以上に成功を呼び込むと言われています。

つまり自信があるというだけで、自分の能力にかなりのバフがかかるというわけです。

 

パワプロのたとえばかりで申し訳ないですが、初期のノーマルグローブ装備で練習をして低い経験点を得続けるか。

それとも高いグローブを買って、数年に渡って高い経験点を得続けるか。

 

筋トレは投資です。

筋肉がつき身体的にもメンタル的にも高い状態を維持するというのは、パワプロでいえばきちんと高いグローブを装備して高い経験点を得やすくするというのに等しいです。

 

しかしおかしなものです。

 

これを見るエンジニア諸兄におかれましては、ことパワプロであればメンタルと身体を丁寧にケアし、より効率的に経験点を稼ぐのを厭わない。

 

にも関わらず、現実世界の自分の体のこととなると、途端に怠惰になってしまうのはなぜでしょうか。

 

運動習慣をつけるコツ

パワプロではできるけど、現実世界ではできない。

その原因は、圧倒的めんどくささです。

 

だってね。パワプロシムピープルなんかであれば、
ポチッとボタン押したら数秒でトレーニングしてくれるわけで。

 

一方、現実世界。

 

まず筋トレそのものが苦しいし、死ぬほど疲れるし。。。

そもそも物理的に移動しなきゃならないしでとんでもないクソゲーです。

リアル志向もやりすぎるとゲーム性をおとすの典型です。

 

現実世界はクソゲー

 

ということは、とにかくそのクソゲー感を払拭するための工夫が必要です。

 

意志力に頼ってはいけません。

 

自分が今までどれだけ豆腐みたいな柔らかい意志で生きてきたかを考えてください。

 

僕は持ち前の意志力の弱さで一浪一留しています。

ソリューションアーキテクトアソシエイトの勉強も進まず1度も受験できていません。

クラウドラクティショナーはいつの間にか失効しました。

もう自分に期待してはいけません。

 

意志力がなくてもできる方法を確立するのです。仕組みで解決しましょう。

 

では具体的にはどうすれば筋トレを習慣化できるか。

以下で語っていきます。

 

近場の24時間ジムを契約する

まず、ジムに行くハードルを徹底的に落とします。

家の近く、職場の近く、最寄り駅の近くなど5分以内で行けるジムを契約しましょう。

僕は家から自転車で5分のAnytimeを契約して、通っています。

 

24時間営業であることも重要です。

 

社会人で子持ちをやっていると本当に時間が限られます。

正直まともな時間に筋トレに行ってる暇なんてないのです。

家庭はやることで満ちています。

 

そこを無視して自分だけの時間を謳歌し過ぎると、離婚リスク、家庭内不和、子供の非行などにつながります。

 

そのため、子供が小さければ寝かしつけの後。

家族が起きてくる前の早朝などが、唯一子持ち親に残された時間だったりします。

 

そんなとき、早朝だろうと深夜だろうと運営しているジムであれば行きやすくなります。

僕もフルリモートになる前は、5時や、21時辺りに筋トレに行ってました。

 

また、最寄り駅の近くのジムもおすすめです。

通勤経路の中にジムがあると、めちゃくちゃ習慣化しやすくなります。

 

既存の習慣に紐つけてジムに行く

「帰りの電車から降りたらジム」に行く、という具合に

既に行っている習慣に紐つけてジムに行くようにします。

これを「習慣の積み上げ」といいます。

 

また、それを手帳に書くと自分の中で小さなコミットメントとなり、成功確率がアップします。

「昼飯食べたらジム」と書いてある(汚)

これは科学的に証明されていて、具体的にいつやるかまで書いてコミットメントすると、成功確率が上がるという研究結果があります。

 

既存の習慣を筋トレの契機とすることで、成功確率を上げることができます。

詳しくは、参考書籍にあげたジェームズ・クリアー式 複利で伸びる1つの習慣をご参照ください。

 

ゲーミフィケーションで自分に小さな報酬を

嘘みたいな話なのですが、スタンプを集めるようなノリで記録を取ると、継続しやすくなります。

例えば、ジムに行った日は手帳に✗をつける。などとやってみてください。

連続ログインボーナスみたいな

ソシャゲの連続ログインボーナスみたいなUI、1度は見たことがあると思います。

それを自分自身で作って、自分に見せてあげてください。

 

不思議なもので、✗をつける。

その小さな動作が小さな幸福感をもたらしてくれます。

これを毎日続けると、やめられなくなります。

 

連続ログインボーナスよろしく、こんなに続いてるのに辞めちゃうのもったいないなという情報が目から入ってきます。

良い意味でサンクコストバイアスが効き、余計に辞めづらい状況を作ることができます。

 

アプリで重量の記録をして プチゲーミフィケーション

Strongというアプリを使って、重量の記録を行っています。

このアプリの良いところは、前回の記録が入力画面に表示されることです。


前回の記録がでないと、自分の限界がどこにあるのかが分からず、

漫然とトレーニングをすることになります。

適切な負荷がかけられません。

 

すると、成長が鈍化し、挫折しやすくなります。

 

逆に前回の自分を超えられた場合の恍惚感。

挫折リスクがガラガラと崩れていくのを実感できます。

 

また、これまでの成長を種目別に振り替えるのもおすすめです。

ベンチプレスのベスト重量の遷移

自分がどのぐらい成長したのかが可視化されるので、ゲームみたいで面白くなります。

 

まとめ

フルリモートエンジニアは、ただでさえ運動習慣が失われがちです。

長期的な視野で見た場合、無策でいると健康リスクが大きすぎます。

そのため、筋トレ習慣は非常に大切です。

 

筋トレ習慣をつけるには、とにかくハードルを下げ、一個一個の挫折リスクを潰していくこと。これに尽きます。

 

これは何も特別なことではなく、日々の開発プロセスと同じことです。

テスト駆動開発よろしく、アジャイルよろしく、小さな課題を洗い出しては徹底的に潰し続ける。

同じことをプログラミングではなく、自分の身体で実践するのです。

 

元気でいないと良いコードは書き続けられません。

技術的な研鑽と同じぐらい、身体的研鑽も重要です。

是非ここであげたテクニックをもとに、筋トレライフを楽しんでみてくださいね!

 

クロスマートのエンジニアになりませんか

クロスマートではPM、エンジニア、BizDevなど広く一緒に働く仲間を募集中です。

組織も事業も急拡大していて、やること満載です。

ご興味がある方は、是非こちらを御覧ください!

 

フルリモート勤務で昼休みにジムに行こう!!(え

 

xorder.notion.site

 

一人目デザイナーとしてぬるっと組織に入り込むためのすゝめ


こんにちは。

2023年5月よりクロスマートでUIUXデザイナーとして参画している大島です。正社員デザイナー1号として弊社をどんどんPRしたいところではありますが、社歴としては3ヶ月程度の新参者のため、今回は一人目デザイナーとして組織に馴染むための立ち回りで効果的だったな〜と感じたことを発信したいと思います。

組織に馴染むために意識したこと

海外ドラマ「SUITS」の個人的名シーン(というか金言)をお借りしました。このあと、ごちゃごちゃと書いておりますが今日言いたいことはこれが全てです。

デザイナーというのは、他職種からみて生態の分かりづらい存在だと思っています。実際、どう絡んで、どんな依頼をしたらいいの?といった疑問は尽きません。まずはメンバーに対し、どういう技術を持っていて、どういうアウトプットで還元できるデザイナーなのかを視覚的に伝えることに注力しました。

たとえば、UXリサーチの分野でどの程度貢献できそうかを示すため、NPSアンケートの結果をKJ法をつかって資料にまとめてみました。

依頼内容としては

「NPSのカテゴライズと、どう機能反映させていくかの提案、みたいなのもやってもらえると〜」という内容だったので、ビジュアル的にもKJ法でまとめておくと提案や発見がし易いだろうと考えての試みでしたが、メンバーに「これを見ながら酒を飲みたい」と言っていただけたので反応は上々だったのではないでしょうか笑。

なお、このタスクを皮切りに、お客様の会社に訪問してユーザーインタビューを実施するという貴重な機会を得ました。弊社のすごいな〜と感じるポイントは、顧客の皆さまと大変近い位置で交流できる事だと思います。とにかくPMを始めとして担当者のフットワークが軽い!インタビューがしたいね、と話してから数分後にはアポが取れているというのは良好な関係性を築けている証拠ですし、スピーディーに対面インタビューができちゃう環境でUXを担当できるのはかなり刺激的です。

ちなみに、弊社のすごいな〜と感じるポイントその2は、こういった粒度の施策に対しても代表がバッチリ目を通してコメントをくれたりするところです。良い意味で姿勢を正して最後までやりきろうという前向きな気持ちになれるところじゃないでしょうか。

「正社員」だからこそ、積極的にやる

弊社のプロダクト「クロスオーダー」は、過去現在、複数の業務委託デザイナーが築き上げた結晶となっています。ゆえに表現は似ているけど使われ方が違うパーツがあったりと整理が必要な部分があったので、「正社員になると決めた私の責任の分野だ。やるぞ!」という強い気持ちでデザインシステムの見直しを提案しているところです。

在籍中の業務委託デザイナーと連携して、どこまでの作り込みが我々にとってのベストなのかの協議と、フロントエンド陣へのUIリファクタリングの打診を経て近日公開を目指しています♪

リモートゆえに、透明人間にならないように意識する

現在、2児のママ×フルタイムのため基本リモートにて勤務させてもらっています。リモートゆえに透明人間にならないよう以下の意識を持って働いています。

  • Slackはどんどん発信・メンバーに絡む!
    • 独り言やスタンプで定期的に霊圧を残しておく
    • ちょっとタメ口調を織り交ぜてみたりして
      少しでも声をかけやすいようなキャラクターを目指す
  • 新人だからこその気づきを還元する
    • 新人の存在価値ってここだと思います。自社プロダクトに詳しくないからこその気づきと、改善案の提出はスピードを持って取り組みました。
    • 会社HPに載ってる本社住所に最寄りの駅改札を掲載してもらったり。
      初回、東京駅ダンジョンを45分彷徨ったのは良き思い出です。

最後に

お決まりとはなりますが、クロスマートはPMはもちろんエンジニアやBizDevなど広く一緒に働く仲間を募集中です。組織も事業も急拡大していて、やること満載なので興味がある場合は是非こちらを御覧ください!