Conversation
全高ラインは packRailBandColumns を通らず常に left: 0 に描かれ、時刻付きの不在や 勤務場所の帯も列0から使うため、同じ日に両方あると必ず重なっていた。勤務場所が レールに載る日が増えたぶん遭遇確率も上がっていた。 全高ラインは既に [0,1440] の範囲を持っており時刻付きの帯と同じ形なので、データ変換は 不要で特別扱いを消すだけで済む。パッキング本体は触っていない。終日/時刻の分岐は 同着順の決定(全高ラインが列0を取る)のためだけに残した。 終日不在が無い日の列割り当ては変わらない ― 入力配列が同一になるため。21日分の 列位置とカード位置をダイジェスト化して変更前後で比較し、変わったのは以前まさに 重なっていた2日だけで他は完全一致、終日不在の無い週はスクリーンショットが SHA256 一致であることを確認済み。 列数の上限は設けない。上限を入れると終日不在が無い日の見え方も変わり、不変性の 保証が崩れるため。 Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HGESE2zBNzoW8MYvtEySBQ
?demo=1 をリロードすると繰り返し予定だけが全部消え、初回起動だけ正常に見えていた。 機序は当初の想定と少し違い、再シードは実際に走っている(掃除の直後なので series が 0件になる)。症状の本体は ensureExpanded が expansionState を見て**再展開をスキップ** することで、掃除で消えたシリーズ由来の occurrence が復活しなかった。 ?demo=1 のときは series 件数を見ず毎起動で投入し直し、投入後に reexpandCurrentWindow を 通す(sync で series 定義が変わったときと同じ状況なので既存の道具をそのまま使う)。 デモ以外では呼ばない ― 通常起動で毎回全展開するのは増分ポリシーの放棄になるため。 あわせて別の穴も塞いだ。Google 連携済みの環境で ?demo=1 を付けると series が0件でない ためデモが1件も入らなかった。件数条件を外したので連携済みでも同じ見え方になる。 cleanupDemoData の意図(デモの残骸を実データ環境に残さない)は変えていない。掃除条件は 「現存する demo series 集合」から「id 規則」に広げ、series が先に消えていても occurrence と override を取り残さないようにした。 メモリ上のみに載せる案は採らない。デモの価値は実データと同じ経路(展開・getSeries・ override)を通ることで、series を IndexedDB から外すと検証台としての意味が落ちる。 なお model/dummy.ts には、直前のレール重なり修正で必要になったデモデータ (終日不在と時刻付きレール項目が同じ日にある形)の追加も含まれる。 Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HGESE2zBNzoW8MYvtEySBQ
起動時にテスト通知を1回出すだけだった通知を、実際の予定リマインダーに繋いだ。
起動時のテスト通知は毎回のノイズなので削除し、設定画面のボタンに置き換えた。
判定は web 側、Rust は文言を受けて通知を出すだけ。Rust 側でスケジュールするには
予定データを Rust に持たせる必要があり、Google 同期と繰り返し展開の複製になる。
**ウィンドウを閉じても通知は届く** ― CloseRequested が prevent_close + hide で
プロセスは生きているため。届かないのはトレイの「終了」で落としている間だけ。
この線引きを設定 UI とドキュメントにそのまま書いた。
予定ごとの setTimeout ではなく 30 秒 tick。同期のたびに occurrence 行は丸ごと
書き換わるのでタイマーは張り直しが要り、隠れた webview のタイマーは間引かれ、
スリープ復帰でずれる。毎 tick 壁時計から判定し直せば tick が遅れても判定は正しい。
何分前かはアプリ独自の一律設定(既定10分)。**Google の予定ごとのリマインダー設定は
そもそも同期していない** ― GoogleEventDTO に該当フィールドが無く、Google は返して
いるのに捨てている。尊重するには protocol・google-events・mapGoogle の4ビルダー・
model/types とバックフィル世代定数の更新が必要なので今回は範囲外とし、代わりに
「Google 側の設定は使わない」ことを設定 UI とドキュメントに明記した。
通知済みキーは `${id}@${startMs}`。開始時刻を埋め込むので、予定が動けばキーが
変わって新時刻で改めて通知し、同じなら二重に通知しない。復元は最後の @ で切る
(calendarId が …@group.calendar.google.com やメール形式のため)。条件は
fireAt <= now かつ **now < startMs** で、2本目が「起動時に過去分が一気に飛ぶ」
事故を単独で防ぐ。終日予定・ミラー・欠席・勤務場所は対象外。
**通知権限は原理的に判定できない。** tauri-plugin-notification 2.3.3 の desktop
実装は show() の結果を捨てて必ず Ok を返し、permission_state() も Granted の
ハードコード。「許可されています」と表示するのは嘘になるので、テスト通知ボタンを
置いて出なければ OS の設定を見るよう案内する形にした。
docs/desktop.md と docs/multiplatform.md の古い TODO 記述も実態に合わせた。
Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HGESE2zBNzoW8MYvtEySBQ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
終日不在の全高ラインを列パッキングに載せる (
e609e52)全高ラインは
packRailBandColumnsを通らず常にleft: 0に描かれ、時刻付きの不在や勤務場所の帯も列0から使うため、同じ日に両方あると必ず重なっていた。勤務場所がレールに載る日が増えたぶん遭遇確率も上がっていた。全高ラインは既に
[0,1440]の範囲を持っており時刻付きの帯と同じ形なので、データ変換は不要で特別扱いを消すだけで済んだ。パッキング本体は無変更。終日不在が無い日の列割り当ては変わらない(入力配列が同一になるため)。21日分の列位置とカード位置をダイジェスト化して変更前後で比較し、変わったのは以前まさに重なっていた2日だけで他19日は完全一致、終日不在の無い週はスクリーンショットが SHA256 一致であることを確認済み。
列数の上限は設けない ― 上限を入れると終日不在が無い日の見え方も変わり、不変性の保証が崩れるため。
demo モードのリロードで繰り返し予定が消えるのを直す (
6c4c488)?demo=1をリロードすると繰り返し予定だけが全部消え、初回起動だけ正常に見えていた。機序は当初の想定と違い、再シードは実際に走っている(掃除の直後なので series が0件になる)。症状の本体はensureExpandedがexpansionStateを見て再展開をスキップすることだった。?demo=1のときは series 件数を見ず毎起動で投入し直し、投入後にreexpandCurrentWindowを通す。デモ以外では呼ばない(通常起動で毎回全展開するのは増分ポリシーの放棄)。別の穴も塞いだ ― Google 連携済みの環境で
?demo=1を付けると series が0件でないためデモが1件も入らなかった。cleanupDemoDataの意図(デモの残骸を実データ環境に残さない)は不変。掃除条件を「現存する demo series 集合」から「id 規則」に広げ、series が先に消えていても occurrence と override を取り残さないようにした。利用者影響は無いが、直近の複数の作業で「demo に繰り返し予定が無い」「編集フォームに到達できない」ための回避作業が繰り返し発生していた。検証環境の不備は以後の全作業に課税される。
デスクトップ版の予定リマインダー (
b8a3866)起動時にテスト通知を1回出すだけだった通知を、実際の予定リマインダーに繋いだ。起動時のテスト通知は毎回のノイズなので削除し、設定画面のボタンに置き換えた。
判定は web 側、Rust は文言を受けて通知を出すだけ。 Rust 側でスケジュールするには予定データを Rust に持たせる必要があり、Google 同期と繰り返し展開の複製になる。
ウィンドウを閉じても通知は届く ―
CloseRequestedがprevent_close+hideでプロセスは生きているため。届かないのはトレイの「終了」で落としている間だけ。この線引きを設定 UI とドキュメントにそのまま書いた。予定ごとの
setTimeoutではなく 30 秒 tick。 同期のたびに occurrence 行は丸ごと書き換わるのでタイマーは張り直しが要り、隠れた webview のタイマーは間引かれ、スリープ復帰でずれる。毎 tick 壁時計から判定し直せば tick が遅れても判定は正しい。Google の予定ごとのリマインダー設定はそもそも同期していない ―
GoogleEventDTOに該当フィールドが無く、Google は返しているのに捨てている(リポジトリ全体で "reminder" が0件)。尊重するには protocol・google-events・mapGoogle の4ビルダー・model/types とバックフィル世代定数の更新が必要なので今回は範囲外とし、代わりに一律分数(既定10分)+「Google 側の設定は使わない」旨の明記とした。別タスクに登録済み。通知済みキーは
${id}@${startMs}。開始時刻を埋め込むので、予定が動けばキーが変わって新時刻で改めて通知し、同じなら二重に通知しない。復元は最後の@で切る(calendarId が…@group.calendar.google.comやメール形式のため)。条件はfireAt <= nowかつnow < startMsで、2本目が「起動時に過去分が一気に飛ぶ」事故を単独で防ぐ。終日予定・ミラー・欠席・勤務場所は対象外。通知権限は原理的に判定できない
tauri-plugin-notification2.3.3 の desktop 実装はshow()の結果を捨てて必ずOkを返し、permission_state()もGrantedのハードコード(crate のソースで確認)。したがって macOS で拒否されていてもアプリ側は知りようがない。API が存在することは、それが意味のある値を返すことを意味しない。 確認せずに「権限を確認して案内する」UI を作ると、拒否されている人に「許可されています」と表示することになる。判定は諦め、設定画面にテスト通知ボタンを置いて、出なければ OS の設定を見るよう案内する形にした。
検証
pnpm --filter web test1267 passed /cargo test27 passed /cargo clippy --all-targets -- -D warningsクリーンwindow.__TAURI__スタブ + モック sync API で end-to-end 検証(時刻到来で1回・過去は出さない・終日は出さない・リロードとフル再同期を跨いでも二重にならない・移動したら新時刻で改めて出る)付随
docs/desktop.mdとdocs/multiplatform.mdに残っていた古い TODO(「実リマインダーのフロント連携は次増分」「Web Push で出す」)を実態に合わせた。🤖 Generated with Claude Code
https://claude.ai/code/session_01HGESE2zBNzoW8MYvtEySBQ