Skip to content

Instantly share code, notes, and snippets.

@tim-smart
Created May 19, 2026 20:58
Show Gist options
  • Select an option

  • Save tim-smart/bb3fd6ad7bb27b03d724a39e88deca23 to your computer and use it in GitHub Desktop.

Select an option

Save tim-smart/bb3fd6ad7bb27b03d724a39e88deca23 to your computer and use it in GitHub Desktop.
import { Cause, Effect, Schema } from "effect"
import { Model } from "effect/unstable/schema"
import { SqlClient, SqlModel } from "effect/unstable/sql"
import type { SqlError } from "effect/unstable/sql/SqlError"
const UserId = Schema.String.pipe(
Schema.brand("UserId")
)
type UserId = typeof UserId.Type
class User extends Model.Class<User>("User")({
id: Model.UuidV7Insert(UserId),
createdAt: Model.DateTimeInsertFromDate,
updatedAt: Model.DateTimeUpdateFromDate
}) {
static readonly tableName = "users"
static readonly idColumn = "id"
static readonly spanPrefix = "UserRepository"
}
export const makeRepository = <
S extends Model.Any & {
readonly tableName: string
readonly idColumn: (keyof S["Type"]) & (keyof S["update"]["Type"]) & (keyof S["fields"])
readonly softDeleteColumn?: keyof S["fields"]
readonly spanPrefix: string
}
>(Model: S): Effect.Effect<
{
readonly insert: (
insert: S["insert"]["Type"]
) => Effect.Effect<
S["Type"],
Schema.SchemaError | SqlError,
S["DecodingServices"] | S["insert"]["EncodingServices"]
>
readonly insertVoid: (
insert: S["insert"]["Type"]
) => Effect.Effect<void, Schema.SchemaError | SqlError, S["insert"]["EncodingServices"]>
readonly update: (
update: S["update"]["Type"]
) => Effect.Effect<
S["Type"],
Schema.SchemaError | SqlError,
S["DecodingServices"] | S["update"]["EncodingServices"]
>
readonly updateVoid: (
update: S["update"]["Type"]
) => Effect.Effect<void, Schema.SchemaError | SqlError, S["update"]["EncodingServices"]>
readonly findById: (
id: S["fields"][S["idColumn"]]["Type"]
) => Effect.Effect<
S["Type"],
Cause.NoSuchElementError | Schema.SchemaError | SqlError,
S["DecodingServices"] | S["fields"][S["idColumn"]]["EncodingServices"]
>
readonly delete: (
id: S["fields"][S["idColumn"]]["Type"]
) => Effect.Effect<void, Schema.SchemaError | SqlError, S["fields"][S["idColumn"]]["EncodingServices"]>
},
never,
SqlClient.SqlClient
> =>
SqlModel.makeRepository(Model, {
tableName: Model.tableName,
idColumn: Model.idColumn,
softDeleteColumn: Model.softDeleteColumn,
spanPrefix: Model.spanPrefix
})
export const makeUserRepo = makeRepository(User)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment