Trim the state database; Popular lists feeds the way Directory does
Drops the created columns on users, subscriptions and sessions, which were written by every insert and read by nothing, and migrate()'s add list, whose columns all predate 0.3.0. Removes Db::subscribed_feed_ids (no callers), Db::subscriber_count (one caller wanting > 0) and Managed.orphaned (never read). The old-database test now builds the tables with foreign keys on. Popular now lists the feeds inside an OPML or a Patreon creator, never the collection, as Directory does. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TAC7sLVqfKmY6rsTLXzNgk
This commit is contained in:
@@ -50,10 +50,10 @@ entries feed_id, guid, title, link, published, description, first_seen,
|
||||
image, duration, episode, season PK (feed_id, guid)
|
||||
enclosures id, feed_id, guid, url UNIQUE, mime, length, path, state,
|
||||
bytes_done, downloaded_at, last_error
|
||||
users id, name, pass_hash, is_admin, created
|
||||
sessions token, user_id, created, seen
|
||||
users id, name, pass_hash, is_admin
|
||||
sessions token, user_id, seen
|
||||
subscriptions user_id, feed_id, keywords, auto_download, allow_explicit,
|
||||
max_new_per_check, created PK (user_id, feed_id)
|
||||
max_new_per_check PK (user_id, feed_id)
|
||||
entry_state user_id, feed_id, guid, read, flagged, position
|
||||
PK (user_id, feed_id, guid)
|
||||
```
|
||||
@@ -62,9 +62,12 @@ Read state is `entry_state` alone. `entries` had `read`, `flagged` and `position
|
||||
before accounts; two bugs came from queries still reading them, and `migrate()` drops them from an
|
||||
older database.
|
||||
|
||||
Schema changes: add the table or column to `SCHEMA`, and for a column also to the list in
|
||||
`migrate()`, which does `PRAGMA table_info` then `ALTER TABLE ADD COLUMN`. `Db::memory()` runs the
|
||||
same path as `Db::open`, so a migration-only column cannot pass tests while missing in production.
|
||||
Schema changes: add the table or column to `SCHEMA`. `CREATE TABLE IF NOT EXISTS` leaves a table
|
||||
that already exists alone, so a new column on one also needs an `ALTER TABLE ADD COLUMN` in
|
||||
`migrate()`, checked with `PRAGMA table_info` the way its `retired` list is for drops. None is
|
||||
needed today: every column added so far predates 0.3.0, the oldest version an upgrade may start
|
||||
from. `Db::memory()` runs the same path as `Db::open`, so a migration cannot pass the tests while
|
||||
missing in production.
|
||||
|
||||
## Control socket
|
||||
|
||||
@@ -115,7 +118,7 @@ else a `401`.
|
||||
| `POST /api/enclosures/{id}/download`, `DELETE /api/enclosures/{id}` | `?force=true` overrides the shared-file warning |
|
||||
| `POST /api/fetch` | |
|
||||
| `GET /api/opml`, `POST /api/opml` | export your subscriptions; subscribe to every feed in an OPML |
|
||||
| `GET /api/popular`, `GET /api/directory`, `POST /api/popular/{id}` | the ten most subscribed feeds with an OPML counted as one, and every listable feed A to Z with an OPML's feeds in place of the OPML, with everyone counted (id, title, art, count, whether it is yours; never a URL, never a private feed); subscribe by id |
|
||||
| `GET /api/popular`, `GET /api/directory`, `POST /api/popular/{id}` | the ten most subscribed feeds, and every listable feed A to Z, with an OPML's feeds in place of the OPML and everyone counted (id, title, art, count, whether it is yours; never a URL, never a private feed); subscribe by id |
|
||||
| `GET /api/settings`, `PATCH /api/settings` | admin-only to write |
|
||||
| `GET /api/users`, `POST /api/users`, `PATCH /api/users/{id}`, `DELETE /api/users/{id}` | admin-only; the only admin cannot be demoted or removed |
|
||||
| `GET /api/events` | SSE, the same broadcast the socket carries |
|
||||
|
||||
@@ -6,6 +6,22 @@ reasoning lives. New write-ups go at the top.
|
||||
|
||||
See [README.md](../README.md) for what the thing is.
|
||||
|
||||
## 2026-09-12 — Trimming the state database
|
||||
|
||||
An audit of the database layer, with a read-only copy of production to check it against. The
|
||||
data was already clean: no tables or indexes left from older versions, 47 free pages after the
|
||||
column drops earlier the same day, and one stray `entry_state` row. The code had five things:
|
||||
|
||||
- `migrate()` still added eight columns to any table missing them. All eight shipped in 0.2.0 and
|
||||
upgrades now start from 0.3.0 at the oldest, so the list and its loop went; the `retired` drop
|
||||
list stays, since a database coming from 0.4.0 still has the old read columns.
|
||||
- `created` on `users`, `subscriptions` and `sessions` was written by every insert and read by
|
||||
nothing. They joined `retired`. The old-database test now builds all three tables, foreign keys
|
||||
included, since `DROP COLUMN` on a table that references another was the part worth proving.
|
||||
- `Db::subscribed_feed_ids` had no callers, though its doc said the scanner walked it.
|
||||
`Db::subscriber_count` had one caller asking whether it was above zero, which
|
||||
`subscriber_counts().contains_key` answers. `Managed.orphaned` was selected and never read.
|
||||
|
||||
## 2026-09-12 — Cutting what had outlived its reason
|
||||
|
||||
A whole-repo audit for over-engineering listed twelve things to cut, and all of them went.
|
||||
|
||||
@@ -73,10 +73,9 @@ re-subscribing does not pull the back catalogue again.
|
||||
**Popular** and **Directory** sit at the top of the feed list, above your own feeds. Popular, also
|
||||
shown in the Add feed dialog, lists the ten feeds with the most subscribers on this server, you
|
||||
included. Directory lists every one of them A to Z. Your own feeds are marked Subscribed.
|
||||
It shows a title, artwork and a count, never a URL or who reads it. An OPML subscription is one
|
||||
feed in Popular, since everyone subscribed to it counts for every feed inside; Directory lists the
|
||||
feeds inside it one by one instead, and never the OPML, so you can take just the shows you want.
|
||||
Anything that looks private is left out: a login configured for the feed, credentials in its URL,
|
||||
It shows a title, artwork and a count, never a URL or who reads it. An OPML subscription is listed
|
||||
as the feeds inside it, one by one, and never the OPML itself, so you can take just the shows you
|
||||
want. Anything that looks private is left out: a login configured for the feed, credentials in its URL,
|
||||
or a key such as `auth=` or `token=` in the query, or a feed from a paid-feed service such as
|
||||
Patreon or Supercast, which put the key in the path, and any feed inside an OPML that looks private
|
||||
itself. Those are someone's paid subscriptions, and listing them would let anyone here read what
|
||||
|
||||
Reference in New Issue
Block a user