Skip to content

refactor: DRY toAuthContext, parallel checkAll, clean up IIFEs, improve JSDoc#2

Merged
n-hallberg merged 1 commit intoamadeni:mainfrom
echo-ex-void:refactor/echo-review-improvements
Mar 16, 2026
Merged

refactor: DRY toAuthContext, parallel checkAll, clean up IIFEs, improve JSDoc#2
n-hallberg merged 1 commit intoamadeni:mainfrom
echo-ex-void:refactor/echo-review-improvements

Conversation

@echo-ex-void
Copy link
Copy Markdown
Collaborator

@echo-ex-void echo-ex-void commented Mar 15, 2026

Non-breaking cleanup based on Echo's code review:

  • DRY toAuthContext — extracted to types.ts, imported in primitives.ts and authorized.ts
  • Parallel checkAllPromise.all instead of sequential awaits in capabilities.ts
  • Remove IIFE wrappers — plain function bodies in checker getters (6 functions)
  • JSDoc for zid — clarifies it only checks string type, not Convex ID format

CI: 22/22 tests pass, prettier/eslint/tsc/cspell all green.

Greptile Summary

This PR is a clean, non-breaking refactor that consolidates shared logic, improves performance, and enhances documentation with no functional regressions.

  • DRY toAuthContext: The helper was duplicated verbatim in both primitives.ts and authorized.ts. It is now defined once in types.ts (alongside the AuthContext type it constructs) and imported where needed. Both import sites correctly use a value import (import { toAuthContext }) while continuing to use import type for the pure-type exports.
  • Parallel checkAll: The sequential for…of / await loop is replaced with Promise.all. Each has(ctx, role, key) call is an independent DB read with no shared mutable state, so concurrent execution is correct in all Convex contexts (query, mutation, action). The as const tuple assertion and final Object.fromEntries(…) as Record<Key, boolean> cast are idiomatic TypeScript for this pattern.
  • IIFE removal (6 functions): The self-invoking wrappers in the three getPermissionCheckerFor* functions in both authorized.ts and primitives.ts were unnecessary — the outer arrow function body is equivalent. The pre-existing IIFE in hasCapabilityChecker (a type-guard, not a checker-getter) is intentionally out of scope.
  • zid JSDoc: Accurately warns consumers that only typeof value === 'string' is checked, not the actual Convex ID format — important context for anyone relying on this validator for ID validation.

No bugs or logic errors were found.

Confidence Score: 5/5

  • This PR is safe to merge — all changes are pure refactoring or documentation with no behavioral regressions.
  • Every change is either a DRY extraction of an identical function, a cosmetic IIFE removal with provably identical semantics, or a documentation improvement. The only functional change (Promise.all in checkAll) is a correct parallelisation of independent, side-effect-free DB reads. All 22 tests pass and the full CI suite is green.
  • No files require special attention.

Important Files Changed

Filename Overview
src/types.ts Adds the shared toAuthContext runtime helper, extracted from both primitives.ts and authorized.ts; correctly co-located with the AuthContext type it constructs.
src/capabilities.ts Sequential for…of loop in checkAll replaced with Promise.all; all has calls are independent DB reads so parallel execution is safe in every Convex context (query, mutation, action).
src/authorized.ts Local toAuthContext duplicate removed and imported from ./types; IIFE wrappers removed from three getPermissionCheckerFor* functions — semantics are identical to before.
src/primitives.ts Same IIFE cleanup as authorized.ts applied to three getCapabilityCheckerFor* functions; local toAuthContext duplicate removed. One pre-existing IIFE in hasCapabilityChecker is intentionally out of scope for this PR.
src/zod-helpers.ts JSDoc-only update clarifying that zid validates string type only, not the actual Convex ID format — improves consumer awareness with no runtime change.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[checkAll called\nctx, role] --> B[keys = Object.keys registry]
    B --> C[Promise.all\nkeys.map]
    C --> D1[has ctx, role, key1]
    C --> D2[has ctx, role, key2]
    C --> D3[has ctx, role, keyN]
    D1 --> E{admin role?}
    D2 --> E
    D3 --> E
    E -- yes --> F[return true]
    E -- no --> G[getOverride ctx, key]
    G --> H{override found?}
    H -- yes --> I[override.roles.includes role]
    H -- no --> J[registry.defaultRoles.includes role]
    I --> K[boolean result]
    J --> K
    F --> K
    K --> L[entries array\nreadonly tuples]
    L --> M[Object.fromEntries entries\nas Record Key boolean]
Loading

Last reviewed commit: 4c165b6

@n-hallberg
Copy link
Copy Markdown
Contributor

@greptile

@n-hallberg n-hallberg merged commit 5d82712 into amadeni:main Mar 16, 2026
2 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.

2 participants