Photoruction工事中!

Photoructionの開発ブログです!

Photoruction Androidアプリのアーキテクチャとこれからについて

Photoruction Advent Calendar2021の15日目です。

はじめまして。Androidチームに業務委託としてかかわっている @kgmyshin というものです。

この記事では Photoruction Android アプリのアーキテクチャについて触れていきます。

経緯

PhotoructionのAndroidプロジェクトは、しっかりしたアーキテクチャやルールを設けるタイミングを失ったまま開発を続けてしまっていたため、無秩序気味のコードとなってしまっていました。

そもそも十分に知見がある人を採用できない中でスピードを出さないといけないケースもあるので、これ自体は別に責められるべきことではないです。

ただ結果としてみんなが思い思いのコードを書いてしまう。そして、コードの読解に時間がかかる、修正したいがそもそも影響範囲がめちゃくちゃ広いといったコードになってしまっているため、そこは今後の開発のために対処が必要です。

といった経緯もあり。わりかし知見がある私に「アーキテクチャの方針を決めてもらいたい」というタスクが降ってきたのでした。

ここら辺の現状については、あすの久木田さんの記事でもう少し詳細に書かれると思います。

アーキテクチャの選定のための要素

アーキテクチャ選定に至っては様々な変数があるのですが、その中でもとりわけ大きい変数は以下の二つです。

  • 作るアプリの複雑度や規模
  • チームの習熟度

作るアプリの複雑度や規模という観点について。Photoruction というアプリは、オフラインでアプリがしっかり動く必要があることと、機能が単純に多いという特徴があります。アーキテクチャは対象のアプリによって適切なものが変わってきます。

下記は アプリにおけるアーキテクチャを示したものではないですし、最近採用されるアーキテクチャではないですが、この図からは、複雑さによって適したアーキテクチャは変わってくるということがわかると思います。

f:id:photoruction_tech_blog:20211209142528p:plain

Martin Fowler著: Patterns of Enterprise Application Architecture より引用

肌感ですが。この図に Photoruction アプリを差し込むなら、かなり右の方によるアプリだと感じています。

チームの習熟度について。こちらは現行アプリがレガシーな技術であったり、そもそもアーキテクチャなどが導入されていなかったということもあり、 まだ アーキテクチャなどの精通しているメンバーは多くないというのが現状だと感じています。

まずは秩序だったアーキテクチャがあることに慣れてもらうフェーズ

以上のような要素の中、自分が選択したものは Android Developer サイトにアーキテクチャガイドのアーキテクチャを少しPhotoruction用にかみ砕いたものでした。

このアーキテクチャの特徴は、 ViewModel と Repository があるだけの単純なものです。

Photoruction用にかみ砕いて、実際には次のようなアーキテクチャになっています。

f:id:photoruction_tech_blog:20211209142545p:plain

Photoructionアプリは 、先にも述べた通り複雑度が高く規模が大きいアプリです。そのことだけを考慮すると、主観では この Android Developer のアーキテクチャは適していない、というか粒度が大きすぎて足りていない部分があります。

しかし、今回はチームの習熟度という要素を優先して、このアーキテクチャを選びました。

もし、チームの習熟度を無視して、粒度の細かい高難易度のものを選定してしまっても、学習コストが高くて、そこに自分ががっつりコミットする時間がないうえに、もしうまくコードが書けるようになっても、アーキテクチャの細部を理解するまえに「そういうもの」「おまじない」という扱いになりかねなくチームの習熟度への貢献には至らないと考えたためです。(今のところその予定はないですが)自分が抜けてしまっても大丈夫なようにするためには、チームの習熟度を高めることの方が重要なのです。

このアーキテクチャのゴールは「秩序をしっかり作って、秩序に慣れてもらうこと」です。

これが徐々に根付いていけば、例えばルールが決まってないところが出てきて、チーム内でコードの書き方等にブレが出てきた際に、チームでルールを決めようとする振る舞いが散見されるようになります。

まだまだ導入の道半ばですが、実際にそういうケースを見かけることが多くなってきてます。

あと、余談ですが、DIコンテナライブラリ等も使用しておりません。めんどくさいですが、手動で似たようなことを実現してもらっています。手動でやってるので、ゆくゆくは DI コンテナライブラリが何をやっていて、何がうれしいかを知って、導入しましょうという流れになるのかもしれません。

このアーキテクチャだと、まだまだ課題がたくさんあるよね?ってなった時が次のフェーズ

このアーキテクチャだと、まだまだ粒度が大きすぎて課題がたくさんあるよね、と課題を認識できるようになったら次のフェーズです。

では、次はどんなアーキテクチャにするのかについては、特になにも決めておりません。というより自分がすべてを決めるべきではないと感じています。アーキテクチャに沿って開発してきたが、そのアーキテクチャにはいろんな課題があった、じゃあどういうアーキテクチャがいいかをチームで考えてもらって、そこにその時のAndroidアプリ開発事情、チームメンバーの志向を取り入れて、議論する。可能な限り、その際にサポートしようと思っています。

株式会社フォトラクションでは一緒に働く仲間を募集しています。

playwrightを使ってWEBのE2Eテストを自動化してみた 〜失敗談編〜

こんにちは!株式会社PhotoructionでQAエンジニアをしています内田です。 Photoruction Advent Calendar 2021の14日目の記事です。

playwrightを使ってE2Eテストの自動化をすすめる上で失敗したこと・詰まったこととその解決策を記載していきます。 E2Eテストの自動化を検討中の方の役に立てたら幸いです。

目次


  1. 失敗したこと・詰まったことリスト
    1. 自動化の進め方・構成での失敗談
      1. テスト実行時間が長すぎる
      2. テスト実行がコマンド実行できる人しかできない
      3. テストのどの箇所で落ちたのかがわからない
      4. テストで実行している内容が実装者しかわからない
      5. テスト実行によりデータ量がどんどん増えてく
    2. playwrightの使い方での失敗談
      1. 実行環境によってキャプチャ差分が出ちゃう
      2. ファイルダウンロードできない
      3. モーダルが完全表示される前に次の操作をしてしまう
  2. まとめ

自動化の進め方・構成での失敗談


テスト実行時間が長すぎる

背景 : 「テスト用ユーザー増やすの面倒だし、とりあえず直列実行すればいいよね・・?」という軽い感覚で直列実行にしか対応しない記述の仕方をしていました。実行時間が長すぎてストレスを感じました。

対策 : テストを並列処理できるよう実装を変えました。

教訓 : 最初から並列実行できるようにしておくべきでした。並列処理を実装することにより実行時間が1/2程度に削減できました。

コマンド実行できる人しかテスト実行できない

背景 : playwrightはコマンドライン上で実行するツールです。テスターさんがE2Eテストを実行したいタイミングにテスト実行依頼するというフローを挟まないといけませんでした。

対策GitHub Actionsのワークフロー手動実行機能を使ってテスト実行できるようにしました。

テストのどの箇所で落ちたのかがわからない

背景 : テスト実行しfailedになってもどのステップで落ちたのかがわからない

対策 : ①アクションタイムアウトの設定にしました ②操作キャプチャ動画を残す設定にしました

テストで実行している内容が実装者しかわからない

背景 : たとえば「写真アップロードのテスト」でもどの写真をアップするのか、拡張子はなにか、ドラッグ&ドロップでアップロードするのか・・・などの操作詳細がテスト実装者にしかわからず、テスターさんへの共有ができてませんでした。

対策 : テスト実装前に自動テストでの操作詳細をドキュメントに記載しました。

テスト実行によりデータ量がどんどん増えてく

背景 : データ作成テストによりデータ量が増えていき、MAX登録数に達したり他のテストで参照されるデータが参照できなくなる自体が発生しました。

対策 : データ作成テストとデータ削除テストをセットで実施するようにしました。

playwrightの使い方での失敗談


実行環境によってキャプチャ差分が出ちゃう

背景 : 一部のE2Eテストで要素で判定できないテストがあり、画像比較テストを導入しています。当方の環境はMac/Windows上で開発&GitHub Actionsでテスト実行 という構成でした。Mac/Windows/Linux上で撮影したキャプチャに差分が出てしまいました。

Mac

f:id:photoruction_tech_blog:20211209142209p:plain

Linux

f:id:photoruction_tech_blog:20211209142235p:plain

差分

f:id:photoruction_tech_blog:20211209142257p:plain

結構差分ってあるんですね・・・。

対策 : ゴールデンファイル(正解とするキャプチャ)をDockerを用いてLinux上で撮影しました。

ファイルダウンロードできない

背景 : ダウンロードボタンをクリックする実装をしてもダウンロードが始まらず詰まりました。

対策 : オプションに説明がありました。ちゃんとドキュメントは見るべきですね・・・。

https://playwright.dev/docs/api/class-testoptions#test-options-accept-downloads

playwright.config.jsに以下の設定を追加しました。

const config = {
(略)
    use: {
        acceptDownloads: true,
    }
}

モーダルが完全表示される前に次の操作をしてしまう

背景 : 弊社のサービスはモーダルがゆっくり上から降りてくるアニメーションで表示されます。こんな感じです。

f:id:photoruction_tech_blog:20211209142358g:plain

モーダルがブラウザに表示された瞬間、つまり完全に降りきる前にモーダル内の操作が始まってしまい、テストが落ちることがよくありました。

対策 : モーダルの移動アニメーションが終わるのを待ちました。下記の記述を加えました。

await page.click('{モーダルを表示させるボタン}');
const modal = await page.$('{モーダルの要素}');
await modal.waitForElementState('visible');
await modal.waitForElementState('stable');
// 次の操作へ・・

まとめ


自動テスト未経験者が手探りで自動化を進めています。振り返ってみると詰まったことだらけでした。 自動化を検討している人やplaywrightを使っている人の参考になれば幸いです。

   

株式会社フォトラクションでは一緒に働く仲間を募集しています

corporate.photoruction.com

www.wantedly.com

playwrightを使ってWEBのE2Eテストを自動化してみた 〜導入編〜

こんにちは!株式会社PhotoructionでQAエンジニアをしています内田です。 Photoruction Advent Calendar 2021の13日目の記事です。

手動で実行していた最低限のリグレッションテストを自動化してみたのでその記録です。

目次


  1. 自動化しようとした背景
  2. 自動化してみた結果所感
    1. スムーズに導入できなかったよ
  3. 導入までの道のり
    1. ツール選定
    2. 自動テスト実装
      1. 実装詳細
  4. まとめ

自動化しようとした背景


  • 毎回同じテストの実施が面倒なのでなんとかしたい(これが1番)
  • テスト工数削減

の目的で自動化を検討しはじめました

自動化してみた結果所感


playwrightの導入はスムーズにできました!

が、テスト実装がスムーズできませんでした・・・(詳細は次の記事へ)

導入までの道のり


ツール選定

世の中には自動テストツールやSaaSがたくさんありますが、playwrightを選んだ理由は下記です

  • 自動テストの導入・実装が簡単なこと
    • テストコード自動生成機能があること
  • 手動で実行した場合と比較してコストが安くなること
  • 好きなときにテストをたくさん実行できること

自動テスト実装

インストール

$ npm i -D @playwright/test
$ npx playwright install

configファイル作成します。(なくてもOKです) テストの各種詳細を設定できます。 詳細は公式ドキュメントを参照ください。 以下おすすめの設定です。

// playwright.config.js

const config = {
    use: {
        browserName: 'chromium',
        video: 'on', 
        acceptDownloads: true,
        actionTimeout: 10000,
    },
    timeout: 40000,
    testDir: './testcase',
    expect: {
        toMatchSnapshot: { threshold: 0.2 }
    },
    maxFailures: 10
};

テストファイル作成

弊社サービスの写真機能の表示切り替えが有効かを確認するテストをサンプルで記載します。 表示切り替えボタンをクリックすると、写真一覧の表示がタイル表示⇔リスト表示に切り替わる機能です。 手動で操作すると以下の操作になります。

操作手順としては以下になります。 ①ログインする ②テスト対象ページをひらく ③切り替えボタンをクリック ④切り替えボタンを再度クリック テストコードは以下です。

//testcase/photo.test.js

const { test, expect } = require('@playwright/test');
const path = require('path');

test.beforeAll(async ({ browser }) => {
    let context = await browser.newContext();
    let page = await context.newPage();
    {{ログイン処理}} ・・・手順①
    // ログイン情報を保存
    await page.context().storageState({ path: path.join({{保存先のパス}}, 'strageState.json') });
        {{対象の画面への遷移など事前準備をしておく}} ・・・手順②
    await context.close();
});

test.describe('写真機能', () => {
    test('表示形式が変更できるか', async ({ page }, testInfo) => {
        await page.waitForSelector('#photo_list >> .photo'); // 写真の要素
        await page.click('#change_display'); ・・・手順③
        expect(await page.screenshot()).toMatchSnapshot([testInfo.title, {{実行環境情報}} ,'表示形式リスト.png']);
        await page.click('#change_display'); ・・・手順④
          await page.waitForSelector('#photo_list >> .photo'); // 写真の要素
        expect(await page.screenshot()).toMatchSnapshot([testInfo.title,  {{実行環境情報}}, '表示形式タイル.png']);
    })
});

テスト実行

$ npx playwright test

※テスト初回実行時のみ、キャプチャのゴールデンファイル(正とするファイル)が生成されます

実行結果

こんな感じの出力になります configで指定したフォルダ配下に.webmの拡張子でキャプチャビデオが生成されています キャプチャビデオはこんな感じです。 test()で囲った部分から操作キャプチャが開始されます。

まとめ


playwrightを導入すること自体は簡単でした。 目的であった手動テスト工数削減も少しずつですが達成できています。 今後は自動テスト項目数を増やしたり、メンテナンスしやすいコードにしたいと考えています。 機会があればCIでのテスト実行方法も記事化したいです。

この記事の続きはこちら kojichu.photoruction.com

   

株式会社フォトラクションでは一緒に働く仲間を募集しています www.wantedly.com

corporate.photoruction.com

gatherで「ちょっと、いいですか?」ができる空間を作った話

こんにちは!株式会社フォトラクションでWebエンジニアをしている田中喜規です! Photoruction Advent Calendar 2021の12日目の記事です。

 

2020年からテレワーク環境が続いていますね。

 

これまでのようにオフィスに出社ができない状況だと、社内のコミュニケーションの絶対量は少なくなってしまいますよね。

おそらく、どの会社でも、こうした悩みや課題があるのではないでしょうか。

 

今年から、PhotoructionのWebエンジニアチームでは、gather.town(以下gatherと省略)というツールを使って、チームのコミュニケーションを促進しようと頑張っていました!

 

 

目次

 

gatherとは?


ポケモンドラクエを彷彿とさせる、レトロなUIで、さまざまなスペースを選択し、複数人のユーザーがチャットやビデオ通話ができるサービスです。

 

出社時と同じ感覚を得られる

Zoomやgoogle.meetは、URLリンクから参加できる人全員が一律同じ空間で、会話ができるものとなっていると思います。いわゆる、「Web会議ツール」ですよね。

 

gatherは、Web会議だけではなく、もっと用途が広いです。

Photoructionでは、以下のように、社員1人1人が部屋を作って、作業。

 

用がある時に、他メンバーの部屋を訪ねるようなイメージです。 「オンラインオフィスサービス」として利用してます。

f:id:photoruction_tech_blog:20211203104027p:plain

(私田中の自室です笑。宇宙船内で、ソロキャンプをしています)

パーソナルスペース

gatherでは、以下の状況で会話に参加ができます

  • 一定の距離感にいるか
  • パーソナルスペースにいるか
  • パブリックスペース(大部屋など、全員にアナウンスできる場所)

 

パーソナルスペースは、Zoomやgoogle.meetのように、同じ空間にいるメンバー全員に会話が聞こえるということはなく、オフラインの出社と同じ感覚で、ある一定の距離感の範囲内でないと会話が聞こえない仕組みとなっています。

 

実際のオフィスで、会議室を利用して打ち合わせを行う要領で、メンバー複数人で会話が可能です。打ち合わせが終われば、そのまま、自室に帰って各々の業務に戻る形で運用しています。

f:id:photoruction_tech_blog:20211203104441p:plain

ちょっと、いいですか?ができる空間を作りたい


元々、弊社のWebエンジニアチーム内の課題として、コミュニケーションが希薄になっていることが課題の1つとしてありました。

 

現在Photorucitonのエンジニアチームは、完全リモートでの働き方となっています。

定例やPJごとのミーティングがない限りは黙々と、業務を進めていくことになります。

勿論それはそれで利点になっているのですが、チーム全体でものづくりをしている意識や、困ったときに、助け合いができるような連帯感が薄いことに課題感がありました。

 

オフィスワークでよくある、隣のメンバーへの「ちょっと、いいですか?」ができれば、それだけで問題が解決することも、リモートワークでは時にはgoogle.meetで開催をセッティングし、slackで質問内容を考え、送信することが必要になります。

 

また、日々のちょっとしたやり取りから、メンバー間の関係性ができて、より良い職場環境となることも、リモートワーク環境以前では、当たり前のように生まれていたと思います。

 

そんな、「ちょっと、いいですか?」ができる環境づくりに適しているツールとして、gatherを活用していく運びになりました。

gather内でやったこと


用途は多岐に渡り、さまざまな楽しみ方ができます!

  • ランチ会(Webチーム内で週一)
  • bug bash(Photoructionのバグを社内で見つける月一イベント)
  • オンライン飲み会(不定期)

bug bashの時の様子

f:id:photoruction_tech_blog:20211203104512p:plain

 

無人島で、オンライン飲み会を開催(パブリックスペースがなく、密になりながら乾杯)

f:id:photoruction_tech_blog:20211203104536p:plain

実際、効果はあったか?


田中の独断と偏見だと、かなり働きやすくなったと思いました!

話しかけにいっていいんだ!って安心感を得た部分があり、「聞くハードル」が下がったように思います。

 

また、slackで何か問題が流れてて、gather内でその件について話をしていたりすると、

それを聞きつけて、他メンバーが心配して、覗きにくる場面もあったので、「コロナ前のオフィスワーク」にかなり近い雰囲気、連帯感も感じられました。

 

Webエンジニアチームに関わらず、他部署のチームも気軽に話しかけに来てくださることもよくあるので、間違いなく、コミュニケーションは増えたと思います!

 

コミュニケーションの問題なので、ツールを導入して解決!ということはないですが、解決のひとつのきっかけになるかもしれないので、個人的にはおすすめです笑。

 

株式会社フォトラクションでは一緒に働く仲間を募集しています 

 

PMの私がチームとの向き合い方で大切にしていること

はじめに

株式会社フォトラクションでプロダクトマネージャー(PM)をしています千葉由孝と申します。

Photoruction Advent Calendar 2021の11日目の記事です。 私は、非IT企業から転職して開発経験もないままPMを任されました。その後、まもなく新規サービスの立ち上げに携わることになります。そんな怒涛のような経験の中で、プロジェクトで発生する問題の向き合い方やチームメンバーとの向き合い方がチームを構築する上で特に大切だと感じました。自分の経験と学んだことを整理して書いてみましたので何かの参考になったらうれしいです。

 

自己紹介


少し私の自己紹介をします。私は前職で、事務所ビルやマンションなどの大型物件の施工管理を担当していました。いわゆる現場監督です。

突然ですが、建設現場で働く職人さんはめちゃめちゃかっこいいのって知っていますか?

自分たちが作ったものに対するプロ意識が非常に高く、使う人のことをいつも考えています。その妥協しない仕事振りはとても魅力的でした。こういう人たちが日本の建設業を支えていると思うととても誇らしい気持ちになります。また、建設業は建物や道路など生活の基盤を作る重要な産業です。

魅力がたくさんある一方で、現場監督の仕事は書類と格闘する長時間労働の日々でした。紙図面を持ち歩き、毎日現場で検査を行ったりと、職人さんが帰ってから夜遅くまで大量の書類作成に追われます。そんな日々を過ごすうちに、建設業で働く人々をもっと楽にする方法はないのかと考えるようになりました。そして、現場で培った経験を活かしかゆいところに手が届くプロダクトを作りたいという思いで転職しました。

建設業のことばかり書いてしまいましたが、私はそんな建設業が大好き人間です。この情熱でPMとして今日まで活動してきました。

 

チームを構築するために大切にしていること


私は、建設業のドメイン知識は自信がありましたが、それだけでは良いプロダクトを作ることはできません。PMの仕事はビジネス、テクノロジー、UXの領域が必要になります。ですがこの広い領域のスキルを一朝一夕で身に着けることは当然ながら難しい。そのため、スキルや知識がある人に協力を得たり、スキルを補完し合う関係性をチームで構築していくことが大切になります。

そのために私が意識していることは以下の2点です。

1.問題が発生したら自分ごと化してチームメンバーに共感し行動する

2.相手との目線合わせや役割の理解を大切にする

 

1.問題が発生したら自分ごと化してチームメンバーに共感し行動する


どのプロジェクトもそうだと思いますが、進めていく中で、大なり小なり様々な問題が発生します。チームの問題を解決に導くのもPMの役割です。私は、チームメンバーが直面する問題を人任せにせず、自分の問題として捉え、当事者意識も持つようにしています。

その上で、対応するメンバーの置かれた状況や気持ちを理解するところから行動を起こすようにしています。自分で解決できそうなら静観して見守ります。困っていたら一緒に手伝います。もしくは他のメンバーを巻き込みチームで解決するように支援をします。メンバーの気持ちに共感し、その人が力を発揮しやすい解決策を考えることも大切だと思います。

この大切さに気づいたのは、あるプロジェクトで起きた出来事がきっかけでした。担当エンジニアは実装方法について悩んでいたのですが、自分の領域外だと思い、エンジニアに任せっきりにしてしまいました。エンジニアは課題を抱えたまま、時間が経ち、リリースの延期など大きな問題に発展することになりました。私の当事者意識が欠けていたことが、課題の放置に繋がってしまったのだと思います。

 

2.相手との目線合わせや役割の理解を大切にする


PMの仕事は開発からビジネス領域まで多岐にわたるので、他部署の人と会話や議論をする機会が多くあります。私が意識しているのは、その人がどういう目線でプロダクトについて話しているのかを理解することです。

時には、さらに進んでその人の思考のプロセスをトレースするくらいその部署の人になりきることを意識しています。少し過剰かもしれませんが、それくらい意識しないと他人を理解することが難しいからです。

例えば、営業の人であれば、どういう伝え方が顧客に刺さるのか、顧客の業務がどのくらい改善されるのか、競合他社との違いや優位性は何なのかといったことを考えているかもしれません。

エンジニアであれば、実装する機能を顧客がどのように使ってくれるのか、実装にモダンな技術が使われているのかといったことを考えているかもしれません。(あくまで一例なのでみんなそうというわけでなく、目線が違うということが伝わればありがたいです。)

また、その人を理解するには、どんな業務をやっているのか役割を理解することも大切です。

以前は、他部署の方と話すときになかなか理解してもらえず苦労していたことが多かったですが、相手の役割や目線の理解し、準備をしっかりして相手目線で話すことで、共通理解を作りやすくなったと感じています。

 

まとめ


PMになって1年半余りの経験を通して、プロジェクトの問題の向き合い方、チームメンバーや関係者との向き合い方について記載しました。

不確実なプロダクト開発の中で、日々起こる問題を乗り越えていけるチーム作りが必要ですし、そのためには、関係者の協力を集め、必要なスキルを補完し合う関係性を構築していくことが大切だと感じています。

これからも建設業で働く人々に役立つプロダクト作りに邁進していきます。

読んでいただきありがとうございました!

 

 

株式会社フォトラクションでは一緒に働く仲間を募集していますhttps://corporate.photoruction.com/careers/ https://www.wantedly.com/companies/photoruction/projects

カスタマーサクセス・サポートを経験したプロダクトマネージャーの強みと苦労について

こんにちは!株式会社フォトラクションでPMグループリーダーをしている市橋です。 Photoruction Advent Calendar 2021の10日目の記事です。

本記事では、カスタマーサクセス(CSM・サポート)を経てプロダクトマネージャー(PM・PdM)にキャリアチェンジした私が考える、ユーザーに近いポジションからプロダクトマネージャーになったことによる強みと苦労している点ついて簡単にまとめています。

同じようにカスタマーサクセスやカスタマーサポート(以降、CSとします)または他の職種から、プロダクトマネージャー(以降、PMとします)へのキャリアチェンジを考えている方の参考になれば嬉しいです。

目次

私の簡単な経歴


私は建築系の学科を卒業後、大手建設コンサルタント企業で道路設計をしていました。

建設業界は労働人口が減少しており、今後さらなる生産性や魅力の向上が求められています。

そんな中、「建設の世界を限りなくスマートにする」というミッションを掲げてアプローチしている弊社で、業界で働く人達がスマートに働けるようにサポートしたいと思い、2019年末にCSMの立ち上げメンバーとして入社しました。

フォトラクションのCS


フォトラクションのCSは、photoructionを導入いただいている企業の方が、よりphotoructionを使いこなしていただけるために、以下のようなことをしています。

  • 導入いただいた企業様への操作説明会の実施
  • 各企業様との月次定例会を開催し、利用状況の確認や今後より活用できるようにするためのアクションプランの策定
  • 利用状況を計測し、使えている方・使えていない方それぞれの要因分析
  • 問い合わせ対応・サポートサイトの作成

PMへのキャリアチェンジを考えたきっかけ


日々photoructionをご利用いただいている方と接していく中で、「こんなことができなくて困ってるんだよね」や「この部分が使いづらいんだよね〜」と言ったご意見を聞いていくうちに、

「こんな機能だったら使いやすいのに」「自分だったらどうやって改良していくだろう」という考えを抱くようになっていきました。

もともと、ものづくりが好きだった(学生自体は建築の模型づくりが好きだったり、自宅の家具をDIYしたり、プログラミングを勉強して簡単なサイトをつくってみたりしていた)こともあって、

photoructionを最大限使っていただけるようにサポートするよりも、使いやすいサービスを作ることでphotoructionユーザーの方々に貢献したいと思うようになりました。

2021年の初めにその思いを当時の上司に伝えてみたところ、「いいんじゃない?市橋くんに向いているかもね。やってみなよ!」とすんなり後押ししてもらえました。(大感謝です!)

その後、2021年3月からCSと兼務する形でPMグループに異動しました。

強み1 : 機能やユーザーの使い方を一番把握している


使いこなしてもらえるようにサポートするため、また、使い方に関するお問い合わせに対して適切に答えるためには、サポートする側が一番使い方を熟知している必要があります。

使い方を熟知するためには、文字通りすべての画面・すべてのボタンを確認しました。

この画面ではどんな挙動をするのか、これは何のための機能なのか、ユーザーの課題を解決するためにはどのように操作するのがいいのかを徹底的に確認します。

嬉しいこと(?)に、photoructionには多種多様な機能があるため、すべての機能を把握するためには日々触り倒して体に染み込ませる必要があります。(稀にお客様からのお問合せで存在を知る機能もあったり、、、)

PMとして新機能を企画する際には、既存の機能との親和性や機能追加することによる影響などを正しく把握する必要があります。

最前線でユーザーと向き合ってきたおかげで、PMに転向してからは既存仕様の理解にあてる時間はほぼなし。開発メンバーから仕様や既存の使い方を確認された際にも即時に返答することができています。

強み2 : 定量調査の経験を企画に活かすことができる


CSとしてユーザーの利用状況を正しく把握するためには、定例会でのヒアリング内容(定性データ)に加えて、アクティブ率などの定量的なデータも活用する必要があります。

私が入社した当時、アクティブ率やデータ量の推移は逐一エンジニアに確認しないと取得できない状況だったため、自分たちで取得できるような仕組みをつくることにしました。

Google Analyticsを用いたアクティブ率の算出や、SQLを書いてデータベースに蓄積されたデータの取得をしながら、利用状況確認用のダッシュボードを作成しました。

(私がCSから異動したあとの今でも、KPIとして活用されています)

私がPMになった時点では、企画段階で定量データを確認する習慣がありませんでした。

仕様検討時に、既存ユーザーの活用状況や蓄積データ量を確認しておくことで、企画精度の向上や開発メンバーに説明する際にも納得感のある説明を行うことができます。

私がPMグループになってからは、社内で非エンジニア向けのSQL勉強会を主催し、PMグループのメンバー全員がデータを見るクセを付けられるように動いています。

また、photoructionの開発組織では、今後ユーザーの行動ログ解析ができるような体制をつくっていく動きをしています。

今後はより精度の高い定量データや、ユーザーインタビューによる定性的なデータなどを活用して、より利用していただいている方々のためになるようなサービス開発をしていきたいと思っています。

苦労 : 開発に関する知識が不足している


photoructionのPMグループは、開発する機能の企画部分(プロダクトマネジメント領域)と、企画した機能をリリースまで持っていく部分(プロジェクトマネジメント領域)を担っています。

企画の部分については、建設業に関するドメイン知識(私は道路計画が専門だったので、建築の施工についての知識は十分ではありませんが)と、CSで培ったユーザーとプロダクト理解の部分でカバーしています。

ただ、プロダクトマネージャー界隈で有名なThe Product Management Triangle でも記されているとおり、PMに求められるスキル・知識はユーザー・ビジネス・開発というとても広い領域で求められます。

特に、プロダクト開発やUI/UXデザイン領域については0からのスタート、かつ、プロジェクトマネジメント部分も任されていることもあってとても苦労しています。

PMという立場上、実装する上での実装難易度の想定であったり、エンジニアからの技術的な提案を受ける際にも、素早く適切な意思決定をしないといけません。

今の開発チームのメンバーは、私が開発領域の知識が少ないことを考慮して、分かりやすい表現を使っていただいていますが(大感謝)、素早く質の高い意思決定をするためには、開発に関する知識がどうしても必要になってきます。

まとめ


前述のとおり、世間一般的に言われるプロダクトマネージャーとして必要なスキル領域はとても広く、実際にやってみるとものすごく難しく感じます。

ただ、最初からすべてのスキルを持っている人はそうそういないのと、色々なバックグラウンドを持ったPMがチームにいたほうが、不足している部分をお互いに補えるので強いチームになれると思います。

現在のPMグループは私を含めて3名在籍しています。

建設業界出身という共通点はありますが、持っているドメイン知識領域はそれぞれバラバラですし、スキル面でも得意不得意な領域はそれぞれ異なっています。

そのおかげで、不足している部分をお互いで補うことによって、チームとしてプロダクト開発に臨めています。

私にPMとして期待されていることは、CS出身者である強みを生かして、photoructionを利用していただいている方の気持ちを一番理解しているPMになることだと思っています。

今、開発畑以外のところで活躍している方々で、PMへの転向を考えている方は、「いいプロダクトをつくりたい」という気持ちと「自分がプロダクトをつくる上で活かせることはなにか」を考え続けることが一番大事だと思います。

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

Photoruction Advent Calendar 2021の投稿はまだまだ続きます。

他の記事も是非読んでみてください!

 

株式会社フォトラクションでは一緒に働く仲間を募集しています

corporate.photoruction.com

www.wantedly.com

LaravelプロジェクトにViteを用いてVue + Composition API + TypeScript環境を構築

こんにちは!株式会社フォトラクションでWebエンジニアをしています南風原はえばる)です。 Photoruction Advent Calendar 2021の9日目の記事です。

導入

現在、担当している案件のフロントエンドがほぼリプレイス並みの開発というタイミングもあり、技術スタックを新しく見直しました。

開発環境はViteを用いてVue.js + Vue Composition API + TypeScriptで機能開発を行っています。

今回は環境構築までの流れを書いていこうと思います。

 

その前に、現状のPhotorucutionのフロントエンド事情を軽く説明します。

プロダクトの約7割はBackbone.js、jQueryで実装されており、画面の表示はHandlebars.jsというテンプレートエンジンとLaravelのbladeファイルを用いて実装されています。

3年くらい前から新機能の開発はVue.jsで開発していく流れにはなっていますが、まだまだレガシーコード満載な状況です笑

今後さらにフロントエンドの開発環境が良いものとなるように一緒に改善に取り組んでいけるエンジニアを絶賛募集中です!

Viteとは

ViteはVue.jsの開発者であるEvan You氏が開発しているノーバンドルで高速に動作するビルドツールになります。

「ヴィート」と読むそうで、フランス語で「高速」の意味らしいです。(このツールを知った当初は、バイトって読んでました笑)

「高速」というだけあって、プロジェクトの作成も一瞬。ビルド時間もあっというまで開発体験がめちゃくちゃいいです。

Vue.js以外にも、ReactやPreactのビルドもサポートしているそうです。

vitejs.dev

環境構築編

[前提] 既存プロジェクトの大体のディレクトリ構成になります。

root/
 ├ app/
 ├ bootstrap/
 ├ config/
 ├ database/
 ├ public/
 │ └ js/
 │   └ dst/
 ├ resources/
 │ └ assets/
 │   └ js/
 │    └ app/
 │ └ lang/
 │ └ views/
 ├ package.json

1. Viteを使って新しくプロジェクトを作成

既存プロジェクトで使用しているパッケージとは分離するために、新しいディレクトリを作成しViteをインストールします。(メッセージの指示に従って環境のセットアップをしていく)

$ mkdir resources/assets/js/app/[newProject]
$ cd resources/assets/js/app/[newProject]
$ npm init vite@latest

2. Viteで作成した新プロジェクトに移動しビルド実行

$ cd [newProject]/
$ npm install
$ npm run dev

3. Viteプロジェクトのビルド時に生成されたファイルの出力先を変更

vite.config.js 内にビルド時のファイル出力先を既存プロジェクトのファイルパスになるようにします。

build: {
  outDir: '../../../../../public/js/dst/[newProject]'
},

4. scssファイルのインポート設定

vite.config.js 内にコンポーネント共通で参照するscssファイルのパスを追加します。

css: {
    preprocessorOptions: {
      scss: {
        additionalData:
          `@import "./src/assets/scss/variables.scss";
          @import "./src/assets/scss/common.scss";`,
      }
    }
  }

5. 既存プロジェクト(Laravel)にViteプロジェクトを読み込むヘルパー関数を作成

<?php

use GuzzleHttp\\Client;
use Illuminate\\Support\\HtmlString;

function vite_assets($path, $fileName): HtmlString
{
    $devServerIsRunning = false;
    if (config('app.env') === 'local') {
        try {
            $client = new Client();
            $res = $client->get("<https://localhost:3000/{$fileName}>");
            $devServerIsRunning = true;
        } catch ( \\Exception $e ) {
        }
    }
    // ローカルサーバに接続できた場合
    if ($devServerIsRunning) {
        return new HtmlString(<<<HTML
            <script type="module" src="<https://localhost:3000/@vite/client>"></script>
            <script type="module" src="<https://localhost:3000/{$fileName}>"></script>
        HTML);
    }
    // その他の環境ではコンパイルしたjsを返す
    $manifest = json_decode(file_get_contents(public_path("{$path}/manifest.json")), true);
    return new HtmlString(<<<HTML
        <script type="module" src="/{$path}/{$manifest[$fileName]['file']}"></script>
        <link rel="stylesheet" href="/{$path}/{$manifest[$fileName]['css'][0]}">
    HTML);
}

※ローカルサーバー(https://localhost:3000/)で開発する際はlocalhostへのアクセス許可が必要になります。

LaravelのbladeファイルにVueコンポーネントをマウントする方法

既存機能の一部分に新しく作成したVueコンポーネントを表示したいパターンが有るかと思います。

その場合の方法を紹介します。

import FeatureContent from '@/pages/FeatureContent.vue'

// 任意の要素(DOM)の変化を監視する
const observer = new MutationObserver(records => {
  records.forEach(mutation => {
    const target = (mutation.target as any).getAttribute('id')

    switch (target) {
      case 'feature_content': {
        const app = setFeatureContentApp()
        vue = app
        break
      }
    }
  })
})

const featureApp = document.getElementById('feature_app')

if (featureApp) {
  observer.observe(featureApp, {
    attributes: true,
    subtree: true,
    attributeFilter: ['class'],
  })
}

// Vueコンポーネントを任意のDOMにマウントする
const setFeatureContentApp = () => {
  const featureContentElm = document.getElementById('feature_content')
  if (!featureContentElm) return
    return new Vue({
      render: (h) => h(FeatureContent),
    }).$mount('#feature_content')

bladeファイル

<div id="feature_app">
  <div id="feature_menu">
	<!-- 既存View -->
  </div>
  <div id="feature_content" /> ← 新Vueコンポーネントがマウントされる
</div>

まとめ

Backbone.jsで作成された既存機能をVue.jsにリプレイスしていく場合、全てを一から作り直すというのは時間と開発コストがかかります。

上記のような方法で、既存機能への影響を最小限に抑えながら少しずつリプレイスをしていくことが可能だということを今回担当している案件を通して学べました。

これから先、UI/UX含めフロントエンドをどんどんアップデートしていき、ユーザへより一層価値の高いサービスを提供できるようなプロダクトを作っていきたいものです。

ぜひ、一緒にフロントエンド開発を盛り上げていただける方をお待ちしております!

 

株式会社フォトラクションでは一緒に働く仲間を募集していますhttps://corporate.photoruction.com/careers/

corporate.photoruction.com

www.wantedly.com