feat(collections): new podcast smart collections are BORN reversed

Per user request, same shape as 0e29eff7 — a default flip, no internal
logic changes: POST /api/collections with an episodes-scope filter_tree
now seeds view_settings.chain_order = "reverse" on the new row, so the
collection lands with "Feed order (reversed)" selected in the detail
header's dropdown and the chain/page order follows the stored value as
if picked. Books-scope smart collections and statics get nothing
seeded; an explicit client chain_order is never clobbered; existing
collections are untouched (the seed exists only at creation).

Pins: TestSmartCollectionBornReversed (episodes seeded, explicit keep,
books-scope and static no-seed); TestEpisodeCollectionsFilterTree's
native expectations flip to the born-reversed reality (changelogged).
One misplaced pin from 81e54f89 corrected: the API envelope's match
list is not chain-ordered and never was — order pins live on the SSR
page and reader chain.
This commit is contained in:
John O'Keefe committed 2026-11-01 11:53:24 -05:00
1 parent 0e29eff7b7
commit d56031f334
3 files changed
+106 -8

No files matched your search

+18
View File
@@ -263,6 +263,24 @@ func (h *CollectionHandler) CreateCollection(c *echo.Context) error {
}
treeJSON = b
}
// New podcast smart collections are BORN with the reversed listening
// default (2026-11-01 user request): seed chain_order into
// view_settings at creation — the dropdown shows "Feed order
// (reversed)" selected and the chain/page machinery reads the stored
// value exactly as if picked. Episodes-scope trees only (books have
// no episode chain); merge semantics never clobber a value the
// request itself sent; existing collections are untouched.
if treeJSON != nil {
if t, perr := services.ParseFilterTree(string(treeJSON)); perr == nil &&
t.FilterScope() == services.ScopeEpisodes {
if req.ViewSettings == nil {
req.ViewSettings = map[string]interface{}{}
}
if _, exists := req.ViewSettings["chain_order"]; !exists {
req.ViewSettings["chain_order"] = "reverse"
}
}
}
collection, err := h.collectionService.CreateCollection(
c.Request().Context(),
userUUID,