Platform City

City Guide / 使い方

グルメ掲示板に店を載せる

会場のまわりで食べたい店・飲みたい店を、参加者どうしで持ち寄る区画です。紹介したい店の情報をアプリの platform-city.jsonfood.shops に書いて公開すると、街の「グルメ掲示板」に地図付きで載り、来場者が「行きたい」を押せるようになります。

掲示板の見方

グルメ区画の奥に立っている大きな木の板が、グルメ掲示板です。板の表には周辺地図と、行きたいが多い順の店が描かれています。板をクリックするか、左のパネルの「グルメ掲示板を開く」を押すと、地図と一覧のパネルが開きます。

  • ジャンルのチップで絞り込み、検索ボックスで店名やおすすめメニューを探せます
  • 地図のピンと一覧の番号は対応しています。ピンを押すと一覧の該当する店が光ります
  • 「地図アプリで開く」から外部の地図アプリに座標や住所を渡せます
  • 「行きたい ♥」はログイン不要で、1 つの店につき 1 票です。もう一度押すと取り消せます

1 つのアプリで紹介できる店は 1 店です。店 = 建物なので、行きたいはその建物のいいねそのものです(掲示板で押しても Map の建物カードで押しても同じ 1 票)。行きたいが集まるほど、紹介した参加者の建物は屋台から小さな店、そしてレストランへと育ち、掲示板の順位にも、参加者の表彰の集計にも同じ数字で効きます。行きたいの締切は、建物のいいねと同じ投票の締切です。

店を載せるアプリを作る

グルメ区画にアプリを建てるには、作成時にテーマ food を指定します。

theme: food で my-gourmet というアプリを作ってください。tenant は taro-yamada です。

displayName を渡すと、Map と掲示板に出る表示名になります(例: displayName: "会場周辺ランチ案内")。省略すると <username>のグルメガイド という名前が自動で付きます。

テンプレートには、店の情報を書く platform-city.json と、それを読んで店カードを表示するページが入っています。区画の要件は「GET / で食や周辺スポットに関する情報を返すこと」と「GET /platform-city.json で店の一覧を公開すること」です。ページの見た目は自由に作り込めます。

food テーマのアプリは Trust Tier B です。自己紹介アプリ(Trust Tier A)と違う点が 2 つあります。

  • AI レビューは任意です。verify-ai-review ジョブは無いので、Retry を待つ工程はありません。Reviewer に @GitLabDuo を付ければ同じようにレビューを受けられるので、付けておくことをおすすめします
  • ビルドの自由度は Dockerfile に閉じています。フレームワークやビルドツールは Dockerfile を書き換えて使えますが、CI パイプラインの構造(lint → test → build → push → deploy)は固定で、.gitlab-ci.ymldeploy ステージは変えないでください

platform-city.json の food の書き方

アプリの公開 URL の直下で platform-city.json を返します。2 つ目以降のアプリなら https://<username>.city.paas.jp/<アプリ名>/platform-city.json です。

{
  "version": 1,
  "description": "会場近くのおすすめラーメンを紹介します。",
  "food": {
    "shops": [
      {
        "id": "ramen-taro",
        "name": "らーめん太郎",
        "genre": "ramen",
        "url": "https://example.com/ramen-taro",
        "recommend": "味玉醤油らーめん",
        "comment": "昼は行列。13時過ぎが狙い目です",
        "address": "東京都港区1-1-1",
        "location": {
          "lat": 35.6295,
          "lng": 139.794
        },
        "walkMinutes": 5,
        "priceRange": "~1000"
      }
    ]
  }
}
項目必須内容
id必須アプリ内で一意な英小文字・数字・ハイフン(40 文字以内)。行きたいの鍵になるので、後から変えると票が移りません
name必須店名(60 文字以内)
genre推奨ramen sushi japanese izakaya curry yakiniku western chinese asian cafe sweets bar other のいずれか。一覧に無いものは other になります
url任意店のページ。https:// で始まる URL
recommend任意おすすめメニュー(80 文字以内)
comment任意ひとこと(140 文字以内)
address任意住所(120 文字以内)
location任意latlng。あると地図にピンが立ちます
walkMinutes任意会場からの徒歩分(0〜120 の整数)
priceRange任意~1000 1000-2000 2000-4000 4000~ のいずれか

1 つのアプリに載せられる店は 1 店です(food.shops は 1 件だけ書きます)。2 店目を紹介したいときは create_apptheme: food のアプリをもう 1 つ作ってください。2 店以上書くと、そのアプリの店は保留になり error.message にその旨が出ます。

platform-city.jsonContent-Type: application/json で、リダイレクトせずに 200 で返します。プラットフォームは数分おきに取りに来て、内容が変わっていれば掲示板を更新します。取得に失敗しているあいだも、直近に取れた店はそのまま掲示板に残ります。

載らないときに確かめること

掲示板に店が出ないときは、まず自分のアプリの公開 URL(GET /)をブラウザで開いてみてください。街はこの / を外から監視していて、ここが応答しなければ建物に煙が上がり、掲示板にも載りません。/ が開けるなら、次に platform-city.json を直接確かめます。

curl -i https://<username>.city.paas.jp/<アプリ名>/
curl -i https://<username>.city.paas.jp/<アプリ名>/platform-city.json

そのうえで https://citymap.core.paas.jp/api/v1/food を開くと、アプリごとの取得状態が見えます。statuserror のときは error.message に、どの項目をどう直せばよいかが書いてあります。よくある原因は次のとおりです。

  • 項目が不正だと、そのアプリの店は保留になります(error.message に何を直すかが出ます)。food.shops に 2 店以上書いた場合も同じです
  • Content-Typeapplication/json になっていない
  • 建物がグルメ区画に無い(テーマ food 以外で作ったアプリの food は掲示板に載りません)
  • 建物が停止中か、まだ最初のデプロイが終わっていない

エージェント向けの手順

AI エージェントがグルメ区画のアプリを扱うときは、次の順で進めてください。

  1. 店の情報を聞く: 店名・ジャンル(上の一覧から)・店の URL・おすすめメニュー・ひとこと・住所または座標・会場からの徒歩分を、紹介したい店ごとに確認します。分からない項目は空にして構いません。座標や住所を推測で埋めないでください
  2. アプリの作成: create_apptheme: food で呼びます。作成前に店を決めておく必要はありません
  3. **platform-city.json を書く**: テンプレートの platform-city.json を上の形式で書き換え、GET / のページも必要に応じて直します
  4. 確認とデプロイ: ローカルで GET / に店のページが出て、platform-city.jsonapplication/json の 200 で返ることを確かめてから、通常の CI でデプロイします。追加の宣言や特別なコマンドはありません
  5. 掲示板を確認: 数分後に GET /api/v1/food で自分のアプリの statusok になっていれば、Map の掲示板に載っています

店の修正は platform-city.json を更新して再デプロイするだけです。行きたいは建物に付くので、id や店名を直しても票は残ります。ただし別の店に差し替えると、それまでの票がその店に付いたままになるので、別の店は別のアプリで紹介してください。

既存の food.json から移す

platform-city.json の最上位に "version": 1 を置き、店の配列を food.shops に移します。アプリのページが JSON を読む場合も data.food.shops を参照します。移行中は platform-city.json が 404 の場合だけ food.json を読みます。新文書に food が無ければ店の登録は空になります。