Skip to content

Commit

Permalink
play with vertical slice
Browse files Browse the repository at this point in the history
incomplete (frontend not updated)
  • Loading branch information
patroza committed Nov 2, 2024
1 parent 959fd3d commit 973aa06
Show file tree
Hide file tree
Showing 29 changed files with 86 additions and 100 deletions.
14 changes: 8 additions & 6 deletions api/src/Blog.controllers.ts → api/src/Blog/Blog.controllers.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import { BogusEvent } from "api/Events.js"
import { OperationsDefault } from "api/lib/layers.js"
import { matchFor } from "api/lib/routing.js"
import { BlogPostRepo, Events, Operations, UserRepo } from "api/services.js"
import { Events, Operations } from "api/services.js"
import { UserRepo } from "api/User/UserRepo.js"
import { Duration, Effect, Schedule } from "effect"
import { Option } from "effect-app"
import { NonEmptyString2k, NonNegativeInt } from "effect-app/Schema"
import { BlogPost } from "models/Blog.js"
import { BlogRsc } from "resources.js"
import { BogusEvent } from "resources/Events.js"
import { OperationsDefault } from "./lib/layers.js"
import { BlogResources } from "resources.js"
import { BlogPost } from "./Blog.js"
import { BlogPostRepo } from "./BlogPostRepo.js"

export default matchFor(BlogRsc)([
export default matchFor(BlogResources)([
BlogPostRepo.Default,
UserRepo.Default,
OperationsDefault,
Expand Down
10 changes: 5 additions & 5 deletions api/src/resources/Blog.ts → api/src/Blog/Blog.resources.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { S } from "api/lib.js"
import { InvalidStateError, NotFoundError, OptimisticConcurrencyException } from "effect-app/client"
import { OperationId } from "effect-app/Operations"
import { BlogPost, BlogPostId } from "models/Blog.js"
import { S } from "./lib.js"
import { BlogPostView } from "./views.js"
import { BlogPost, BlogPostId } from "./Blog.js"
import { BlogPostView } from "./PostView.js"

export class CreatePost extends S.Req<CreatePost>()("CreatePost", BlogPost.pick("title", "body"), {
allowRoles: ["user"],
Expand All @@ -26,6 +26,6 @@ export class PublishPost extends S.Req<PublishPost>()("PublishPost", {
id: BlogPostId
}, { allowRoles: ["user"], success: OperationId, failure: S.Union(NotFoundError) }) {}

// codegen:start {preset: meta, sourcePrefix: src/resources/}
export const meta = { moduleName: "Blog" } as const
// codegen:start {preset: meta, sourcePrefix: src/Blog/}
export const meta = { moduleName: "Blog.resources" } as const
// codegen:end
2 changes: 1 addition & 1 deletion api/src/models/Blog.ts → api/src/Blog/Blog.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { UserFromId } from "api/User/User.js"
import { S } from "effect-app"
import { UserFromId } from "./User.js"

export const BlogPostId = S.prefixedStringId<BlogPostId>()("post", "BlogPostId")
export interface BlogPostIdBrand {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Model } from "@effect-app/infra"
import { RepoDefault } from "api/lib/layers.js"
import { UserFromIdResolver } from "api/User/User.js"
import { UserRepo } from "api/User/UserRepo.js"
import { Effect } from "effect"
import { Context } from "effect-app"
import { NonEmptyString255, NonEmptyString2k } from "effect-app/Schema"
import { BlogPost } from "models/Blog.js"
import { UserFromIdResolver } from "models/User.js"
import { UserRepo } from "./UserRepo.js"
import { BlogPost } from "./Blog.js"

export type BlogPostSeed = "sample" | ""

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { BlogPost } from "models/Blog.js"
import { S } from "resources/lib.js"
import { UserViewFromId } from "../resolvers/UserResolver.js"
import { S } from "api/lib.js"
import { UserViewFromId } from "api/User/UserResolver.js"
import { BlogPost } from "./Blog.js"

export class BlogPostView extends S.ExtendedClass<BlogPostView, BlogPostView.Encoded>()({
...BlogPost.omit("author"),
Expand Down
2 changes: 1 addition & 1 deletion api/src/resources/Events.ts → api/src/Events.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { S } from "api/lib.js"
import type { Schema } from "effect-app/Schema"
import { S } from "resources/lib.js"

export class BogusEvent extends S.ExtendedTaggedClass<BogusEvent, BogusEvent.Encoded>()("BogusEvent", {
id: S.StringId.withDefault,
Expand Down
8 changes: 4 additions & 4 deletions api/src/HelloWorld.controllers.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { getRequestContext } from "@effect-app/infra/api/setupRequest"
import { generate } from "@effect-app/infra/test"
import { matchFor } from "api/lib/routing.js"
import { UserRepo } from "api/services.js"
import { Effect, S } from "effect-app"
import { User } from "models/User.js"
import { HelloWorldRsc } from "resources.js"
import { HelloWorldResources } from "resources.js"
import { User } from "./User/User.js"
import { UserRepo } from "./User/UserRepo.js"

export default matchFor(HelloWorldRsc)([
export default matchFor(HelloWorldResources)([
UserRepo.Default
], ({ GetHelloWorld }) =>
Effect.gen(function*() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { RequestContext } from "@effect-app/infra/RequestContext"
import { S } from "./lib.js"
import { UserView } from "./views.js"
import { S } from "api/lib.js"
import { UserView } from "./User/UserView.js"

class Response extends S.Class<Response>()({
now: S.Date.withDefault,
Expand All @@ -14,6 +14,6 @@ export class GetHelloWorld extends S.Req<GetHelloWorld>()("GetHelloWorld", {
echo: S.String
}, { allowAnonymous: true, allowRoles: ["user"], success: Response }) {}

// codegen:start {preset: meta, sourcePrefix: src/resources/}
export const meta = { moduleName: "HelloWorld" } as const
// codegen:start {preset: meta, sourcePrefix: src/}
export const meta = { moduleName: "HelloWorld.resources" } as const
// codegen:end
4 changes: 2 additions & 2 deletions api/src/Operations.controllers.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { matchFor } from "api/lib/routing.js"
import { Operations } from "api/services.js"
import { Effect } from "effect-app"
import { OperationsRsc } from "resources.js"
import { OperationsResources } from "resources.js"
import { OperationsDefault } from "./lib/layers.js"

export default matchFor(OperationsRsc)([
export default matchFor(OperationsResources)([
OperationsDefault
], ({ FindOperation }) =>
Effect.gen(function*() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import { clientFor, S } from "api/lib.js"
import { Duration, Effect } from "effect-app"
import { NotFoundError } from "effect-app/client"
import { Operation, OperationFailure, OperationId } from "effect-app/Operations"
import { clientFor } from "./lib.js"
import * as S from "./lib/schema.js"

export class FindOperation extends S.Req<FindOperation>()("FindOperation", {
id: OperationId
}, { allowAnonymous: true, allowRoles: ["user"], success: S.NullOr(Operation) }) {}

// codegen:start {preset: meta, sourcePrefix: src/resources/}
export const meta = { moduleName: "Operations" } as const
// codegen:start {preset: meta, sourcePrefix: src/}
export const meta = { moduleName: "Operations.resources" } as const
// codegen:end

// Extensions
Expand Down
6 changes: 3 additions & 3 deletions api/src/Me.controllers.ts → api/src/User/Me.controllers.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { matchFor } from "api/lib/routing.js"
import { UserRepo } from "api/services.js"
import { Effect } from "effect-app"
import { MeRsc } from "resources.js"
import { MeResources } from "resources.js"
import { UserRepo } from "./UserRepo.js"

export default matchFor(MeRsc)([
export default matchFor(MeResources)([
UserRepo.Default
], ({ GetMe }) =>
Effect.gen(function*() {
Expand Down
9 changes: 9 additions & 0 deletions api/src/User/Me.resources.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { S } from "api/lib.js"
import { NotFoundError } from "effect-app/client"
import { User } from "./User.js"

export class GetMe extends S.Req<GetMe>()("GetMe", {}, { success: User, failure: NotFoundError }) {}

// codegen:start {preset: meta, sourcePrefix: src/User/}
export const meta = { moduleName: "Me.resources" } as const
// codegen:end
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@ import { NotFoundError, NotLoggedInError } from "@effect-app/infra/errors"
import { generate } from "@effect-app/infra/test"
import { RepoConfig } from "api/config.js"
import { RepoDefault } from "api/lib/layers.js"
import { Q, UserProfile } from "api/services.js"
import { Array, Effect, Exit, Layer, Option, pipe, Request, RequestResolver, S } from "effect-app"
import { fakerArb } from "effect-app/faker"
import { Email } from "effect-app/Schema"
import fc from "fast-check"
import type { UserId } from "models/User.js"
import { User } from "models/User.js"
import { Q } from "../lib.js"
import { UserProfile } from "../UserProfile.js"
import type { UserId } from "./User.js"
import { User } from "./User.js"

export type UserSeed = "sample" | ""

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { clientFor } from "api/lib.js"
import { Effect, Exit, Request, RequestResolver } from "effect"
import { Array, Option, pipe, S } from "effect-app"
import { ApiConfig, NotFoundError } from "effect-app/client"
import { HttpClient } from "effect-app/http"
import { type Schema } from "effect-app/Schema"
import { UserId } from "models/User.js"
import { clientFor } from "resources/lib.js"
import * as UsersRsc from "../Users.js"
import { UserView } from "../views/UserView.js"
import { UserId } from "./User.js"
import * as UsersRsc from "./Users.resources.js"
import { UserView } from "./UserView.js"

interface GetUserViewById extends Request.Request<UserView, NotFoundError<"User">> {
readonly _tag: "GetUserViewById"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { User } from "models/User.js"
import { S } from "resources/lib.js"
import { S } from "api/lib.js"
import { User } from "./User.js"

export class UserView extends S.ExtendedClass<UserView, UserView.Encoded>()({
...User.pick("id", "role"),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { matchFor } from "api/lib/routing.js"
import { Q, UserRepo } from "api/services.js"
import { Q } from "api/services.js"
import { Array } from "effect"
import { Effect, Order } from "effect-app"
import { UsersRsc } from "resources.js"
import type { UserView } from "resources/views.js"
import { UsersResources } from "resources.js"
import { UserRepo } from "./UserRepo.js"
import type { UserView } from "./UserView.js"

export default matchFor(UsersRsc)([
export default matchFor(UsersResources)([
UserRepo.Default
], ({ IndexUsers }) =>
Effect.gen(function*() {
Expand Down
10 changes: 5 additions & 5 deletions api/src/resources/Users.ts → api/src/User/Users.resources.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { UserId } from "models/User.js"
import { S } from "./lib.js"
import { UserView } from "./views/UserView.js"
import { S } from "api/lib.js"
import { UserId } from "./User.js"
import { UserView } from "./UserView.js"

export class IndexUsers extends S.Req<IndexUsers>()("IndexUsers", {
filterByIds: S.NonEmptyArray(UserId)
Expand All @@ -12,6 +12,6 @@ export class IndexUsers extends S.Req<IndexUsers>()("IndexUsers", {
})
}) {}

// codegen:start {preset: meta, sourcePrefix: src/resources/}
export const meta = { moduleName: "Users" } as const
// codegen:start {preset: meta, sourcePrefix: src/User/}
export const meta = { moduleName: "Users.resources" } as const
// codegen:end
5 changes: 1 addition & 4 deletions api/src/controllers.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
// codegen:start {preset: barrel, include: ./*.controllers.ts, import: default}
import blogControllers from "./Blog.controllers.js"
import helloWorldControllers from "./HelloWorld.controllers.js"
import meControllers from "./Me.controllers.js"
import operationsControllers from "./Operations.controllers.js"
import usersControllers from "./Users.controllers.js"

export { blogControllers, helloWorldControllers, meControllers, operationsControllers, usersControllers }
export { helloWorldControllers, operationsControllers }
// codegen:end
10 changes: 10 additions & 0 deletions api/src/lib.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// codegen:start {preset: barrel, include: ./lib/*.ts, exclude: ./lib/schema.ts}
export * from "./lib/basicRuntime.js"
export * from "./lib/layers.js"
export * from "./lib/middleware.js"
export * from "./lib/observability.js"
export * from "./lib/req.js"
export * from "./lib/routing.js"
// codegen:end

export * as S from "./lib/schema.js"
12 changes: 2 additions & 10 deletions api/src/resources/lib/req.ts → api/src/lib/req.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { NotLoggedInError, UnauthorizedError } from "@effect-app/infra/errors"
import { Duration, Layer, Request as EffectRequest } from "effect-app"
import type { Role } from "api/User/User.js"
import type { RPCContextMap } from "effect-app/client"
import { makeRpcClient } from "effect-app/client"
import type { Role } from "models/User.js"

import { makeClientFor } from "effect-app/client/clientFor"
import { RequestCacheLayers } from "./routing.js"

type CTXMap = {
// we put `never`, because we can't access this service here in the client, and we also don't need to
Expand All @@ -26,11 +25,4 @@ export const { TaggedRequest: Req } = makeRpcClient<RequestConfig, CTXMap>({
requireRoles: UnauthorizedError
})

export const RequestCacheLayers = Layer.mergeAll(
Layer.setRequestCache(
EffectRequest.makeCache({ capacity: 500, timeToLive: Duration.hours(8) })
),
Layer.setRequestCaching(true),
Layer.setRequestBatching(true)
)
export const clientFor = makeClientFor(RequestCacheLayers)
File renamed without changes.
14 changes: 7 additions & 7 deletions api/src/resources.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import type {} from "@effect/platform/HttpClient"

export { ClientEvents } from "./resources/Events.js"
export { ClientEvents } from "./Events.js"

// codegen:start {preset: barrel, include: ./resources/*.ts, exclude: [./resources/index.ts, ./resources/lib.ts, ./resources/integrationEvents.ts, ./resources/Messages.ts, ./resources/views.ts, ./resources/Events.ts], export: { as: 'PascalCase', postfix: 'Rsc' }}
export * as BlogRsc from "./resources/Blog.js"
export * as HelloWorldRsc from "./resources/HelloWorld.js"
export * as MeRsc from "./resources/Me.js"
export * as OperationsRsc from "./resources/Operations.js"
export * as UsersRsc from "./resources/Users.js"
// codegen:start {preset: barrel, include: ./**/*.resources.ts, exclude: [./resources/index.ts, ./resources/lib.ts, ./resources/integrationEvents.ts, ./resources/Messages.ts, ./resources/views.ts, ./resources/Events.ts], export: { as: 'PascalCase' }}
export * as BlogResources from "./Blog/Blog.resources.js"
export * as HelloWorldResources from "./HelloWorld.resources.js"
export * as OperationsResources from "./Operations.resources.js"
export * as MeResources from "./User/Me.resources.js"
export * as UsersResources from "./User/Users.resources.js"
// codegen:end
9 changes: 0 additions & 9 deletions api/src/resources/Me.ts

This file was deleted.

5 changes: 0 additions & 5 deletions api/src/resources/lib.ts

This file was deleted.

4 changes: 0 additions & 4 deletions api/src/resources/views.ts

This file was deleted.

1 change: 0 additions & 1 deletion api/src/services.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
// codegen:start {preset: barrel, include: services/*.ts }
export * from "./services/DBContext.js"
export * from "./services/Events.js"
export * from "./services/lib.js"
export * from "./services/UserProfile.js"
Expand Down
4 changes: 0 additions & 4 deletions api/src/services/DBContext.ts

This file was deleted.

2 changes: 1 addition & 1 deletion api/src/services/UserProfile.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { parseJwt } from "@effect-app/infra/api/routing/schema/jwt"
import { Role } from "api/User/User.js"
import { Context, S } from "effect-app"
import { UserProfileId } from "effect-app/ids"
import { Role } from "models/User.js"

export class UserProfile extends Context.assignTag<UserProfile>()(
S.Class<UserProfile>()({
Expand Down

0 comments on commit 973aa06

Please sign in to comment.