1import * as AWS from "alchemy/AWS";
2import { Stack } from "alchemy/Stack";
3import * as Effect from "effect/Effect";
4import * as Layer from "effect/Layer";
5import { HttpServerRequest } from "effect/http/HttpServerRequest";
6import * as HttpServerResponse from "effect/http/HttpServerResponse";
7import { Database, DatabaseAurora } from "./Database.ts";
8import { NetworkLive } from "./Network.ts";
9
10export default class ServiceFunction extends AWS.Lambda.Function<ServiceFunction>()(
11 "ServiceFunction",
12 Stack.useSync((stack) => ({
13 main: import.meta.url,
14 memory: stack.stage === "prod" ? 1024 : 512,
15 runtime: "nodejs24.x",
16 })),
17 Effect.gen(function* () {
18 const db = yield* Database;
19
20 return {
21 fetch: Effect.gen(function* () {
22 const request = yield* HttpServerRequest;
23
24 if (
25 request.method === "GET" &&
26 new URL(request.originalUrl).pathname === "/"
27 ) {
28 const response = yield* db
29 .query<{
30 database: string;
31 current_time: string;
32 current_user: string;
33 }>(
34 "select current_database() as database, now()::text as current_time, current_user::text as current_user",
35 )
36 .pipe(
37 Effect.match({
38 onFailure: (error) => ({
39 status: 500 as const,
40 body: {
41 ok: false,
42 error: error.message,
43 },
44 }),
45 onSuccess: (rows) => ({
46 status: 200 as const,
47 body: {
48 ok: true,
49 connection: rows[0] ?? null,
50 },
51 }),
52 }),
53 );
54
55 return yield* HttpServerResponse.json(response.body, {
56 status: response.status,
57 });
58 }
59
60 return HttpServerResponse.text("Not found", { status: 404 });
61 }),
62 };
63 }).pipe(
64 Effect.provide(
65 Layer.provideMerge(
66 Layer.mergeAll(DatabaseAurora),
67 Layer.mergeAll(NetworkLive, AWS.RDS.ConnectHttp),
68 ),
69 ),
70 ),
71) {}