「変な記事がめっちゃ増えてる」:作られた経路ごとに数えて入口を塞いだ。数え方も 2 回、間違えた
トレカダッシュ 開発の記録 / 2026年8月
iOS アプリ「トレカダッシュ」について、ユーザーから、こういう指示が来ました。「変な記事が、めっちゃ増えてる。締切も入っていないし、おかしい記事ばかり。恒久的に解決して。ほかの経路で作った記事も、徹底的に調べて」。
この記事は、記事を作られた経路ごとに数えて、入口を塞いだ記録です。そして、数え方を、2 回間違えた記録でもあります。
数字は、2026 年 8 月 28 日の作業の記録から書いています。
経路ごとに、数えた
記事は、いくつかの経路(X の店の公式の投稿、店のサイト、まとめサイト、AI による探索など)で作られます。経路ごとに、どんな「変な記事」があるかを、数えました。
| 経路 | 抽選 | 締切なし | 検索結果が行き先 | トップページが行き先 | まとめ自身が行き先 |
|---|---|---|---|---|---|
| X(店の公式) | 118 | 11 | 0 | 1 | 0 |
| 店のサイト(直接) | 63 | 1 | 1 | 0 | 0 |
| まとめサイト A | 39 | 33 | 3 | 2 | 8 |
| まとめサイト B | 28 | 11 | 0 | 1 | 5 |
| AI による探索 | 4 | 2 | 0 | 0 | 0 |
| 合計 | 252 | 58 | 4 | 4 | 13 |
数え方を、2 回、訂正した
- 最初は、全記事で数えて、「1,398 件中 1,204 件が、締切なし(86%)」と出しました。締切は、抽選だけの概念です。先着の販売(1,055 件)と予約(91 件)には、元々ありません。項目の意味を、確かめずに数えました。
- 「保存された塊が、別の店(98%)」と書きましたが、実際は、投稿の全文が保存されていて、先頭がたまたま Amazon だっただけでした。先頭のマーカーだけを見て、断定しました。
見つけた穴と、直し
1. まとめの表に残る「終わった回」を、毎日取り込んでいた(33 件)
相手のまとめサイトは、過去の回も、表に残します。実データでは、あるお店の「7 月 13 日〜14 日」を、8 月 27 日に取り込み、締切は過去なので採用されず、締切が空の記事になっていました。締切が無いと、「締切が過ぎたら消す」仕組みが働かず、永久に残ります。
入口を、3 段で塞ぎました。
- 受付期間を日付で読んで、終了済みの行は、取らない。
- 締切が取れなければ、作らない。
- 店の行が終了済みなら、作らない。
実地で確かめました。印を消して、取り込みを再実行し、24 店を読んで、新規は 0 件でした。
2. 応募リンクが、応募ページでなかった(報告 5 件)
検索結果のページ(?keywords=)や、サイトのトップページが、行き先として採用されていました。応募リンクを採用する、唯一の関門に、「検索結果の URL らしさ」と「トップページの URL らしさ」の判定を足しました。全部の経路が、この関門 1 本を通るので、ここだけで効きます。
3. 記事が投稿の全文を持ち、読む側が切り忘れると、先頭の店を読む(39 件)
記事の元の文(sourceText)には、その店の塊だけを入れるようにしました。全文は、検証用に、別の項目へ。読む側が何をしても、別の店の値を拾えない形にしました。
4. 締切が、自分の店の行と食い違っていた(6 件中 5 件)
締切は、「本文の塊、応募リンク先、添付の画像」の順に探します。しかし、あとの 2 つは、その店の情報とは限りません。実データでは、保存された締切と、その店の行が、53 日、18 日、20 日ずれていました。どれも、終わった抽選が、受付中として並ぶ状態です。
「終わりが明示されたときだけ返す」関数を作り、締切を確定させる最後に、行と食い違ったら、行を信じる関門を入れました。注意点は、「6 月 19 日〜」のような、始まりだけの行でも、その日を返す関数を、そのまま上書きに使ってはいけないことです。
掃除は、ドライランから
- 「締切が無い記事を隠す」処理:33 件。実行する前に、1 件ずつ、自分の行の期間を読み、33 件全部が終了済みで、受付中は 0 件と確かめてから、実行。
- 「締切を、行に合わせ直す」処理:5 件。隠さず、過ぎていれば、既存の締切超過の仕組みに、消させる。
どちらの修復も、毎日 4 時 20 分と 4 時 30 分に、自動で実行するようにしました(190 個から 192 個)。
結果
| 対応前 | 対応後 | |
|---|---|---|
| 表示中の抽選 | 252 件 | 199 件 |
| 締切なし | 58 件 | 25 件 |
| まとめ A 由来の締切なし | 33 件 | 0 件 |
| 締切が過ぎたまま表示 | 5 件 | 0 件 |
| 「相手は終了、こちらは受付中」 | 12 件 | 7 件 |
残る 7 件は、こちらが新しい回をつかんでいる側の可能性が高いものです(相手の表が古い)。
分かったこと
経路ごとに数える。そして、数え方そのものを疑う。
- 経路ごとに、数える。どこから変な記事が入るのかが、表で見えます。
- 項目の意味を、確かめてから数える。締切は、抽選だけの概念でした。
- 先頭のマーカーだけで、断定しない。全文が保存されていただけでした。
- 締切が取れなければ、作らない。空の締切の記事は、永久に残ります。
- 別の店の値を拾えない形にする。読む側の注意に、頼らない。
- 食い違ったら、その店の行を信じる。応募リンク先や画像は、その店の情報とは限りません。
この話に出てくるもの
- トレカダッシュ — トレカの抽選・予約・先着の情報を集める iPhone アプリ
- 表示中の記事のリンク先を、実際に開いて確かめた — 別の角度の点検
- 競合サイトと突き合わせて、取りこぼしを数えた — まとめサイトとの突き合わせ
- 「同じ応募ページ」なら「同じ店」と決めつけていた — まとめ由来の別の問題
ほかの記録
- 「自動化できるものは全部自動化して」:まず数えると、修復処理 66 個が一度も定期実行から呼ばれていなかった。全部は載せず、6 個だけ載せた — HTTP の 319 個と定期実行の 184 個を呼び出しで突き合わせると、66 個が手で叩かないと動かなかった。継続的なものだけを、下見のあとで 6 個載せた。キューに積む処理が順番待ちを見ておらず、待ち行列が伸び続けていたことも直した。
- 「気づくだけでなく、そもそも起こさない」:報告だけの監視を、見つけてその場で埋める形に作り替えた — 取りこぼしの監視は報告するだけで、人が気づくまで埋まらなかった。見つけたその場で記事を作る形にし、黙って捨てる分岐にログを入れ、リンクが無い記事も応募方法を出した。カバー率は 92% から 100% に。
- 同じ報告が 3 回目:SwiftUI のボタンが「文字の上でしか」反応しなかった。過去 2 回の「修正」は効いていなかった — 「当選」「落選」ボタンが文字の上しか反応しない報告は 3 回目。過去 2 回は修飾子の順序を直しても効かず、ButtonStyle の中で見た目を組み立てて、6 か所を差し替えた。同じ日の「郵送なのに位置情報」も同じ根っこだった。
コメント
感想や、記事の間違いの指摘は、ここへ。書くには、GitHub のアカウントが要ります。
押すと、giscus(giscus.app)と GitHub に接続します。押さなければ、接続しません。詳しくはあつかいに書いています。