( rsLive: Layer.Layer<DbService | UserStoreService | MemberDirectory | WorkOsMirror>, )
| 96 | // account seat-gate, and the createOrganization free-limit gate each provide it |
| 97 | // where they run.) |
| 98 | export const makeProtectedApiLive = ( |
| 99 | rsLive: Layer.Layer<DbService | UserStoreService | MemberDirectory | WorkOsMirror>, |
| 100 | ) => { |
| 101 | // The neutral `IdentityProvider`, built per request: it reads `UserStoreService` |
| 102 | // + `MemberDirectory` from `rsLive` and the WorkOS control plane (`WorkOSClient` + `ApiKeyService`, |
| 103 | // stateless config — no per-request I/O socket) for the org-resolution path. |
| 104 | // `orDie` because a WorkOS config error is unrecoverable. |
| 105 | const identityLive = workosIdentityLayer.pipe( |
| 106 | Layer.provide(rsLive), |
| 107 | Layer.provide(ApiKeyService.WorkOS.pipe(Layer.provide(CoreSharedServices))), |
| 108 | Layer.provide(CoreSharedServices), |
| 109 | // oxlint-disable-next-line executor/no-effect-escape-hatch -- boundary: a boot-time WorkOS misconfiguration is unrecoverable |
| 110 | Layer.orDie, |
| 111 | ); |
| 112 | // The per-request layer the combine rebuilds in the request fiber's scope: the |
| 113 | // postgres socket (`rsLive`) PLUS the identity layer that reads it. Combining it |
| 114 | // into the auth middleware collapses `requires: IdentityProvider | DbService | |
| 115 | // UserStoreService` to `never` (so `.layer` is a real Layer instead of the "Need |
| 116 | // to combine" sentinel) AND keeps the socket request-scoped. Exposed as a |
| 117 | // factory so tests can swap in a counting fake — see |
| 118 | // `apps/cloud/src/api.request-scope.node.test.ts`. |
| 119 | const requestScopedLive = rsLive.pipe(Layer.provideMerge(identityLive)); |
| 120 | const protectedMiddleware = ExecutionStackMiddleware.combine( |
| 121 | requestScopedMiddleware(requestScopedLive), |
| 122 | ).layer; |
| 123 | return ProtectedCloudApiLive.pipe( |
| 124 | Layer.provide(protectedMiddleware), |
| 125 | Layer.provideMerge(AutumnService.Default), |
| 126 | Layer.provideMerge(RouterConfigLive), |
| 127 | ); |
| 128 | }; |
| 129 | |
| 130 | export const ProtectedApiLive = makeProtectedApiLive(RequestScopedServicesLive); |
no test coverage detected