toyota
|
5bf01aecec
|
docs(auth-plugin): usage-guide のスキル一覧をフル同期(PR #148 レビュー Minor 対応)
セクション 2「基本フロー」のコマンド注釈、セクション 3「実装スキル」を
6 スキルすべて掲載した一覧表に差し替え。新規追加した firebase-auth-mfa /
firebase-auth-emulator と既存の firebase-auth-design / auth-requirements-extraction
を usage-guide の本流(プロンプト例より前)から参照できるようにした。
- セクション 2 のフロー注釈:
/auth-design: authentication-architect + firebase-auth-design
/implement: firebase-auth-setup / firebase-auth-frontend /
firebase-auth-mfa / firebase-auth-emulator
- セクション 3 を「認証スキル一覧」に差し替え、フェーズ×責務×主要なポイント
(2 段階失効・3 パターンガード・auth_time 仕様・SMS MFA でローカル E2E)を表で。
関連: PR #148 (usage-guide にプロンプト例を追加) のレビュー Minor 対応。
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
2026-05-26 13:04:53 +09:00 |
|
Yoichi Toyota
|
9c2f65ed2b
|
Merge pull request #148 from xtone/docs/auth-plugin-usage-prompts
docs(auth-plugin): usage-guide にプロンプト例(T-021 再パイロット実例)を追加
|
2026-05-26 13:03:49 +09:00 |
|
toyota
|
880f8bac64
|
docs(auth-plugin): usage-guide にプロンプト例(T-021 再パイロット実例)を追加
各フェーズで実際にどのような指示文を入力すれば適切なスキル/レシピが起動するかを、
T-021 再パイロット(医療×MFA required×Next.js+Rails)の実プロンプトを引用して
9 セクションで例示。
- 7.1 要件定義: 案件前提と DP-007/008 を undecided で引き継ぎ
- 7.2 設計: DP-007/008/責務仕分け/セッション戦略/ページ3パターンを一度に決定
- 7.3 スキーマ検証: B-01 解消の確認(ネガティブ検証込み)
- 7.4 backend 実装: setup + mfa の Rails レシピ + 2 段階失効
- 7.5 frontend 実装: AuthGate + 3 パターン + /login/signup 分離
- 7.6 ローカル E2E: emulator スキル + Docker + SMS MFA で MFA required を検証
- 7.7 ブラウザ動作確認: 最小 UI 実装
- 7.8 不具合報告: 実機再現 + 原因特定 + スキル根本対応をセットで指示
- 7.9 プロンプト設計のコツ: 判断は人間/実装は AI、横断機能は新スキル化など
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
2026-05-26 12:55:26 +09:00 |
|
Yoichi Toyota
|
7b3ba75c0e
|
Merge pull request #147 from xtone/feat/T-021-fix-mfa-revoke
fix(T-021): MFA変更時の失効をsoft失効に修正(auth_time が enroll で更新されない仕様への対応)
|
2026-05-26 12:49:48 +09:00 |
|
Yoichi Toyota
|
86ccad3439
|
Merge pull request #146 from xtone/feat/T-021-frontend-page-access
feat(T-021): フロントエンドの3パターンページ振る舞いを既定化
|
2026-05-26 12:36:21 +09:00 |
|
toyota
|
257624d91a
|
fix(T-021): 旧メソッド名 revoke_tokens! の残存箇所をスキル全体で整合
Vertex AI レビュー指摘(Major 3 + Minor 1): 差分外の既存テキストに旧名が残存:
- firebase-auth-mfa/SKILL.md L59: backend.revoke_tokens → revoke_refresh_tokens
- firebase-auth-mfa/SKILL.md L78: 手順4 revoke_tokens → revoke_refresh_tokens
- firebase-auth-setup/references/rails.md L233: 旧 user.revoke_tokens! 参照を
hard_revoke_tokens! / revoke_refresh_tokens! の使い分けに更新
- firebase-auth-mfa/references/rails.md L5: 土台参照を hard_revoke_tokens! /
revoke_refresh_tokens! に更新
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
2026-05-26 12:35:57 +09:00 |
|
toyota
|
3d7dea3ab7
|
fix(T-021): MFA変更時の失効をsoft失効に修正(auth_time が enroll で更新されない仕様への対応)
T-021 再パイロットの実機動作確認で発見した不具合の根本対応。
不具合: MFA enrollment → /auth/mfa/changed → 直後に /consultations が
401(token revoked) を返す(実機で Playwright 再現済み)。
原因: Firebase の auth_time クレームは MFA enrollment では更新されない
(最後の認証イベント時刻のまま)。一方、スキル側は MFA 変更時にサーバ側
tokens_valid_after = now で即拒否する設計になっていたため、enroll 直後の
同セッションが auth_time < tokens_valid_after で 401 になっていた。
修正: トークン失効を 2 段階に分離。
- hard 失効(退会・パスワード変更・不正検知): tokens_valid_after = now
+ IaaS refresh 失効(即拒否)
- soft 失効(MFA 変更): IaaS refresh のみ失効。サーバ側 tokens_valid_after
は触らない(同セッション維持、他デバイスは次回更新で締め出し)
反映先:
- firebase-auth-setup/SKILL.md: 運用契約3を「2段階の失効」に改訂
- firebase-auth-setup/references/rails.md: User#hard_revoke_tokens! と
revoke_refresh_tokens! の分離、判定ロジックは据え置き、表で使い分け明示
- firebase-auth-mfa/SKILL.md: backend契約 revoke_tokens → revoke_refresh_tokens、
既知の制約に「auth_time は enrollment で更新されない」+「emulator は
emailVerified=true が前提」を追記
- firebase-auth-mfa/references/rails.md: MfaController#changed を soft 失効に変更
関連: T-021 / PR #145 (firebase-auth-emulator)
実機検証: ~/RubymineProjects/t-021-repilot-telemedicine で Playwright 再現
→ サンプル backend を修正 → /consultations 200 で復旧確認済み
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
2026-05-26 12:30:03 +09:00 |
|
Yoichi Toyota
|
41a44d03d3
|
Merge pull request #145 from xtone/feat/T-021-emulator-skill
feat(T-021): ローカル検証スキル firebase-auth-emulator を新設
|
2026-05-26 12:13:22 +09:00 |
|
Yoichi Toyota
|
c3b1be6aec
|
Merge pull request #144 from xtone/docs/T-021-repilot-telemedicine
docs(T-021): MVP 再パイロット報告書(High 解消後の再検証)
|
2026-05-26 12:13:02 +09:00 |
|
toyota
|
55b4f5c38a
|
feat(T-021): フロントエンドの3パターンページ振る舞いを既定化
要望: スキルが既定で「protected-only / public-aware / guest-only」の3パターンを
提供し、/login と /signup を別ページとして相互リンクし callback を引き継ぐ。
MFA enrollment と /settings/* は認証必須を既定とする。要件で別指定があれば
要件優先(warn_and_document)。
反映先:
- firebase-auth-frontend/SKILL.md:
- 「デフォルトページ構成と認証アクセス制御」節を追加
- 3 パターンの定義、デフォルトページ一覧、callback URL 仕様(open redirect 防止)、
ガード実装契約(FW 非依存)
- firebase-auth-frontend/references/nextjs.md:
- <AuthGate type="protected|public-aware|guest"> 雛形
- /login /signup /mfa/enroll /settings(layout) / のスケルトン(相互リンク+callback)
- BFF 採用時の middleware 例
- firebase-auth-frontend/references/hotwire.md:
- PageAccessControl concern(protected_only/guest_only/authenticate_user!/redirect_if_authenticated/safe_callback)
- SessionsController(/login) と RegistrationsController(/signup) を別 controller
で相互リンク + callback 引き継ぎ、MfaEnrollmentsController/SettingsController は
protected_only、HomeController は public-aware
- auth-requirements-extraction/SKILL.md: ページ単位の認証要否チェックリスト追加
- firebase-auth-design/auth-section.template.md: ページ単位アクセス制御表を追加
(案件のページを A/B/C で記入、逸脱は decision_record に根拠を残す)
関連: T-021 / DP-008(MFA) / ADR-002(セッション戦略)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
2026-05-26 12:11:15 +09:00 |
|
toyota
|
17bc7e0d06
|
docs(T-021): Phase 2(docker emulator で E2E 動作確認)を再パイロット報告に追記
ユーザー要望「実際に動かして確認」「Docker でエミュレーター環境」に応えた
Phase 2 の結果を report に追加。
- 構成: docker compose(auth-emulator 14.4.0 + JRE17 / Rails 8.1 / Next.js)
- E2E 12 ステップ全 PASS:
- MFA required 強制(403 mfa_required) ←実機で発火
- SMS MFA enrollment/challenge(verificationCodes REST 取得)
- MFA 付きトークンで保護リソース 200
- ロール認可(患者=自分のみ / 医師=全件)
- 退会→204 + 診療データ保持(ADR-002 分離)
- 退会後再ログイン拒否(F-7)
- 実証: RN-3「MFA E2E は実 Firebase 要」を SMS MFA で実質解消
- 派生発見: emulator MFA enrollment は emailVerified=true が前提
- セクション番号(Rollout/関連)を6→7, 7→8に繰り上げ
関連: PR #145(firebase-auth-emulator スキル新設)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
2026-05-26 11:22:24 +09:00 |
|
toyota
|
9670701a53
|
fix(T-021): emulator スキルのレビュー指摘3件に対応(Major)
Vertex AI レビュー指摘:
- Major #1 (nextjs.md L31): _canInitEmulator ガードの優先順位が紛らわしい
→ try/catch で HMR 再評価時の2回目接続エラーを握りつぶす素直な形に置換
- Major #2 (docker-compose.md L33): firebase-tools のバージョン未固定(再現性)
→ ARG FIREBASE_TOOLS_VERSION でピン留め、更新は B-06 で公式リリース確認と注記
- Major #3 (rails.md L21): 本番混入ガードがコードテンプレートに含まれない
→ app_auth.rb 末尾に「production && emulator? なら abort」を追加(推奨止まりから昇格)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
2026-05-26 11:07:06 +09:00 |
|
toyota
|
55efafa990
|
feat(T-021): ローカル検証スキル firebase-auth-emulator を新設
T-021 再パイロットでの「実際に動かして確認」要望に応えるため、Auth Emulator
を Docker で起動して E2E 検証する横断スキルを新設する。backend/client/MFA
にまたがるため既存スキルではなく新スキルに集約(MFA と同じ論理)。
調査の結果:
- SMS(phone) MFA はエミュレーター対応 → MFA required の E2E がローカルで動く
- TOTP MFA はエミュレーター非対応(firebase-tools #6224)
- ID トークンは unsigned → backend は EMULATOR_HOST 検出時に署名検証スキップ
- Admin REST は http://EMULATOR_HOST/identitytoolkit.googleapis.com + Bearer owner
成果物:
- SKILL.md: 接続パラメータ・契約(backend/client)・手順・既知の制約・判断ポイント
- references/docker-compose.md: firebase.json / 自前 Dockerfile(node+JRE) / compose
- references/rails.md: verify_token 署名スキップ + Admin REST host 切替 + 本番混入防止
- references/nextjs.md: connectAuthEmulator + SMS MFA E2E + SMS コード REST 取得
- 既存スキル(setup/frontend/mfa)/auth-plugin-guide に相互参照を追加
関連: T-021 / DP-007 / DP-008 / firebase-tools #6224
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
2026-05-26 10:59:09 +09:00 |
|
toyota
|
b89df53199
|
docs(T-021): B-05(F-9) の解消実証行を再パイロット報告に追加
Vertex AI レビュー指摘(Major): セクション6で B-05 を Rollout Go 根拠に
挙げているのに、セクション4の解消実証テーブルに B-05 行が欠落していた。
F-9(DP-27 follow-up / CLAUDE.md→skill化)行を追加。B-05 は構造/規約改訂で
実機テストではなく「skill ベース運用 context でプラグインが回るか」の確認
という性質を明記し、判定根拠と実証の整合を取った。
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
2026-05-26 10:33:00 +09:00 |
|
toyota
|
e39708e981
|
docs(T-021): MVP 再パイロット報告書を追加(High 解消後の再検証)
T-022 パイロットで発見した穴を訂正バックログで解消した後の再ドッグフード結果。
前回(みんなの読書会/BtoC/Rails のみ)と条件を変え、医療「オンライン診療・問診」
×MFA required×Next.js+Rails×ロール別認可で /req-collect→/design→/implement を通した。
実証:
- F-1/B-06 環境前提: rbenv 3.3.6/Rails 8.1 で回避(明文化手順どおり)
- F-2/B-01 スキーマ本実装: requirements/design 検証 PASS + ネガティブ検証で検証が効く
- F-3/B-02 運用詳細: 退会Admin削除/証明書キャッシュ/失効を実装・テスト
- F-4/B-03 責務仕分け: design.responsibility_split を明示、実装が分割どおり
- F-5/B-04 MFA: firebase-auth-mfa で required を backend強制+client、テスト通過
- B-10 frontend: firebase-auth-frontend(nextjs) で tsc/build 通過
- backend 9 tests 0 failures / zeitwerk OK / frontend tsc EXIT0・next build 成功
新発見(Med2/Low1): RN-1 セッション戦略の DP 未登録(pending-decisions に起票)/
RN-2 スキーマ検証が手動(B-07未整備) / RN-3 MFA E2E は実 Identity Platform 必要。
High な穴は出ず、Rollout 着手を支持する材料が揃った(最終判定は豊田)。
関連: T-021 / T-022 / DP-007/008 / B-01,02,03,04,06,10
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
2026-05-25 20:10:04 +09:00 |
|
Yoichi Toyota
|
0c5a9809e7
|
Merge pull request #143 from xtone/feat/B-04-mfa-skill
feat(B-04): MFA(DP-008)実装スキル firebase-auth-mfa を新設
|
2026-05-25 18:12:03 +09:00 |
|
toyota
|
804fe90490
|
fix(B-04): QR issuer をレシピ間でプレースホルダに統一
Vertex AI レビュー指摘(Minor): hotwire.md の generateQrCodeUrl issuer が
サンプル案件名ハードコードで nextjs.md と不整合。両レシピを "<アプリ名>"
プレースホルダに統一し、案件ごとに置換する旨をコメントで明示。
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
2026-05-25 17:15:02 +09:00 |
|
toyota
|
6187a0760a
|
fix(B-04): hotwire の SMS challenge を送信/入力の2段に分割
Vertex AI レビュー指摘(Major): SMS の第2要素コードは SMS 送信後にしか
得られないため、resolveChallenge で code を事前受領する形は不正。Next.js
版と同じく startSmsChallenge(送信→verificationId 取得)/ completeSmsChallenge
(受信コード入力)の2段に分離し、TOTP は resolveTotpChallenge に分けた。
SKILL.md の契約注記と Stimulus 例も整合させた。
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
2026-05-25 17:09:20 +09:00 |
|
toyota
|
6e4917bc25
|
feat(B-04): MFA(DP-008)実装スキル firebase-auth-mfa を新設
T-022 パイロット発見 F-5 / Issue #131 の解消。MFA は登録/追加認証=client、
検証・管理者強制・失効=backend、第2要素検証=iaas にまたがる横断機能のため、
backend専用(firebase-auth-setup)/client専用(firebase-auth-frontend)とは別の
新スキルに集約する。
- SKILL.md: 言語非依存契約 + mfa_requirement(required/optional/admin_only/none)
の実装マッピング + 既知の制約(Identity Platform 必須 等) + 判断ポイント
- references/rails.md (backend): firebase.sign_in_second_factor 検証 / require_mfa!
/ enrollment 状態確認(Identity Toolkit REST mfaInfo) / 変更時のトークン失効 / TestAdapter
- references/hotwire.md, nextjs.md (client): TOTP/SMS の enrollment・challenge・unenroll
- 既存スキル/テンプレに相互参照を追加、backlog/pilot-report の B-04/F-5 を更新
関連: DP-008 / SKL-12 / CONV-14 / T-021 / T-022
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
2026-05-25 17:03:21 +09:00 |
|
Yoichi Toyota
|
7f7637ec61
|
Merge pull request #142 from xtone/feat/B-10-frontend-auth-skill
feat(B-10 / #141): フロントエンド認証実装スキル(Hotwire / Next.js)
|
2026-05-25 16:44:22 +09:00 |
|
toyota
|
0e3730384e
|
fix(B-10): use ternary for getIdToken in hotwire withdraw for consistency
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
2026-05-25 16:38:52 +09:00 |
|
toyota
|
fc7e982c0c
|
fix(B-10): persist emailForSignIn and return Promise from getIdToken in recipes
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
2026-05-25 16:27:43 +09:00 |
|
toyota
|
a87794a805
|
fix(B-10): implement signInWithEmailLink/completeEmailLink in frontend recipes
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
2026-05-25 16:22:13 +09:00 |
|
toyota
|
3f96a20937
|
fix(B-10): in-memory token persistence and withdraw() example in frontend recipes
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
2026-05-25 16:17:04 +09:00 |
|
toyota
|
ccbb690dbf
|
feat(B-10): add firebase-auth-frontend skill with hotwire and nextjs recipes
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
2026-05-25 16:11:38 +09:00 |
|
Yoichi Toyota
|
b41274453a
|
Merge pull request #140 from xtone/feat/B-03-design-responsibility
feat(B-03 / #130): design に責務仕分け(responsibility_split)を追加
|
2026-05-25 16:03:30 +09:00 |
|
toyota
|
e235214f81
|
fix(B-03): align template owner values to schema enum (single value)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
2026-05-25 15:59:29 +09:00 |
|
toyota
|
23d9681f86
|
feat(B-03): add responsibility_split (backend/client/iaas) to design schema and template
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
2026-05-25 15:52:12 +09:00 |
|
Yoichi Toyota
|
cc5308eb38
|
Merge pull request #139 from xtone/feat/B-06-env-prereq
docs(B-06 / #129): 実行環境前提の明文化(バージョン非固定・公式最新方針)
|
2026-05-25 15:48:18 +09:00 |
|
toyota
|
2aadb6fb79
|
docs(B-06): add environment setup guide with latest-stable version policy
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
2026-05-25 15:43:05 +09:00 |
|
Yoichi Toyota
|
0291251967
|
Merge pull request #138 from xtone/feat/B-05-conv06-skill-template
feat(B-05 / #128): テンプレCLAUDE.md→plugin-guide skill化+CONV-06改訂(DP-27)
|
2026-05-25 15:38:04 +09:00 |
|
toyota
|
77b6aae487
|
docs(B-05): document all template placeholders incl. applicable_domains/dependent_modules
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
2026-05-25 15:34:01 +09:00 |
|
toyota
|
81a3777004
|
feat(B-05): replace template CLAUDE.md with plugin-guide skill (DP-27, CONV-06)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
2026-05-25 15:29:25 +09:00 |
|
Yoichi Toyota
|
a72a79ec88
|
Merge pull request #137 from xtone/feat/B-02-firebase-auth-setup-ops
feat(B-02 / #127): firebase-auth-setup の運用詳細追加+言語非依存化
|
2026-05-25 15:00:45 +09:00 |
|
toyota
|
c084917374
|
fix(B-02): avoid FD leak (StringIO) and add iat/sub verification in rails recipe
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
2026-05-25 14:55:49 +09:00 |
|
toyota
|
6411402700
|
fix(B-02): add googleauth dependency and get_user implementation to rails recipe
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
2026-05-25 14:46:03 +09:00 |
|
toyota
|
5ab5e69759
|
fix(B-02): complete rails recipe revoke/delete helpers with DB-based revocation
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
2026-05-25 14:40:13 +09:00 |
|
toyota
|
1f02cdee44
|
fix(B-02): guard unregistered user in rails recipe auth (require_registered_user!)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
2026-05-25 14:32:51 +09:00 |
|
toyota
|
b91e77c478
|
feat(B-02): make firebase-auth-setup language-agnostic with ops details and rails recipe
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
2026-05-25 14:22:25 +09:00 |
|
Yoichi Toyota
|
4f1462f243
|
Merge pull request #135 from xtone/docs/T-022-closure
docs(T-022): backlogのIssueリンク化とRollout No-go判定の記録
|
2026-05-25 14:10:03 +09:00 |
|
Yoichi Toyota
|
336f41732e
|
Merge pull request #136 from xtone/feat/B-01-io-contract-schemas
feat(B-01 / #126): I/O契約スキーマの本実装(T-011〜013)
|
2026-05-25 14:09:22 +09:00 |
|
toyota
|
0176375903
|
docs(B-01): conform auth-plugin samples and skill docs to real schemas
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
2026-05-25 13:58:02 +09:00 |
|
toyota
|
955df876c8
|
feat(B-01): implement real I/O contract schemas from T-011/T-012/T-013
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
2026-05-25 13:58:02 +09:00 |
|
toyota
|
f93386a834
|
docs(T-022): link backlog to GitHub issues and record No-go decision
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
2026-05-25 13:37:25 +09:00 |
|
Yoichi Toyota
|
c452f7a63b
|
Merge pull request #125 from xtone/docs/T-022-pilot-report
docs(T-022): 内部パイロット報告書・訂正バックログ(xtone-auth-plugin)
|
2026-05-25 13:06:44 +09:00 |
|
toyota
|
2d53e60ae7
|
fix(T-022): correct F-number cross-reference in pilot-report priority list
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
2026-05-25 13:02:42 +09:00 |
|
toyota
|
00ef6db57e
|
docs(T-022): add internal pilot report, backlog and pending DP for xtone-auth-plugin
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
2026-05-25 12:53:33 +09:00 |
|
Yoichi Toyota
|
ef216c3c29
|
Merge pull request #124 from xtone/feat/T-021-auth-plugin-mvp
feat(T-021): 認証モジュールプラグイン(xtone-auth-plugin / MVP垂直スライス)
|
2026-05-25 11:35:14 +09:00 |
|
toyota
|
890aafc723
|
fix(T-021): correct typo Firembase -> Firebase in sample design.yaml
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
2026-05-25 11:22:34 +09:00 |
|
toyota
|
0eeefb23e3
|
docs(ai-delivery): link xtone-auth-plugin and mark T-021 in structure
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
2026-05-25 10:44:20 +09:00 |
|