ServerShared
Operation Pipeline
The standard lifecycle for server-side operations: Prepare, Execute, and After.
The runOperationPipeline utility (found in features/shared/operation-pipeline.ts) is the primary way we structure complex side-effects in Selegic.
The pipeline structure
An operation is broken down into three distinct phases:
prepare: Gathers dependencies, validates inputs, and runsbeforehooks.execute: Performs the primary business logic (e.g., database persistence).after: RunsafterSuccesshooks and cleanup tasks.
Why use it?
- Automatic Observability: Every pipeline run automatically increments a metric counter and opens an OpenTelemetry span.
- Consistent Order: Ensures hooks always run in the correct order relative to the database transaction.
- Error Propagation: Uses Effect-TS to bubble errors correctly from any stage of the pipeline.
Usage example
const program = runOperationPipeline({
prepare: Effect.gen(function*() {
const params = yield* beforeHooks.run(...);
return { params };
}),
execute: ({ params }) => repository.save(params),
after: (prepared, result) => afterHooks.run(prepared.params, result),
metrics: {
service: metrics,
name: "record_create_total",
attributes: { entity: "contact" }
},
span: {
name: "crud.create",
attributes: { entity: "contact" }
}
});Internal details
The pipeline is implemented using Effect.gen. If any of the phases fail, the remaining phases (except for cleanup blocks not shown here) are skipped, and the error is returned.