このコミットが含まれているのは:
2026-10-31 13:50:10 +09:00
コミット dba409c3e8
33個のファイルの変更、1490行の追加、236行の削除
+45 -8
ファイルの表示
@@ -35,7 +35,9 @@ Web とワーカーは同一リリース、Rails secret、アプリケーショ
- POST `/counts/export/jobs`:要求検証・実行時点の固定・署名付きジョブトークンの発行。
- GET `/counts/export/jobs/:token`:状態、実際の処理済みレコード数、判明している総数。
- DELETE `/counts/export/jobs/:token`:取消を永続記録。
- GET `/counts/export/files/:token`:生成完了後の署名付きファイルトークンによる取得。
- POST `/counts/export/jobs/:token/download`:セッション所有者の開始確認要求を登録。
- GET `/counts/export/files/:token?job=...&attempt=...`:実 GET の認可・送出開始の確認。
- GET `/counts/export/files/:token`:既存クライアント向けの認可付きダウンロード。
ジョブ・ファイルのトークンは作成元のセッションに紐付く。
既存の BAN・CSRF 制御を使用する。フロントは約800ms間隔で状態を取得する。
@@ -80,16 +82,22 @@ processed は CSV では実際に生成したデータ行数、JSON のクロス
通常の Counts 応答では、使用していない全履歴の population_count は計算しない。
キーは null、population_count_computed は false とし、0に置き換えない。
現在条件の output_count は権限適用前、visible_output_count は権限適用後の
通常の集計行数(明細では明細行数)。小計・合計の物理行は含めない。
summary は非公開履歴を含む同じ母集団を集計する。非公開の軸はサーバーの CASE 式で
単一の予約値へまとめてから GROUP BY し、output_count / visible_output_count はその
安全化した通常行数を表す。excluded_count は返さない。details は従来どおり
output_count が権限適用前、visible_output_count が適用後の明細行数である。
小計・合計の物理行は行数に含めない。
CSV の物理行と JSON の pivot_cell には集計レコードを含むため、両者を混同しない。
除票境界・参照禁止集合は GROUP BY で識別キー単位にまとめる。
投稿の参照判定は、全除票履歴を JSON_CONTAINS / FIND_IN_SET で反復照合せず、
保存済みスナップショットから参照IDを JSON_TABLE で展開して照合する。
権限条件付きの母集団件数は同一 export インスタンス内で再利用する。
多段小計は、認可済み母集団の CTE を MySQL の無制限 LIMIT で実体化させ、
各枝が同じ認可判定をやり直すことを避ける。計数は COUNT(DISTINCT v.id) のまま。
多段小計は、全軸の JOIN へ実際に寄与するレコードを CTE に保持し、各枝で同じ
母集合を使う。changed_field には直前版がある実変更だけが寄与する。タグが行軸に
ない場合は DISTINCT 投稿版を数える。タグが行軸にある場合は投稿版×タグを数え、
全行軸の葉単位から小計・合計を求める。変更項目も行軸ならその寄与も保持する。
private のタグ・変更項目をまとめても、内部の寄与は捨てず、ラベルだけを保護する。
スキーマ上、以下の追加インデックスが候補となる。migration は作成・実行していない。
@@ -122,6 +130,35 @@ systemd の EnvironmentFile と Web の環境を照合し、directory の owner
アクセス制限、容量、期限切れ削除、worker heartbeat と restart を公開前に確認する。
この作業では systemctl・worker 起動・本番環境への適用を行っていない。
リリース保留:非公開グループと複数値・変更項目軸の交差集計、生成ファイルへの秘匿値の
非混入、実 GET の middleware/proxy 経由の開始通知は、回帰テストと実環境の確認が必要。
テスト・型チェック・build は未実行。
これらのコード対策と回帰テストを追加しているが、テスト・型チェック・build は未実行。
middleware/proxy 経由の転送は別途実環境で確認する。
## 開始確認の競合と権限
開始受付は pending、実 GET の単独取得は streaming、最初の Rack yield 後は started。
同じ job の重複受付は既存 attempt を返す。streaming への遷移はプロセス間ロックで
単独取得し、同一 attempt の二重 GET を拒否する。開始前の attempt は45秒で失効する。
Frontend は30秒の独立タイマーで確認を打ち切る。一時的なポーリング通信断は同じ
attempt で再取得するが、別の GET は始めない。取消失敗後の再試行は利用者の再操作で行う。
ファイル・ジョブは owner、署名、期限、現在の権限 revision 及び artifact_policy を
検証する。最初の送出前にも現ユーザー・BAN・ファイル権限を再確認する。旧ポリシーの
生成物は再利用しない。送出中は各チャンクで取消状態を確認し、例外時はログと failed
状態を記録して body を閉じる。コミット後に head で別レスポンスを書かない。
ResponseBody に to_path を提供せず、sendfile middleware による ACK の迂回を避ける。
Last-Modified と X-Accel-Buffering: no を設定するが、プロキシの動作まで保証しない。
サーバーの最初の Rack yield は、クライアントの受信開始の厳密な証明ではない。
非管理者の summary では、公開集計属性は操作日時・異動区分。その他の属性に対する
抽出条件・補助タグ検索は拒否する。measures / column_order はマスク後の式だけと
比較するため、推測した private ID は一致しない。予約値そのものの条件指定は拒否する。
private ID の正誤に応じて許可可否を変えないため、条件の一致探索を避けられる。
非公開列を含む列順変更は API の column_values_editable でも不可と通知する。
公開列の値を使うソートは引き続き利用できる。
明細には元の認可を適用し、抽出条件自体や取得済みの全言語値を表示設定で改変しない。
外部タグ履歴の linked_tags は名前しか記録していないため、非公開タグの記録名を含む
スナップショットを保守的に非公開とする。名前全体を空白区切りの境界で照合する。
区切りが曖昧な旧データでは過剰な秘匿の可能性はあるが、参照 ID がない旧形式から
名前の公開可否を楽観的に推定しない。