Skip to content

decision(lists): list folders still ship on the web but were removed from macOS #49

Description

@Adron

Summary

List Folders were removed from the macOS app in PR #19 (refactor/lists-remove-list-folders, merged 2026-09-06) on the understanding that the feature was retired. It was not. The web app still ships a full list-folder tree, the API still serves it, and /help/lists documents it in detail as a current subscriber feature.

This is now a one-way parity divergence: lists organised into folders on the web appear flat on the Mac, and a folderId set elsewhere is invisible and uneditable here.

Evidence (live, 2026-09-07)

The routes are live and Bearer-reachable:

GET    /api/folders        → 200  {"folders":[]}          (test account has none)
POST   /api/folders                                       (subscriber-gated)
PUT    /api/folders/{id}
DELETE /api/folders/{id}

Their OpenAPI summaries:

  • GET — "Get all non-deleted list folders for the authenticated user"
  • POST — "Create a new list folder (subscribers only)"
  • PUT — "Rename or move a list folder"
  • DELETE — "Soft-delete a list folder; detach its lists first"

And every list row carries folderId — visible in the GET /api/lists/watching payload probed the same day.

/help/lists ▸ List folders (current, subscriber feature):

  • "a folder can hold lists, other folders, or both, so you can build whatever hierarchy works best"
  • Creating: New Folder on the Lists page, name 1–80 chars, optional parent; names unique among siblings
  • Subfolders: "There is no separate subfolder action; any folder you create with a parent set becomes a subfolder" — nest as deeply as you like
  • Moving a folder: pick a new parent or "No parent (root)"; a folder cannot be moved underneath itself or one of its own descendants
  • Moving a list into a folder: the list's Edit Schema view, Folder field, or "No folder" to return it to the top level
  • Renaming; Deleting ("removes any subfolders inside it, but never deletes lists: any lists in the removed folders are moved back to the top level")

/help/getting-started also lists "Lists tree: A navigable tree of your lists and list folders" as a Dashboard element.

⚠️ Owner decision required before any code

Two defensible positions:

  1. Rebuild it. The web ships it, the API serves it, and folder structure created on the web is currently invisible on the Mac. Restore feature parity.
  2. Keep the divergence deliberately. The macOS app already has owned-list parentID parent/child nesting (unaffected by PR refactor(lists): remove the List Folders feature, keep parent/child list nesting #19 and still shipping), which covers much of the same organising need. If folders are genuinely being retired platform-wide, the right move is to leave macOS as-is and let the web catch up.

What is not defensible is the current state, where the divergence is undocumented and reads as an oversight. Whichever way this goes, record the decision in docs/decisions/ so the next parity sweep does not re-file this issue.

⚠️ Note that GitHub issue #28 ("New Folder still shows up in Lists") was closed as stale against a pre-PR-#19 binary. That was correct at the time and is unrelated to this — that issue was about a leftover control, this is about the absent feature.

Division of labor — only if the decision is "rebuild"

Kit

  • Restore FoldersEndpoint (the four routes above) and its DTO. Much of this can be recovered from git history: git show 1afb89d is the removal commit.
  • Add folderId to the list create/update request bodies.
  • Contract tests against a folder actually created on the test account (there are none today, so the populated shape is unverified — create one and record it).

Domain

  • ListFolder model + a tree projection that handles arbitrary nesting.
  • ListsService folder CRUD, with create gated on the subscriber entitlement.
  • Enforce the documented invariants client-side so the user gets an immediate answer instead of a server error: unique name among siblings, 1–80 chars, and no move under self or a descendant (a cycle check).
  • Deleting a folder cascades to subfolders and re-parents its lists to root — model this so the UI can warn accurately.

App

  • Folder tree in the Lists sidebar with create / rename / move / delete.
  • A Folder picker in the list's schema-edit view, including "No folder".
  • Delete confirmation that states exactly what happens to subfolders and to the lists inside.

Tests

  • happy — create, rename, move, delete round-trip
  • invalid — duplicate sibling name; 0-char and 81-char names; moving a folder under its own descendant
  • upstream-failure — delete rejected because lists must be detached first → actionable message, tree unchanged
  • boundary — deeply nested folders; deleting a folder with subfolders and lists

Acceptance criteria

  • A decision is recorded in docs/decisions/, whichever way it goes.
  • If rebuilt: folder structure created on the web is visible and editable on the Mac, and vice versa.
  • Full E2E gate green.

Notes

New finding from the 2026-09-07 parity sweep. This effectively re-opens the old G6. Sized M if rebuilt, XS if the divergence is confirmed deliberate.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-decisionOwner decision required before any codeparityWeb-parity gap with the InterlinedList web appwontfixThis will not be worked on

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions