Skip to content

[US-18.2 / OBT-257] Console: Phases page is admin-only; managers only move phase status - #39

Open
levigtri wants to merge 4 commits into
mainfrom
levigft/obt-257-us-182-console-phases-page-is-admin-only-managers-only-move
Open

[US-18.2 / OBT-257] Console: Phases page is admin-only; managers only move phase status#39
levigtri wants to merge 4 commits into
mainfrom
levigft/obt-257-us-182-console-phases-page-is-admin-only-managers-only-move

Conversation

@levigtri

@levigtri levigtri commented Jul 13, 2026

Copy link
Copy Markdown
Member

Summary

Phases are a platform-owned catalog: only a PlatformAdmin defines them and organizes their dependencies, and every phase automatically belongs to every project. A manager's only phase action is moving the status of a phase on a project they manage.

The console did not reflect that. /app/phases — the full phase CRUD plus the dependency graph editor — was the one route under /app that was not wrapped in AdminRoute (unlike users and apps), and its sidebar entry sat in contentNavItems, so any manager could reach it and create, rename or delete a phase and rewire the dependency graph platform-wide. The project's Phases tab also exposed Attach/Detach, letting a manager remove a phase from their own project.

This gates the Phases page behind AdminRoute, removes the attach/detach UI (the endpoints are gone in US-18.1), and lifts the phase status union into the shared types so ProjectPhasesTab and MapPage stop duplicating it. Pairs with US-18.1 / OBT-256 on the backend.

Changes

  1. Gate the phase catalog behind AdminRoutesrc/App.tsx — the phases route is now <AdminRoute><PhasesPage /></AdminRoute>, so a manager hitting the URL directly gets AccessDeniedPage instead of the editor.
  2. Move the Phases nav entry to the admin sectionsrc/components/layout/Sidebar.tsx/app/phases moves from contentNavItems to adminNavItems, hiding it from non-admins in both the desktop and mobile navs.
  3. Share the PhaseStatus typesrc/types/phase.ts, src/types/index.tsPhaseStatus (not_started | in_progress | completed | blocked) and PHASE_STATUSES now live in the shared types and are re-exported by name from the index. ProjectPhaseResponse.status is typed PhaseStatus instead of string.
  4. Drop attach/detach from the API clientsrc/services/api.tsprojectsAPI.attachPhase and projectsAPI.detachPhase are removed (their endpoints no longer exist); updatePhaseStatus now takes PhaseStatus rather than a free string.
  5. Project Phases tab is status-onlysrc/components/pages/ProjectPhasesTab.tsx — removes the AttachPhaseDialog, the "Attach Phase" button, the per-node detach (X) button and its ConfirmDialog. Keeps the read-only dependency graph and the status popover, now driven by the shared PHASE_STATUSES, and drops the unchecked as PhaseStatus cast. The empty state explains that phases are defined by a platform admin and apply to every project.
  6. MapPage uses the shared typesrc/components/pages/MapPage.tsxPHASE_STATUS_COLORS is keyed by PhaseStatus instead of a plain string, so the four status values are no longer duplicated and the ?? not_started fallback becomes unnecessary.

Type of Change

  • New feature (non-breaking change which adds functionality)
  • Bug fix (non-breaking change which fixes an issue)
  • Breaking change
  • Documentation update

Testing

  • npm run typecheck — passes
  • npm run lint — 0 errors (the pre-existing ProjectsPage.tsx exhaustive-deps warning remains)
  • npm run build — passes

Manual, against the US-18.1 branch of the API:

  1. As a manager: the sidebar no longer shows "Phases"; navigating to /app/phases directly renders Access Denied.
  2. As a manager, on a project you manage → Phases tab: every phase created by the admin is listed; there is no Attach/Detach; clicking a phase opens the status popover and the update persists.
  3. As a platform admin: the Phases page still lists, creates, edits, deletes phases and edits dependencies; a newly created phase immediately shows up on every project's Phases tab.

Summary by CodeRabbit

  • Access Changes

    • Restricted the Phases page to platform administrators.
    • Made the Map navigation available to platform administrators and managers.
  • Improvements

    • Simplified project phase management to focus on updating statuses.
    • Removed phase attach/detach controls and related dialogs from the project phases view.
    • Standardized supported phase statuses for more consistent display and updates.

levigtri added 3 commits July 13, 2026 19:17
The Phases page exposes global phase CRUD and the dependency graph editor,
but its route was not wrapped in AdminRoute (unlike users/apps) and its nav
entry sat in contentNavItems, so any manager could reach it and create,
rename or delete a phase and rewire dependencies platform-wide.

Gate /app/phases behind AdminRoute and move the sidebar entry to adminNavItems.
The status union was declared locally in ProjectPhasesTab and duplicated by
MapPage, while the shared ProjectPhaseResponse typed status as a plain string
and forced an unchecked cast.

Move PhaseStatus and PHASE_STATUSES into src/types/phase.ts and consume them
from both pages and from projectsAPI.updatePhaseStatus.
Every phase defined by a platform admin belongs to every project, so a
per-project selection no longer exists and a manager must not be able to
remove a phase from their own project.

Remove the Attach Phase dialog, the per-node detach button and its confirm
dialog from ProjectPhasesTab, along with the attachPhase/detachPhase API
methods whose endpoints are gone. The tab keeps the read-only graph and the
status popover — the manager's only phase write.
@linear-code

linear-code Bot commented Jul 13, 2026

Copy link
Copy Markdown

OBT-257

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The update introduces shared typed phase statuses, removes phase attachment and detachment controls, restricts the phases route to platform admins, moves Map into content navigation, and changes map phase-color lookup behavior.

Changes

Phase management

Layer / File(s) Summary
Typed phase status contract
src/types/phase.ts, src/types/index.ts, src/services/api.ts, src/components/pages/MapPage.tsx
Phase statuses are defined as shared literals, re-exported, and applied to project phase responses, status updates, and map color mappings.
Project phase status controls
src/components/pages/ProjectPhasesTab.tsx, src/services/api.ts
The phases tab keeps status editing while removing attach/detach state, controls, dialogs, and API methods.
Route access and map navigation
src/App.tsx, src/components/layout/Sidebar.tsx, src/components/pages/MapPage.tsx
The phases route requires AdminRoute, Map is placed in content navigation, and map phase colors use direct status lookups.

Suggested reviewers: joaocarvoli

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main change: phases admin-only access and managers limited to phase status updates.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch levigft/obt-257-us-182-console-phases-page-is-admin-only-managers-only-move

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/components/pages/MapPage.tsx (1)

45-50: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Restore the fallback for unexpected phase statuses

ProjectPhaseResponse.status is only trusted at compile time; if the API returns a value outside PhaseStatus, PHASE_STATUS_COLORS[p.status] becomes undefined and colors.bg throws while rendering the popup. Restore ?? PHASE_STATUS_COLORS.not_started here.

Suggested fix
-              const colors = PHASE_STATUS_COLORS[p.status]
+              const colors = PHASE_STATUS_COLORS[p.status] ?? PHASE_STATUS_COLORS.not_started
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/pages/MapPage.tsx` around lines 45 - 50, Restore the fallback
in the popup color lookup using PHASE_STATUS_COLORS: when resolving colors from
p.status, apply PHASE_STATUS_COLORS.not_started whenever the status key is
missing or unexpected, while preserving mapped colors for valid PhaseStatus
values.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/components/pages/MapPage.tsx`:
- Around line 45-50: Restore the fallback in the popup color lookup using
PHASE_STATUS_COLORS: when resolving colors from p.status, apply
PHASE_STATUS_COLORS.not_started whenever the status key is missing or
unexpected, while preserving mapped colors for valid PhaseStatus values.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: QUIET

Plan: Pro Plus

Run ID: c25b3e71-1ad8-4da2-9d57-edac5c43d870

📥 Commits

Reviewing files that changed from the base of the PR and between 130fc4a and 372369b.

📒 Files selected for processing (7)
  • src/App.tsx
  • src/components/layout/Sidebar.tsx
  • src/components/pages/MapPage.tsx
  • src/components/pages/ProjectPhasesTab.tsx
  • src/services/api.ts
  • src/types/index.ts
  • src/types/phase.ts

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant