yushonomamaru.com
Tech Stack & Architecture
updated 2026-05-16
01 — Overview
サイト概要
フレームワーク
Astro 6.1 + Preact 10(Island)
スタイル
Tailwind CSS 4.2(Vite プラグイン)
ランタイム
Node.js 22.12+ / npm
言語
TypeScript(.ts / .tsx)+ Astro
ホスティング
Cloudflare Pages(CDN)
DNS
Cloudflare DNS(SPF / DKIM / MX)
認証 ① サイト全体
Cloudflare Access + Google OAuth
認証 ② /admin のみ
Supabase Magic Link(メールのログインリンク)
バックエンド
Supabase(Auth / DB / Realtime)
メール送信
Resend(Supabase カスタム SMTP)
エディタ
Cursor & Claude Code(二刀流)
02 — Tech Stack
技術スタック
▲
Astro 6.1
静的サイトジェネレーター
.astro → HTML/CSS/JS にビルド
Framework ⚛
Preact 10
軽量 React 互換 UI ライブラリ
@astrojs/preact で Island として埋め込み
UI Island TS
TypeScript
Preact コンポーネント(.tsx)と
lib/supabase.ts などの共有ロジック
Language ◆
Tailwind CSS 4.2
ユーティリティファースト CSS
@tailwindcss/vite で導入(CSS-first)
Styling 🔒
Cloudflare Zero Trust
サイト全体のアクセス制御
許可メアドのみ閲覧可能
Auth (site) G
Google OAuth 2.0
Cloudflare Access の IdP
Google アカウントでサインイン
IdP S
Supabase
PostgreSQL + Realtime(WebSocket)+ RLS
@supabase/supabase-js 2.105 でブラウザから直接アクセス
BaaS ✉
Resend
Supabase のカスタム SMTP
/admin 向けログインリンク付きメール送信
Email ⚙
GitHub
ソースコード管理
main push → 自動デプロイ発火
VCS ☁
Cloudflare Pages
静的サイトホスティング + CDN
GitHub 連携で自動ビルド & プレビュー配信
Hosting ⊙
Cloudflare DNS
yushonomamaru.com の DNS 管理
SPF / DKIM / MX レコードも設定済み
DNS ⬡
Node.js 22 + npm
Astro のビルド・開発環境
npm run dev / npm run build
Runtime ⌘
Cursor & Claude Code
AI 二刀流で開発!
Cursor で確認 → Claude Code で実装
IDE / AI 03 — Architecture
アーキテクチャ図
04 — Pages
ページ構成
| ページ | URL | ソースファイル | 状態 | 動的処理 |
| ホーム | / | src/pages/index.astro | LIVE | なし(純静的) |
| 旅行 | /travel | src/pages/travel/index.astro | LIVE | なし |
| 福岡旅行 2026 | /fukuoka | src/pages/fukuoka/index.astro | LIVE | なし |
| 福岡 屋台マップ | /fukuoka/yatai | src/pages/fukuoka/yatai/index.astro | LIVE | なし |
| 熱海旅行 2026 | /26atami | src/pages/26atami/index.astro | LIVE | なし |
| 女子3人旅 2026 | /26girls-trip | src/pages/26girls-trip/index.astro | LIVE | なし |
| 那須 親族旅行 2026 | /26nasu-trip | src/pages/26nasu-trip/index.astro | LIVE | なし |
| 家族 | /family | src/pages/family/index.astro | LIVE | Supabase ballet_urls / saved_urls + Realtime(Preact Island・CF Access ゲート) |
| 写真 | /photos | src/pages/photos/index.astro | LIVE | なし(Google フォト共有アルバム一覧) |
| お問い合わせ | /contact | src/pages/contact/index.astro | LIVE | Supabase contacts テーブルに INSERT(Preact Island・anon) |
| 管理画面 | /admin | src/pages/admin/index.astro | LIVE | Supabase メールのログインリンクで認証 → contacts SELECT(Preact Island・authenticated) |
| 技術スタック | /tech-stack | src/pages/tech-stack/index.astro | LIVE | なし(このページ) |
| 404 | /* | src/pages/404.astro | LIVE | — |
05 — File Structure
ファイル構成
yushonomamaru/
├── astro.config.mjs ← Astro 設定(Preact + Tailwind Vite プラグイン)
├── package.json ← 依存パッケージ(Astro / Preact / Tailwind / Supabase)
├── tsconfig.json
├── public/
│ ├── favicon.svg
│ └── images/
│ └── home-hero.svg ← トップページのヒーロー画像
├── src/
│ ├── assets/
│ │ ├── astro.svg
│ │ └── background.svg
│ ├── components/
│ │ ├── BalletUrlList.tsx ← バレエ出席確認リスト(Preact + Supabase Realtime)
│ │ ├── SavedUrlList.tsx ← 汎用URLメモ(Preact + Supabase Realtime)
│ │ ├── ContactForm.tsx ← お問い合わせフォーム(Preact → Supabase contacts INSERT)
│ │ ├── AdminContactList.tsx ← 管理画面用問い合わせ一覧(メールのログインリンクで認証 → contacts SELECT)
│ │ ├── Header.astro ← 共通ヘッダー(PC + ハンバーガーナビ)
│ │ └── Welcome.astro
│ ├── layouts/
│ │ └── Layout.astro ← 共通レイアウト(Header 含む)
│ ├── lib/
│ │ └── supabase.ts ← Supabase クライアント初期化 + 行型定義
│ ├── pages/
│ │ ├── 26atami/ ← 熱海旅行ページ(旅程 + 旅行記)
│ │ ├── 26girls-trip/ ← 女子3人旅ページ
│ │ ├── 26nasu-trip/ ← 那須 親族旅行ページ
│ │ ├── admin/ ← 問い合わせ管理画面(ナビ非表示・独自ヘッダー)
│ │ ├── contact/ ← お問い合わせフォームページ
│ │ ├── family/ ← 家族ページ(CF Access ゲート、ballet_urls + saved_urls)
│ │ ├── fukuoka/ ← 福岡旅行ページ
│ │ │ └── yatai/ ← 屋台マップ
│ │ ├── photos/ ← 写真ページ(Google フォト共有アルバム集)
│ │ ├── tech-stack/ ← このページ
│ │ ├── travel/ ← 旅行一覧(マル予防接種証明書リマインダー付き)
│ │ ├── 404.astro
│ │ └── index.astro ← ホーム
│ └── styles/
│ └── global.css
├── supabase/
│ └── migrations/ ← DB スキーマ / RLS の SQL マイグレーション
│ ├── 20260502_create_contacts.sql
│ ├── 20260502_drop_family_auth_add_saved_urls.sql
│ └── 20260502_allow_authenticated_on_family_tables.sql
└── docs/
└── system-architecture.md ← システム構成ドキュメント(このページの元ネタ)
06 — Data Flow
データの流れ
デプロイフロー
git push (main)
→ GitHub Webhook
→ Cloudflare Pages ビルド
→ CDN エッジに配信
/family ページ(CF Access で認証)
ブラウザでアクセス
→ Cloudflare Access が Google OAuth で許可メアド確認
→ 通過後そのまま BalletUrlList / SavedUrlList を表示
→ ページ内の追加ログインなし
/family ページ(Realtime 同期)
端末 A でURL追加・編集・削除
→ Supabase ballet_urls / saved_urls 更新
→ WebSocket で即時配信
→ 端末 B / C に自動反映
/contact ページ(送信)
フォーム送信(Preact)
→ Supabase contacts に INSERT
→ RLS: anon の INSERT のみ許可
→ 即時保存完了
/admin ページ(一覧)
管理者メアド宛のログインリンクで認証
→ セッション確立後に SELECT
→ RLS: authenticated のみ許可
→ contacts 一覧を表示
07 — Database
Supabase スキーマ & RLS
DDL は supabase/migrations/ の SQL ファイルで管理。anon キーが公開されてもテーブル単位の RLS で守れる設計。
| テーブル | 主なカラム | 用途 | RLS ポリシー | Realtime |
| ballet_urls | id, url, label, done, added_at, created_by | バレエ出席確認URLのチェックリスト | anon + authenticated: SELECT / INSERT / UPDATE / DELETE すべて許可 (CF Access が前段ガード) | ON |
| saved_urls | id, url, title, memo, added_at | 家族で共有したい汎用 URL メモ | anon + authenticated: SELECT / INSERT / UPDATE / DELETE すべて許可 (CF Access が前段ガード) | ON |
| contacts | id, name, email, message, created_at | お問い合わせフォームの受信箱 | anon + authenticated: INSERT のみ許可 SELECT は authenticated のみ(/admin 用) | OFF |
08 — Environment
環境変数
本番環境は Cloudflare Pages のダッシュボードで管理。PUBLIC_ プレフィックスの変数はブラウザに公開されるが、サイト全体は CF Access が前段で守り、Supabase 側も RLS でガードするので問題ない設計。
| 変数名 | 用途 | 公開 |
| PUBLIC_SUPABASE_URL | Supabase プロジェクトの URL | ブラウザ公開 |
| PUBLIC_SUPABASE_ANON_KEY | Supabase 匿名キー(RLS で保護) | ブラウザ公開 |
09 — Deployment
ビルド & デプロイ
ローカル開発
npm run dev → :4321
本番デプロイ
git push main → 自動
プレビュー
PR 作成 → Cloudflare Pages がプレビュー URL 生成
ブランチ戦略
feature ブランチ → PR → main マージで本番反映