# Buzzware Tech (fork) — Issue Tracker

Everything found so far, in the order it should be worked. Nothing here is
opinion — each item was reproduced or confirmed in the actual code/logs.

Status key: 🔴 not started · 🟡 guided (fix written, not applied to your repo) · 🟢 fixed & confirmed

---

## Phase 0 — Security (do this first, takes 2 minutes)

- [x] 🟢 **Firebase Admin SDK key rotated.**
      Old exposed key (`e6cb8d1973`) deleted from disk. New key (`b5a924fbed`) generated and is `.gitignore`'d by the `*-firebase-adminsdk-*.json` pattern — confirmed not tracked by git. Keep this file outside the repo folder for production deployments.

---

## Phase 1 — Things that block the app from running at all

- [x] 🟢 `apps/web/app/assets/` folder was completely missing (favicon/icon/og-image imports in `root.tsx` had nowhere to resolve → 500 on every route). **Confirmed present in your latest upload — fixed.**
- [x] 🟢 `packages/i18n/locales` was a broken symlink (Windows checked it out as a plain text file instead of a real symlink → every translation lookup failed → raw i18n keys shown everywhere, e.g. `sidebar.new_work_item`). **Confirmed as a real directory in your latest upload — fixed.**
- [x] 🟢 `apps/web/core/services/timezone.service.ts` was hitting a dead Django endpoint (`/api/timezones/` → 502). **Confirmed rewritten to use `Intl.supportedValuesOf` locally — fixed.**

---

## Phase 2 — Crashes / broken interactions

- [x] 🟢 **Project creation crashes:** `fileService.uploadWorkspaceAsset is not a function`.
      File: `apps/web/core/services/file.service.ts`
      **Confirmed fixed in code** — all 9 stub methods (`uploadUserAsset`, `uploadWorkspaceAsset`, `uploadProjectAsset`, `deleteUserAsset`, `deleteOldUserAsset`, `deleteWorkspaceAsset`, `deleteOldWorkspaceAsset`, `updateBulkProjectAssetsUploadStatus`, `updateBulkWorkspaceAssetsUploadStatus`) are present. No crash; uploads are stubs (see Phase 4 for implementation).

- [x] 🟢 **`setState` during render warning** — `WorkspaceMenuRoot`.
      File: `apps/web/core/components/workspace/sidebar/workspace-menu-root.tsx`
      **Confirmed fixed in code** — `SyncMenuOpenState` helper component (lines 32–43) wraps the state sync in `useEffect`. Clean.

- [x] 🟢 **Nested `<button>` — `MemberDropdown`.**
      File: `apps/web/core/components/dropdowns/member/base.tsx`
      **Confirmed fixed in code** — outer wrapper is `<div role="button">` with widened `referenceElement` type.

- [x] 🟢 **Nested `<button>` — sidebar kebab menus (7 files).**
      Files: `modules/quick-actions.tsx`, `views/quick-actions.tsx`, `cycles/quick-actions.tsx`, `comments/quick-actions.tsx`, `issues/layout-quick-actions.tsx`, `issues/issue-layouts/quick-action-dropdowns/issue-detail.tsx`, `inbox/content/inbox-issue-header.tsx`
      **Confirmed moot** — `CustomMenu` (`packages/ui/src/dropdowns/custom-menu.tsx` lines 272–284) now detects `IconButton` by `displayName`/`name` and uses `React.cloneElement` directly, bypassing the wrapping `<button>` entirely. No changes needed at call sites.

- [x] 🟢 **Onboarding → `/t/` double-redirect on sign-in.**
      File: `apps/web/core/lib/wrappers/authentication-wrapper.tsx`
      **Confirmed fixed in code** — `isProfileLoading` guard (`!!currentUser?.id && !currentUserProfile?.id`) present at line 114 blocks rendering until profile resolves.

- [x] 🟢 **Nested `<a>` in `<a>` — `ProjectCard`.**
      File: `apps/web/core/components/project/card.tsx`
      **Confirmed not present** — Settings button is `<div role="button">` (not a `Link`); no nested `Link`-inside-`Link` found in the component.

- [ ] 🔴 **Sidebar submenu (Cycles / Modules / Views / Pages / Intake) renders empty.**
      File: `apps/web/core/components/workspace/sidebar/project-navigation.tsx`
      Cause candidates (needs confirming against your data):
  1. Every item except "Work items" is gated by a project feature flag (`project?.cycle_view`, `project?.module_view`, `project?.issue_views_view`, `project?.page_view`, `project?.inbox_view`) read off `getPartialProjectById(projectId)` — if these are `undefined`/`false` on the project doc, the items are correctly hidden by design, not a bug.
  2. But your pasted DOM showed the panel completely empty (not even "Work items", which is unconditional) — that points at `getPartialProjectById(projectId)` returning nothing at all when this renders, i.e. a timing/store issue, not a flags issue.
  3. Intake's missing Firestore security rule is now fixed (see Phase 3 — fixed). If the panel is still empty after deploying the new rules, the cause is the store timing issue above.
     Needs a console check of `getPartialProjectById` output for the affected project.

- [ ] 🔴 **`blob:http://localhost:3000/...` `net::ERR_FILE_NOT_FOUND`.**
      Seen once in a pasted log, tied to an `<Image>` commit. Not yet traced — likely a stale/revoked object URL used for an optimistic image preview (e.g. avatar/cover image picker) outliving its blob. Needs the component that creates the `URL.createObjectURL(...)` for that preview.

---

## Phase 3 — Firestore security rules

- [x] 🟢 **All missing `match` blocks added and logic bugs fixed** in `firestore.rules`.

  **Logic bugs fixed:**
  - `isWorkspaceAdmin()` now compares `role == 20` (numeric — confirmed `EUserWorkspaceRoles.ADMIN = 20` written by `workspace.service.ts` and `project-member.service.ts`). Was `== "admin"` (string), meaning **no one** could ever pass admin-gated rules.
  - `isProjectMember(wId, pId)` now checks `exists(.../projects/{pId}/members/{uid})` — was just an alias for `isWorkspaceMember()`, providing no per-project isolation.

  **Missing paths added:**
  | Path | Status |
  |---|---|
  | `/config/{docId}` | ✅ Added — Admin app can now read instance config |
  | `/anchors/{hash}` | ✅ Added (public read) — Space app share links work |
  | `.../projects/{pId}/inbox/{id}` + `versions` | ✅ Added — Intake visible |
  | `/workspaces/{wId}/stickies/{id}` | ✅ Added |
  | `/workspaces/{wId}/draftIssues/{id}` | ✅ Added |
  | `.../issues/{iId}/relations,reactions,attachments,versions` | ✅ Added |
  | `.../pages/{pgId}/versions` | ✅ Added |
  | `.../estimates/{eId}/points` | ✅ Added |
  | `/workspaces/{wId}/comments/{cId}/reactions` | ✅ Added |

  **Next step:** Run `firebase deploy --only firestore:rules` to push the new rules to Firebase.

---

## Phase 4 — Known stubs (won't crash, but don't do anything real yet)

Not bugs to "fix" so much as features to actually build when you get to them:

| Feature                                                                    | File(s)                                     |
| -------------------------------------------------------------------------- | ------------------------------------------- |
| In-app notifications                                                       | `workspace-notification.service.ts`         |
| Webhooks                                                                   | `webhook.service.ts`                        |
| Analytics dashboards                                                       | `analytics.service.ts`                      |
| Integrations (GitHub/Jira/marketplace)                                     | `integrations/*.service.ts`                 |
| File/asset uploads (attachments, covers, avatars, editor images, Unsplash) | `file.service.ts`                           |
| Workspace member invites                                                   | `workspace.service.ts` (`inviteWorkspace*`) |

One of these is **not** a graceful stub and needs different handling:

- [x] 🟢 **API Tokens settings page** — `packages/services/src/developer/api-token.service.ts` now stubbed. `list()` returns `[]`, `destroy()` no-ops, `create`/`retrieve` reject with a clear message. Page renders gracefully with no network errors.

---

## Phase 5 — Cosmetic / cleanup (low priority)

- [x] 🟢 `PlaneLogo` (`packages/propel/src/icons/brand/plane-logo.tsx`) and `BuzzwareLockup` props are fixed. Both components now accept and respect `width`, `height`, and `className` props correctly.
- [x] 🟢 Stale comment in `apps/web/.env` removed. Header now accurately states the app runs on Firebase with no backend server.
- [ ] 🔴 `apps/web/core/services/api.service.ts` — (Retained: APIService is still imported by other files in `packages/services`, so it is not safe to delete).

---

## Suggested order of attack

1. Rotate the exposed key (Phase 0) — 2 minutes, do it now regardless of anything else.
2. Apply the 4 guided fixes in Phase 2 that already have exact code written (`file.service.ts`, `workspace-menu-root.tsx`, `member/base.tsx`, `authentication-wrapper.tsx`).
3. Fix the remaining 7 nested-button files using the same pattern as the one already applied.
4. Trace and fix the `ProjectCard` nested `<a>` and the sidebar-submenu empty-panel issue — these need one more diagnostic pass each.
5. Decide, from Phase 3, which Firestore rules gaps matter for your current milestone (at minimum: `/config/instance` and `/anchors/{hash}` if you plan to demo Admin or Space at all) and write the missing `match` blocks + fix the two logic bugs.
6. Treat Phase 4 as a backlog, not bugs — prioritize by which stubbed feature you actually need next.
7. Phase 5 whenever you have downtime.
