feat: コレクションの定員制限 — waiting list 等で上限人数を Firestore rules で強制する
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 38/100
- Issue type
- Feature
- Clarity
- Mostly clear
- Activity status
- Active
- Tech stack
- typescript
- Domain
- backend, build-system, database
Research direction
Start by reading the existing mirror and getAfter() patterns, then inspect publishManifest.ts, publishProject.ts, publishChecks.ts, and appViews.ts. Review the MulmoServer Firestore rules and publish flow, followed by MulmoTerminal's batch-write handling. Done means capacity is validated and projected, counters are initialized and removed, rules enforce atomic increments and decrements, and client writes include the required counter updates.
Written by the indexing model from the issue text.
Description
背景
waiting list やイベント申込など、コレクションに書き込めるドキュメント数の上限を指定したい。
現状 Firestore rules にはコレクション内のドキュメントを数える機能がないため、rule 化されていなかった。
クライアントサイドでの制限ではユーザが直接 DB を触れるため不十分 — rules で強制する必要がある。
方針: カウンタードキュメント + バッチ書き込み + getAfter()
Firestore rules の getAfter() はバッチ書き込み内の「書き込み後の状態」を参照できる。
mirror パターン(予約 + 公開プロジェクションのアトミック書き込み)と同じ手法。
仕組み
- publish 時:
apps/{aid}/counters/{cid}に{ count: 0 }を作成 - ドキュメント作成時: クライアントはバッチで「レコード作成 + カウンタ +1」を同時に書く
- rules: バッチ後のカウンタが上限以下かチェック
// rules(イメージ)
let config = get(/databases/$(database)/documents/apps/$(aid)/config/$(cid)).data;
let counterDoc = /databases/$(database)/documents/apps/$(aid)/counters/$(cid);
let counterBefore = get(counterDoc).data.count;
let counterAfter = getAfter(counterDoc).data.count;
// create 時
allow create: if
config.capacity == null // capacity 未設定なら従来通り無制限
|| (counterAfter <= config.capacity
&& counterAfter == counterBefore + 1); // 正確に +1 であること
- 削除時: バッチで「レコード削除 + カウンタ -1」。
selfDelete、writerDeleteどちらも同様 - カウンタなしの直接書き込み → rules が拒否(
getAfter()がカウンタ更新を要求)
セキュリティ
- カウンタ更新なしの create → 拒否
- カウンタを +2 以上にする →
counterAfter == counterBefore + 1で拒否 - カウンタだけ更新してレコードなし → カウンタの rules で対応(単独更新を拒否)
- 直接 SDK でアクセスしても rules で弾かれる
sharedapp 側の変更
1. 宣言 (publishManifest.ts)
CollectionConfigZ に capacity を追加:
capacity: z.number().int().positive().optional(),
コレクション単位で宣言する(SubmitZ ではなく)。
member が作成するレコードも上限に含まれるべきため。
2. 射影 (publishProject.ts)
capacity を config ドキュメントにそのまま射影。
3. バリデーション (publishChecks.ts)
capacityを宣言したコレクションはsubmitOnlyやimmutableとの組み合わせをチェック- 削除を伴うコレクション(
selfDelete、writerDelete)ではカウンタのデクリメントが必要になることを確認
4. ビュー射影 (appViews.ts)
ページに capacity と現在の count を渡し、「残り X 枠」の表示を可能にする。
MulmoServer 側の変更
5. Firestore rules
counters/{cid}パスの read/write ルール追加- items の create 時:
capacityが宣言されていればgetAfter()でカウンタチェック - items の delete 時: カウンタのデクリメントチェック
- カウンタ単独の更新を拒否
6. publish 処理
capacity付きコレクションの publish 時にcounters/{cid}ドキュメントを初期化- unpublish 時にカウンタドキュメントを削除
MulmoTerminal 側の変更
7. バッチ書き込み対応
capacity付きコレクションへの create/delete をバッチ書き込みに変更mirrorと同時にcapacityがある場合、3 ドキュメント(レコード + mirror + カウンタ)の 1 バッチ
考慮事項
- ホットスポット: カウンタドキュメントに書き込みが集中するが、waiting list 規模(秒間数十件以下)なら問題ない
get()コスト:capacity未宣言のコレクションでは一切追加コストなし(config.capacity == nullで早期リターン)- 既存アプリへの影響:
capacityはオプショナル。宣言しなければ従来通り無制限 - カウンタの整合性: 何らかの理由でカウンタがずれた場合、owner が手動でリセットできる仕組みも検討
既存パターンとの関係
mirror: 同じバッチ書き込み +getAfter()パターンstampField: 順序保証(定員の「先着」を決める)。capacityと組み合わせて使うケースが多いはずmaxBytes: こちらはホスト側制限(NOT a rule)で設計思想が異なる。capacityは rules 強制が必須
- Dominant language
- TypeScript
- Stars
- 1
- Forks
- 0
- Avg merge
- 13m
- Merged PRs (30d)
- 10
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from receptron/sharedapp
-
enhancement
Difficulty 5/5 Over a week Newbie friendliness 42/100
Maintainers usually reply within 1 day
-
enhancement
Difficulty 5/5 Over a week Newbie friendliness 35/100
Maintainers usually reply within 1 day
-
enhancement
Difficulty 5/5 Over a week Newbie friendliness 35/100
Maintainers usually reply within 1 day
All issues in receptron/sharedapp
Similar issues
-
Difficulty 1/5 Under an hour Newbie friendliness 78/100
lichess-org/api#678 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
PostHog/posthog.com#20628 ·
Maintainers usually reply within 1 day
-
bug status:Needs Triage
Difficulty 1/5 Under an hour Newbie friendliness 92/100
jupyterlab/jupyterlab#19964 ·
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
agentscope-ai/QwenPaw#8064 · 1 comment ·
Maintainers usually reply within 1 day
-
area: notebooks-jupyter bug theme: new notebook frontend
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
posit-dev/positron#16347 · 1 comment ·
Maintainers usually reply within 1 day