feat: views[].ownRead — 参加者の 1 ページだけを自分の行に絞る - #76
Conversation
`participantScope` は公開コレクションを own の分岐に届く前に `all` で確定させる。 それは正しい既定で、行が世界に読めるのに書き手にだけ少なく見せるのは「隠している」 ことになるから。ただしそれで表現できない画面がある —— 雑誌の書き手のデスクは 「自分が出したものを直す」ための場所で、そこに全記事(本文込み。ルールは欄を 落とせない)を渡すのは、増えない一覧を描くために書庫と一緒に増える読みになる。 `views[].ownRead` は `collections` の部分集合で、`live` と同じ形。宣言しなければ 既存アプリの投影は 1 バイトも変わらない。 **権限ではない。** 行の読める範囲は一切動かず、動くのは 1 ページのクエリだけ。 `public.read` の外のコレクションでは参加者は元から自分の行しか読めず、この鍵は 何も変えない。私的なものが私的なのはルールがそう言うからで、ここではない。 **新しい語彙を投影しない。** 出るのは `scope: "own"` と既存の `emailField` / `uidField` / `ownDocId` だけで、この鍵を知らないホストも正しく `where` を組む。だから `APP_PROTOCOL` は動かない(`ProjectedViewCollection.limit` と同じ論法)。**mulmoserver の変更もルール変更も不要。** - `ownScope` を `participantScope` から切り出した(複製ではなく分割 —— 2 つ目の 写しは「own とは何か」で両者がずれる場所になる) - ゲート 3 件: `collections` の部分集合であること、participant 以外は拒否 (member は全件が仕事、public には持ち主が居ない)、own の当てが無い宣言は拒否 (投影から落ちてページは何も渡されず、絞る前より少なくなる。しかも無言) - 既存の limit × own の拒否を、アプリ全体ではなく**そのビューの**スコープを見る形に。 1 つのアプリの 2 つの participant ページが別スコープを持てるようになったため - max-lines のラチェットを 1303 -> 1344(設定のコメントが言う「育てた変更の中で上げる」) test 568 全緑、`check:apps` の実アプリ 10 本も全て publish。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CRe3fgJnWNLRAqrjvjpHLn
There was a problem hiding this comment.
Sorry @snakajima, you've used your own review budget of 250,000 diff characters for the last 7 days.
You can request another review in 11 hours and 10 minutes by commenting @sourcery-ai review. Upgrade to get a review now.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (6)
Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review. 📝 WalkthroughWalkthroughChangesParticipant own-row view reads
Estimated code review effort: 3 (Moderate) | ~20 minutes Merge Risk: ⚪ Minimal · up to The opt-in setting narrows selected participant views to the reader’s own rows while preserving existing defaults, access rules, and ownership selectors; invalid declarations are rejected. No actionable merge-blocking risk remains after normal checks and review. Sequence Diagram(s)sequenceDiagram
participant AuthoredApp
participant viewProblems
participant tierViews
participant ownScope
AuthoredApp->>viewProblems: validate views[].ownRead
viewProblems->>ownScope: resolve ownership selector
ownScope-->>viewProblems: ProjectedViewCollection or null
AuthoredApp->>tierViews: publish normalized participant view
tierViews->>ownScope: resolve opted-in collection scope
ownScope-->>tierViews: scope: "own"
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning Some tools did not complete. Review the errors below. 🔧 ESLint
eslint.config.jsOops! Something went wrong! :( ESLint: 10.9.0 Error: The 'jiti' library is required for loading TypeScript configuration files. Make sure to install it. src/appViews.tsESLint skipped: the matched ESLint configuration already failed (unknown). src/publishChecks.tsESLint skipped: the matched ESLint configuration already failed (unknown).
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Reviewer's GuideIntroduces an opt-in Flow diagram for per-view ownRead projectionflowchart TD
A[NormalizedView with ownRead] --> B[viewOwnReadProblems]
B -->|valid participant subset with own identity mapping| C[tierViews]
B -->|invalid declaration| D[Publish refusal]
C --> E[scopeFor]
E -->|ownRead includes cid| F[ownScope]
E -->|otherwise| G[participantScope]
F --> H[Existing own query constraints]
G --> H
H --> I[Per-view limitFor]
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
@coderabbitai review |
✅ Action performedReview finished.
|
参加者のあるページだけを「読み手が出した行」に絞る opt-in を足します。MulmoTerminal の雑誌アプリ(書き手のデスク)が動機ですが、鍵自体は汎用です。
なぜ既定では絞れないのか
participantScopeは公開コレクションを own の分岐に届く前にallで確定させます:これは正しい既定で、変えていません。 行が世界に読めるのに書き手にだけ少なく見せるのは、他人が読めるものを隠していることになるからです。関数のコメントが言うとおり、公開分岐は後付けではありません。
表現できないのは別の画面です。雑誌の書き手のデスクは「自分が出したものを直す」ための場所で、そこに全記事を渡すのは —— 本文込みで、ルールは欄を落とせないので —— 増えない一覧を描くために書庫と一緒に増える読みになります。
形
liveと同じ、collectionsの部分集合:{ "id": "write", "audience": "participant", "collections": ["articles"], "ownRead": ["articles"], "live": ["articles"] }宣言しなければ既存アプリの投影は1 バイトも変わりません(テストで固定)。
2 つ、はっきりさせておきたいこと
権限ではありません。 行の読める範囲は一切動かず、動くのは 1 ページのクエリだけです。
public.readの外のコレクションでは参加者は元から自分の行しか読めないので、この鍵は何も変えません。私的なものが私的なのはルールがそう言うからであって、ここではない。新しい語彙を投影しません。 出るのは
scope: "own"と既存のemailField/uidField/ownDocIdだけで、この鍵を知らないホストも正しくwhereを組みます。なのでAPP_PROTOCOLは動かしていません(ProjectedViewCollection.limitの「A READER THAT DOES NOT KNOW THIS KEY...」と同じ論法)。mulmoserver の変更もルール変更も不要で、viewConstraints→ownConstraintsが既にscope === "own"を処理しています(liveの購読も同じ関数を通ります)。中身
ownScopeをparticipantScopeから切り出しました。 複製ではなく分割です —— 2 つ目の写しは「own とは何か」で拡大側と縮小側がずれる場所になります。ownReadが渡すクエリは、ルールが認めるクエリと同じでなければなりません。collectionsに無い cid — ページはそのクエリを渡されていないので絞る対象が無い(liveと同じ算術)emailFieldもuidFieldもidFrom: "auth.uid"も無いとownScopeは null を返し、tierViewsがそのコレクションを落とす。ページは何も渡されず、絞る前の全件より少なくなる。しかも無言。3 つのうちこれが一番長い文言なのはそのためですparticipantScopeだけを見ると別のページについて答えることになります(通してはいけない組を通し、問題ない組を断る)。ownReadは refusal の 1 家族として入るので、分割ではなく数値を上げるのが筋だと判断しました。確認
yarn test568 全緑(新規 13 件)yarn check:apps— 実アプリ 10 本すべて publish(既存の宣言に影響が無いことの実地確認)yarn lint/yarn typecheck/yarn formatcleanこの後
@receptron/sharedappを公開したら MulmoTerminal 側で bump し、稼働中の雑誌アプリ(ai-journal)の participant ビューで使います。そこでは/m/と/p/が 1 つのdesk.htmlを共有できなくなるので(/p/では「一覧には全員の記事が並びます」が嘘になる)、ページを分けます。magazine.mdテンプレートにも入れる予定です。work in mulmoterminal
Summary by Sourcery
Support participant views that opt in to displaying only the current reader’s rows while preserving existing defaults and access rules.
New Features:
views[].ownReadsetting that narrows participant-page reads to the current participant’s own rows for selected collections.Bug Fixes:
Enhancements:
ownReadtargets view collections, is used only on participant views, and has a configured way to identify the reader’s rows.Build:
Tests:
Summary by CodeRabbit
New Features
Bug Fixes