Organizations: create-org flow, public org profile page, and discoverable owner-only management (profile edit + member add/remove) #348
Labels
No labels
actions
bug
cli
duplicate
enhancement
fork
forum
git storage
help wanted
insights
invalid
issues
moderation
oidc
ownership transfer
packages
pr/merge protection rules
projects
pull requests
question
releases
sponsorships
tags
webhooks
wiki
wontfix
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
crueber/walhub#348
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What's requested
The ability to create an organization and manage it — with an org profile (like the owner profile from #234) that org admins can edit. Managing includes adding/removing users; only an org admin (owner) may add/remove people or edit the profile.
What already exists (verified — this is mostly a UI/reveal ticket)
The backend is substantially built:
Org{Version, Org, DisplayName, Description, CreatedAt, UpdatedAt}atorgs/<org>/org.json;Members{Version, []Member{Principal, OrgRole, JoinedAt}}atmembers.json;Teamatteams/<slug>.json(internal/identity/orgs.go:16-47).CreateOrg(:101, two-step create with creator→owner bootstrap at :115/:167),GetOrg(:221),PutOrg(:233),ListOrgs(:258),GetMembers(:312),SetMember(:319),RemoveMember(:360), plus full Teams CRUD (:425-552).OrgOwner/OrgMember(internal/identity/identity.go:90-94);CheckOrgOwnergate for org writes (internal/identity/gate.go:79-91)./api/v1/orgs[/...](GET/PUT/DELETE org),/orgs/{org}/members(GET collection; PUT/DELETE member),/orgs/{org}/teamsCRUD (internal/identity/http.go:296, 378, 434, 530), plus invites (http_invites.go).web/src/pages/Org.jsxat/:org/settings— tabs Profile / Members / Teams / Invitations, with role selects, invite-link form, and "org owner required" 403 handling. Team page at/:owner/teams/:slug.isOrgOwner→ admin in access resolution,access.go:234-236).The gaps
orgs.createcall inweb/src, no/orgs/newroute, no button on any page). The only documented route is/:org/settings— for an org that already exists./:org/settingsis the management view; there is no visitor-facing/:orglanding that renders the org profile (display name, description) plus its public repos — a visitor clicking an org name in/explorelands on the repo list only. The owner-profile equivalent is #234's/:ownerprofile work; orgs need the same shape (reuse #234's profile patterns and #247/#283 listing data).GET /api/v1/ownersand/exploremix orgs and users implicitly (an org is just an owner prefix) — with #283's activity rollup landed, org entries should be distinguishable (anis_orgmarker or joined org list) so the UI can badge them and link to the org profile rather than a bare repo list./:org/settings→ Members tab (direct PUT) and the Invitations tab (invite links) — functional, but nothing links to it (no "manage" affordance on an org page or in the nav for org owners).Proposed design
/explorenext to the existing New-repo/Import CTAs, and/or from the user menu) → small form (org name + display name + description) →POST /api/v1/orgs(the create service exists; verify the HTTP route accepts creation and the name-validation rules) → navigate to/:org/settings./:org: currently/:orgfalls through to the repo-list view (route/:owner); extend it to render an org header (display name, description, org badge) above the repo list when the owner is an org — mirror #234's owner-profile shape (GetOrgexists; the profile-vs-user distinction can ride the #283/#345 listing rollup or aListOrgsmembership check). Include a "Manage" link (settings) visible only to org owners.is_orgor akindfield) so/explorebadges them (same pattern as the #281 mirror indicator).CheckOrgOwnergates PUT org, member add/remove, and team writes; the UI already surfaces 403s as "org owner required". Keep that; add client-side gating so non-owner members see read-only views rather than 403 forms (useuseRole/org membership state, same pattern as repo role gating).CreateOrgalready bootstraps that at orgs.go:115) and ties into #346 (orgs a user belongs to become valid repo-owner choices) and #347 (org members' pushes resolve via org membership).Acceptance criteria
/:org/settings./:orgrenders a public org profile (display name, description, org badge) above the org's repo list for any visitor; "Manage" link appears only for org owners./explorebadges them and links to the profile view.CheckOrgOwner(403 for non-owners — unchanged); client gating is cosmetic-on-top.This ticket is a prerequisite for #346 and #347 - both now carry a sequencing header pointing here: the member-org half of their ownership guardrails is untestable until orgs can be created and managed through the UI. Implementation order: #348 -> #346 -> #347.
Fix PR: #355 (branch fix/issue-348) — create-org UI at /orgs/new, public org profile on /:org, is_org badges on /explore, owner-only management gating. All acceptance criteria covered; server CheckOrgOwner gates unchanged. Not merging — review requested.
REVIEW PR #355 (fix/issue-348, commit
420171e+ review fixupc3e091c) — verified in scratch worktree /tmp/pr355 (since removed).ACCEPTANCE vs #348 (all 4 gaps closed):
SEAM / PRIVILEGE / LAW CHECKS:
ONE FIX APPLIED (pushed as
c3e091c): web/src/lib/orgs.js shipped myOrgRole (roster-role lookup) with tests, but nothing imported it — Org.jsx gates on server can_edit, not a local roster lookup. Dead code + doc claimed it as an in-use rule. Removed helper + its 2 tests, fixed the 12_web_ui.md decision line. Small, re-tested.VERIFICATION (scratch worktree, post-fix): go test -race internal/api ✓ + internal/identity ✓; api coverage 95.3% ✓ (≥95 gate); gofmt/vet clean; node --test 692/692 pass (smoke.test.js excluded — see note); orgs.test.js 5/5; vite build + esbuild SDK bundle green; go build ./... clean; go.mod + package.json untouched (no new deps); docs decisions in 01_identity_permissions.md + 07_api.md + 12_web_ui.md (law 12 ✓).
NOTE (no browser, per instructions): web/test/unit/smoke.test.js fails in THIS environment only — something answers :8080/healthz but / returns 503 (setup-only-mode signature), so the smoke assertions trip. Environmental, unrelated to the PR (test self-skips when no server is up; I did not touch the live process). Browser proof (light/dark + 390px) still open as the PR notes.
MERGE RECOMMENDATION: ready to merge (after normal CI; browser pass still open per the PR's own note).
Fixed by PR #355 (review clean + one dead-code removal by reviewer; create flow, profile gating, is_org seam, #345 no-regress verified), merged. Closing.