Lalabase
Tickets, Doku, Zeiterfassung und Kundengespräche an einem Ort, durchsuchbar per KI. Für Softwarefirmen mit Kundenprojekten. Open Source: auf deinem eigenen Server oder in unserer Cloud in Deutschland.
Translation pending
招待特典の受付フォーム
Translation pending
BusinessTypeScript · PLpgSQLGitHub @snabeshima-botOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Loading the full README. The saved excerpt is shown below.
招待チケットで人を呼んでくれたお客様(招待者)から、特典の送付先を集めて発送まで管理するシステムです。 公演ごとに作っていた Google フォーム(人数で分岐するセクション形式)の置き換えです。Read the full README ↗
招待チケットで人を呼んでくれたお客様(招待者)から、特典の送付先を集めて発送まで管理するシステムです。 公演ごとに作っていた Google フォーム(人数で分岐するセクション形式)の置き換えです。
/{公演のURL名}: スマホ向けのステップ形式。招待者情報 → 招待した人数 → 特典ごとの希望メンバー → 送付先 → 確認(個人情報の取り扱いに同意)→ 受付番号とQRの表示
/{URL名}/edit?token=… から、受付期間中は希望メンバーと送付先を直せる(人数・チケット番号は直せない。発送準備に入ると直せなくなる)/admin(会社の Google アカウントでログイン。@focpro.co.jp は初回ログインで自動的にスタッフになる)
| 状態 | 意味 |
|---|---|
| 受付 | お客様が送信した直後。人数は未確認 |
| 人数確認済 | スタッフが人数を確認した。発送対象になる |
| 発送準備 | 発送作業中(宛名を出力した) |
| 発送済 | 発送した(追跡番号の取り込みなど) |
| 保留 / 無効 | 発送対象から外す。無効は集計からも外す |
公演日から「個人情報の保存期間」(初期値90日)が過ぎると、送付先・電話・メールは毎日の定期処理で自動削除されます。
| 対策 | 内容 |
|---|---|
| 暗号化 | 氏名・電話・郵便番号・住所・メールは、サーバーで AES-256-GCM で暗号化してから DB に保存(鍵 PII_ENCRYPTION_KEY は DB とは別に環境変数で管理)。重複チェックは別の鍵 PII_HASH_KEY の HMAC で行う |
| ログイン | 管理画面は会社の Google アカウントでログイン。staff_email_domains(初期値 focpro.co.jp)のドメインで Google が確認したアドレスだけが自動でスタッフになる。ほかのアカウントはログインしても何も見えない。パスワードでのログインも残してあり、その場合は認証アプリ(TOTP)の2段階認証が必須。DB の RLS も「Google ログインか2段階認証済み」のスタッフしか通さない |
| 秘密鍵を持たない | アプリは Supabase の service_role 鍵を持たない。公開フォームは publishable key で、公開中の公演情報の読み取りと、サーバーキー(APP_SERVER_KEY。DB にはハッシュだけ)を確認する送信・修正用の関数しか使えない |
| 自動ログアウト | 30分操作がなければログアウト(サーバー側と画面側の両方) |
| 画面での伏せ字 | 回答詳細では個人情報を伏せ字で出し、「表示」を押したときだけ見せる。表示は操作ログに残る。当日受付にはニックネームしか出ない |
| 操作ログ | 個人情報の表示・CSV出力・ラベル印刷・人数確定・状態変更などを記録(追記のみ。画面から消せない) |
| 公開フォーム | 送信はサーバー経由(サーバーキーが必要)で、Turnstile と送信回数制限(同じ IP から10分に5件まで)をかける |
| 修正リンク | 推測できないランダムなトークン(DB にはハッシュだけ保存)。受付終了か発送準備で使えなくなる |
| 同意 | 利用目的・保存期間・問い合わせ先をフォームに表示し、同意を必須にして日時を保存 |
| 削除 | 公演日から保存期間(初期値90日)を過ぎると、送付先・連絡先・ハッシュ・修正トークンを DB の定期実行(pg_cron、毎日 3:00 JST)で自動削除し、操作ログに残す |
| HTTP | CSP・HSTS・X-Frame-Options などを設定。管理画面と修正ページはキャッシュさせず、検索エンジンにも載せない |
暗号化鍵の扱い: PII_ENCRYPTION_KEY を失うと保存済みの個人情報は読めなくなります。作ったらパスワード管理ツールなどに控え、変えないでください。漏れた疑いがある場合は、公演ごとの受付を止めてから相談してください(鍵の入れ替えは今のところ未対応です)。
スタッフにするドメインの追加: Supabase の SQL Editor で insert into staff_email_domains (domain) values ('example.co.jp');。ドメイン以外の人を個別に追加する場合は、その人が一度 Google でログインしたあと insert into staff (user_id, display_name) select id, email from auth.users where email = '…';。外す場合は delete from staff where user_id = …。
staff に登録したユーザーだけに限定
public_submit_invitation 関数(サーバーキー必須)を呼んで1トランザクションで登録supabase/migrations/ テーブル・RLS・DB関数(public_submit_invitation, public_*_invitation_by_token, set_confirmed_count, purge_personal_data, スタッフ自動登録のトリガー)
supabase/seed.sql 開発用データ(SCRAMBLE SMILE のメンバーと 2nd SMILE の特典)
src/app/[slug]/ 公開フォーム(edit/ は修正リンク)
src/app/admin/ 管理画面
src/app/api/ 郵便番号検索
src/lib/ 特典の計算・入力チェック・暗号化(crypto.ts)・伏せ字・CSV・メールなど
db-tests/ 素の Postgres で動く DB テスト
e2e/run.mjs Playwright の E2E
npm install
npx supabase start # ローカルの Supabase(Docker が必要)。migrations と seed.sql が入る
cp .env.example .env.local # `npx supabase status` の URL / Publishable key を書く(APP_SERVER_KEY はそのままでよい)
# PII_ENCRYPTION_KEY と PII_HASH_KEY は `openssl rand -base64 32` で別々に作る
# ローカルでは Google ログインの代わりにパスワードのスタッフを作る(SUPABASE_SECRET_KEY にローカルの Secret key を書く)
npm run staff:create -- [email protected] password1234 "鍋島"
npm run dev # http://localhost:3000/2nd-smile と http://localhost:3000/admin
# 初回ログイン時に認証アプリの登録画面が出ます
テスト:
npm test # ユニットテスト(特典の計算・入力チェック・CSV)
npm run test:db # DB テスト(ローカルの Postgres。DATABASE_URL で接続先を変えられる)
npm run test:e2e # E2E(supabase start と npm run build && npm start が動いている状態で。スタッフは認証アプリ未登録にしておく)
npm run typecheck && npm run lint
公開までの残りの手順は docs/DEPLOY.md を参照。
| もの | 場所 |
|---|---|
| DB・ログイン | Supabase プロジェクト「Syotaitokuten」 |
| 公開 | Vercel プロジェクト「syotaitokuten」(GitHub の main に入ると自動で公開) |
| メール | Resend(送信元 [email protected]) |
本番の環境変数は Vercel に設定済み。PII_ENCRYPTION_KEY / PII_HASH_KEY / APP_SERVER_KEY は Vercel の画面(Settings → Environment Variables)で確認できるので、パスワード管理ツールにも控えておくこと。
APP_SERVER_KEY を変えるときは、Vercel の値と DB のハッシュを両方変える:
update app_private.server_keys set key_hash = encode(sha256(convert_to('<新しいキー>', 'UTF8')), 'hex') where name = 'app';
マイグレーションを追加したら npx supabase link --project-ref <ref> → npx supabase db push で本番に流す。
NEXT_PUBLIC_TURNSTILE_SITE_KEY と TURNSTILE_SECRET_KEY を Vercel に追加してください(送信回数の制限は設定なしでも効いています)