Repository navigation
feat: organizations in the API - #1268
rohitsasi720 wants to merge 2 commits into
Conversation
The app links @organization mentions now that the API tells each mention's kind, but had nothing to open: organization pages are web-only. This adds GET /api/v1/organizations/{handle}, public like users/{handle}, returning the fields the web's organization page shows.
A mention keeps the case it was written in, so @laravel asks for Laravel. Also lists the endpoint in the knowledge base.
|
No actionable comments were generated in the recent review.
|
| Layer / File(s) | Summary |
|---|---|
Organization lookup and response app/Http/Requests/ShowApiOrganizationRequest.php, routes/api.php, app/Http/Controllers/Api/OrganizationController.php, tests/Feature/Controllers/Api/OrganizationControllerTest.php, KNOWLEDGE_BASE.md |
The route connects the organization lookup request to a controller that returns the matched profile under data. Feature tests cover profile fields, case-insensitive lookup, and not-found responses. The documentation lists the controller and endpoint. |
Priority:
Estimated code review effort: 2 (Simple) | ~10 minutes
Change: Feature
Sequence Diagram(s)
sequenceDiagram
participant Client
participant Route as api-organization.show
participant Request as ShowApiOrganizationRequest
participant Profiles as Profile records
participant Controller as OrganizationController
Client->>Route: GET organization handle
Route->>Request: Resolve and authorize organization
Request->>Profiles: Find organization by case-insensitive handle
Profiles-->>Request: Matching profile or no match
Request-->>Controller: Authorized request with profile
Controller-->>Client: JSON response with profile under data
Possibly related issues
dev-null-sh/dev-null.sh#938— The endpoint can resolve organization profiles by handle, which supports organization mention resolution.dev-null-sh/dev-null.sh#857— The documentation now includes the organization endpoint for the public API.
Possibly related PRs
- dev-null-sh/dev-null.sh#1262 — This PR adds the API representation for the organization profiles introduced in that PR.
- dev-null-sh/dev-null.sh#1156 — This endpoint uses the
Profilemodel introduced in that PR.
Suggested reviewers: mnapoli, nunomaduro
Merge Risk: 
Minimal · up to 431e1
-
The endpoint is ready to merge, with no actionable risk identified.
Security architecture risk: 
Minimal · up to 431e1
-
The endpoint exposes the same limited organization-profile fields already available on the web. It preserves existing authentication and throttling controls, restricts lookup to organizations, and does not modify profile data. No material security risk introduced or worsened by this change was identified.
Retained concerns
No architecture-level concerns identified.Security review details
-
Security Blast Radius
- observed — An unauthenticated caller can query persisted organization profiles by handle, not just organizations mentioned to that caller. The returned scope is limited to the six public profile fields already used by the web page; internal identifiers, synchronization timestamps, and the user relation are outside the serialization allowlist.
Trust Boundaries and Controls
- observed — The organization-type predicate prevents user-profile selection, and parameter binding separates the untrusted handle from SQL syntax. For unsigned requests, the existing middleware temporarily removes any ambient authenticated user and restores it in a finally block, including when downstream processing throws.
Resilience and Maintainability Implications
- observed — The shared serialization allowlist is backed by an added exact-JSON assertion that excludes additional model fields. This provides a regression check against accidental response expansion, although the tests were inspected rather than executed during this review.
-
Pre-merge checks: 
4 · 
1
-
Failed checks: 1 warning Passed checks: 4 passedFull details: Docstring Coverage
-
Explanation
Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 2 functions across 4 files. (1 skipped: 1 unsupported.)
Resolution
Write docstrings for the functions missing them to satisfy the coverage threshold.
-
Finishing Touches
-
🧪 Generate unit tests (beta)
-
- Create a new PR
-
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Comment @coderabbitai help to get the list of available commands.
A mention now says whether it names a user or a GitHub organization, and tapping @laravel opened a profile that devnull doesn't have: "No query results for model [App\Models\User] laravel". An organization mention now opens an Organization screen beneath the tab, drawn like the web's page from GET /api/v1/organizations/{handle} (dev-null-sh/dev-null.sh#1268). Until devnull has that, the screen offers the page on the web.
|
Closing this: f8e60e2 (feat: orgs on the native mac os app) added the same One difference, in case it's worth a follow-up: this PR matched the handle in any case ( |
* Open mentioned GitHub organizations in their own screen A mention now says whether it names a user or a GitHub organization, and tapping @laravel opened a profile that devnull doesn't have: "No query results for model [App\Models\User] laravel". An organization mention now opens an Organization screen beneath the tab, drawn like the web's page from GET /api/v1/organizations/{handle} (dev-null-sh/dev-null.sh#1268). Until devnull has that, the screen offers the page on the web. * Leave devnull's error off the organization screen The page says itself when it didn't load, and offers the page on the web.
Summary
Since #1262, the API marks each mention as a
useror anorganization, but organization pages exist only on the web. When someone taps an organization mention in the mobile app, the app has nothing to fetch. Before the app read the mention's kind, a tap on@laravelopened a profile and failed with "No query results for model [App\Models\User] laravel".This adds
GET /api/v1/organizations/{handle}, so the app can show an organization's page natively. Likeusers/{handle}, it is public and also works for signed requests. It returns what the web's organization page shows.Changes
GET /api/v1/organizations/{handle}(api-organization.show), in the samethrottle:apiand optional-signature group asusers/{handle}.Api\OrganizationController@showreturns{"data": {handle, name, avatar_url, bio, location, website}}. These are theProfilemodel's visible fields, the same ones the web page gets.id,github_id,typeand the timestamps stay hidden.ShowApiOrganizationRequestfinds the organization profile by handle and returns 404 for anything else, including a handle a user has.@Laravelasks forLaravel. It usesLOWER(handle) = ?likeUpdateStaleHandles, whichprofiles_lower_handle_indexcovers./@{handle}lookup is unchanged and still matches case exactly.KNOWLEDGE_BASE.mdlists the endpoint with the public read API and links it from the Organization pages section.PRODUCT.mdalready covers organization pages and the app's API, so it is unchanged.Validation
All checks ran locally, not in hosted CI.
php -d memory_limit=-1 vendor/bin/pest --parallel --ci: 4779/4779 passed, at the first revision. After the review fixes, the organization and arch tests were rerun: 15/15 passed.composer test:lintexits 0. Its only warnings were already there.composer test:type-coverage: 100.0%.--coverage --exactly=100.0, because this machine has no coverage driver. The new tests exercise every new line, and CI will confirm the exact figure.bun run test:unitwas not run, because no frontend code changed.Independent review
An independent reviewer agent, separate from the implementer, did a read-only review.
3a6eabe2(production)79c2ac14: CODE: PASS. It asked for the knowledge base update and flagged the case-sensitive lookup.431e176d: the knowledge base entry, the case-insensitive match plus a test, and a PHPDoc line.431e176d: CODE: PASS, no findings.Limitations
/@Laravelstill matches case exactly, unlike this endpoint. That is left for a follow-up.Summary by CodeRabbit