<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>画像API on 設計書</title><link>https://Hitamuki.github.io/image-upload/design/api/images/</link><description>Recent content in 画像API on 設計書</description><generator>Hugo</generator><language>ja</language><atom:link href="https://Hitamuki.github.io/image-upload/design/api/images/index.xml" rel="self" type="application/rss+xml"/><item><title>署名付きURL 発行</title><link>https://Hitamuki.github.io/image-upload/design/api/images/api001-upload/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://Hitamuki.github.io/image-upload/design/api/images/api001-upload/</guid><description>&lt;h1 id="署名付きurl-発行"&gt;署名付きURL 発行&lt;a class="anchor" href="#%e7%bd%b2%e5%90%8d%e4%bb%98%e3%81%8durl-%e7%99%ba%e8%a1%8c"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;h2 id="id"&gt;ID&lt;a class="anchor" href="#id"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;api001-upload&lt;/p&gt;
&lt;h2 id="エンドポイント"&gt;エンドポイント&lt;a class="anchor" href="#%e3%82%a8%e3%83%b3%e3%83%89%e3%83%9d%e3%82%a4%e3%83%b3%e3%83%88"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th style="text-align: left"&gt;メソッド&lt;/th&gt;
 &lt;th style="text-align: left"&gt;パス&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;POST&lt;/td&gt;
 &lt;td style="text-align: left"&gt;&lt;code&gt;/images/presigned-url&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="概要"&gt;概要&lt;a class="anchor" href="#%e6%a6%82%e8%a6%81"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;S3アップロード用の署名付きURLを発行する。&lt;/p&gt;
&lt;h2 id="リクエスト"&gt;リクエスト&lt;a class="anchor" href="#%e3%83%aa%e3%82%af%e3%82%a8%e3%82%b9%e3%83%88"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="ボディ"&gt;ボディ&lt;a class="anchor" href="#%e3%83%9c%e3%83%87%e3%82%a3"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th style="text-align: left"&gt;物理名&lt;/th&gt;
 &lt;th style="text-align: left"&gt;論理名&lt;/th&gt;
 &lt;th style="text-align: left"&gt;型&lt;/th&gt;
 &lt;th style="text-align: center"&gt;必須&lt;/th&gt;
 &lt;th style="text-align: left"&gt;説明&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;fileName&lt;/td&gt;
 &lt;td style="text-align: left"&gt;ファイル名&lt;/td&gt;
 &lt;td style="text-align: left"&gt;string&lt;/td&gt;
 &lt;td style="text-align: center"&gt;✓&lt;/td&gt;
 &lt;td style="text-align: left"&gt;アップロードするファイル名&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;fileSize&lt;/td&gt;
 &lt;td style="text-align: left"&gt;ファイルサイズ&lt;/td&gt;
 &lt;td style="text-align: left"&gt;number&lt;/td&gt;
 &lt;td style="text-align: center"&gt;✓&lt;/td&gt;
 &lt;td style="text-align: left"&gt;ファイルサイズ（バイト単位）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;contentType&lt;/td&gt;
 &lt;td style="text-align: left"&gt;Content-Type&lt;/td&gt;
 &lt;td style="text-align: left"&gt;string&lt;/td&gt;
 &lt;td style="text-align: center"&gt;✓&lt;/td&gt;
 &lt;td style="text-align: left"&gt;MIMEタイプ&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;fileName&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;fileSize&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;number&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;contentType&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="バリデーション"&gt;バリデーション&lt;a class="anchor" href="#%e3%83%90%e3%83%aa%e3%83%87%e3%83%bc%e3%82%b7%e3%83%a7%e3%83%b3"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th style="text-align: left"&gt;検証項目&lt;/th&gt;
 &lt;th style="text-align: left"&gt;条件&lt;/th&gt;
 &lt;th style="text-align: left"&gt;レスポンス&lt;/th&gt;
 &lt;th style="text-align: left"&gt;メッセージ&lt;/th&gt;
 &lt;th style="text-align: left"&gt;備考&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;ファイルサイズ&lt;/td&gt;
 &lt;td style="text-align: left"&gt;5MB 超&lt;/td&gt;
 &lt;td style="text-align: left"&gt;&lt;code&gt;400 Bad Request&lt;/code&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;MSG-API-001&lt;/td&gt;
 &lt;td style="text-align: left"&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;Content-Type&lt;/td&gt;
 &lt;td style="text-align: left"&gt;許可リスト外&lt;/td&gt;
 &lt;td style="text-align: left"&gt;&lt;code&gt;400 Bad Request&lt;/code&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;MSG-API-002&lt;/td&gt;
 &lt;td style="text-align: left"&gt;許可 Content-Type: &lt;code&gt;image/jpeg&lt;/code&gt; &lt;code&gt;image/png&lt;/code&gt; &lt;code&gt;image/gif&lt;/code&gt; &lt;code&gt;image/webp&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;アップロード枚数上限&lt;/td&gt;
 &lt;td style="text-align: left"&gt;同一ユーザーが 5 枚以上保持&lt;/td&gt;
 &lt;td style="text-align: left"&gt;&lt;code&gt;409 Conflict&lt;/code&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;MSG-API-003&lt;/td&gt;
 &lt;td style="text-align: left"&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;レート制限&lt;/td&gt;
 &lt;td style="text-align: left"&gt;同一 IP から 1 分間に 10 回超&lt;/td&gt;
 &lt;td style="text-align: left"&gt;&lt;code&gt;429 Too Many Requests&lt;/code&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;MSG-API-C001&lt;/td&gt;
 &lt;td style="text-align: left"&gt;共通仕様に準拠&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="presigned-url-有効期限"&gt;Presigned URL 有効期限&lt;a class="anchor" href="#presigned-url-%e6%9c%89%e5%8a%b9%e6%9c%9f%e9%99%90"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;発行から &lt;strong&gt;300 秒（5 分）&lt;/strong&gt; 以内に PUT が完了しない場合 URL は無効となる。期限切れ時はクライアントが発行から再試行する。&lt;/p&gt;</description></item><item><title>アップロード完了・メタデータ登録</title><link>https://Hitamuki.github.io/image-upload/design/api/images/api002-upload/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://Hitamuki.github.io/image-upload/design/api/images/api002-upload/</guid><description>&lt;h1 id="アップロード完了メタデータ登録"&gt;アップロード完了・メタデータ登録&lt;a class="anchor" href="#%e3%82%a2%e3%83%83%e3%83%97%e3%83%ad%e3%83%bc%e3%83%89%e5%ae%8c%e4%ba%86%e3%83%a1%e3%82%bf%e3%83%87%e3%83%bc%e3%82%bf%e7%99%bb%e9%8c%b2"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;h2 id="id"&gt;ID&lt;a class="anchor" href="#id"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;api002-upload&lt;/p&gt;
&lt;h2 id="エンドポイント"&gt;エンドポイント&lt;a class="anchor" href="#%e3%82%a8%e3%83%b3%e3%83%89%e3%83%9d%e3%82%a4%e3%83%b3%e3%83%88"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th style="text-align: left"&gt;メソッド&lt;/th&gt;
 &lt;th style="text-align: left"&gt;パス&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;POST&lt;/td&gt;
 &lt;td style="text-align: left"&gt;&lt;code&gt;/images&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="概要"&gt;概要&lt;a class="anchor" href="#%e6%a6%82%e8%a6%81"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;S3への直接アップロード完了後、マジックナンバー検証を行いメタデータをDBに登録する。&lt;/p&gt;
&lt;h2 id="リクエスト"&gt;リクエスト&lt;a class="anchor" href="#%e3%83%aa%e3%82%af%e3%82%a8%e3%82%b9%e3%83%88"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="ボディ"&gt;ボディ&lt;a class="anchor" href="#%e3%83%9c%e3%83%87%e3%82%a3"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th style="text-align: left"&gt;物理名&lt;/th&gt;
 &lt;th style="text-align: left"&gt;論理名&lt;/th&gt;
 &lt;th style="text-align: left"&gt;型&lt;/th&gt;
 &lt;th style="text-align: center"&gt;必須&lt;/th&gt;
 &lt;th style="text-align: left"&gt;説明&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;key&lt;/td&gt;
 &lt;td style="text-align: left"&gt;S3オブジェクトキー&lt;/td&gt;
 &lt;td style="text-align: left"&gt;string&lt;/td&gt;
 &lt;td style="text-align: center"&gt;✓&lt;/td&gt;
 &lt;td style="text-align: left"&gt;S3上の保存パス&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;key&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="バリデーション"&gt;バリデーション&lt;a class="anchor" href="#%e3%83%90%e3%83%aa%e3%83%87%e3%83%bc%e3%82%b7%e3%83%a7%e3%83%b3"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th style="text-align: left"&gt;検証項目&lt;/th&gt;
 &lt;th style="text-align: left"&gt;条件&lt;/th&gt;
 &lt;th style="text-align: left"&gt;レスポンス&lt;/th&gt;
 &lt;th style="text-align: left"&gt;メッセージ&lt;/th&gt;
 &lt;th style="text-align: left"&gt;備考&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;S3ファイル存在&lt;/td&gt;
 &lt;td style="text-align: left"&gt;ファイルが存在しない&lt;/td&gt;
 &lt;td style="text-align: left"&gt;&lt;code&gt;404 Not Found&lt;/code&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;MSG-API-005&lt;/td&gt;
 &lt;td style="text-align: left"&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;マジックナンバー&lt;/td&gt;
 &lt;td style="text-align: left"&gt;許可フォーマット外&lt;/td&gt;
 &lt;td style="text-align: left"&gt;&lt;code&gt;422 Unprocessable Entity&lt;/code&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;MSG-API-004&lt;/td&gt;
 &lt;td style="text-align: left"&gt;S3ファイルを削除（失敗時422）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;S3削除失敗&lt;/td&gt;
 &lt;td style="text-align: left"&gt;削除操作のエラー&lt;/td&gt;
 &lt;td style="text-align: left"&gt;&lt;code&gt;500 Internal Server Error&lt;/code&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;MSG-API-006&lt;/td&gt;
 &lt;td style="text-align: left"&gt;トランザクション不整合リスク&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;アップロード枚数上限&lt;/td&gt;
 &lt;td style="text-align: left"&gt;排他ロック取得後に5件以上&lt;/td&gt;
 &lt;td style="text-align: left"&gt;&lt;code&gt;409 Conflict&lt;/code&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;MSG-API-003&lt;/td&gt;
 &lt;td style="text-align: left"&gt;SELECT FOR UPDATEで競合防止後にチェック&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="マジックナンバー検証"&gt;マジックナンバー検証&lt;a class="anchor" href="#%e3%83%9e%e3%82%b8%e3%83%83%e3%82%af%e3%83%8a%e3%83%b3%e3%83%90%e3%83%bc%e6%a4%9c%e8%a8%bc"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;S3上のファイルの先頭バイト列を読み取り、実際のMIMEタイプを検証する。ファイルサイズはS3 HeadObjectメタデータから取得し、クライアント送信値に依存しない。&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th style="text-align: left"&gt;フォーマット&lt;/th&gt;
 &lt;th style="text-align: left"&gt;マジックナンバー&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;JPEG&lt;/td&gt;
 &lt;td style="text-align: left"&gt;&lt;code&gt;FF D8 FF&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;PNG&lt;/td&gt;
 &lt;td style="text-align: left"&gt;&lt;code&gt;89 50 4E 47 0D 0A 1A 0A&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;GIF&lt;/td&gt;
 &lt;td style="text-align: left"&gt;&lt;code&gt;47 49 46 38&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;WebP&lt;/td&gt;
 &lt;td style="text-align: left"&gt;&lt;code&gt;52 49 46 46&lt;/code&gt; (offset 0) + &lt;code&gt;57 45 42 50&lt;/code&gt; (offset 8)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="レスポンス"&gt;レスポンス&lt;a class="anchor" href="#%e3%83%ac%e3%82%b9%e3%83%9d%e3%83%b3%e3%82%b9"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="201-created"&gt;201 Created&lt;a class="anchor" href="#201-created"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th style="text-align: left"&gt;物理名&lt;/th&gt;
 &lt;th style="text-align: left"&gt;論理名&lt;/th&gt;
 &lt;th style="text-align: left"&gt;型&lt;/th&gt;
 &lt;th style="text-align: center"&gt;必須&lt;/th&gt;
 &lt;th style="text-align: left"&gt;説明&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;id&lt;/td&gt;
 &lt;td style="text-align: left"&gt;画像ID&lt;/td&gt;
 &lt;td style="text-align: left"&gt;string&lt;/td&gt;
 &lt;td style="text-align: center"&gt;✓&lt;/td&gt;
 &lt;td style="text-align: left"&gt;登録された画像のID&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;url&lt;/td&gt;
 &lt;td style="text-align: left"&gt;閲覧用URL&lt;/td&gt;
 &lt;td style="text-align: left"&gt;string&lt;/td&gt;
 &lt;td style="text-align: center"&gt;✓&lt;/td&gt;
 &lt;td style="text-align: left"&gt;画像の閲覧用URL&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;url&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="ステータスコード"&gt;ステータスコード&lt;a class="anchor" href="#%e3%82%b9%e3%83%86%e3%83%bc%e3%82%bf%e3%82%b9%e3%82%b3%e3%83%bc%e3%83%89"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th style="text-align: left"&gt;コード&lt;/th&gt;
 &lt;th style="text-align: left"&gt;説明&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;201&lt;/td&gt;
 &lt;td style="text-align: left"&gt;成功&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;404&lt;/td&gt;
 &lt;td style="text-align: left"&gt;S3上にファイルが存在しない&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;409&lt;/td&gt;
 &lt;td style="text-align: left"&gt;アップロード枚数上限超過（5件以上）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;422&lt;/td&gt;
 &lt;td style="text-align: left"&gt;マジックナンバー検証失敗（S3ファイルを削除）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;500&lt;/td&gt;
 &lt;td style="text-align: left"&gt;S3削除失敗またはDB登録失敗&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="内部処理シーケンス"&gt;内部処理シーケンス&lt;a class="anchor" href="#%e5%86%85%e9%83%a8%e5%87%a6%e7%90%86%e3%82%b7%e3%83%bc%e3%82%b1%e3%83%b3%e3%82%b9"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;pre class="mermaid"&gt;sequenceDiagram
 autonumber
 actor User
 participant Hono as Hono Middleware
 participant Domain as Domain Service
 participant S3 as S3 Client
 participant DB as Repository

 User-&amp;gt;&amp;gt;+Hono: 完了通知 (key, request_id, trace_id )
 Hono-&amp;gt;&amp;gt;Domain: 完了通知 (key, request_id, trace_id)
 Domain-&amp;gt;&amp;gt;+S3: HeadObject（ファイルの存在確認・メタデータ取得）
 S3--&amp;gt;&amp;gt;-Domain: metadata (fileSize, ContentType, ...)
 Domain-&amp;gt;&amp;gt;+S3: GetObject（先頭バイト取得）
 S3--&amp;gt;&amp;gt;-Domain: fileBytes
 Domain-&amp;gt;&amp;gt;Domain: マジックナンバー検証
 alt 検証失敗
 Domain-&amp;gt;&amp;gt;+S3: DeleteObject
 S3--&amp;gt;&amp;gt;-Domain: result
 Domain--&amp;gt;&amp;gt;Hono: Error (422 Unprocessable Entity)
 else 検証成功
 Domain-&amp;gt;&amp;gt;+DB: SELECT FOR UPDATE（排他ロック取得 + 件数確認）
 DB--&amp;gt;&amp;gt;-Domain: currentCount
 alt 5件以上
 Domain--&amp;gt;&amp;gt;Hono: Error (409 Conflict)
 else 5件未満
 Domain-&amp;gt;&amp;gt;+DB: INSERT メタデータ (id, key, fileSize, contentType, ...)
 DB--&amp;gt;&amp;gt;-Domain: result
 alt DB保存成功
 Domain--&amp;gt;&amp;gt;Hono: Success (201, id, url)
 else DB保存失敗
 Domain--&amp;gt;&amp;gt;Hono: Error (500 Internal Server Error)
 end
 end
 end
 Hono--&amp;gt;&amp;gt;-User: Response&lt;/pre&gt;&lt;h2 id="懸案事項"&gt;懸案事項&lt;a class="anchor" href="#%e6%87%b8%e6%a1%88%e4%ba%8b%e9%a0%85"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="s3とdb間の分散トランザクション"&gt;S3とDB間の分散トランザクション&lt;a class="anchor" href="#s3%e3%81%a8db%e9%96%93%e3%81%ae%e5%88%86%e6%95%a3%e3%83%88%e3%83%a9%e3%83%b3%e3%82%b6%e3%82%af%e3%82%b7%e3%83%a7%e3%83%b3"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;現状&lt;/strong&gt;:&lt;/p&gt;</description></item><item><title>画像一覧取得</title><link>https://Hitamuki.github.io/image-upload/design/api/images/api003-upload/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://Hitamuki.github.io/image-upload/design/api/images/api003-upload/</guid><description>&lt;h1 id="画像一覧取得"&gt;画像一覧取得&lt;a class="anchor" href="#%e7%94%bb%e5%83%8f%e4%b8%80%e8%a6%a7%e5%8f%96%e5%be%97"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;h2 id="id"&gt;ID&lt;a class="anchor" href="#id"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;api003-upload&lt;/p&gt;
&lt;h2 id="エンドポイント"&gt;エンドポイント&lt;a class="anchor" href="#%e3%82%a8%e3%83%b3%e3%83%89%e3%83%9d%e3%82%a4%e3%83%b3%e3%83%88"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th style="text-align: left"&gt;メソッド&lt;/th&gt;
 &lt;th style="text-align: left"&gt;パス&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;GET&lt;/td&gt;
 &lt;td style="text-align: left"&gt;&lt;code&gt;/images&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="概要"&gt;概要&lt;a class="anchor" href="#%e6%a6%82%e8%a6%81"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;アップロード済み画像のメタデータ一覧（ID・ファイル名）を取得する。画像の実体（バイナリ・閲覧用URL）はここでは取得しない。ユーザーがリストから画像を選択した時点で api004-upload により個別取得する。&lt;/p&gt;
&lt;h2 id="レスポンス"&gt;レスポンス&lt;a class="anchor" href="#%e3%83%ac%e3%82%b9%e3%83%9d%e3%83%b3%e3%82%b9"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="200-ok"&gt;200 OK&lt;a class="anchor" href="#200-ok"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th style="text-align: left"&gt;物理名&lt;/th&gt;
 &lt;th style="text-align: left"&gt;論理名&lt;/th&gt;
 &lt;th style="text-align: left"&gt;型&lt;/th&gt;
 &lt;th style="text-align: center"&gt;必須&lt;/th&gt;
 &lt;th style="text-align: left"&gt;説明&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;id&lt;/td&gt;
 &lt;td style="text-align: left"&gt;画像ID&lt;/td&gt;
 &lt;td style="text-align: left"&gt;string&lt;/td&gt;
 &lt;td style="text-align: center"&gt;✓&lt;/td&gt;
 &lt;td style="text-align: left"&gt;登録された画像のID&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;fileName&lt;/td&gt;
 &lt;td style="text-align: left"&gt;ファイル名&lt;/td&gt;
 &lt;td style="text-align: left"&gt;string&lt;/td&gt;
 &lt;td style="text-align: center"&gt;✓&lt;/td&gt;
 &lt;td style="text-align: left"&gt;アップロードされたファイル名&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;createdAt&lt;/td&gt;
 &lt;td style="text-align: left"&gt;作成日時&lt;/td&gt;
 &lt;td style="text-align: left"&gt;string&lt;/td&gt;
 &lt;td style="text-align: center"&gt;✓&lt;/td&gt;
 &lt;td style="text-align: left"&gt;ISO-8601形式の作成日時&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;fileName&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;createdAt&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;iso-8601&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="ステータスコード"&gt;ステータスコード&lt;a class="anchor" href="#%e3%82%b9%e3%83%86%e3%83%bc%e3%82%bf%e3%82%b9%e3%82%b3%e3%83%bc%e3%83%89"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th style="text-align: left"&gt;コード&lt;/th&gt;
 &lt;th style="text-align: left"&gt;説明&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;200&lt;/td&gt;
 &lt;td style="text-align: left"&gt;成功（0件の場合は空配列）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="内部処理シーケンス"&gt;内部処理シーケンス&lt;a class="anchor" href="#%e5%86%85%e9%83%a8%e5%87%a6%e7%90%86%e3%82%b7%e3%83%bc%e3%82%b1%e3%83%b3%e3%82%b9"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;pre class="mermaid"&gt;sequenceDiagram
 autonumber
 actor User
 participant Hono as Hono Middleware
 participant Domain as Domain Service
 participant DB as Repository

 User-&amp;gt;&amp;gt;+Hono: 一覧取得リクエスト
 Hono-&amp;gt;&amp;gt;+Domain: 一覧取得リクエスト
 Domain-&amp;gt;&amp;gt;+DB: findAll()
 DB--&amp;gt;&amp;gt;-Domain: [{id, fileName, createdAt}]
 Domain--&amp;gt;&amp;gt;-Hono: Success
 Hono--&amp;gt;&amp;gt;-User: 200 OK&lt;/pre&gt;&lt;h2 id="懸案事項"&gt;懸案事項&lt;a class="anchor" href="#%e6%87%b8%e6%a1%88%e4%ba%8b%e9%a0%85"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="ユーザーごとの絞り込み未実装"&gt;ユーザーごとの絞り込み未実装&lt;a class="anchor" href="#%e3%83%a6%e3%83%bc%e3%82%b6%e3%83%bc%e3%81%94%e3%81%a8%e3%81%ae%e7%b5%9e%e3%82%8a%e8%be%bc%e3%81%bf%e6%9c%aa%e5%ae%9f%e8%a3%85"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;現状&lt;/strong&gt;: 全ユーザーの画像を返却している&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;影響&lt;/strong&gt;: 他ユーザーの画像が見えてしまう、プライバシー問題&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;対応方針&lt;/strong&gt;: 認証ミドルウェアから取得したユーザーIDで絞り込み&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="パフォーマンス問題"&gt;パフォーマンス問題&lt;a class="anchor" href="#%e3%83%91%e3%83%95%e3%82%a9%e3%83%bc%e3%83%9e%e3%83%b3%e3%82%b9%e5%95%8f%e9%a1%8c"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;現状&lt;/strong&gt;: 全件取得でページネーションなし&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;影響&lt;/strong&gt;: 画像数増加時のレスポンス悪化、メモリ消費&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;対応方針&lt;/strong&gt;: ページネーションとキャッシュ導入&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="tbd"&gt;TBD&lt;a class="anchor" href="#tbd"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="並び順とソート機能"&gt;並び順とソート機能&lt;a class="anchor" href="#%e4%b8%a6%e3%81%b3%e9%a0%86%e3%81%a8%e3%82%bd%e3%83%bc%e3%83%88%e6%a9%9f%e8%83%bd"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;作成日順のデフォルトソート&lt;/li&gt;
&lt;li&gt;ファイル名順、サイズ順のソートオプション&lt;/li&gt;
&lt;li&gt;昇順・降順の指定&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="検索機能拡張"&gt;検索機能拡張&lt;a class="anchor" href="#%e6%a4%9c%e7%b4%a2%e6%a9%9f%e8%83%bd%e6%8b%a1%e5%bc%b5"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ファイル名の部分一致検索&lt;/li&gt;
&lt;li&gt;メタデータによる検索（将来的な機能拡張）&lt;/li&gt;
&lt;li&gt;タグによる絞り込み&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>画像閲覧用URL取得</title><link>https://Hitamuki.github.io/image-upload/design/api/images/api004-upload/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://Hitamuki.github.io/image-upload/design/api/images/api004-upload/</guid><description>&lt;h1 id="画像閲覧用url取得"&gt;画像閲覧用URL取得&lt;a class="anchor" href="#%e7%94%bb%e5%83%8f%e9%96%b2%e8%a6%a7%e7%94%a8url%e5%8f%96%e5%be%97"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;h2 id="id"&gt;ID&lt;a class="anchor" href="#id"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;api004-upload&lt;/p&gt;
&lt;h2 id="エンドポイント"&gt;エンドポイント&lt;a class="anchor" href="#%e3%82%a8%e3%83%b3%e3%83%89%e3%83%9d%e3%82%a4%e3%83%b3%e3%83%88"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th style="text-align: left"&gt;メソッド&lt;/th&gt;
 &lt;th style="text-align: left"&gt;パス&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;GET&lt;/td&gt;
 &lt;td style="text-align: left"&gt;&lt;code&gt;/images/:id&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="概要"&gt;概要&lt;a class="anchor" href="#%e6%a6%82%e8%a6%81"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;指定した画像IDに対応する閲覧用Presigned URLを取得する。&lt;/p&gt;
&lt;h2 id="リクエスト"&gt;リクエスト&lt;a class="anchor" href="#%e3%83%aa%e3%82%af%e3%82%a8%e3%82%b9%e3%83%88"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="パスパラメータ"&gt;パスパラメータ&lt;a class="anchor" href="#%e3%83%91%e3%82%b9%e3%83%91%e3%83%a9%e3%83%a1%e3%83%bc%e3%82%bf"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th style="text-align: left"&gt;物理名&lt;/th&gt;
 &lt;th style="text-align: left"&gt;論理名&lt;/th&gt;
 &lt;th style="text-align: left"&gt;型&lt;/th&gt;
 &lt;th style="text-align: center"&gt;必須&lt;/th&gt;
 &lt;th style="text-align: left"&gt;説明&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;id&lt;/td&gt;
 &lt;td style="text-align: left"&gt;画像ID&lt;/td&gt;
 &lt;td style="text-align: left"&gt;string (UUID)&lt;/td&gt;
 &lt;td style="text-align: center"&gt;✓&lt;/td&gt;
 &lt;td style="text-align: left"&gt;閲覧したい画像のID&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="レスポンス"&gt;レスポンス&lt;a class="anchor" href="#%e3%83%ac%e3%82%b9%e3%83%9d%e3%83%b3%e3%82%b9"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="200-ok"&gt;200 OK&lt;a class="anchor" href="#200-ok"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th style="text-align: left"&gt;物理名&lt;/th&gt;
 &lt;th style="text-align: left"&gt;論理名&lt;/th&gt;
 &lt;th style="text-align: left"&gt;型&lt;/th&gt;
 &lt;th style="text-align: center"&gt;必須&lt;/th&gt;
 &lt;th style="text-align: left"&gt;説明&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;url&lt;/td&gt;
 &lt;td style="text-align: left"&gt;閲覧用URL&lt;/td&gt;
 &lt;td style="text-align: left"&gt;string&lt;/td&gt;
 &lt;td style="text-align: center"&gt;✓&lt;/td&gt;
 &lt;td style="text-align: left"&gt;画像の閲覧用Presigned URL&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;expiresAt&lt;/td&gt;
 &lt;td style="text-align: left"&gt;有効期限&lt;/td&gt;
 &lt;td style="text-align: left"&gt;string&lt;/td&gt;
 &lt;td style="text-align: center"&gt;✓&lt;/td&gt;
 &lt;td style="text-align: left"&gt;URLの有効期限（ISO-8601形式）&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;url&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;expiresAt&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;iso-8601&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="ステータスコード"&gt;ステータスコード&lt;a class="anchor" href="#%e3%82%b9%e3%83%86%e3%83%bc%e3%82%bf%e3%82%b9%e3%82%b3%e3%83%bc%e3%83%89"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th style="text-align: left"&gt;コード&lt;/th&gt;
 &lt;th style="text-align: left"&gt;説明&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;200&lt;/td&gt;
 &lt;td style="text-align: left"&gt;成功&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td style="text-align: left"&gt;404&lt;/td&gt;
 &lt;td style="text-align: left"&gt;指定IDの画像が存在しない&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="内部処理シーケンス"&gt;内部処理シーケンス&lt;a class="anchor" href="#%e5%86%85%e9%83%a8%e5%87%a6%e7%90%86%e3%82%b7%e3%83%bc%e3%82%b1%e3%83%b3%e3%82%b9"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;pre class="mermaid"&gt;sequenceDiagram
 autonumber
 actor User
 participant Hono as Hono Middleware
 participant Domain as Domain Service
 participant DB as Repository
 participant S3 as S3 Client

 User-&amp;gt;&amp;gt;+Hono: 閲覧URLリクエスト (id)
 Hono-&amp;gt;&amp;gt;+Domain: 閲覧URLリクエスト (id)
 Domain-&amp;gt;&amp;gt;+DB: findById(id)
 DB--&amp;gt;&amp;gt;-Domain: image (s3Key)
 Domain-&amp;gt;&amp;gt;+S3: getSignedUrl (GetObject, s3Key, expires=3600)
 S3--&amp;gt;&amp;gt;-Domain: url
 Domain--&amp;gt;&amp;gt;-Hono: Success (url, expiresAt)
 Hono--&amp;gt;&amp;gt;-User: 200 OK&lt;/pre&gt;&lt;h2 id="懸案事項"&gt;懸案事項&lt;a class="anchor" href="#%e6%87%b8%e6%a1%88%e4%ba%8b%e9%a0%85"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="アクセス権限の未実装"&gt;アクセス権限の未実装&lt;a class="anchor" href="#%e3%82%a2%e3%82%af%e3%82%bb%e3%82%b9%e6%a8%a9%e9%99%90%e3%81%ae%e6%9c%aa%e5%ae%9f%e8%a3%85"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;現状&lt;/strong&gt;: 画像IDさえ知っていれば誰でも閲覧可能&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;影響&lt;/strong&gt;: 他ユーザーのプライベート画像にアクセス可能になる&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;対応方針&lt;/strong&gt;: 画像所有者のみアクセス許可の認可チェック&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="tbd"&gt;TBD&lt;a class="anchor" href="#tbd"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="アクセス制御の細粒度化"&gt;アクセス制御の細粒度化&lt;a class="anchor" href="#%e3%82%a2%e3%82%af%e3%82%bb%e3%82%b9%e5%88%b6%e5%be%a1%e3%81%ae%e7%b4%b0%e7%b2%92%e5%ba%a6%e5%8c%96"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;画像ごとの公開・非公開設定&lt;/li&gt;
&lt;li&gt;特定ユーザーへのアクセス許可機能&lt;/li&gt;
&lt;li&gt;一時的なアクセスURL発行&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="キャッシュ戦略"&gt;キャッシュ戦略&lt;a class="anchor" href="#%e3%82%ad%e3%83%a3%e3%83%83%e3%82%b7%e3%83%a5%e6%88%a6%e7%95%a5"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;CloudFrontによるCDNキャッシュ&lt;/li&gt;
&lt;li&gt;閲覧URLのキャッシュ期間最適化&lt;/li&gt;
&lt;li&gt;画像の最適化（リサイズ）とキャッシュ&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>