|
1 | | -import type { Effect } from "effect" |
| 1 | +import { Effect, Match } from "effect" |
2 | 2 |
|
| 3 | +import { dockerGitOpenApi, renderDockerGitOpenApiFailure } from "./api-http.js" |
3 | 4 | import { |
4 | 5 | type BaseCreateProjectBody, |
5 | 6 | baseCreateProjectBody, |
6 | 7 | type CreateProjectRequestDraft, |
7 | 8 | optionalProjectResourceFields, |
8 | 9 | type OptionalProjectResourceFieldsBody |
9 | 10 | } from "./api-project-create-body.js" |
10 | | -import { CreateProjectAcceptedResponseSchema } from "./api-schema.js" |
11 | 11 | import type { CreateProjectAcceptedResponse } from "./api-schema.js" |
12 | | -import { openApiJsonSchema } from "./openapi-client.js" |
13 | 12 |
|
14 | 13 | type CreateProjectAcceptedBody = Readonly< |
15 | 14 | & BaseCreateProjectBody |
@@ -39,10 +38,42 @@ export const createProjectAcceptedBody = (draft: CreateProjectRequestDraft): Cre |
39 | 38 | ...optionalProjectResourceFields(draft) |
40 | 39 | }) |
41 | 40 |
|
| 41 | +// CHANGE: Publish the async project creation boundary with an explicit Effect signature. |
| 42 | +// WHY: exported web API helpers must expose typed success, error, and requirement channels. |
| 43 | +// QUOTE(ТЗ): "исправь" |
| 44 | +// REF: PR#431 CodeRabbit review 4535473023 |
| 45 | +// SOURCE: n/a |
| 46 | +// FORMAT THEOREM: forall draft d: accepted(d) -> Effect<CreateProjectAcceptedResponse, string, never>. |
| 47 | +// PURITY: SHELL |
| 48 | +// EFFECT: Effect<CreateProjectAcceptedResponse, string, never> |
| 49 | +// INVARIANT: only HTTP 202 is accepted as the asynchronous creation success branch. |
| 50 | +// COMPLEXITY: O(1)/O(1), excluding HTTP transport. |
| 51 | +/** |
| 52 | + * Starts asynchronous project creation through the typed OpenAPI client. |
| 53 | + * |
| 54 | + * @param draft - Validated project creation draft plus optional resource limits. |
| 55 | + * @returns Effect that resolves to the accepted async creation response. |
| 56 | + * |
| 57 | + * @pure false - performs HTTP IO when the returned Effect is executed. |
| 58 | + * @effect Effect<CreateProjectAcceptedResponse, string, never> |
| 59 | + * @invariant HTTP 202 returns the accepted response; HTTP 201 is rejected as a sync branch mismatch. |
| 60 | + * @precondition draft fields were validated by the UI create flow. |
| 61 | + * @postcondition downstream callers observe only accepted async responses or string-rendered failures. |
| 62 | + * @complexity O(1)/O(1), excluding HTTP transport and response body size. |
| 63 | + * @throws Never - failures are represented in the Effect error channel. |
| 64 | + */ |
42 | 65 | export const startCreateProject = ( |
43 | 66 | draft: CreateProjectRequestDraft |
44 | 67 | ): Effect.Effect<CreateProjectAcceptedResponse, string> => |
45 | | - openApiJsonSchema(CreateProjectAcceptedResponseSchema, (client) => |
46 | | - client.POST("/projects", { |
47 | | - body: createProjectAcceptedBody(draft) |
48 | | - })) |
| 68 | + dockerGitOpenApi.POST("/projects", { |
| 69 | + body: createProjectAcceptedBody(draft) |
| 70 | + }).pipe( |
| 71 | + Effect.mapError(renderDockerGitOpenApiFailure), |
| 72 | + Effect.flatMap((success) => |
| 73 | + Match.value(success).pipe( |
| 74 | + Match.when({ status: 202 }, ({ body }) => Effect.succeed(body)), |
| 75 | + Match.when({ status: 201 }, () => Effect.fail("HTTP 201: unexpected synchronous project creation response")), |
| 76 | + Match.exhaustive |
| 77 | + ) |
| 78 | + ) |
| 79 | + ) |
0 commit comments