t3-code-android-nightly/.repos/alchemy-effect/packages/alchemy/test/AWS/QApps/bindings-handler.ts
Julius Marminge 6f9cea00ae
chore(refs): sync Effect and Alchemy references to 4.0.1 and beta.80 (#16170)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-05 13:22:30 -07:00

167 lines
5.7 KiB
TypeScript

import * as AWS from "@/AWS";
import * as Effect from "effect/Effect";
import * as Layer from "effect/Layer";
import { HttpServerRequest } from "effect/http/HttpServerRequest";
import * as HttpServerResponse from "effect/http/HttpServerResponse";
export class QAppsTestFunction extends AWS.Lambda.Function<AWS.Lambda.Function>()(
"QAppsTestFunction",
) {}
/**
* Every route answers `{ …fields }` on success or `{ errorTag }` when the
* operation fails with a TYPED error — the test asserts on concrete fields
* (or a typed tag), which proves the binding wiring, the instance-id/app-id
* injection, and the IAM grants (app-ARN-scoped for the session/permission
* bindings, account-level for the instance-level bindings). An untyped
* error crashes into a 500.
*/
const errorTagged = <A, E extends { _tag: string }, R>(
effect: Effect.Effect<A, E, R>,
): Effect.Effect<A | { errorTag: string }, never, R> =>
effect.pipe(
Effect.map((a): A | { errorTag: string } => a),
Effect.catch((e) => Effect.succeed({ errorTag: e._tag })),
);
const TEXT_CARD_ID = "11111111-1111-4111-8111-111111111111";
const QUERY_CARD_ID = "22222222-2222-4222-8222-222222222222";
/**
* Q App binding fixture: deploys a Q App into the Q Business application
* environment instance named by QAPPS_INSTANCE_ID plus a Lambda bound to a
* representative set of Q Apps bindings (both builders: app/session-scoped
* and instance-level). Only deployed behind the AWS_TEST_QAPPS gate — the
* QApp resource itself cannot exist without an entitled Q Business instance.
*/
export default QAppsTestFunction.make(
{ main: import.meta.url, functionUrl: true },
Effect.gen(function* () {
const instanceId = yield* Effect.sync(
() => process.env.QAPPS_INSTANCE_ID ?? "",
);
const app = yield* AWS.QApps.QApp("BindingsQApp", {
instanceId,
description: "alchemy QApps bindings fixture",
appDefinition: {
cards: [
{
textInput: {
id: TEXT_CARD_ID,
title: "Source Text",
type: "text-input",
},
},
{
qQuery: {
id: QUERY_CARD_ID,
title: "Summary",
type: "q-query",
prompt: "Summarize the following text: @Source Text",
},
},
],
},
tags: { fixture: "qapps-bindings" },
});
const appVersion = yield* app.appVersion;
const startQAppSession = yield* AWS.QApps.StartQAppSession(app);
const getQAppSession = yield* AWS.QApps.GetQAppSession(app);
const stopQAppSession = yield* AWS.QApps.StopQAppSession(app);
const describeQAppPermissions =
yield* AWS.QApps.DescribeQAppPermissions(app);
const listQApps = yield* AWS.QApps.ListQApps(app);
const listCategories = yield* AWS.QApps.ListCategories(app);
const bound = {
startQAppSession,
getQAppSession,
stopQAppSession,
describeQAppPermissions,
listQApps,
listCategories,
};
return {
fetch: Effect.gen(function* () {
const request = yield* HttpServerRequest;
const url = new URL(request.originalUrl ?? request.url, "http://x");
const pathname = url.pathname;
if (pathname === "/bindings") {
return yield* HttpServerResponse.json({ bound: Object.keys(bound) });
}
if (pathname === "/session") {
// start → get → stop, proving app-id injection and the session
// sub-resource grant end-to-end.
const started = yield* errorTagged(
startQAppSession({ appVersion: yield* appVersion }),
);
if ("errorTag" in started) {
return yield* HttpServerResponse.json(started);
}
const state = yield* errorTagged(
getQAppSession({ sessionId: started.sessionId }),
);
const stopped = yield* errorTagged(
stopQAppSession({ sessionId: started.sessionId }),
);
return yield* HttpServerResponse.json({
sessionId: started.sessionId,
status: "errorTag" in state ? undefined : state.status,
getErrorTag: "errorTag" in state ? state.errorTag : undefined,
stopErrorTag: "errorTag" in stopped ? stopped.errorTag : undefined,
});
}
if (pathname === "/apps") {
const result = yield* errorTagged(listQApps({ limit: 10 }));
return yield* HttpServerResponse.json(
"errorTag" in result ? result : { count: result.apps.length },
);
}
if (pathname === "/categories") {
const result = yield* errorTagged(listCategories());
return yield* HttpServerResponse.json(
"errorTag" in result
? result
: { count: result.categories?.length ?? 0 },
);
}
if (pathname === "/permissions") {
const result = yield* errorTagged(describeQAppPermissions());
return yield* HttpServerResponse.json(
"errorTag" in result
? result
: {
resourceArn: result.resourceArn,
count: result.permissions?.length ?? 0,
},
);
}
return yield* HttpServerResponse.json(
{ error: "Not found", pathname },
{ status: 404 },
);
}).pipe(Effect.orDie),
};
}).pipe(
Effect.provide(
Layer.mergeAll(
AWS.QApps.StartQAppSessionHttp,
AWS.QApps.GetQAppSessionHttp,
AWS.QApps.StopQAppSessionHttp,
AWS.QApps.DescribeQAppPermissionsHttp,
AWS.QApps.ListQAppsHttp,
AWS.QApps.ListCategoriesHttp,
),
),
),
);