Skip to content

blocked: backend asks - following feed, session-only routes, article_series 502, shape confirmations #58

Description

@Adron

Summary

A single place to record and act on the remaining backend dependencies. Each carries a paste-ready prompt for the InterlinedList API session (base URL https://interlinedlist.com). None of these can be closed from the client.

Nothing here blocks the rest of the parity work — every other open parity issue is client-buildable today. This issue exists so the asks are tracked rather than rediscovered on each sweep.


1. Following / home feed — the one high-impact blocker

Re-verified still broken 2026-09-05. An authenticated GET /api/messages?limit=50 and GET /api/messages?limit=50&scope=following return the identical 50 messages from the identical author set, a month after the first report. MessagesService.timeline short-circuits .following to an empty "coming soon" page (MessagesService.swift:364); the All/Mine/Following picker is fully wired and flips one branch the moment the feed exists.

This also blocks the Following Only option in the viewing-preference work.

PROMPT: Add a followed-accounts timeline feed. Preferred: extend GET /api/messages with ?scope=following (or add GET /api/feed/following), returning only messages authored by accounts the caller follows, using the same paginated envelope as GET /api/messages (same limit/offset/hasMore shape). Bearer auth. Document it. Note: as of 2026-09-05 the live server silently ignores scope/feed/following/filter on GET /api/messages, so this needs a real implementation, not just docs. The macOS client already has the UI wired and flips one branch to consume it.


2. Session-only routes lock out every Bearer client

The live OpenAPI spec declares 45 operations as x-auth-type: session"requires the web session cookie only; a Bearer token is not accepted". Setting aside admin, cron, Stripe, and architecture-aggregates, these are the ones a native app legitimately needs:

Route What it costs the native client
POST /api/lists/invite/{token} Cannot accept a list email invite
POST /api/documents/invite/{token} Cannot accept a document email invite
POST /api/lists/shared/{token} Cannot claim an editor/admin list share link
POST /api/documents/shared/{token} Cannot claim an editor/admin document share link
POST /api/auth/send-verification-email Cannot offer Resend verification email
GET /api/user/engagement No engagement stats (confirmed 401 under Bearer, 2026-09-07)
GET/PUT /api/user/dashboard-layout Dashboard is unbuildable
GET/PUT /api/user/front-wall-layout Front wall is unbuildable
GET /api/widgets/*, and by extension the widget surface Widgets are unbuildable
GET /api/auth/accounts, POST /api/auth/switch, POST /api/auth/remove-account Multi-account switching is unbuildable

The read halves (GET /api/lists/invite/{token} etc.) are public, so the client can show an invite landing page and then hand the user to the browser to accept — a poor but honest experience.

Note the spec's own prose is stale here: its description lists "exports, organizations, LinkedIn targets, GitHub helpers, message dig, message edit" as session-only, but the per-operation x-auth-type values show all of those as sync-token. Worth flagging in the same ask.

PROMPT: The macOS client authenticates with a Bearer sync token (POST /api/auth/sync-token). Several operations are declared x-auth-type: session and reject Bearer, which makes them unreachable for native and CLI clients. Please make the following Bearer-reachable, or document a supported alternative: (1) the claim/accept halves of the invite and share-link flows — POST /api/lists/invite/{token}, POST /api/documents/invite/{token}, POST /api/lists/shared/{token}, POST /api/documents/shared/{token}. Accepting an invite is documented as always free, so there is no entitlement reason for the restriction. (2) POST /api/auth/send-verification-email, so a native app can offer the documented "Resend verification email" action. (3) GET /api/user/engagement. Separately: the OpenAPI info.description lists exports, organizations, LinkedIn targets, GitHub helpers, message dig, and message edit as session-only, but their per-operation x-auth-type is sync-token — please reconcile the prose with the operation values.


3. article_series returns 502 provider_error on every attempt

Found 2026-09-05, re-confirmed 2026-09-06. POST /api/ai/suggest {"feature":"article_series"} fails with {"error":"The AI provider rejected the request.","code":"provider_error"} on three separate attempts across two days, with different briefs, all well over the ten-word minimum. The same account, key, and model succeed for writing_assist, message_series, powered_template, and powered_document — so it is not entitlement, quota, or input length. The macOS client blames the provider rather than the user, so it degrades honestly, but Article Series cannot work for any client until this is fixed.

PROMPT: POST /api/ai/suggest with {"feature":"article_series","input":"<a multi-sentence brief>"} returns 502 {"error":"The AI provider rejected the request.","code":"provider_error"} every time, for a subscriber whose other AI features (writing_assist, message_series, powered_template, powered_document) all succeed on the same request path. Reproduced three times across 2026-09-05 and 2026-09-06 with different briefs. Please check the article_series prompt/schema construction and what the provider is actually rejecting — likely a malformed tool/response schema for that feature specifically — and confirm the artifact shape it should return (the other features return {artifact:{kind,…}}).


4. GitHub issue shapes still cannot be exercised end-to-end

The test account is GitHub-linked now (GET /api/github/repos → 200, up from the old 400 "not linked"), but the repo list comes back empty and GET /api/github/orgs returns [] — so issue create/update/comment request and response envelopes remain unverified. The routes are settled (PR #24 repointed the client at the flat three-segment paths); only the payloads are unknown.

This one may not need the backend at all — granting the .env test account access to a single repository would unblock it locally. Try that first.


5. Smaller confirmations and additive niceties

Each is worked around today; these make the client correct or cheaper. Additive fields are always safe — the client decodes by name and ignores unknowns.

  • Auth decision on GET /api/messages (returns 200 with public content and no Authorization header). No client change either way; needs a documented decision. (P1-F)
  • Follow action returns followedBy — the client decodes {follow:{status}} and needs a second GET /api/follow/{userId}/status call. A relationship block on the follow/unfollow/approve/reject responses removes a round-trip. (P2-B)
  • Typed notification kinds + routePath — deep-linking works via a client-side typed projection; a stable routePath collapses it to a plain URL and unblocks APNs push routing. (P2-C)
  • Markdown export/api/exports/* is CSV-only, so the client renders Markdown itself, costing N+1 refetches for bulk export. (P2-F)
  • Schema DSL select/markdown token specField:select(a|b|c) is a client convention, still API-unconfirmed. This blocks the per-field validation work. (P2-G)
  • Document version / ETag for sync conflict detection. (P3-A)
  • folderId on sync-response documents, including preserved copies and deleted documents. (P3-B)
  • GitHub-backed list refresh metadata + githubSource on createlastRefreshedAt, refreshStatus, refreshError; blocks part of the GitHub-backed-lists work. (P3-C)
  • RateLimit-* headers universally — currently only on POST /api/messages and POST /api/documents/sync. (P3-E)
  • List clone-with-rows — "save to my lists" copies title/description/schema but no rows, because no clone endpoint exists. (P3-G)

Full paste-ready prompts for each live in work-consolidation.md §2c.


Acceptance criteria

  • Each numbered item is either resolved upstream or explicitly deferred with a reason.
  • When one lands, the client-side issue it blocks is unblocked and linked here.

Notes

Consolidates work-consolidation.md §2a and §2c. Re-verify before acting — three items previously filed as backend blockers (P1-H2, P2-I, P3-D) turned out to be client-side errors and were fixed in PR #24/#25. Probe first, ask second.

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

    blockedCannot proceed — backend-gated or spike-firstparityWeb-parity gap with the InterlinedList web app

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions