History

cloud/local/examples: thread per-user ScopeStack through HTTP + MCP

- cloud: resolves userId from the authenticated session and builds a [userOrgScope, orgScope] stack via createScopedExecutor(userId, orgId, orgName). userId threaded through execution-stack, mcp-session, and MCP dispatch init. - cloud env refactor: deletes the lazy Proxy apps/cloud/src/env.ts in favor of cloudflare:workers env imported at call sites; adds env-augment.d.ts to type secrets not present in generated wrangler types. - cloud/server.ts: env-guarded OTEL wiring (skips instrument() when AXIOM_TOKEN absent); captures rawFetch before instrument() mutates it so dev requests still land on the Hono app. - cloud/services/db.ts: prefers DATABASE_URL over the hyperdrive proxy so local dev works without the tunnel. - vite.config.ts: devCrashGuard plugin that prints uncaught Worker errors with a stable exit. - hosts/mcp: optional debug flag surfaces verbose session logging, wired up from cloud mcp-session. - local/examples/marketing: migrated to scopes: [scope].

Rhys Sullivan committed 6 months ago

Commit d4e311e1 parent 427699c25 files · +320 −174Browse files

Showing the changes to apps/cloud/src/api (2 of 25 files). Show all

Unified · Split

2 files
  1. apps/cloud/src/api/autumn.ts +2 −2
  2. apps/cloud/src/api/protected.ts +12 −6
apps/cloud/src/api/autumn.ts+2−2
@@ -1,9 +1,9 @@
1+import { env } from "cloudflare:workers";
12 import { Effect } from "effect";
23 import { HttpServerRequest, HttpServerResponse } from "@effect/platform";
34 import { autumnHandler } from "autumn-js/backend";
45
56 import { WorkOSAuth } from "../auth/workos";
6−import { server } from "../env";
77 import { HttpResponseError, isServerError, toErrorServerResponse } from "./error-response";
88 import { SharedServices } from "./layers";
99
@@ -59,7 +59,7 @@ export const AutumnApiApp = Effect.gen(function* () { · 49 unmodified lines
5959 email: session.email,
6060 },
6161 clientOptions: {
62− secretKey: server.AUTUMN_SECRET_KEY,
62+ secretKey: env.AUTUMN_SECRET_KEY ?? "",
6363 },
6464 pathPrefix: "/autumn",
6565 }),
apps/cloud/src/api/protected.ts+12−6
@@ -27,12 +27,18 @@ const lookupOrgForRequest = (request: HttpServerRequest.HttpServerRequest) => · 26 unmodified lines
2727 const session = yield* workos.authenticateRequest(webRequest);
2828 if (!session || !session.organizationId) return null;
2929
30− return yield* authorizeOrganization(session.userId, session.organizationId);
30+ const org = yield* authorizeOrganization(session.userId, session.organizationId);
31+ if (!org) return null;
32+ return { org, userId: session.userId };
3133 });
3234
33−const createProtectedApp = (organizationId: string, organizationName: string) =>
35+const createProtectedApp = (userId: string, organizationId: string, organizationName: string) =>
3436 Effect.gen(function* () {
35− const { executor, engine } = yield* makeExecutionStack(organizationId, organizationName);
37+ const { executor, engine } = yield* makeExecutionStack(
38+ userId,
39+ organizationId,
40+ organizationName,
41+ );
3642
3743 const requestServices = Layer.mergeAll(
3844 Layer.succeed(ExecutorService, executor),
@@ -58,8 +64,8 @@ const createProtectedApp = (organizationId: string, organizationName: string) => · 19 unmodified lines
5864
5965 export const ProtectedApiApp = Effect.gen(function* () {
6066 const request = yield* HttpServerRequest.HttpServerRequest;
61− const org = yield* lookupOrgForRequest(request);
62− if (!org) {
67+ const session = yield* lookupOrgForRequest(request);
68+ if (!session) {
6369 return yield* Effect.fail(
6470 new HttpResponseError({
6571 status: 403,
@@ -69,7 +75,7 @@ export const ProtectedApiApp = Effect.gen(function* () { · 3 unmodified lines
6975 );
7076 }
7177
72− const app = yield* createProtectedApp(org.id, org.name);
78+ const app = yield* createProtectedApp(session.userId, session.org.id, session.org.name);
7379 return yield* app;
7480 }).pipe(
7581 Effect.provide(SharedServices),