Manual QA issue for the organization flow in Boundless: creating organizations, managing profile/settings, members and invitations, navigation, archive/delete, and public org profile. Use this to run through the flows and record any bugs or UX issues.
Scope
- App area:
/organizations and all org sub-routes; /org/[slug] (public profile); /accept-invitation/[invitationId].
- Auth: Flows assume the tester is signed in unless noted (e.g. public profile, accept-invitation).
- Backend: Depends on Better Auth organization APIs and backend org/hackathon APIs (e.g.
NEXT_PUBLIC_API_URL). Invitations and member list depend on backend/Better Auth behavior.
1. Entry points & navigation
| Entry |
URL / Action |
What to check |
| Org list |
Nav → “Organizations” or /organizations |
Redirects to org dashboard when logged in; list loads or empty state shows. |
| New org |
“Add Organization” / “Create Organization” → /organizations/new |
Redirects to create flow; auth guard sends unauthenticated users to sign-in. |
| Org dashboard |
Click an org card from /organizations |
Card click sets active org and navigates to /organizations/[id]; sidebar and breadcrumbs reflect current org. |
| Layout |
Any /organizations/... (except /organizations and /organizations/new) |
Header shows breadcrumbs (Organizations > Org name > …); sidebar shows Hackathons, Settings, “Host Hackathon”; mobile shows hamburger sidebar. |
| Public profile |
Direct or shared link /org/[slug] |
Loads org by slug; metadata/OG correct; “Organization not found” when slug invalid or backend error. |
Things to point out
- Org ID in URL: Dashboard/settings/hackathons use ID (
/organizations/[id]/...). Layout derives orgId from path and expects ID format (e.g. 24-char hex). If the backend ever returns or links using slug in these paths, links can break.
- Breadcrumbs: Second crumb uses
activeOrg.name; if org is slow to load, name can be blank or show a skeleton.
- Header org selector:
OrganizationSelector is commented out in OrganizationHeader.tsx; quick actions (e.g. “Host Hackathon”, “New Organization”) still depend on activeOrg / path.
2. Create organization
| Step |
Action |
What to check |
| 2.1 |
Go to /organizations/new |
Profile tab only (no Links/Members/Transfer); form empty. |
| 2.2 |
Fill Name |
Slug auto-derives (e.g. from slugify(name)); can override manually. |
| 2.3 |
Slug field |
Debounced slug check (e.g. authClient.organization.checkSlug); UI shows available/taken/invalid (e.g. min length). |
| 2.4 |
Tagline & About |
Both required on submit; clear validation messages. |
| 2.5 |
Logo |
Optional; upload (or URL if supported); preview updates. |
| 2.6 |
Submit |
Create org (Better Auth organization.create); success toast; redirect to /organizations/[newOrgId]/settings after short delay. |
| 2.7 |
Duplicate slug |
Try creating another org with same slug when “taken”; backend/checkSlug should block or show error. |
Things to point out
- Required fields: Name, tagline, about are enforced; empty optional fields (e.g. links) should not block create.
- Slug source: Slug is sent to backend; public profile uses slug (
/org/[slug]). Ensure create/update keep slug unique and URL-safe.
- Post-create: Redirect goes to settings (not dashboard); user can then open “Hackathons” from sidebar.
3. Organization settings (existing org)
| Step |
Action |
What to check |
| 3.1 |
Open /organizations/[id]/settings |
Tabs: Profile, Links, Members, Transfer Ownership. |
| 3.2 |
Profile |
Name, slug, logo, tagline, about, links load from activeOrg (or initialData). Edits save via updateOrganization; success/error toasts. |
| 3.3 |
Links |
Website, X, GitHub, others; save persists and survives refresh. |
| 3.4 |
Members |
List of members; roles; “Invite by email” and pending invitations (if backend supports). |
| 3.5 |
Transfer Ownership |
Only for owner; flow and confirmation; backend must enforce. |
Things to point out
- Active org sync: Settings page calls
setActiveOrg(organizationId) on mount so sidebar/header context is correct when navigating from list or direct URL.
- Slug edit: Changing slug on profile affects
/org/[slug]; ensure slug check runs on edit (exclude current org) and duplicate slug is rejected.
4. Members & invitations
| Step |
Action |
What to check |
| 4.1 |
Settings → Members |
Members list loads (Better Auth / backend); roles and avatars/names if returned. |
| 4.2 |
Invite by email |
Add one or more emails; “Invite” calls authClient.organization.inviteMember per email; success/error toasts; pending invitations appear. |
| 4.3 |
Pending list |
Shows email, role, expiry; “Cancel” calls cancel-invitation API; list updates after cancel. |
| 4.4 |
Accept invitation (invitee) |
Open link /accept-invitation/[invitationId] (invitee logged in or after sign-in). Accept runs authClient.organization.acceptInvitation; success → redirect to /organizations/[organizationId]; error → message and “Go to Home”. |
| 4.5 |
Accept invitation (invalid/expired) |
Use wrong or expired invitationId; expect error state and clear message. |
Things to point out
- Invitation link: Must use
invitationId (e.g. from email); link format and env (e.g. NEXT_PUBLIC_APP_URL) must match so invitee lands on the app.
- Permissions: Only owners can cancel invitations; others see an error (e.g. “Only organization owners can cancel invitations”).
- Member list after invite: Depends on backend; if members are refetched after invite, list should update; same for cancel.
5. Organization list & actions
| Step |
Action |
What to check |
| 5.1 |
/organizations |
Cards show name, logo, created date, hackathon count, grant count; archived orgs have “Archived” and different style. |
| 5.2 |
Search |
Filter by name; empty state when no match; “Clear search” resets. |
| 5.3 |
Sort |
Newest / Oldest / Name A–Z / Name Z–A; order persists while on page. |
| 5.4 |
Edit (card menu) |
“Edit Organization” → /organizations/[id]/settings. |
| 5.5 |
Archive |
Confirm dialog; archive API; toast; if archived org was active, redirect to /organizations; card shows “Archived” and “Unarchive”. |
| 5.6 |
Unarchive |
Confirm; unarchive API; toast; card returns to normal. |
| 5.7 |
Delete |
Delete dialog with checkbox “I understand…”; delete only enabled when checked; delete API; toast; redirect to /organizations if deleted org was active. |
Things to point out
- Delete: Irreversible; copy states that hackathons, grants, submissions, settings are deleted. Confirm checkbox prevents misclicks.
- Archive vs delete: Archive hides from “active” list but keeps data; delete is permanent. Confirm backend behavior matches UI.
- Card click: Clicking card (not menu) sets active org and goes to
/organizations/[id]; loading state (e.g. isThisOrgLoading) should prevent double navigation.
6. Sidebar & quick actions
| Step |
Action |
What to check |
| 6.1 |
From org context |
Sidebar: Hackathons, Grants (disabled), Settings; Quick actions: “Host Hackathon”, “Create Grants” (disabled). |
| 6.2 |
“Host Hackathon” |
Goes to /organizations/[id]/hackathons/new. |
| 6.3 |
“Settings” |
Goes to /organizations/[id]/settings (or “New Organization” when derivedOrgId is missing). |
| 6.4 |
Mobile |
Hamburger opens sheet with same nav; no layout shift or wrong org. |
Things to point out
- Grants: “Grants” and “Create Grants” are disabled (coming soon); no 404 or broken links.
- Org context: Sidebar uses
pathname to derive derivedOrgId; on /organizations/[id]/hackathons/... the correct org is used for links.
7. Public organization profile
| Step |
Action |
What to check |
| 7.1 |
Open /org/[slug] (valid slug) |
Fetches getOrganizationProfile(slug); shows name, description, etc.; metadata/OG for sharing. |
| 7.2 |
Invalid slug |
“Organization not found” or error state. |
| 7.3 |
OG image |
/api/og?slug=... used for social preview; image and title/description correct. |
Things to point out
- Slug vs ID: Public URL is slug; dashboard/settings use ID. Ensure backend profile by slug is stable and that orgs with incomplete profile (e.g. missing tagline) don’t break the page.
8. Edge cases & cross-cutting
| Area |
What to check |
| Auth |
Sign out from org page → redirect or clear state; sign in again → org list and active org make sense. |
| Loading |
Org list loading spinner; active org loading (e.g. breadcrumb skeleton); no flash of wrong org name. |
| Errors |
Network/server errors show toast or inline message; no uncaught errors or white screen. |
| Deep links |
Direct URL to /organizations/[id]/settings or /organizations/[id]/hackathons loads with correct org and sidebar. |
| Search (header) |
⌘K / search opens OrganizationHeaderSearch; if backend supports GET /organizations/search?q=..., results and navigation work (see docs/BACKEND_ORGANIZATION_SEARCH.md). |
9. Acceptance checklist (summary)
10. Files to keep in mind
| Area |
Files |
| Routes |
app/(landing)/organizations/page.tsx, .../new/page.tsx, .../[id]/page.tsx, .../[id]/settings/page.tsx, app/(landing)/accept-invitation/[invitationId]/page.tsx, app/(landing)/org/[slug]/page.tsx |
| Layout |
app/(landing)/organizations/layout.tsx (org ID from path, sidebar visibility) |
| List & cards |
components/organization/OrganizationContent.tsx, components/organization/cards/OrganzationCards.tsx |
| Settings |
components/organization/OrganizationSettings.tsx, tabs/ProfileTab.tsx, tabs/LinksTab.tsx, tabs/MembersTab.tsx, tabs/TransferOwnershipTab.tsx |
| Header & sidebar |
components/organization/OrganizationHeader.tsx, components/organization/OrganizationSidebar.tsx |
| Delete |
components/organization/DeleteOrganizationDialog.tsx |
| Provider |
lib/providers/OrganizationProvider.tsx (create, update, delete, archive, setActiveOrg, fetch orgs) |
Use this issue for manual test runs and paste any failures or unclear behavior (with steps and env) as comments so the team can fix or refine the flow.
Manual QA issue for the organization flow in Boundless: creating organizations, managing profile/settings, members and invitations, navigation, archive/delete, and public org profile. Use this to run through the flows and record any bugs or UX issues.
Scope
/organizationsand all org sub-routes;/org/[slug](public profile);/accept-invitation/[invitationId].NEXT_PUBLIC_API_URL). Invitations and member list depend on backend/Better Auth behavior.1. Entry points & navigation
/organizations/organizations/new/organizations/organizations/[id]; sidebar and breadcrumbs reflect current org./organizations/...(except/organizationsand/organizations/new)/org/[slug]Things to point out
/organizations/[id]/...). Layout derivesorgIdfrom path and expects ID format (e.g. 24-char hex). If the backend ever returns or links using slug in these paths, links can break.activeOrg.name; if org is slow to load, name can be blank or show a skeleton.OrganizationSelectoris commented out inOrganizationHeader.tsx; quick actions (e.g. “Host Hackathon”, “New Organization”) still depend onactiveOrg/ path.2. Create organization
/organizations/newslugify(name)); can override manually.authClient.organization.checkSlug); UI shows available/taken/invalid (e.g. min length).organization.create); success toast; redirect to/organizations/[newOrgId]/settingsafter short delay.Things to point out
/org/[slug]). Ensure create/update keep slug unique and URL-safe.3. Organization settings (existing org)
/organizations/[id]/settingsactiveOrg(or initialData). Edits save viaupdateOrganization; success/error toasts.Things to point out
setActiveOrg(organizationId)on mount so sidebar/header context is correct when navigating from list or direct URL./org/[slug]; ensure slug check runs on edit (exclude current org) and duplicate slug is rejected.4. Members & invitations
authClient.organization.inviteMemberper email; success/error toasts; pending invitations appear./accept-invitation/[invitationId](invitee logged in or after sign-in). Accept runsauthClient.organization.acceptInvitation; success → redirect to/organizations/[organizationId]; error → message and “Go to Home”.invitationId; expect error state and clear message.Things to point out
invitationId(e.g. from email); link format and env (e.g.NEXT_PUBLIC_APP_URL) must match so invitee lands on the app.5. Organization list & actions
/organizations/organizations/[id]/settings./organizations; card shows “Archived” and “Unarchive”./organizationsif deleted org was active.Things to point out
/organizations/[id]; loading state (e.g.isThisOrgLoading) should prevent double navigation.6. Sidebar & quick actions
/organizations/[id]/hackathons/new./organizations/[id]/settings(or “New Organization” whenderivedOrgIdis missing).Things to point out
pathnameto derivederivedOrgId; on/organizations/[id]/hackathons/...the correct org is used for links.7. Public organization profile
/org/[slug](valid slug)getOrganizationProfile(slug); shows name, description, etc.; metadata/OG for sharing./api/og?slug=...used for social preview; image and title/description correct.Things to point out
8. Edge cases & cross-cutting
/organizations/[id]/settingsor/organizations/[id]/hackathonsloads with correct org and sidebar.OrganizationHeaderSearch; if backend supportsGET /organizations/search?q=..., results and navigation work (seedocs/BACKEND_ORGANIZATION_SEARCH.md).9. Acceptance checklist (summary)
/organizationsand see list or empty state; “Create Organization” and “Add Organization” work./org/[slug]loads for valid slug; not found for invalid slug; OG/metadata correct.10. Files to keep in mind
app/(landing)/organizations/page.tsx,.../new/page.tsx,.../[id]/page.tsx,.../[id]/settings/page.tsx,app/(landing)/accept-invitation/[invitationId]/page.tsx,app/(landing)/org/[slug]/page.tsxapp/(landing)/organizations/layout.tsx(org ID from path, sidebar visibility)components/organization/OrganizationContent.tsx,components/organization/cards/OrganzationCards.tsxcomponents/organization/OrganizationSettings.tsx,tabs/ProfileTab.tsx,tabs/LinksTab.tsx,tabs/MembersTab.tsx,tabs/TransferOwnershipTab.tsxcomponents/organization/OrganizationHeader.tsx,components/organization/OrganizationSidebar.tsxcomponents/organization/DeleteOrganizationDialog.tsxlib/providers/OrganizationProvider.tsx(create, update, delete, archive, setActiveOrg, fetch orgs)Use this issue for manual test runs and paste any failures or unclear behavior (with steps and env) as comments so the team can fix or refine the flow.