Skip to content

refactor/replace ServerOnly authorizer with defineSubOperation and internalCall#510

Merged
JohanHjelsethStorstad merged 2 commits intomainfrom
refactor/remove-server-only-authorizer
Mar 5, 2026
Merged

refactor/replace ServerOnly authorizer with defineSubOperation and internalCall#510
JohanHjelsethStorstad merged 2 commits intomainfrom
refactor/remove-server-only-authorizer

Conversation

@theodorklauritzen
Copy link
Copy Markdown
Member

@theodorklauritzen theodorklauritzen commented Feb 23, 2026

Summary

  • Convert all defineOperation calls using ServerOnly/ServerOnlyAuthorizer as their authorizer to defineSubOperation
  • Update all call sites that previously used bypassAuth: true to use .internalCall() instead
  • Remove ServerOnly/ServerOnlyAuthorizer imports from all converted files

Motivation

The old pattern relied on a runtime auth bypass convention (bypassAuth: true) to call server-internal operations. defineSubOperation + .internalCall() makes the server-only intent explicit in the type system, which is cleaner and less error-prone.

Test plan

  • TypeScript check passes (tsc --noEmit — no errors)
  • Run the app locally and verify affected features work (visibility, CMS, groups, notifications, cabin booking, events, etc.)

🤖 Generated with Claude Code

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request refactors server-internal operations from using defineOperation with ServerOnly/ServerOnlyAuthorizer to using defineSubOperation, and updates all call sites to use .internalCall() instead of the bypassAuth: true pattern. This makes the server-only intent explicit in the type system.

Changes:

  • Converted 20+ server-internal operations from defineOperation with ServerOnly/ServerOnlyAuthorizer to defineSubOperation across CMS, permissions, groups, visibility, notifications, and cabin booking services
  • Updated 50+ call sites to use .internalCall() instead of passing bypassAuth: true
  • Removed ServerOnly/ServerOnlyAuthorizer imports from all converted files and added defineSubOperation imports where needed

Reviewed changes

Copilot reviewed 38 out of 38 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/services/visibility/operations.ts Converted create and destroy operations to defineSubOperation
src/services/permissions/operations.ts Converted readPermissionsOfUser to defineSubOperation
src/services/notifications/operations.ts Converted createSpecial to defineSubOperation
src/services/notifications/subscription/operations.ts Converted createDefault to defineSubOperation
src/services/groups/operations.ts Converted 5 operations (readCurrentGroupOrder, readCurrentGroupOrders, readGroup, readUsersOfGroups, readGroupsOfUser) to defineSubOperation
src/services/groups/committees/operations.ts Converted readFromGroupIds to defineSubOperation; updated call sites to use .internalCall()
src/services/groups/interestGroups/operations.ts Updated call sites to use .internalCall()
src/services/groups/memberships/*.ts Updated call sites to use .internalCall() for group operations
src/services/cms/paragraphs/operations.ts Converted create, destroy, and isSpecial to defineSubOperation
src/services/cms/images/operations.ts Converted create, destroy, and isSpecial to defineSubOperation
src/services/cms/links/operations.ts Converted create, destroy, and isSpecial to defineSubOperation
src/services/cms/articles/operations.ts Converted create and destroy to defineSubOperation
src/services/cms/articleSections/operations.ts Converted create and destroy to defineSubOperation
src/services/cabin/booking/operations.ts Converted 4 internal booking operations to defineSubOperation
src/services/users/operations.ts Updated call sites to use .internalCall()
src/services/shop/purchase/operations.ts Updated call sites to use .internalCall()
src/services/screens/pages/create.ts Updated call sites to use .internalCall()
src/services/omegaquotes/operations.ts Updated call sites to use .internalCall()
src/services/ombul/operations.ts Updated call sites to use .internalCall()
src/services/news/operations.ts Updated call sites to use .internalCall()
src/services/news/actions.ts Updated call sites to use .internalCall()
src/services/lockers/reservations/operations.ts Updated call sites to use .internalCall()
src/services/images/collections/*.ts Updated call sites to use .internalCall()
src/services/frontpage/operations.ts Updated call sites to use .internalCall()
src/services/flairs/operations.ts Updated call sites to use .internalCall()
src/services/events/registration/operations.ts Updated call sites to use .internalCall()
src/services/events/operations.ts Updated call sites to use .internalCall()
src/services/education/schools/create.ts Updated call sites to use .internalCall()
src/services/career/operations.ts Updated call sites to use .internalCall()
src/services/career/jobAds/operations.ts Updated call sites to use .internalCall()
src/services/career/companies/operations.ts Updated call sites to use .internalCall()
src/services/articleCategories/operations.ts Updated call sites to use .internalCall()
src/auth/nextAuth/authOptions.ts Updated call site to use .internalCall()
src/app/lockers/[id]/page.tsx Updated call site to use .internalCall()
Comments suppressed due to low confidence (2)

src/services/cms/articles/operations.ts:52

  • Missing await before cmsImageOperations.destroy.internalCall(). This async operation should be awaited to ensure the CMS image is deleted before the destroy operation completes. Without await, the promise is returned but not waited for, which could lead to race conditions or the image not being deleted if an error occurs.
            cmsImageOperations.destroy.internalCall({ params: { cmsImageId: article.coverImageId } })

src/services/groups/committees/operations.ts:194

  • Missing await before articleOperations.destroy.internalCall(). This async operation should be awaited to ensure the article is deleted before the destroy operation completes. Without await, the promise is returned but not waited for, which could lead to race conditions or the article not being deleted if an error occurs.
        articleOperations.destroy.internalCall({ params: { articleId: committee.committeeArticleId } })

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 41 out of 41 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@JohanHjelsethStorstad JohanHjelsethStorstad changed the title refactor: replace ServerOnly authorizer with defineSubOperation and internalCall refactor/replace ServerOnly authorizer with defineSubOperation and internalCall Mar 5, 2026
theodorklauritzen and others added 2 commits March 5, 2026 18:31
…nternalCall

Convert all service operations using ServerOnly/ServerOnlyAuthorizer to
defineSubOperation, and update all call sites to use .internalCall() instead
of bypassAuth: true. This makes the server-only intent explicit in the type
system rather than relying on a runtime auth bypass convention.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
These authorizers are no longer used now that all service operations
have been converted to defineSubOperation with internalCall.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@JohanHjelsethStorstad JohanHjelsethStorstad force-pushed the refactor/remove-server-only-authorizer branch from 7911963 to 622c401 Compare March 5, 2026 17:31
@JohanHjelsethStorstad JohanHjelsethStorstad merged commit c794b87 into main Mar 5, 2026
4 checks passed
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.

3 participants