From 4f9e30dd9a46a9445b0725b60faa4a591cb05175 Mon Sep 17 00:00:00 2001 From: Adron Hall Date: Sat, 5 Sep 2026 22:59:13 -0700 Subject: [PATCH 1/2] fix(assets): strip alpha channel from the 1024 app icon The primary marketing icon shipped as RGBA. Every pixel was fully opaque, but App Store upload validation rejects the *presence* of an alpha channel (ITMS-90717), so this would have failed at the first archive upload. - Re-saved AppIcon-1024.png as RGB; RGB pixel data is byte-for-byte unchanged, so the artwork is identical - The dark-appearance variant keeps its alpha, which Apple expects for appearance-specific icons - Asset catalog compiles clean; build verified green after the change Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01WFg1zPdWuasXD9ab6HJGHk --- .../AppIcon.appiconset/AppIcon-1024.png | Bin 78832 -> 42180 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/InterlinedList/Assets.xcassets/AppIcon.appiconset/AppIcon-1024.png b/InterlinedList/Assets.xcassets/AppIcon.appiconset/AppIcon-1024.png index 1721481b083dd594c2f8910cb4f7d87807c1dd6a..dbed4d6ed6908a13baadde1dca6a45febcb6e2c8 100644 GIT binary patch literal 42180 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 Date: Sat, 5 Sep 2026 22:59:26 -0700 Subject: [PATCH 2/2] docs: refresh submission/parity/access docs and add App Store listing copy All three tracking docs had drifted behind the code, each in a way that overstated what was left to build. - the-gaps-access.md: G1-G7 were fixed 2026-08-15 and merged 2026-08-16 (PRs #17-#23) but the doc still read as an open backlog. Added a closure callout, a per-gap status column, and file/line evidence verified against the current tree; kept the free-user gating path as an open coverage note - App-Store-Deployment.md: section 0 still listed GitHub, tag discovery, offline sync, post-as-org, and doc inline images as unbuilt. Rewrote the shipped-phases table and feature summary, ticked Tier 0/Tier 1 (splitting Phase 9 into shipped code vs. the two open portal steps), converted the deferred-blockers table to statuses, added Associated Domains to the capability/App-ID steps, and extended the smoke-test list - the-gaps.md: the remaining-work row was stale (feat/github-oauth-universal- links is merged, supportsNativeAuth is true, the entitlement is in the repo). Split it into phases 17-19 plus the two genuinely open items (G11 presence, bare /lists/:id inbound) and updated asks A1/A2 - App-Store-Deployment-Checklist.md: rewritten around what is actually left, recording this session's verifications - privacy/support/terms URLs 200, AASA live with the right appID and cached by Apple's CDN, Release signing config, exactly two entitlements, and that no usage-description strings are needed (media comes only from out-of-process PhotosPicker) - Corrected the 6.5" screenshot device: iPhone 15 Plus renders 1290x2796, not 1242x2688. A verified 6.5" simulator (iPhone 11 Pro Max on iOS 17.5) is named in both docs; both capture sizes were confirmed against a running build - New App-Store-Listing-Copy.md: subtitle, promotional text, description, keywords, What's New, review notes, age-rating answers, and a privacy nutrition label audited against APIClient request bodies (adds Photos/Videos and Search History, which the old table missed). All fields length-checked and free of billing language per Guideline 3.1.1 - README: GitHub sign-in is no longer hidden; the backend mobile OAuth branch shipped 2026-08-14 Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01WFg1zPdWuasXD9ab6HJGHk --- App-Store-Deployment-Checklist.md | 69 +++++++---- App-Store-Deployment.md | 175 ++++++++++++++++++---------- App-Store-Listing-Copy.md | 184 ++++++++++++++++++++++++++++++ README.md | 2 +- the-gaps-access.md | 97 ++++++++++------ the-gaps.md | 33 ++++-- 6 files changed, 438 insertions(+), 122 deletions(-) create mode 100644 App-Store-Listing-Copy.md diff --git a/App-Store-Deployment-Checklist.md b/App-Store-Deployment-Checklist.md index cbb1c2a..c5a4a69 100644 --- a/App-Store-Deployment-Checklist.md +++ b/App-Store-Deployment-Checklist.md @@ -1,6 +1,16 @@ # App Store Deployment — Pre-Flight Checklist -Last updated: 2026-07-08 +Last updated: 2026-09-05 + +**Where we are:** iOS engineering for v1 is **done** — every deployment phase plus the +whole `the-gaps.md` parity backlog and the `the-gaps-access.md` access remediation have +shipped, and the last verification run was **823 unit tests, 0 failures, build green** +(E2E excluded). **Everything below that's still unchecked is submission logistics, not +code.** Full procedure for each item lives in `App-Store-Deployment.md`. + +**Critical path:** Apple portal (App ID + Push + Associated Domains → regen profile) → +APNs `.p8` → demo account → ASC record + listing copy + privacy label → screenshots → +build bump → archive → TestFlight device smoke test → submit. --- @@ -9,7 +19,10 @@ Last updated: 2026-07-08 - [x] Phase 0.5 — Info.plist hygiene done (`ITSAppUsesNonExemptEncryption`, `arm64`, icon) - [x] Phase 9 — Push notifications wired (PushService, register/unregister, `aps-environment: development` entitlement in place; Xcode auto-signing upgrades to production on archive) - [x] Phase 14 — UGC safety shipped (report message/user, block/unblock, mute, terms gate on register, blocked users in settings) -- [x] Unit tests — All 8 moderation API methods have bearer token + 401 error tests; `ModerationModelTests` covers `BlockedUser`/`MutedUser` Codable decoding +- [x] Phases 10, 11, 13b, 15, 16 shipped (doc inline images, GitHub integration, tag discovery, post-as-org, offline document sync) +- [x] `the-gaps.md` parity backlog closed — D1–D3, G1–G10, G12–G14 (G11 document presence is the only deliberate deferral) +- [x] `the-gaps-access.md` G1–G7 access-control remediation shipped (PRs #17–#23) +- [x] Unit tests — full suite green: **823 tests, 0 failures** (2026-09-05, `-skip-testing:InterlinedListTests/E2EReadOnlyTests`) --- @@ -21,9 +34,10 @@ Last updated: 2026-07-08 | Your role on team `BJA9558E4B` is Admin or App Manager | ☐ | Check in App Store Connect | | APNs Auth Key (.p8) created, Key ID recorded, handed to backend | ☐ | Portal → Certificates, IDs & Profiles → Keys → enable APNs; one-time download | | Demo reviewer account registered and confirmed working on production | ☐ | Register at interlinedlist.com with email/password; keep creds in password manager | -| Privacy Policy URL live | ✅ | `https://interlinedlist.com/privacy` → 200 (verified 2026-07-07) | -| Support URL live | ✅ | `https://interlinedlist.com/help` → 307 redirect (acceptable for ASC) | -| Community Guidelines / EULA URL live and linked from `RegisterView` | ✅ | `https://interlinedlist.com/terms` → 200 (verified 2026-07-07) | +| Privacy Policy URL live | ✅ | `https://interlinedlist.com/privacy` → 200 (re-verified 2026-09-05) | +| Support URL live | ✅ | `https://interlinedlist.com/help` → 200 (re-verified 2026-09-05; was a 307 in July) | +| Community Guidelines / EULA URL live and linked from `RegisterView` | ✅ | `https://interlinedlist.com/terms` → 200 (re-verified 2026-09-05) | +| Universal Links AASA served + cached by Apple | ✅ | `/.well-known/apple-app-site-association` → 200 `application/json`, `appID: BJA9558E4B.com.interlinedlist.app`; Apple CDN copy → 200 (verified 2026-09-05) | --- @@ -32,9 +46,10 @@ Last updated: 2026-07-08 | Item | Status | Notes | |---|---|---| | App ID `com.interlinedlist.app` registered in portal with Push Notifications enabled | ☐ | Portal → Identifiers → App IDs | -| Automatic signing, team `BJA9558E4B`, archive signs cleanly | ☐ | Target → Signing & Capabilities | -| No unused capabilities or entitlements | ☐ | Only `aps-environment` is present | -| Build number incremented from any prior upload | ☐ | `agvtool next-version -all` | +| **Associated Domains enabled on the App ID + provisioning profile regenerated** | ☐ | The entitlement (`applinks:interlinedlist.com`) is already in `InterlinedList.entitlements` and the backend AASA is live — **without the portal capability the archive won't provision** | +| Automatic signing, team `BJA9558E4B`, archive signs cleanly | ◑ | Config verified 2026-09-05 (`CODE_SIGN_STYLE=Automatic`, `DEVELOPMENT_TEAM=BJA9558E4B`, bundle id `com.interlinedlist.app`, iOS 17.0, `TARGETED_DEVICE_FAMILY=1`, `ITSAppUsesNonExemptEncryption=false`, `arm64`). The **archive itself hasn't been run** — it needs the portal capabilities first | +| No unused capabilities or entitlements | ✅ | Verified 2026-09-05 — exactly two: `aps-environment` and `com.apple.developer.associated-domains` | +| Build number incremented from any prior upload | ☐ | Currently `MARKETING_VERSION 1.0` / `CURRENT_PROJECT_VERSION 1`, never uploaded — `agvtool next-version -all` before each upload | --- @@ -47,24 +62,28 @@ Last updated: 2026-07-08 | Primary category: Social Networking | ☐ | App Information tab | | Privacy Policy URL entered | ☐ | `https://interlinedlist.com/privacy` | | Support URL entered | ☐ | `https://interlinedlist.com/help` | -| Age rating questionnaire completed | ☐ | Fill after Phase 14 confirmed — expected 17+ | +| Age rating questionnaire completed | ☐ | UGC social app with report/block/mute shipped — expected 17+ | --- ## Assets +*Listing copy, privacy-label answers, age-rating answers, and review notes are all +drafted in **`App-Store-Listing-Copy.md`** — paste them straight into ASC.* + | Item | Status | Notes | |---|---|---| -| App icon: no empty wells, no alpha channel (verified in Xcode asset catalog) | ☐ | `InterlinedList/Assets.xcassets/AppIcon.appiconset/AppIcon-1024.png` | -| Screenshots: 6.9" set uploaded (iPhone 16 Pro Max, 1320 × 2868 px) | ☐ | Minimum screens: Feed, Compose, Lists, Profile, Settings | -| Screenshots: 6.5" set uploaded (iPhone 15 Plus, 1242 × 2688 px) | ☐ | Same minimum screens | +| App icon: no empty wells, no alpha channel | ✅ | **Fixed 2026-09-05** — `AppIcon-1024.png` shipped as RGBA (fully opaque, but Apple rejects any alpha: ITMS-90717). Re-saved as RGB, pixels unchanged. The dark-appearance variant keeps its alpha, which Apple expects | +| Screenshots: 6.9" set captured (iPhone 16 Pro Max, 1320 × 2868 px) | ☐ | **Blocked on a logged-in session** — capture pipeline verified end to end (app installs, launches, `xcrun simctl io … screenshot` yields exactly 1320 × 2868), but this session has no simulator tap/type tooling, so the app can't be driven past the login screen. Use the `qa-screenshotter` agent or drive it by hand. Screens: Feed, Compose, Lists, Profile, Settings | +| Screenshots: 6.5" set captured (1242 × 2688 px) | ☐ | Same blocker. **Note: iPhone 15 Plus is 1290 × 2796, not 6.5"** — the earlier note in this file was wrong. A correct 6.5" device is provisioned: **`IL-6.5in-11ProMax`** (iPhone 11 Pro Max on iOS 17.5, UDID `C272D802-6737-46CC-A943-87C80749FF67`), verified to render at 1242 × 2688 | | App name (≤30 chars): "InterlinedList" | ☐ | Verify uniqueness in ASC at record creation | -| Subtitle (≤30 chars) | ☐ | e.g. "Social lists, shared" | -| Description (≤4,000 chars) | ☐ | | -| Keywords (≤100 chars total, comma-separated) | ☐ | | -| Promotional text (≤170 chars) | ☐ | Changeable without a new submission | -| What's New: "Initial release." | ☐ | | -| App Privacy nutrition label completed and saved in ASC | ☐ | See §4 in `App-Store-Deployment.md` for declared data types | +| Subtitle (≤30 chars) | ✅ drafted | "Social lists, shared" (20) — `App-Store-Listing-Copy.md` | +| Description (≤4,000 chars) | ✅ drafted | 1,944 chars, no billing language — `App-Store-Listing-Copy.md` | +| Keywords (≤100 chars total, comma-separated) | ✅ drafted | 90 chars — `App-Store-Listing-Copy.md` | +| Promotional text (≤170 chars) | ✅ drafted | 142 chars — `App-Store-Listing-Copy.md` | +| What's New: "Initial release." | ✅ drafted | `App-Store-Listing-Copy.md` | +| App Privacy nutrition label completed and saved in ASC | ✅ drafted | Audited against `APIClient` bodies 2026-09-05; adds **Photos/Videos** and **Search History**, which the old table missed — `App-Store-Listing-Copy.md` | +| Privacy usage-description strings in `Info.plist` | ✅ n/a | Verified 2026-09-05: media comes only from SwiftUI `PhotosPicker` (out-of-process), and there is no camera, location, contacts, or microphone use — **no usage-description strings required** | --- @@ -81,16 +100,22 @@ Last updated: 2026-07-08 ### Smoke-test checklist (real device, before submitting) - [ ] Email/password login and registration -- [ ] OAuth (at least one provider — Mastodon or Bluesky) -- [ ] Compose + post (text, image) +- [ ] OAuth (at least one provider — Mastodon or Bluesky); GitHub linking via the mobile OAuth branch +- [ ] Compose + post (text, multi-image); trending-tag strip and live link preview - [ ] Feed scroll, dig/undig, reply -- [ ] Lists and Documents CRUD -- [ ] Organizations list loads (Bearer auth fix shipped 2026-07-07) +- [ ] Lists and Documents CRUD; document inline image upload +- [ ] Direct Messages — inbox, open a thread, send, unread badge *(the recipient-tap fix from 2026-07-31 has never been re-driven by hand — exercise it here)* +- [ ] Sharing — create/copy/revoke a share-link; open a shared list/document link +- [ ] GitHub-backed list — add, close, and reopen an issue; confirm the list refreshes +- [ ] Offline document sync — edit in airplane mode, reconnect, confirm the edit persists +- [ ] Organizations list loads; post as an organization - [ ] Deep-link callbacks (`interlinedlist://reset-password`, `interlinedlist://verify-email`) +- [ ] Universal Links — tap an `https://interlinedlist.com/user/...` link and confirm it opens in-app - [ ] Push notification receipt and tap routing - [ ] Settings, sign-out, delete-account flow - [ ] Report a message (tap `...` on any post → Report) - [ ] Block a user (tap `...` on any post or visit their profile → Block) +- [ ] **Free (non-subscriber) account** — premium controls are hidden (not paywalled) and no upsell copy appears anywhere *(never yet exercised live; the only test account is a subscriber)* ### Review notes template diff --git a/App-Store-Deployment.md b/App-Store-Deployment.md index 436a16e..7eaa040 100644 --- a/App-Store-Deployment.md +++ b/App-Store-Deployment.md @@ -1,9 +1,23 @@ # App Store Deployment — InterlinedList iOS Single reference for getting the app from its current state to the App Store. -For the full context behind each item, see `GAP-APPLE.md`, `GAP-NEXT-STEPS.md`, -and `GAP-ENDPOINTS.md`. This document synthesises them into an actionable -submission checklist targeted at whoever is doing the work. +For feature/parity context see `the-gaps.md` (iOS↔web parity + backend asks) and +`the-gaps-access.md` (access-control audit); this document synthesises them into an +actionable submission checklist targeted at whoever is doing the work. +*(The older `GAP-APPLE.md` / `GAP-NEXT-STEPS.md` / `GAP-ENDPOINTS.md` split was +consolidated into those two docs and no longer exists.)* + +> **▶ Status — 2026-09-05.** **iOS engineering for v1 is done.** Every Tier 0 and +> Tier 1 phase below has shipped, plus the whole parity backlog (`the-gaps.md` +> D1–D3, G1–G10, G12–G14) and all seven access-control gaps (`the-gaps-access.md` +> G1–G7). Working tree `dev` = `main` = origin, clean; last verification run +> **823 unit tests, 0 failures, build green** (E2E excluded). +> +> **Everything still open is submission logistics, not code:** Apple portal setup +> (App ID + Push + **Associated Domains**), APNs `.p8`, ASC record + listing copy + +> privacy label, screenshots, demo reviewer account, build-number bump, archive → +> TestFlight device smoke test → submit. Work §§2, 4, 5, 6, 7, 8 in that order; the +> tick-list lives in `App-Store-Deployment-Checklist.md`. **App details at a glance** @@ -11,12 +25,13 @@ submission checklist targeted at whoever is doing the work. |---|---| | Bundle ID | `com.interlinedlist.app` | | Version | `1.0` | -| Build | `1` (increment every upload) | +| Build | `1` — **not yet bumped**; increment before the first upload and every re-upload | | Deployment target | iOS 17.0 | | Device family | iPhone only | | Team ID | `BJA9558E4B` | | Signing | Automatic | | URL scheme | `interlinedlist://` | +| Universal Links | `applinks:interlinedlist.com` — entitlement in the repo, AASA live on the backend; **portal capability not yet enabled** | | Third-party SDKs | None (pure Apple frameworks) | ### Subscription & billing direction @@ -42,10 +57,33 @@ The following phases are complete and in the current build: | 8 | Organizations — CRUD, members, roles, join; post-as-org deferred to Phase 15 | 2026-06-25 | | 12 | Settings panel — theme, default visibility, connected accounts, About, sign-out, notification preferences | 2026-06-25 | | 13a | Feed search — `.searchable` → `GET /api/messages/search` | 2026-06-25 | - -**What works today:** auth (email + OAuth ×5), feed (infinite scroll, dig, reply, search, link previews), compose (text/image/video, cross-post, repost, scheduled), lists (CRUD, folders, schema editor, watchers), documents (CRUD, folders, search, public reader), public browse, notifications (tray, preferences), profile, follow, organizations, settings, exports. - -**Not yet built (remaining phases):** inline document image upload, post as org, offline document sync, realtime, GitHub integration, tag discovery. +| 0.5 | Info.plist hygiene (`ITSAppUsesNonExemptEncryption`, `arm64`, icon) | 2026-07-05 | +| 14 | UGC safety — report message/user, block/unblock, mute, terms gate on register | 2026-07-05 | +| 9 | Push notifications — `PushService`, APNs delegate, register/unregister, tap routing | 2026-07-05 | +| — | Parity Tier 0 — D1/D2/D3 verb fixes (POST/PUT → PATCH) on profile, message edit, notification read | 2026-07-31 | +| — | G1 Direct Messages · G2 Sharing (share-links + doc collaborators) · G3 Templates · G5 LinkedIn targets · G6 People search · G7 Muted users · G8 Exports · G12 Active sessions | 2026-07-31 | +| 11 | GitHub integration — GitHub-backed lists, issue read/create/close, repo picker (G4) | 2026-07-31 | +| 16 | Offline document sync — delta pull, outbox push, conflict-copy (G9, slices 1–3) | 2026-08-02 | +| 10 | Document inline image upload (`uploadDocumentImage` + editor picker) | 2026-08-13 | +| — | Markdown editor format toolbar · email share-invites | 2026-08-13 | +| — | Access-control remediation — `the-gaps-access.md` G1–G7 (PRs #17–#23) | 2026-08-16 | +| 13b | Tag discovery — trending strip + `#` autocomplete (G13) · composer link preview (G14) · document deep links (G10) | 2026-08-15 | +| 15 | Post on behalf of an organization (`organizationId` in compose) | 2026-08-16 | +| — | Multi-image compose · unified sharing screen · inbound shared-list viewer · GitHub issue-close refresh | 2026-09-02 | + +**What works today:** auth (email + OAuth ×5, identity linking), feed (infinite +scroll, dig, reply, search, link previews, trending tags), compose (text, multi-image, +video, cross-post incl. LinkedIn targets, repost, scheduled, post-as-org, live link +preview), lists (CRUD, parent/child nesting, schema editor, watchers, GitHub-backed +lists), documents (CRUD, folders, search, inline images, templates, collaborators, +public reader, offline delta sync with conflict copies), sharing (share-links, email +invites, inbound shared list/document viewers), direct messages, public browse, +notifications (tray, preferences, push), profile, follow, people search, moderation +(report/block/mute), organizations, active sessions, settings, exports, deep links. + +**Not built — and deliberately so:** live document presence/collaborative cursors +(`the-gaps.md` G11, optional); multi-account switching and a general realtime channel +(backend-blocked, X1/X3); billing/dashboard/admin surfaces (web-only by design). **Shipped since last update (2026-07-05):** Phase 0.5 (Info.plist: arm64, ITSAppUsesNonExemptEncryption), Phase 14 (UGC safety: report message/user, block/unblock user, mute, terms acceptance on register, blocked users in settings), Phase 9 (push notifications: PushService, APNs delegate, register/unregister device token). @@ -60,16 +98,16 @@ The following phases are complete and in the current build: ## 1. Feature Completion — What Must Ship Before Submission -### Tier 0 — Hard ship-blockers (nothing uploads without these) +### Tier 0 — Hard ship-blockers (nothing uploads without these) — ✅ ALL SHIPPED -#### Phase 14 — UGC Safety & Moderation `Large` ⛔ +#### Phase 14 — UGC Safety & Moderation `Large` — ✅ SHIPPED 2026-07-05 Apple Guideline 1.2 requires every UGC/social app to provide: (1) report objectionable content, (2) block abusive users, (3) a posted community- guidelines/zero-tolerance EULA accepted at registration, and (4) a developer contact (the support URL covers this). **The app has none of 1–3 today.** -**Start with a backend discovery pass** — it is unconfirmed whether the -server exposes any of these endpoints. Probe and document in `GAP-ENDPOINTS.md §H`: +**Backend discovery (done):** every endpoint below exists and accepts Bearer; +all eight `APIClient` moderation methods are wired and unit-tested. | Need | Candidate endpoint | |---|---| @@ -80,10 +118,7 @@ server exposes any of these endpoints. Probe and document in `GAP-ENDPOINTS.md | List blocked users | `GET /api/blocks` or `GET /api/user/blocks` | | Mute a user | `POST /api/users/{id}/mute` (confirm if server-backed) | -If the endpoints don't exist, this is **blocked on backend** — escalate -immediately, as it is the true critical-path blocker. - -iOS work (after backend is confirmed): +iOS work — all complete: - [x] `Menu` overflow on every message row in `FeedView`, `MessageThreadView` → "Report…" action → `ReportSheet` (reason picker + optional detail) → POST → toast - [x] "Report @user" on `UserProfileView` - [x] "Block @user" on message overflow and `UserProfileView`; optimistic local filter on feed @@ -96,59 +131,59 @@ iOS work (after backend is confirmed): - [x] Unit tests (MockURLSession) for all new API methods; decoding tests for new models - [x] `#Preview` for all new views; `.accessibilityLabel` on all new controls -#### Phase 0.5 — Info.plist Hygiene `Tiny` ⛔ -One-file PR; do this in parallel with Phase 14. +#### Phase 0.5 — Info.plist Hygiene `Tiny` — ✅ SHIPPED 2026-07-05 -- [ ] Add to `InterlinedList/Info.plist`: +- [x] Add to `InterlinedList/Info.plist`: ```xml ITSAppUsesNonExemptEncryption ``` -- [ ] Replace the stale `armv7` entry in `UIRequiredDeviceCapabilities` with `arm64`: +- [x] Replace the stale `armv7` entry in `UIRequiredDeviceCapabilities` with `arm64`: ```xml UIRequiredDeviceCapabilities arm64 ``` -- [ ] Confirm `AppIcon` asset catalog has no empty wells and no alpha channel on the 1024×1024 PNG +- [ ] Confirm `AppIcon` asset catalog has no empty wells and no alpha channel on the 1024×1024 PNG — **still to verify in Xcode before archiving** --- -### Tier 1 — v1 parity (land before or alongside the first submission) - -#### Phase 9 — Push Notifications (APNs) `Medium` ⭑ -- [ ] Add **Push Notifications** capability + `aps-environment` entitlement in Xcode (Target → Signing & Capabilities → "+ Capability") -- [ ] Enable **Push Notifications** on the App ID in the developer portal (§ below) -- [ ] Create APNs Auth Key (.p8) in portal → Keys → hand Key ID + Team ID + `.p8` to backend owner -- [ ] New `Services/PushService.swift` — request permission after login; POST device token to `POST /api/push/register`; DELETE on logout via `DELETE /api/push/unregister` -- [ ] Route push notification taps through the existing `interlinedlist://` deep-link handler -- [ ] Handle foreground presentation and badge clearing on app open -- [ ] Wire lifecycle hooks via `UIApplicationDelegateAdaptor` in `InterlinedListApp.swift` -- [ ] New `APIClient` methods: `registerPushDevice`, `unregisterPushDevice` - -#### Phase 10 — Document Inline Image Upload `Small` -- [ ] In the document editor (`Views/DocumentsView.swift`), add `PhotosPicker` → `POST /api/documents/:id/images/upload` → insert `![alt](url)` at cursor -- [ ] Reuse existing `uploadImage` patterns for progress + failure handling -- [ ] New `APIClient` method: `uploadDocumentImage(documentId:data:mimeType:)` -- [ ] Unit test (MockURLSession, multipart shape) - -#### Phase 15 — Post on Behalf of an Organization `Small` -- [ ] Confirm the create-message endpoint accepts an org-author field (likely `organizationId` in camelCase body); if not, document in `GAP-ENDPOINTS.md` and defer -- [ ] "Post as" picker in `ComposeView` (self vs. orgs where user is owner/admin) -- [ ] Thread org ID through `postMessage(...)` and `CreateMessageBody` +### Tier 1 — v1 parity (land before or alongside the first submission) — ✅ ALL SHIPPED (code); portal/key steps remain + +#### Phase 9 — Push Notifications (APNs) `Medium` — ◑ iOS side shipped 2026-07-05; **two portal steps still open** +- [x] Add **Push Notifications** capability + `aps-environment` entitlement in Xcode (`InterlinedList.entitlements` carries `aps-environment: development`; Xcode auto-signing upgrades it to `production` on an App Store archive) +- [ ] **OPEN —** Enable **Push Notifications** on the App ID in the developer portal (§5.1) +- [ ] **OPEN —** Create APNs Auth Key (.p8) in portal → Keys → hand Key ID + Team ID + `.p8` to backend owner (§2) +- [x] New `Services/PushService.swift` — request permission after login; POST device token to `POST /api/push/register`; DELETE on logout via `DELETE /api/push/unregister` +- [x] Route push notification taps through the existing `interlinedlist://` deep-link handler +- [x] Handle foreground presentation and badge clearing on app open +- [x] Wire lifecycle hooks via `UIApplicationDelegateAdaptor` in `InterlinedListApp.swift` +- [x] New `APIClient` methods: `registerPushDevice`, `unregisterPushDevice` + +#### Phase 10 — Document Inline Image Upload `Small` — ✅ SHIPPED 2026-08-13 +- [x] In the document editor (`Views/DocumentsView.swift:797,893`), `PhotosPicker` → `POST /api/documents/:id/images/upload` → insert `![alt](url)` at cursor +- [x] Reuse existing `uploadImage` patterns for progress + failure handling +- [x] New `APIClient` method: `uploadDocumentImage(documentId:data:mimeType:)` (`APIClient.swift:814`) +- [x] Unit test (MockURLSession, multipart shape) + +#### Phase 15 — Post on Behalf of an Organization `Small` — ✅ SHIPPED 2026-08-16 +- [x] Confirmed: the create-message endpoint accepts `organizationId` (camelCase body) +- [x] "Post as" picker in `ComposeView` (self vs. orgs where user is owner/admin — role-filtered at `ComposeView.swift:558-565`, sent at `:715`) +- [x] Thread org ID through `postMessage(...)` and `CreateMessageBody` (`APIClient.swift:332,341`) --- ### Deferred — post-v1 -| # | Phase | Effort | Blocker | +| # | Phase | Effort | Status | |---|---|---|---| -| 16 | Document offline delta sync | Large | none (feature-flagged) | -| 17 | Realtime updates (WebSocket/SSE) | Large | backend realtime endpoint | -| 11 | GitHub integration | Medium | backend Bearer auth for `/api/github/*` | -| 13b | Tag discovery | Small | `GET /api/tags/trending` endpoint | -| 18 | LinkedIn org cross-post targets | Small | undocumented `linkedInTargets` contract | +| 16 | Document offline delta sync | Large | ✅ **Shipped 2026-08-02** — slices 1–3 incl. conflict copies; flag `ILOfflineDocSync` default-on | +| 17 | Realtime updates (WebSocket/SSE) | Large | ❌ **Not buildable** — no SSE/WebSocket endpoint exists (`the-gaps.md` X3). Realtime is per-feature polling (DM `/updates`, doc `/presence`) | +| 11 | GitHub integration | Medium | ✅ **Shipped 2026-07-31** — backend now accepts Bearer; issue read/create/close, repo picker, mobile OAuth linking live | +| 13b | Tag discovery | Small | ✅ **Shipped 2026-08-15** — `/api/tags/{trending,autocomplete}` shipped on the backend; trending strip + `#` autocomplete in `FeedView` | +| 18 | LinkedIn org cross-post targets | Small | ✅ **Shipped 2026-07-31** — real `{kind,pageId?,personalPageId?}` contract; multi-select picker in `ComposeView` | +| — | Live document presence (collaborative cursors) | Medium | ⏳ **Still deferred** — `the-gaps.md` G11, optional; `/api/documents/:id/presence` is ready when wanted | --- @@ -198,8 +233,9 @@ Team ID: BJA9558E4B ## 4. Required Assets ### App icon -- Already present: `InterlinedList/Assets.xcassets/AppIcon.appiconset/AppIcon-1024.png` +- Present: `InterlinedList/Assets.xcassets/AppIcon.appiconset/AppIcon-1024.png` (+ a dark-appearance variant) - Must be 1024×1024 px, flat PNG, **no alpha/transparency**, **no rounded corners** (Apple rounds it) +- ✅ **Fixed 2026-09-05** — the primary icon was RGBA (fully opaque, but Apple rejects the *presence* of an alpha channel with **ITMS-90717** at upload). Re-saved as RGB with pixel data unchanged; `sips -g hasAlpha` now reports `no`. The dark-appearance variant intentionally keeps its alpha - Open the asset catalog in Xcode and confirm there are no yellow warnings or empty wells ### Screenshots (required — iPhone only) @@ -208,7 +244,14 @@ Apple requires at least one of the two mandatory sizes: | Size | Simulator | Resolution | |---|---|---| | **6.9"** (required) | iPhone 16 Pro Max | 1320 × 2868 px | -| **6.5"** (required) | iPhone 15 Plus or 14 Plus | 1242 × 2688 px | +| **6.5"** (required) | iPhone 11 Pro Max / XS Max on the iOS 17.5 runtime | 1242 × 2688 px | + +> **Correction (2026-09-05):** an earlier revision named *iPhone 15 Plus* for the +> 6.5" slot — that device renders **1290 × 2796** and ASC will reject it there. No +> installed modern device produces 1242 × 2688, so a 6.5" simulator was created for +> this purpose and verified: **`IL-6.5in-11ProMax`**, UDID +> `C272D802-6737-46CC-A943-87C80749FF67` (iPhone 11 Pro Max on iOS 17.5). Both +> devices were confirmed to emit exactly the required pixel dimensions. Apple scales down to smaller devices from these two, so you don't need additional sizes unless you want pixel-perfect control on smaller screens. @@ -228,6 +271,10 @@ Minimum screens to capture (in order of user-facing importance): ### Store listing copy +**Drafted and length-checked in `App-Store-Listing-Copy.md`** (2026-09-05) — subtitle, +promotional text, description, keywords, What's New, review notes, age-rating answers, +and the privacy-label table, all within limits and free of billing language. + | Field | Limit | Notes | |---|---|---| | **App name** | 30 chars | "InterlinedList" — verify uniqueness in ASC at record creation | @@ -268,19 +315,23 @@ account and used only for App Functionality / Account Management. ### 5.1 Register the App ID 1. Developer portal → Certificates, IDs & Profiles → Identifiers → "+" 2. App IDs → App. Bundle ID (Explicit): `com.interlinedlist.app` -3. Enable capability: **Push Notifications** -4. Save +3. Enable capabilities: **Push Notifications** *and* **Associated Domains** + (the app ships `applinks:interlinedlist.com`; the backend already serves + `/.well-known/apple-app-site-association` — verified live 2026-08-14) +4. Save, then **regenerate the provisioning profile** so it carries both capabilities ### 5.2 Signing - Target → Signing & Capabilities → **Automatically manage signing**, Team = `BJA9558E4B` - Xcode creates the Apple Distribution certificate and App Store provisioning profile on first archive ### 5.3 Capabilities to add -- **Push Notifications** — required (Phase 9 ships in v1); adds `aps-environment` entitlement +- **Push Notifications** — required (Phase 9 ships in v1); adds `aps-environment` entitlement ✅ present in `InterlinedList.entitlements` +- **Associated Domains** — required for Universal Links; `com.apple.developer.associated-domains = applinks:interlinedlist.com` ✅ present in `InterlinedList.entitlements`, but the **portal capability is not yet enabled** — enable it (§5.1) or the archive will fail to provision - No other capabilities are needed; unused entitlements can trigger provisioning failures ### 5.4 Build number - Keep **Version** `1.0` for the first release +- **Current state: `MARKETING_VERSION = 1.0`, `CURRENT_PROJECT_VERSION = 1` — never uploaded, so bump the build to `2`+ (or leave `1` for the very first upload only) and increment thereafter** - Increment **Build** (`CURRENT_PROJECT_VERSION`) for every upload, including re-uploads after rejection: ```bash agvtool next-version -all # or edit CURRENT_PROJECT_VERSION in Build Settings @@ -360,14 +411,19 @@ Alternatively, drag the exported `.ipa` into **Transporter** (free on the Mac Ap Smoke-test checklist on a real device before submitting for App Store review: - [ ] Email/password login and registration -- [ ] OAuth (at least one provider — Mastodon or Bluesky) -- [ ] Compose + post (text, image) +- [ ] OAuth (at least one provider — Mastodon or Bluesky); GitHub linking via the mobile OAuth branch +- [ ] Compose + post (text, multi-image); trending-tag strip and live link preview - [ ] Feed scroll, dig/undig, reply -- [ ] Lists and Documents CRUD +- [ ] Lists and Documents CRUD; document inline image upload +- [ ] Direct Messages — inbox, open a thread, send, unread badge +- [ ] Sharing — create/copy/revoke a share-link; open a shared list/document link +- [ ] Offline document sync — airplane-mode edit, reconnect, confirm it persists - [ ] Deep-link callbacks (`interlinedlist://reset-password`, `interlinedlist://verify-email`) +- [ ] **Universal Links** — tap an `https://interlinedlist.com/...` link and confirm it opens in-app (needs the portal capability + fresh profile) - [ ] Push notification receipt and tap routing (Phase 9) - [ ] Settings, sign-out, delete-account flow - [ ] Report/block flows (Phase 14) +- [ ] **Free (non-subscriber) account** — confirm premium controls are hidden, not paywalled, and nothing surfaces upsell copy *(never yet exercised live — the only test account is a subscriber)* ### Submit for App Store review 1. ASC → app → version → **Prepare for Submission** @@ -411,10 +467,13 @@ Smoke-test checklist on a real device before submitting for App Store review: Copy this and tick it off just before submitting. -**Feature gates** +**Feature gates** — all green as of 2026-09-05 - [x] Phase 14 — UGC safety shipped (report, block, mute, terms gate) - [x] Phase 0.5 — Info.plist hygiene done (`ITSAppUsesNonExemptEncryption`, `arm64`, icon) - [x] Phase 9 — Push notifications wired (PushService, register/unregister, `aps-environment: development` entitlement in place; Xcode auto-signing upgrades to production on archive) +- [x] Phases 10, 11, 13b, 15, 16 + the full `the-gaps.md` parity backlog (D1–D3, G1–G10, G12–G14) shipped +- [x] `the-gaps-access.md` G1–G7 access-control remediation shipped (PRs #17–#23) +- [x] Build + full unit suite green — **823 tests, 0 failures** (2026-09-05, E2E excluded) **Accounts & credentials** - [ ] Apple Developer Program membership active; agreements accepted in ASC diff --git a/App-Store-Listing-Copy.md b/App-Store-Listing-Copy.md new file mode 100644 index 0000000..4959ea1 --- /dev/null +++ b/App-Store-Listing-Copy.md @@ -0,0 +1,184 @@ +# App Store Listing Copy — InterlinedList iOS + +Paste-ready copy for the App Store Connect record, plus the privacy-label and +age-rating answers. Drafted 2026-09-05 against the shipped v1 feature set. + +**Hard rule carried through every field below:** no price, no "subscribe", no +"upgrade", no link to pay on the web. Subscriber-only features are described in +neutral product terms or omitted. See `App-Store-Deployment.md` §10 (Guideline +3.1.1 anti-steering). + +--- + +## Name and subtitle + +| Field | Value | Length | +|---|---|---| +| **App name** (≤30) | `InterlinedList` | 14 | +| **Subtitle** (≤30) | `Social lists, shared` | 20 | + +Subtitle alternatives if the first reads too thin: +- `Lists, docs, and a feed` (23) +- `Write lists. Share threads.` (27) +- `Your lists, your people` (23) + +--- + +## Promotional text (≤170) — changeable without a new submission + +``` +Nested lists, markdown documents, and a social feed in one place. Post, reply, +share a list with a link, and keep working when you're offline. +``` + +--- + +## Description (≤4,000) + +``` +InterlinedList is a social app for people who think in lists. + +Keep your lists and documents where your conversations are. Post to a feed, +reply in threads, follow people, and share any list or document with a link — +without leaving the app. + +LISTS THAT NEST +• Build lists inside lists, as deep as you need +• Define your own columns — text, numbers, dates, checkboxes, select options +• Reorder, edit inline, and search across everything +• Back a list with a GitHub repository and work its issues as list rows + +DOCUMENTS IN MARKDOWN +• A markdown editor with a formatting toolbar and live preview +• Inline images, folders, and full-text search +• Start from a template instead of a blank page +• Edits are saved locally when you're offline and sync when you're back — + conflicting changes are preserved side by side, never silently overwritten + +A FEED, NOT AN ALGORITHM +• Post text, images, and video; reply, repost, and dig what you like +• Schedule posts, or cross-post to your linked Mastodon, Bluesky, LinkedIn, + and X accounts +• Follow tags, browse what's trending, and search the feed +• Link previews render as you type + +DIRECT MESSAGES +• One-to-one threads with the people you mutually follow +• Send images, see unread counts, and keep conversations near-live + +SHARING AND COLLABORATION +• Create share links with view or edit roles, and revoke them at any time +• Invite collaborators to a document by email +• Add watchers to a list and set what each of them can do +• Post on behalf of an organization you own or administer + +YOURS TO CONTROL +• Report or block anyone, mute accounts you'd rather not see, and manage your + blocked and muted lists in Settings +• See every device signed in to your account and sign any of them out +• Export your messages, lists, list rows, and follows as CSV +• Delete your account from inside the app + +Requires an interlinedlist.com account. Sign in with email or with Mastodon, +Bluesky, LinkedIn, X, or GitHub. +``` + +--- + +## Keywords (≤100 chars, comma-separated, no spaces after commas) + +``` +lists,checklist,notes,markdown,documents,social,feed,share,collaborate,outline,todo,github +``` + +(90 characters. Do **not** repeat the app name or the words in it — Apple indexes +those already.) + +--- + +## What's New (v1.0) + +``` +Initial release. +``` + +--- + +## Review notes + +``` +Demo login: + Email: + Password: + +InterlinedList is a social list-sharing app. The demo account above is a live +production account with sample content in the feed, lists, and documents. + +Subscriptions are managed exclusively at interlinedlist.com. There is no +in-app purchase, paywall, price, or billing UI anywhere in this app. + +Account deletion: Profile -> Edit Profile -> Delete Account (double-confirm). +Report content: tap the "..." menu on any post -> Report. +Block a user: tap the "..." menu on any post, or open their profile -> Block. +Mute a user: profile -> "..." -> Mute; managed in Settings -> Muted Users. +Blocked list: Settings -> Blocked Users. + +Community guidelines and terms are linked from the registration screen and from +Settings -> About: https://interlinedlist.com/terms +``` + +--- + +## Age rating questionnaire + +The app is a user-generated-content social network with reporting, blocking, and +muting shipped. Answer honestly; the combination below typically lands at **17+**: + +| Question | Answer | +|---|---| +| Unrestricted web access | **No** — links open in the system browser; there is no in-app browser | +| User-generated content | **Yes** — posts, replies, lists, documents, direct messages | +| Does the app have content moderation? | **Yes** — in-app report (message and user), block, mute; server-side moderation | +| Contests, gambling, violence, sexual content, drugs, profanity | **None** authored by the app; UGC is covered by the question above | +| Medical/treatment information | **No** | + +--- + +## App Privacy "nutrition label" + +Audited against `APIClient` request bodies on 2026-09-05. The app contains **no +analytics SDK, no ad SDK, and no third-party frameworks at all** — everything below +is sent only to `interlinedlist.com`. + +| Data type | ASC category | Purpose | Linked to user? | Used for tracking? | +|---|---|---|---|---| +| Email address | Contact Info | Account management | Yes | No | +| Display name, username, bio | User Content / Contact Info | App functionality | Yes | No | +| Posts, replies, direct messages | User Content | App functionality | Yes | No | +| Lists, list rows, documents | User Content | App functionality | Yes | No | +| Photos and videos (avatar, post media, document images, DM attachments) | User Content → Photos or Videos | App functionality | Yes | No | +| Search queries (feed search, people search, tag autocomplete) | Search History | App functionality | Yes | No | +| User identifier | Identifiers | App functionality | Yes | No | +| Linked OAuth identities (provider + handle) | Identifiers | Account management | Yes | No | +| Device push token | Identifiers → Device ID | App functionality (notifications) | No | No | + +**Not collected:** location, contacts, health, financial info, browsing history, +advertising data, diagnostics, or usage analytics. Select **"Data Not Used to Track +You"** for every type. + +**Photo access note:** media is chosen through SwiftUI's `PhotosPicker`, which runs +out of process, so the app needs **no** `NSPhotoLibraryUsageDescription` and never +sees the library — only the item the user picks. There is no camera, location, +contacts, or microphone use anywhere in the app, so no other usage-description +strings are required either (verified 2026-09-05). + +--- + +## Field-by-field paste order in App Store Connect + +1. **App Information** → Name, Subtitle, Category (Social Networking), Privacy Policy URL +2. **Pricing and Availability** → Free, all territories +3. **Prepare for Submission** → Promotional text, Description, Keywords, Support URL, What's New +4. **App Privacy** → the table above +5. **Age Rating** → the questionnaire above +6. **App Review Information** → demo account + review notes above diff --git a/README.md b/README.md index eee4069..953ba14 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ An email-verification banner appears beneath the top bar until the account's ema ### Accounts & auth - **Email / password** sign-in (issues a sync token stored in the Keychain) and registration. - **Forgot / reset password** and **email verification**, reachable via `interlinedlist://` deep links. -- **OAuth sign-in** via the system browser (`ASWebAuthenticationSession`) for Mastodon, Bluesky, LinkedIn, and Twitter. *(GitHub is hidden pending backend support for the native callback.)* +- **OAuth sign-in** via the system browser (`ASWebAuthenticationSession`) for Mastodon, Bluesky, LinkedIn, and Twitter. GitHub is included — the backend's mobile OAuth branch shipped 2026-08-14. - **Linked accounts** management (subscribers). - **Change email** and **delete account** from Settings. diff --git a/the-gaps-access.md b/the-gaps-access.md index def01c0..a925b6f 100644 --- a/the-gaps-access.md +++ b/the-gaps-access.md @@ -2,7 +2,14 @@ **Scope:** Does a user only get the things they have access to based on **subscription**, **role**, or **approved/cleared status**? This reviews the iOS client (`InterlinedList/`) and cross-references the backend at `~/Codez/interlinedlist/` for the source-of-truth enforcement. -**Date:** 2026-08-15 · **Reviewer:** automated audit (Claude) +**Audited:** 2026-08-15 · **Reviewer:** automated audit (Claude) · **Remediation verified:** 2026-09-05 + +> **✅ ALL SEVEN GAPS ARE CLOSED.** G1–G7 were fixed on 2026-08-15 and merged +> 2026-08-16 as one PR each (**#17–#23**). Re-verified against the working tree on +> 2026-09-05 — every remediation below is present in shipped code (per-gap evidence +> in each section and in the [§5 table](#5-prioritized-remediation)). This document is +> retained as the **audit record and the pattern reference** for future access-control +> work, not as an open backlog. --- @@ -12,24 +19,26 @@ The gaps are therefore **client-side correctness / consistency / UX**, plus **one App Store-review risk**: -- The client uses three separate access axes — **subscription** (`isSubscriber`), **role** (`OrgRole`, `WatcherRole`), and **cleared status** (`emailVerified`) — but applies them **inconsistently**. One premium surface (list-watcher management) isn't gated at all, while its exact twin (document collaborators) is. -- Entitlement state (`customerStatus`) is **cached and rarely refreshed**, so it goes stale when the subscription changes on the web (where billing lives). -- Authorization `403`s surface the **raw backend message**, and the app's intended friendly/typed 403 handling is **dead code** — a correctness bug and a potential IAP-steering issue if that text contains upsell copy. +*(All three findings below describe the **2026-08-15 audit state**; each was fixed the same day — see the status column and the per-gap "Shipped" notes.)* + +- The client uses three separate access axes — **subscription** (`isSubscriber`), **role** (`OrgRole`, `WatcherRole`), and **cleared status** (`emailVerified`) — but applied them **inconsistently**. One premium surface (list-watcher management) wasn't gated at all, while its exact twin (document collaborators) was. *(Fixed — G1.)* +- Entitlement state (`customerStatus`) was **cached and rarely refreshed**, so it went stale when the subscription changed on the web (where billing lives). *(Fixed — G2.)* +- Authorization `403`s surfaced the **raw backend message**, and the app's intended friendly/typed 403 handling was **dead code** — a correctness bug and a potential IAP-steering issue if that text contains upsell copy. *(Fixed — G3.)* -None of these leak data. All of them can make a paying/entitled user see the wrong thing, or make a non-entitled user tap controls that always fail. +None of these leaked data. All of them could make a paying/entitled user see the wrong thing, or make a non-entitled user tap controls that always fail. ### Severity legend Severity reflects **product/UX correctness and store-review risk**, not data security (all paths are server-enforced). -| ID | Gap | Severity | -|----|-----|----------| -| G1 | List-watcher management not subscriber-gated (inconsistent with documents) | **Medium** | -| G2 | Stale subscription/entitlement state — no refresh on foreground | **Medium** | -| G3 | Authorization 403s surface raw backend text; friendly/typed handling is dead code | **Medium** (store-review) | -| G4 | Client can't distinguish owned vs shared lists (`UserList` has no owner/role field) | **Low** (latent) | -| G5 | Free owners over-restricted from removing document collaborators | **Low** | -| G6 | Email-verification gating coverage is uneven (media upload not pre-gated) | **Low** | -| G7 | `WatchersListView` 401 handling deviates from the app's 401 contract | **Low** | +| ID | Gap | Severity | Status | +|----|-----|----------|--------| +| G1 | List-watcher management not subscriber-gated (inconsistent with documents) | **Medium** | ✅ Fixed `65169a9` (PR #17) | +| G2 | Stale subscription/entitlement state — no refresh on foreground | **Medium** | ✅ Fixed `0fa483a` (PR #18) | +| G3 | Authorization 403s surface raw backend text; friendly/typed handling is dead code | **Medium** (store-review) | ✅ Fixed `eb6b964` (PR #19) | +| G4 | Client can't distinguish owned vs shared lists (`UserList` has no owner/role field) | **Low** (latent) | ✅ Fixed `179889a` (PR #20) | +| G5 | Free owners over-restricted from removing document collaborators | **Low** | ✅ Fixed `a284d60` (PR #21) | +| G6 | Email-verification gating coverage is uneven (media upload not pre-gated) | **Low** | ✅ Fixed `f772fd1` (PR #22) | +| G7 | `WatchersListView` 401 handling deviates from the app's 401 contract | **Low** | ✅ Fixed `d4c5fd6` (PR #23) | --- @@ -60,7 +69,7 @@ Verified in the backend repo. Representative guards: ## 3. Gaps -### G1 — List-watcher management is not subscriber-gated (Medium) +### G1 — List-watcher management is not subscriber-gated (Medium) — ✅ FIXED **The app gates the identical feature two different ways.** Document collaborators, share-links, and share-invites all hide their *create* controls for non-subscribers: @@ -74,9 +83,11 @@ But **`Views/WatchersListView.swift` has no subscriber gate at all.** The "Add w **Fix:** Mirror `DocumentCollaboratorsView`: introduce `canManage = authState.user?.isSubscriber == true`, gate the toolbar "Add watcher" button and the role-change menu on it. Viewing/removing existing watchers can stay available to any owner (the GET and DELETE are not subscriber-gated server-side). +**Shipped (`65169a9`, PR #17):** `WatchersListView.swift:26` now defines `canManage = authState.user?.isSubscriber == true`; the toolbar "Add watcher" button (`:51`) and the row role-change menu (`:82`, `:142`, `:156`) are gated on it. Viewing and removing existing watchers stay available to any owner, matching the server. + --- -### G2 — Stale subscription/entitlement state; no foreground refresh (Medium) +### G2 — Stale subscription/entitlement state; no foreground refresh (Medium) — ✅ FIXED `isSubscriber` is derived from `User.customerStatus`, which is cached in `AuthState.user` and only re-fetched on: - launch/login/OAuth (`Services/AuthState.swift:33,52,76`), @@ -91,9 +102,11 @@ There is **no `scenePhase == .active` refresh** and no refresh before presenting **Fix:** Refresh the user on foreground (`.onChange(of: scenePhase)` → `.active` → `authState.refreshUser()`), and immediately after returning from any web billing/settings link. Cheap `GET /api/user`; keeps entitlement fresh. +**Shipped (`0fa483a`, PR #18):** `InterlinedListApp.swift:39-46` refreshes on foreground — `.onChange(of: scenePhase)` → `if phase == .active, authState.hasToken { await authState.refreshUser() }` — so entitlement and `emailVerified` re-sync after any web-side subscription change. + --- -### G3 — Authorization 403s surface raw backend text; typed handling is dead code (Medium, store-review) +### G3 — Authorization 403s surface raw backend text; typed handling is dead code (Medium, store-review) — ✅ FIXED `checkResponse` maps **any 4xx that has a JSON `{"error": …}` body** to `APIError.server(msg)` — *not* to `APIError.status(403)`: @@ -118,9 +131,11 @@ The backend's `forbidden(msg)` returns `{"error": msg}`, so **403s arrive as `.s **Fix:** Add a typed forbidden case (e.g. map `403` to `APIError.forbidden(msg)` in `checkResponse`, distinct from generic `.server`). Then views can convert authorization failures to **neutral in-app copy** and never surface raw upsell text. At minimum, stop relying on the currently-dead `.status(403)` branches. +**Shipped (`eb6b964`, PR #19):** `APIError.forbidden(String)` exists (`APIClient.swift:23`) and `checkResponse` maps body-bearing 403s to it (`:1796`); bodyless 403s stay `.status(403)`. Views catch the typed case and substitute neutral copy — `ComposeView.swift:728`, `ShareInvitesSheet.swift:167`, `NotificationsView.swift:105`, `DMThreadView.swift:252` — so raw backend text (and any upsell phrasing in it) is never rendered in-app. + --- -### G4 — Client can't distinguish owned vs shared lists (Low, latent) +### G4 — Client can't distinguish owned vs shared lists (Low, latent) — ✅ FIXED `UserList` (`Models/List.swift:122-171`) carries **no `userId` / owner / role field**. `ListDetailView`'s toolbar shows **Manage watchers / Share / Invite** unconditionally (`Views/ListsView.swift:492-515`) with no ownership gate — it *can't* gate, because the model has no ownership signal. @@ -130,9 +145,11 @@ The backend's `forbidden(msg)` returns `{"error": msg}`, so **403s arrive as `.s **Fix:** Add an owner/role field to `UserList` (e.g. `myRole: WatcherRole?` or `isOwner: Bool`) and gate the management toolbar on it — even though it's harmless today, it future-proofs the surface and lets you drop the "presented from a list the user owns" assumption documented at `WatchersListView.swift:8-10`. +**Shipped (`179889a`, PR #20):** `UserList` now decodes `ownerId` and exposes `isOwned(by:)` (`Models/List.swift:272`), which treats a missing `ownerId` as owned so owner-scoped screens keep working on endpoints that omit it. `ListsView.swift:378` gates the management toolbar on `list.isOwned(by: authState.user?.id)`. + --- -### G5 — Free owners over-restricted from removing document collaborators (Low, inverse gap) +### G5 — Free owners over-restricted from removing document collaborators (Low, inverse gap) — ✅ FIXED `DocumentCollaboratorsView.canManage = isSubscriber` (`:23`) hides **Remove** (`:82-90`) as well as Add/role-change. But the backend only subscriber-gates *add* and *role-change* — an **owner can remove a collaborator regardless of subscription** (DELETE is owner-only, not subscriber-gated). @@ -140,9 +157,11 @@ The backend's `forbidden(msg)` returns `{"error": msg}`, so **403s arrive as `.s **Fix:** Split the gate — `Remove` on `isOwner` (always, for an owned doc), `Add`/`role-change` on `isSubscriber`. +**Shipped (`a284d60`, PR #21):** the gate is split in `DocumentCollaboratorsView.swift` — `canManage` (`:24`) still requires a subscription for Add and role-change, while `canRemove` (`:28`) is available to the owner regardless of subscription, matching the owner-only-but-not-subscriber-gated DELETE. + --- -### G6 — Email-verification gating coverage is uneven (Low) +### G6 — Email-verification gating coverage is uneven (Low) — ✅ FIXED Cleared-status gating is applied in some places but not others: @@ -153,14 +172,18 @@ Cleared-status gating is applied in some places but not others: **Fix:** Fold `isEmailVerified` into the media entry-point gates (image/video pickers), consistent with the post button. +**Shipped (`f772fd1`, PR #22):** `ComposeView.canAttachMedia` (`:80`) is now `canUseSubscriberFeatures && isEmailVerified`, so the image/video pickers are hidden for a subscriber with an unverified email instead of failing late with a 403. + --- -### G7 — `WatchersListView` 401 handling deviates from the app's 401 contract (Low, robustness) +### G7 — `WatchersListView` 401 handling deviates from the app's 401 contract (Low, robustness) — ✅ FIXED `changeRole` and `remove` in `WatchersListView.swift:101-124` catch only `APIError.server` and the generic case — they **do not** catch `APIError.status(401)` and route it through `authState.handleUnauthorized()`. This violates the documented 401 contract (`CLAUDE.md`: "Don't log out on a feature-endpoint 401 — route through `handleUnauthorized()`"). Every other management view (`DocumentCollaboratorsView`, `OrganizationMembersView`, `ShareLinksSheet`, `ShareInvitesSheet`) handles it. **Fix:** Add `catch APIError.status(401) { authState.handleUnauthorized() }` to both methods. +**Shipped (`d4c5fd6`, PR #23):** `WatchersListView` routes 401s through `authState.handleUnauthorized()` in all four mutating paths (`:104`, `:117`, `:131`, `:296`), restoring the documented 401 contract. + --- ## 4. What's implemented correctly (keep / use as the pattern) @@ -177,14 +200,24 @@ Cleared-status gating is applied in some places but not others: ## 5. Prioritized remediation -| Priority | Gap | Action | Effort | -|----------|-----|--------|--------| -| 1 | **G1** | Add `isSubscriber` gate to `WatchersListView` Add button + role menu (mirror `DocumentCollaboratorsView`) | S | -| 2 | **G3** | Introduce typed `APIError.forbidden`; map subscriber/authorization 403s to neutral in-app copy; drop dead `.status(403)` branches | S–M | -| 3 | **G2** | Refresh `authState.user` on `scenePhase == .active` and after web billing links | S | -| 4 | **G5** | Split document-collaborator gate: `Remove` on owner, `Add`/role-change on subscriber | S | -| 5 | **G6** | Gate compose media pickers on `isEmailVerified` too | S | -| 6 | **G7** | Route `WatchersListView` 401s through `handleUnauthorized()` | XS | -| 7 | **G4** | Add owner/role field to `UserList`; gate `ListDetailView` management toolbar on it (future-proofing) | M | - -**Bottom line:** No user can *obtain* data or actions the backend doesn't authorize — the server gates every axis. The work here is making the client's affordances match entitlement **consistently** (G1), keep entitlement **fresh** (G2), and present authorization failures **cleanly and store-safely** (G3). +**All seven landed 2026-08-15, merged 2026-08-16 (PRs #17–#23), one PR per gap.** Nothing on this list is open. + +| Priority | Gap | Action | Effort | Status | +|----------|-----|--------|--------|--------| +| 1 | **G1** | Add `isSubscriber` gate to `WatchersListView` Add button + role menu (mirror `DocumentCollaboratorsView`) | S | ✅ `65169a9` · PR #17 | +| 2 | **G3** | Introduce typed `APIError.forbidden`; map subscriber/authorization 403s to neutral in-app copy; drop dead `.status(403)` branches | S–M | ✅ `eb6b964` · PR #19 | +| 3 | **G2** | Refresh `authState.user` on `scenePhase == .active` and after web billing links | S | ✅ `0fa483a` · PR #18 | +| 4 | **G5** | Split document-collaborator gate: `Remove` on owner, `Add`/role-change on subscriber | S | ✅ `a284d60` · PR #21 | +| 5 | **G6** | Gate compose media pickers on `isEmailVerified` too | S | ✅ `f772fd1` · PR #22 | +| 6 | **G7** | Route `WatchersListView` 401s through `handleUnauthorized()` | XS | ✅ `d4c5fd6` · PR #23 | +| 7 | **G4** | Add owner/role field to `UserList`; gate `ListDetailView` management toolbar on it (future-proofing) | M | ✅ `179889a` · PR #20 | + +**Bottom line:** No user can *obtain* data or actions the backend doesn't authorize — the server gates every axis. The work here was making the client's affordances match entitlement **consistently** (G1), keep entitlement **fresh** (G2), and present authorization failures **cleanly and store-safely** (G3) — **all done**. + +### Residual verification (not a gap, a coverage note) + +The **free-user gating path has still never been observed live**: the only test +account (`messenger`) is a subscriber, so every 💲 403 branch above is verified by +source reading and unit tests, not by a live non-subscriber session. A one-off probe +with a free account would close the last observational hole. Carried in +`the-gaps.md` → Part VII as well. diff --git a/the-gaps.md b/the-gaps.md index 964284f..b19d195 100644 --- a/the-gaps.md +++ b/the-gaps.md @@ -124,7 +124,11 @@ Live implementation status — updated as work lands on `dev` (uncommitted unles | **14 — lists into folders** | ~~`folderId` on create/update list, folder picker + move-to-folder + `RenameFolderView`; split `parentId` vs `folderId`~~ | ↩️ **Reverted 2026-08-15** — the list-folder concept was removed by product decision. Lists organize only via parent/child nesting (`parentId`); `ListFolder`, `folderId`, and the `/api/folders` client calls are gone. `ListTreeNode.buildTree(lists:)` now nests purely on `parentId` | | **15 — API re-verification (this pass)** | Live Bearer re-probe + backend-source re-read (2026-08-15): confirmed **A5 shipped** (`folderId` in list GET), surfaced **G13** (tags trending/autocomplete now exist — was X2) and **G14** (`/api/link-metadata` composer preview). No code changes — doc-only update | ✅ **Done** 2026-08-15 | | **16 — G13/G14 + G10 doc deep links (this session)** | **G13**: `TrendingTag`/`TagSuggestion` + `trendingTags()`/`tagAutocomplete()`; server-wide **Trending** strip & `#`-autocomplete wired into `FeedView`'s existing `tagFilter`. **G14**: `linkMetadata(url:)` + live OG preview card in `ComposeView` (`NSDataDetector` URL detection, 400 ms debounce, 429/`failed`→no card). **G10 (documents)**: `.document(id:)` + `.sharedDocument(token:)` deep links → `DocumentLinkView` / read-only `SharedDocumentView` + `resolveSharedDocument()`; parser routes `/documents/:id` and `/documents/shared/:token` (custom-scheme + https) | ✅ **Done** 2026-08-15 — app builds green; **787-test unit suite passes** (+31 new: 12 tags, 9 link-metadata, 6 resolver, +4 parse) | -| — | **iOS-only tail of A1/A2** — merge staged `feat/github-oauth-universal-links` (1 commit ahead of `dev`: flips GitHub `supportsNativeAuth→true` + Associated Domains entitlement); enable the Apple-portal Associated Domains capability & regen profile · **G10 list follow-ons** *(list **share-token** inbound now shipped — `/lists/shared/:token` routes to a read-only `SharedListView` via `resolveSharedList()`/`sharedListData()`; bare `/lists/:id` permalink inbound remains **backend-limited** — no owner username in the URL)* · **G11 presence** *(optional)* | ⏳ remaining | +| **17 — GitHub OAuth + Universal Links entitlement (A1/A2 iOS tail)** | `feat/github-oauth-universal-links` merged: GitHub `supportsNativeAuth → true` (in-app linking via the backend's mobile OAuth branch) + `com.apple.developer.associated-domains = applinks:interlinedlist.com` in `InterlinedList.entitlements` | ✅ **Done** 2026-08 — code side complete. **Residual is non-code:** enable Associated Domains on the App ID in the Apple portal & regen the provisioning profile (tracked in `App-Store-Deployment-Checklist.md`) | +| **18 — sharing parity + GitHub-list fixes** | Unified document + list sharing screen (web parity) · inbound shared-list viewer + web-accept for edit links · GitHub issue list refresh after close/reopen · multi-image compose | ✅ **Done** 2026-09-02/05 (PRs #30–#32, restored to `main` in #35) | +| **19 — offline-sync `relativePath` workaround** | Send `relativePath` on every sync create/update/conflict-copy op so the backend stops silently dropping them (see ask **A7**) | ✅ **Done** 2026-09-02 (`a7d0976`, PR #34) | +| — | **G10 list follow-on** — bare `/lists/:id` permalink inbound *(share-token inbound already ships: `/lists/shared/:token` → read-only `SharedListView` via `resolveSharedList()`/`sharedListData()`)* | ⛔ **backend-limited** — the permalink carries no owner username | +| — | **G11 document presence** — `/api/documents/:id/presence` heartbeat + poll | ⏳ **remaining, optional** — the only unbuilt parity item | **Whole-tree gate (2026-07-31, after the fix pass):** full unit suite **694 tests, 0 failures** (E2E excluded). All work builds and passes together; Phases 1–9 @@ -616,16 +620,17 @@ field). What's left: 2026-08-14).** `/auth/github/{authorize,callback}` now carry the mobile branch (mints a sync token → `interlinedlist://oauth/callback?token=…`); live probe: authorize accepts the mobile `redirect_uri` (307 → github.com) and rejects invalid - ones. Residual is **iOS-only**: merge the staged `feat/github-oauth-universal-links` - branch (**1 commit ahead of `dev`**, still unmerged as of 2026-08-15; flips GitHub - `supportsNativeAuth → true`). *(The standalone `Backend-Asks-A1-A2.md` spec has been - removed; the summary here is authoritative.)* + ones. **iOS tail closed** — `feat/github-oauth-universal-links` is merged (Phase 17): + `OAuthCoordinator.supportsNativeAuth` is now `true` for every provider, so GitHub + links in-app. Nothing outstanding. *(The standalone `Backend-Asks-A1-A2.md` spec has + been removed; the summary here is authoritative.)* - **A2 — Universal Links assets. ✅ DELIVERED (deployed + Apple-CDN-verified 2026-08-14).** `GET /.well-known/apple-app-site-association` serves the AASA JSON - (200, `application/json`, no auth); Apple's CDN copy is cached (200). Residual is - **iOS-only**: enable the Associated Domains capability in the Apple portal + regen - the profile, then merge the staged entitlement (same `feat/github-oauth-universal-links` - branch as A1). + (200, `application/json`, no auth; re-verified 2026-09-05 — `appID: + BJA9558E4B.com.interlinedlist.app`, Apple CDN copy 200). The **entitlement is merged** + (Phase 17). Residual is **non-code**: enable the Associated Domains capability on the + App ID in the Apple portal and regenerate the provisioning profile — tracked in + `App-Store-Deployment-Checklist.md`, not here. - **A3 — Bearer for multi-account?** `/api/auth/{accounts,switch,remove-account}` are session-only. If mobile multi-account is desired, expose a Bearer-compatible switch (or per-account sync-tokens the client caches). Otherwise confirm it stays @@ -708,6 +713,16 @@ for mobile are **multi-account** (session-only) and a **general realtime channel (none exists — poll instead). *(Tag discovery is no longer a dead-end — see the 2026-08-15 update below.)* +> **Update 2026-09-05.** Parity work is **complete except G11** (document presence, +> optional) and the bare `/lists/:id` permalink inbound (**backend-limited**). Verified +> on 2026-09-05: build green, **823 unit tests, 0 failures** (E2E excluded); `dev` = +> `main` = origin, clean tree, no open PRs or issues. The access-control audit +> (`the-gaps-access.md` G1–G7) is likewise fully remediated. Remaining backend asks: +> **A3** (decide Bearer multi-account or formally drop it), **A4/A6** (doc pages), and +> **A7** (`documents/sync` silently dropping ops — iOS has a working client-side +> workaround). Everything else outstanding is **App Store submission logistics** — +> see `App-Store-Deployment-Checklist.md`. +> > **Update 2026-08-14.** The plan above has been executed. **D1–D3 are fixed** and > **G1–G10 + G12 all shipped** (see Progress log; G9 complete through Slice 3). What's > left: **G11** presence (optional); **G10 follow-ons** (list/doc inbound + shared-token