feat(projects): make project network visibility (public/private) effective#282
Merged
Conversation
The project Network column existed but was never bound or used, and the UI "Network" dropdown was wired to the unrelated guest_view_all_features flag. Network is now bound in project create/update (validated as public=2 or secret=0) and enforced: a secret project is listed and openable only by its members and workspace admins, while public projects stay visible to every workspace member. Existing projects default to public, so nothing changes for them. The settings and create-project dropdowns now read and write the real network field instead of guest_view_all_features. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
apps/api/internal/store/project.go (1)
58-71: 🚀 Performance & Scalability | 🔵 TrivialConsider adding database indexes for
ListVisibleByWorkspaceID.The query filters on
projects.workspace_id+projects.networkand uses a subquery onproject_members.member_id. For workspaces with many projects, a composite index onprojects(workspace_id, network)and an index onproject_members(member_id, deleted_at)would improve listing performance.🤖 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 `@apps/api/internal/store/project.go` around lines 58 - 71, Add the missing database indexes for ProjectStore.ListVisibleByWorkspaceID: the query in ListVisibleByWorkspaceID filters on projects.workspace_id and projects.network, and the subquery on model.ProjectMember filters by member_id plus deleted_at. Update the relevant model/migration definitions for model.Project and model.ProjectMember to include a composite index on workspace_id, network and an index on member_id, deleted_at so the workspace project listing stays fast.
🤖 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.
Inline comments:
In `@apps/api/internal/handler/project.go`:
- Line 98: The Create flow in ProjectHandler currently creates the project
before validating body.Network, which can leave behind a default project when
Update later returns ErrInvalidNetwork. Move the network validation into the
Create handler before the h.Project.Create call, using the same validation path
used by Update/ErrInvalidNetwork handling so invalid input is rejected early
with no side effects. Keep the change localized around the ProjectHandler.Create
and Update validation logic so the network field is checked before any project
is persisted.
---
Nitpick comments:
In `@apps/api/internal/store/project.go`:
- Around line 58-71: Add the missing database indexes for
ProjectStore.ListVisibleByWorkspaceID: the query in ListVisibleByWorkspaceID
filters on projects.workspace_id and projects.network, and the subquery on
model.ProjectMember filters by member_id plus deleted_at. Update the relevant
model/migration definitions for model.Project and model.ProjectMember to include
a composite index on workspace_id, network and an index on member_id, deleted_at
so the workspace project listing stays fast.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: d3fe2c55-054c-4e07-8653-c07eadfcdb7e
📒 Files selected for processing (9)
apps/api/internal/handler/project.goapps/api/internal/handler/project_network_test.goapps/api/internal/model/project.goapps/api/internal/service/project.goapps/api/internal/store/project.goapps/web/src/api/types.tsapps/web/src/components/CreateProjectModal.tsxapps/web/src/pages/SettingsPage.tsxapps/web/src/services/projectService.ts
Create persisted the project first and only applied network via a follow-up Update, so an out-of-range network returned a 400 while leaving a default-network project behind (and inviting a duplicate on retry). Validate the value right after binding, before anything is persisted. Addresses a CodeRabbit review finding on #201's sibling PR (#197). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
nazarli-shabnam
approved these changes
Jul 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #197.
Choosing a project's network had no effect:
Project.Networkexisted (default2) but was never bound in create/update or used in listing/access, and the UI "Network" dropdown was wired to the unrelatedguest_view_all_featuresflag.Backend
networkis now bound in project create and update and validated (must bepublic = 2orsecret = 0, else400).ProjectStore.ListVisibleByWorkspaceIDreturns every public project plus the (public or secret) ones the user belongs to; workspace admins/owners still see everything.404to a workspace member who isn't a project member (and isn't a workspace admin).public, so their visibility is unchanged.Frontend
networkfield (public → 2, secret → 0) instead of conflating it withguest_view_all_features.Testing
go vet ./...passes; project + issue handler test suites pass (no regression from theGetByIDchange).handler_test.TestProject_NetworkVisibilitydrives the full HTTP stack: a public project is visible/openable to a non-member workspace member; after switching it to secret, that user no longer sees it in the list and gets404onGetByID, while a project member still sees and opens it; restoring to public re-shows it; an out-of-range network value is rejected400.typecheck+lint+format:checkpass. Note: a live in-browser click-through was blocked this session (the browser tool was disconnected and the local dev session had expired), so the end-to-end coverage here is the HTTP-level integration test above.AI assistance
Produced with the help of Claude Code (Claude Opus 4.8). See the
Co-Authored-Bytrailer on the commit.Summary by CodeRabbit
New Features
Bug Fixes
UI Updates