世界対応の観光アプリを、独学で1人で開発・リリースまでした話(技術編)
Photo by Yura Fresh on Unsplash
こんにちはShotaです。
前回のストーリーでは、完全独学で観光アプリを開発・リリースするまでの過程を紹介しました。今回は、その開発の裏側にある技術的な構成や設計の工夫について詳しくご紹介します。
目次
Ajump Worldとは?
主な機能
使用技術スタック
🔐 セキュリティ・UXを重視した主要な実装ポイント
✔️ 仮登録フローはハッシュ & 暗号化を駆使
✔️ ワンタイムリンク + 再送制御で安全なメール認証
国別の住所フォーマットに対応
検索も多言語
🖼️ 画像処理の工夫と最適化
UI・UX改善のポイント
CloudWatchとログトレーシング
ソースコードについて
📌 最後に
Ajump Worldとは?
Ajump Worldは、旅行者が世界中のスポットを検索し、旅行プランを作成・共有できるWebアプリです。
店舗情報を活用してオリジナルプランを作ることも、他のユーザーのプランを参考にすることもできます。
主な機能
- 店舗ユーザー / 一般ユーザーの2種類の登録
- お店・観光地検索 & プランへの追加
- お店間の距離計算(ハーバサインの公式)でルート最適化
- コメント、プランタイプ、同行者などの属性付きプラン作成
- レビュー投稿(画像付き)
- 公開されたプランの地域別検索
- 多言語対応(英語・日本語)
使用技術スタック
バックエンド:Djagno, Python
データベース:PostgreSQL, Rdis
フロントエンド:HTML, CSS, Bootstrap, JavaScript
インフラ:AWS(EC2, S3, CloudWatch, SES)
その他:Nginx, gunicorn, i18n(国際化)
🔐 セキュリティ・UXを重視した主要な実装ポイント
✔️ 仮登録フローはハッシュ & 暗号化を駆使
- 入力パスワードとメールアドレスが似すぎている場合は拒否
- 仮登録データはRedisへ暗号化して保存
- トークン+ソルト+秘密鍵から生成されたキーでAES暗号
- トークンリンクは署名付きURLにし、改ざん不能に
✔️ ワンタイムリンク + 再送制御で安全なメール認証
- SESでの署名付きリンク送信
- OTPは6桁、失敗回数の記録と制限
- 使用済みリンクは即無効化
国別の住所フォーマットに対応
- 住所要素を国ごとに並び替え
- API送信用の「整形されたフル住所」を作成
- Google Geocoding APIから座標を取得
- お店間の距離計算に活用(旅行プラン最適化)
検索も多言語
- 日本の店舗はひらがな入力を必須化
- ひらがな → ローマ字に変換して保存
- 漢字・ひらがな・ローマ字の3系統の検索に対応
🖼️ 画像処理の工夫と最適化
- 投稿画像からEXIF情報を除去(位置・端末など)
- 保存形式はwebpへ変換し容量圧縮
- 画像ファイル名はuuid4で一意にし、S3上でも衝突なし
UI・UX改善のポイント
- ドラッグ&ドロップでプランの順序を直感的に変更可能
- 非同期fetch通信によるストレスフリーな操作感
- 画像表示はSNSライクなドットナビゲーション
- アプリ内の戻るボタンも最適配置で自然なナビゲーション
CloudWatchとログトレーシング
- 各リクエストに一意のRequest IDを付与し、ログを追跡可能に
- CloudWatch Logsでも確認でき、運用時のトラブル対応を効率化
ソースコードについて
このアプリはすでに本番運用中のため、ソースコードは公開しておりません。
ただし、実装内容や構成は本記事のように技術記事として今後も積極的に共有予定です。
📌 最後に
このアプリ「Ajump World」はすでに以下のURLで公開中です。
アプリ名の「Ajump」は、ASAP (as soon as possible) と Jump を組み合わせた造語です。
「できるだけ早く、旅へ飛び立とう」という意味を込めています。
1人でここまでの機能を開発・公開するのは本当に大変でしたが、「本物のサービス」を目指して積み上げてきました。
開発者として、今後さらに進化させていく予定です。