1import * as Keyspaces from "@/AWS/Keyspaces";
2import * as Lambda from "@/AWS/Lambda";
3import * as Duration from "effect/Duration";
4import * as Effect from "effect/Effect";
5import { HttpServerRequest } from "effect/http/HttpServerRequest";
6import * as HttpServerResponse from "effect/http/HttpServerResponse";
7import path from "pathe";
8
9const main = path.resolve(import.meta.dirname, "restore-handler.ts");
10
11export class KeyspacesRestoreTestFunction extends Lambda.Function<Lambda.Function>()(
12 "KeyspacesRestoreTestFunction",
13) {}
14
15export default KeyspacesRestoreTestFunction.make(
16 {
17 main,
18 functionUrl: true,
19 timeout: Duration.seconds(60),
20 },
21 Effect.gen(function* () {
22 const keyspace = yield* Keyspaces.Keyspace("RestoreKs", {
23 keyspaceName: "alchemy_restore_test_ks",
24 });
25 const table = yield* Keyspaces.Table("Orders", {
26 keyspaceName: keyspace.keyspaceName,
27 tableName: "orders",
28 columns: [
29 { name: "id", type: "uuid" },
30 { name: "total", type: "int" },
31 ],
32 partitionKeys: ["id"],
33 pointInTimeRecovery: true,
34 });
35
36 const restore = yield* Keyspaces.RestoreTable(table, keyspace);
37
38 return {
39 fetch: Effect.gen(function* () {
40 const request = yield* HttpServerRequest;
41 const pathname = new URL(request.originalUrl).pathname;
42
43 // Restore the source table's continuous backup (current time) into a
44 // new table of the same keyspace. RestoreTable is asynchronous — the
45 // response carries the new table's ARN while it is RESTORING; the
46 // test deletes it out-of-band.
47 if (request.method === "POST" && pathname === "/restore") {
48 const result = yield* restore({
49 targetTableName: "orders_restored",
50 }).pipe(
51 Effect.map((response) => ({
52 restoredTableARN: response.restoredTableARN,
53 })),
54 Effect.catch((error) =>
55 Effect.succeed({ error: error._tag } as const),
56 ),
57 );
58 return yield* HttpServerResponse.json(result);
59 }
60
61 return yield* HttpServerResponse.json(
62 { error: "Not found", method: request.method, pathname },
63 { status: 404 },
64 );
65 }).pipe(Effect.orDie),
66 };
67 }).pipe(Effect.provide(Keyspaces.RestoreTableHttp)),
68);