Audit Run 14: tests, indexes, JSDoc, plugin comments, migration headers
- Add composite index on (feed_id, published_at DESC) for item listing
- Add header comments to all migration files
- Add inline comments to all 11 bundled Rhai plugins
- Add JSDoc parameter types across frontend JS
- Add E2E fetch-encrypt-store pipeline test
- Add full plugin lifecycle test (load, fetch, error, circuit break)
- Add 12 sync tests (6 upload, 6 pull/download) with wiremock
- Add wiremock dev-dependency for sync integration testing
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
41 files changed,
+1995 insertions,
-87 deletions
| 137 |
137 |
|
]
|
| 138 |
138 |
|
|
| 139 |
139 |
|
[[package]]
|
|
140 |
+ |
name = "assert-json-diff"
|
|
141 |
+ |
version = "2.0.2"
|
|
142 |
+ |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
143 |
+ |
checksum = "47e4f2b81832e72834d7518d8487a0396a28cc408186a2e8854c0f98011faf12"
|
|
144 |
+ |
dependencies = [
|
|
145 |
+ |
"serde",
|
|
146 |
+ |
"serde_json",
|
|
147 |
+ |
]
|
|
148 |
+ |
|
|
149 |
+ |
[[package]]
|
| 140 |
150 |
|
name = "atk"
|
| 141 |
151 |
|
version = "0.18.2"
|
| 142 |
152 |
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
| 214 |
224 |
|
"tracing-subscriber",
|
| 215 |
225 |
|
"ureq",
|
| 216 |
226 |
|
"uuid",
|
|
227 |
+ |
"wiremock",
|
| 217 |
228 |
|
]
|
| 218 |
229 |
|
|
| 219 |
230 |
|
[[package]]
|
| 849 |
860 |
|
]
|
| 850 |
861 |
|
|
| 851 |
862 |
|
[[package]]
|
|
863 |
+ |
name = "deadpool"
|
|
864 |
+ |
version = "0.12.3"
|
|
865 |
+ |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
866 |
+ |
checksum = "0be2b1d1d6ec8d846f05e137292d0b89133caf95ef33695424c09568bdd39b1b"
|
|
867 |
+ |
dependencies = [
|
|
868 |
+ |
"deadpool-runtime",
|
|
869 |
+ |
"lazy_static",
|
|
870 |
+ |
"num_cpus",
|
|
871 |
+ |
"tokio",
|
|
872 |
+ |
]
|
|
873 |
+ |
|
|
874 |
+ |
[[package]]
|
|
875 |
+ |
name = "deadpool-runtime"
|
|
876 |
+ |
version = "0.1.4"
|
|
877 |
+ |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
878 |
+ |
checksum = "092966b41edc516079bdf31ec78a2e0588d1d0c08f78b91d8307215928642b2b"
|
|
879 |
+ |
|
|
880 |
+ |
[[package]]
|
| 852 |
881 |
|
name = "der"
|
| 853 |
882 |
|
version = "0.7.10"
|
| 854 |
883 |
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
| 1735 |
1764 |
|
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
| 1736 |
1765 |
|
|
| 1737 |
1766 |
|
[[package]]
|
|
1767 |
+ |
name = "hermit-abi"
|
|
1768 |
+ |
version = "0.5.2"
|
|
1769 |
+ |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1770 |
+ |
checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"
|
|
1771 |
+ |
|
|
1772 |
+ |
[[package]]
|
| 1738 |
1773 |
|
name = "hex"
|
| 1739 |
1774 |
|
version = "0.4.3"
|
| 1740 |
1775 |
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
| 1871 |
1906 |
|
checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
|
| 1872 |
1907 |
|
|
| 1873 |
1908 |
|
[[package]]
|
|
1909 |
+ |
name = "httpdate"
|
|
1910 |
+ |
version = "1.0.3"
|
|
1911 |
+ |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1912 |
+ |
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
|
|
1913 |
+ |
|
|
1914 |
+ |
[[package]]
|
| 1874 |
1915 |
|
name = "hyper"
|
| 1875 |
1916 |
|
version = "1.8.1"
|
| 1876 |
1917 |
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
| 1884 |
1925 |
|
"http",
|
| 1885 |
1926 |
|
"http-body",
|
| 1886 |
1927 |
|
"httparse",
|
|
1928 |
+ |
"httpdate",
|
| 1887 |
1929 |
|
"itoa 1.0.17",
|
| 1888 |
1930 |
|
"pin-project-lite",
|
| 1889 |
1931 |
|
"pin-utils",
|
| 2716 |
2758 |
|
]
|
| 2717 |
2759 |
|
|
| 2718 |
2760 |
|
[[package]]
|
|
2761 |
+ |
name = "num_cpus"
|
|
2762 |
+ |
version = "1.17.0"
|
|
2763 |
+ |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2764 |
+ |
checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b"
|
|
2765 |
+ |
dependencies = [
|
|
2766 |
+ |
"hermit-abi",
|
|
2767 |
+ |
"libc",
|
|
2768 |
+ |
]
|
|
2769 |
+ |
|
|
2770 |
+ |
[[package]]
|
| 2719 |
2771 |
|
name = "num_enum"
|
| 2720 |
2772 |
|
version = "0.7.5"
|
| 2721 |
2773 |
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
| 6823 |
6875 |
|
]
|
| 6824 |
6876 |
|
|
| 6825 |
6877 |
|
[[package]]
|
|
6878 |
+ |
name = "wiremock"
|
|
6879 |
+ |
version = "0.6.5"
|
|
6880 |
+ |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
6881 |
+ |
checksum = "08db1edfb05d9b3c1542e521aea074442088292f00b5f28e435c714a98f85031"
|
|
6882 |
+ |
dependencies = [
|
|
6883 |
+ |
"assert-json-diff",
|
|
6884 |
+ |
"base64 0.22.1",
|
|
6885 |
+ |
"deadpool",
|
|
6886 |
+ |
"futures",
|
|
6887 |
+ |
"http",
|
|
6888 |
+ |
"http-body-util",
|
|
6889 |
+ |
"hyper",
|
|
6890 |
+ |
"hyper-util",
|
|
6891 |
+ |
"log",
|
|
6892 |
+ |
"once_cell",
|
|
6893 |
+ |
"regex",
|
|
6894 |
+ |
"serde",
|
|
6895 |
+ |
"serde_json",
|
|
6896 |
+ |
"tokio",
|
|
6897 |
+ |
"url",
|
|
6898 |
+ |
]
|
|
6899 |
+ |
|
|
6900 |
+ |
[[package]]
|
| 6826 |
6901 |
|
name = "wit-bindgen"
|
| 6827 |
6902 |
|
version = "0.51.0"
|
| 6828 |
6903 |
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
| 61 |
61 |
|
tauri = "2.10.2"
|
| 62 |
62 |
|
tauri-plugin-updater = "2"
|
| 63 |
63 |
|
tagtree = { path = "../../MNW/shared/tagtree" }
|
|
64 |
+ |
wiremock = "0.6"
|
|
1 |
+ |
-- Feature: Feed storage
|
| 1 |
2 |
|
-- Create feeds table for registered bussers/sources
|
| 2 |
3 |
|
CREATE TABLE IF NOT EXISTS feeds (
|
| 3 |
4 |
|
id TEXT PRIMARY KEY,
|
|
1 |
+ |
-- Feature: Feed items
|
| 1 |
2 |
|
-- Create feed_items table for all fetched items
|
| 2 |
3 |
|
CREATE TABLE IF NOT EXISTS feed_items (
|
| 3 |
4 |
|
id TEXT PRIMARY KEY,
|
|
1 |
+ |
-- Feature: Busser state
|
| 1 |
2 |
|
-- Create busser_state table for key-value state storage
|
| 2 |
3 |
|
CREATE TABLE IF NOT EXISTS busser_state (
|
| 3 |
4 |
|
id TEXT PRIMARY KEY,
|
|
1 |
+ |
-- Feature: Feed tags
|
| 1 |
2 |
|
-- Feed tags: user-assigned flat tags on feeds for organization.
|
| 2 |
3 |
|
CREATE TABLE IF NOT EXISTS feed_tags (
|
| 3 |
4 |
|
feed_id TEXT NOT NULL REFERENCES feeds(id) ON DELETE CASCADE,
|
|
1 |
+ |
-- Feature: Full-text search
|
| 1 |
2 |
|
-- Full-text search index using FTS5 in external content mode.
|
| 2 |
3 |
|
-- No data duplication: the FTS index references feed_items via rowid.
|
| 3 |
4 |
|
CREATE VIRTUAL TABLE IF NOT EXISTS feed_items_fts USING fts5(
|
|
1 |
+ |
-- Feature: Feed health tracking
|
| 1 |
2 |
|
-- Feed health tracking columns.
|
| 2 |
3 |
|
ALTER TABLE feeds ADD COLUMN consecutive_failures INTEGER NOT NULL DEFAULT 0;
|
| 3 |
4 |
|
ALTER TABLE feeds ADD COLUMN last_error TEXT;
|
|
1 |
+ |
-- Feature: Cloud sync
|
| 1 |
2 |
|
-- SyncKit cloud sync tables and triggers.
|
| 2 |
3 |
|
|
| 3 |
4 |
|
-- Key-value preferences store (Phase 6A).
|
|
1 |
+ |
-- Feature: Circuit breaker
|
| 1 |
2 |
|
-- Circuit breaker: auto-disable feeds after too many consecutive failures.
|
| 2 |
3 |
|
ALTER TABLE feeds ADD COLUMN circuit_broken INTEGER NOT NULL DEFAULT 0;
|
| 3 |
4 |
|
|
|
1 |
+ |
-- Feature: Query feeds
|
| 1 |
2 |
|
-- Query feeds: saved filter rules that act as virtual sources.
|
| 2 |
3 |
|
|
| 3 |
4 |
|
CREATE TABLE IF NOT EXISTS query_feeds (
|
|
1 |
+ |
-- Feature: Item actions
|
| 1 |
2 |
|
ALTER TABLE feed_items ADD COLUMN actions TEXT NOT NULL DEFAULT '[]';
|
|
1 |
+ |
-- Feature: Composite index for list-items-by-feed query
|
|
2 |
+ |
-- Replaces single-column idx_feed_items_feed_id with a composite index
|
|
3 |
+ |
-- on (feed_id, published_at DESC) to eliminate the sort step in:
|
|
4 |
+ |
-- SELECT * FROM feed_items WHERE feed_id = ? ORDER BY published_at DESC
|
|
5 |
+ |
|
|
6 |
+ |
DROP INDEX IF EXISTS idx_feed_items_feed_id;
|
|
7 |
+ |
|
|
8 |
+ |
CREATE INDEX IF NOT EXISTS idx_feed_items_feed_published
|
|
9 |
+ |
ON feed_items(feed_id, published_at DESC);
|
| 1 |
|
- |
// arXiv Plugin for BalancedBreakfast
|
| 2 |
|
- |
// Fetches papers from arXiv by category
|
|
1 |
+ |
// arXiv preprint feed. Queries the arXiv Atom API by category (e.g. cs.AI).
|
|
2 |
+ |
// Parses results with parse_feed(); provides PDF and ar5iv HTML actions.
|
| 3 |
3 |
|
|
| 4 |
4 |
|
const ARXIV_API = "http://export.arxiv.org/api/query";
|
| 5 |
5 |
|
|
| 1 |
|
- |
// Dev.to Plugin for BalancedBreakfast
|
| 2 |
|
- |
// Fetches articles from the Dev.to community API
|
|
1 |
+ |
// Dev.to article feed. Queries the public Forem API with optional tag
|
|
2 |
+ |
// filtering. Extracts reaction/comment counts and reading time from
|
|
3 |
+ |
// the JSON response. Renders cover images inline when present.
|
| 3 |
4 |
|
|
| 4 |
5 |
|
const DEVTO_API = "https://dev.to/api/articles";
|
| 5 |
6 |
|
|
| 1 |
|
- |
// USGS Earthquakes Plugin for BalancedBreakfast
|
| 2 |
|
- |
// Fetches recent earthquake data from the USGS GeoJSON feed
|
|
1 |
+ |
// USGS earthquake feed. Fetches GeoJSON from the USGS summary endpoint.
|
|
2 |
+ |
// Configurable magnitude threshold and time window. Converts millisecond
|
|
3 |
+ |
// timestamps to seconds; color-codes severity by magnitude bracket.
|
| 3 |
4 |
|
|
| 4 |
5 |
|
const USGS_API = "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary";
|
| 5 |
6 |
|
|
| 1 |
|
- |
// GitHub Trending Plugin for BalancedBreakfast
|
| 2 |
|
- |
// Fetches trending repositories via the GitHub search API (no auth required)
|
|
1 |
+ |
// GitHub trending repos. Approximates trending by searching the GitHub
|
|
2 |
+ |
// search API for repos with >100 stars, sorted by star count. Optional
|
|
3 |
+ |
// language filter; no auth required. Formats star counts as "Nk" display.
|
| 3 |
4 |
|
|
| 4 |
5 |
|
const GH_API = "https://api.github.com/search/repositories";
|
| 5 |
6 |
|
|
| 1 |
|
- |
// Hacker News Plugin for BalancedBreakfast
|
| 2 |
|
- |
// Fetches stories from Hacker News API
|
|
1 |
+ |
// Hacker News story feed. Fetches story IDs then individual items from
|
|
2 |
+ |
// the Firebase JSON API. Supports top/new/best/ask/show/job story types.
|
|
3 |
+ |
// Strips basic HTML from self-post text; paginates via offset cursor.
|
| 3 |
4 |
|
|
| 4 |
5 |
|
const HN_API = "https://hacker-news.firebaseio.com/v0";
|
| 5 |
6 |
|
|
| 1 |
|
- |
// Lobsters Plugin for BalancedBreakfast
|
| 2 |
|
- |
// Fetches stories from Lobste.rs — computing-focused link aggregation
|
|
1 |
+ |
// Lobste.rs link-aggregation feed. Fetches stories from the public JSON
|
|
2 |
+ |
// API with hottest/newest/active ordering. Paginates by page number.
|
| 3 |
3 |
|
|
| 4 |
4 |
|
const LOBSTERS_URL = "https://lobste.rs";
|
| 5 |
5 |
|
|
| 1 |
|
- |
// NASA Astronomy Picture of the Day Plugin for BalancedBreakfast
|
| 2 |
|
- |
// Fetches recent APODs from the NASA API (free DEMO_KEY included)
|
|
1 |
+ |
// NASA Astronomy Picture of the Day. Fetches random recent APODs from the
|
|
2 |
+ |
// NASA planetary API. Uses DEMO_KEY by default (30 req/hr); supports both
|
|
3 |
+ |
// image and video media types. Displays HD image when available.
|
| 3 |
4 |
|
|
| 4 |
5 |
|
const NASA_API = "https://api.nasa.gov/planetary/apod";
|
| 5 |
6 |
|
|