@beignet/core 0.0.31 → 0.0.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +115 -0
- package/README.md +346 -21
- package/dist/application/index.d.ts.map +1 -1
- package/dist/application/index.js +63 -47
- package/dist/application/index.js.map +1 -1
- package/dist/domain/entity.d.ts +37 -6
- package/dist/domain/entity.d.ts.map +1 -1
- package/dist/domain/entity.js +9 -7
- package/dist/domain/entity.js.map +1 -1
- package/dist/domain/index.d.ts +4 -4
- package/dist/domain/index.d.ts.map +1 -1
- package/dist/domain/index.js +4 -4
- package/dist/domain/index.js.map +1 -1
- package/dist/events/index.d.ts +6 -0
- package/dist/events/index.d.ts.map +1 -1
- package/dist/events/index.js +20 -10
- package/dist/events/index.js.map +1 -1
- package/dist/flags/index.d.ts +5 -4
- package/dist/flags/index.d.ts.map +1 -1
- package/dist/flags/index.js +10 -9
- package/dist/flags/index.js.map +1 -1
- package/dist/idempotency/index.d.ts +11 -1
- package/dist/idempotency/index.d.ts.map +1 -1
- package/dist/idempotency/index.js +4 -3
- package/dist/idempotency/index.js.map +1 -1
- package/dist/jobs/index.d.ts +449 -9
- package/dist/jobs/index.d.ts.map +1 -1
- package/dist/jobs/index.js +472 -12
- package/dist/jobs/index.js.map +1 -1
- package/dist/outbox/index.d.ts +170 -3
- package/dist/outbox/index.d.ts.map +1 -1
- package/dist/outbox/index.js +192 -8
- package/dist/outbox/index.js.map +1 -1
- package/dist/ports/events.d.ts +2 -2
- package/dist/ports/index.d.ts +6 -1
- package/dist/ports/index.d.ts.map +1 -1
- package/dist/ports/index.js +1 -0
- package/dist/ports/index.js.map +1 -1
- package/dist/providers/instrumentation.d.ts +4 -0
- package/dist/providers/instrumentation.d.ts.map +1 -1
- package/dist/providers/instrumentation.js.map +1 -1
- package/dist/providers/provider.d.ts +10 -2
- package/dist/providers/provider.d.ts.map +1 -1
- package/dist/providers/provider.js.map +1 -1
- package/dist/schedules/index.d.ts +8 -7
- package/dist/schedules/index.d.ts.map +1 -1
- package/dist/schedules/index.js +47 -16
- package/dist/schedules/index.js.map +1 -1
- package/dist/search/index.d.ts +2 -1
- package/dist/search/index.d.ts.map +1 -1
- package/dist/search/index.js +1 -0
- package/dist/search/index.js.map +1 -1
- package/dist/server/hooks/index.d.ts +1 -0
- package/dist/server/hooks/index.d.ts.map +1 -1
- package/dist/server/hooks/index.js +1 -0
- package/dist/server/hooks/index.js.map +1 -1
- package/dist/server/hooks/rate-limit.d.ts +26 -13
- package/dist/server/hooks/rate-limit.d.ts.map +1 -1
- package/dist/server/hooks/rate-limit.js +28 -34
- package/dist/server/hooks/rate-limit.js.map +1 -1
- package/dist/server/hooks/security.d.ts +179 -0
- package/dist/server/hooks/security.d.ts.map +1 -0
- package/dist/server/hooks/security.js +225 -0
- package/dist/server/hooks/security.js.map +1 -0
- package/dist/server/index.d.ts +8 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +8 -0
- package/dist/server/index.js.map +1 -1
- package/dist/server/instrumentation.d.ts.map +1 -1
- package/dist/server/instrumentation.js +22 -6
- package/dist/server/instrumentation.js.map +1 -1
- package/dist/server/providers/loadProviderConfig.d.ts.map +1 -1
- package/dist/server/providers/loadProviderConfig.js +15 -2
- package/dist/server/providers/loadProviderConfig.js.map +1 -1
- package/dist/server/request-context.d.ts +4 -0
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/request-context.js +3 -0
- package/dist/server/request-context.js.map +1 -1
- package/dist/server/runtime-integrity.d.ts +84 -0
- package/dist/server/runtime-integrity.d.ts.map +1 -0
- package/dist/server/runtime-integrity.js +160 -0
- package/dist/server/runtime-integrity.js.map +1 -0
- package/dist/server/server.d.ts +10 -0
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/server.js +55 -1
- package/dist/server/server.js.map +1 -1
- package/dist/server/trusted-proxy.d.ts +77 -0
- package/dist/server/trusted-proxy.d.ts.map +1 -0
- package/dist/server/trusted-proxy.js +129 -0
- package/dist/server/trusted-proxy.js.map +1 -0
- package/dist/tasks/index.d.ts +6 -7
- package/dist/tasks/index.d.ts.map +1 -1
- package/dist/tasks/index.js +22 -5
- package/dist/tasks/index.js.map +1 -1
- package/dist/tenancy/index.d.ts +41 -0
- package/dist/tenancy/index.d.ts.map +1 -0
- package/dist/tenancy/index.js +34 -0
- package/dist/tenancy/index.js.map +1 -0
- package/dist/testing/index.d.ts +6 -0
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +12 -3
- package/dist/testing/index.js.map +1 -1
- package/dist/tracing/execution.d.ts +14 -0
- package/dist/tracing/execution.d.ts.map +1 -0
- package/dist/tracing/execution.js +17 -0
- package/dist/tracing/execution.js.map +1 -0
- package/dist/tracing/index.d.ts +49 -0
- package/dist/tracing/index.d.ts.map +1 -1
- package/dist/tracing/index.js +59 -0
- package/dist/tracing/index.js.map +1 -1
- package/dist/uploads/client.d.ts.map +1 -1
- package/dist/uploads/client.js +44 -6
- package/dist/uploads/client.js.map +1 -1
- package/dist/uploads/index.d.ts +182 -2
- package/dist/uploads/index.d.ts.map +1 -1
- package/dist/uploads/index.js +468 -76
- package/dist/uploads/index.js.map +1 -1
- package/dist/webhooks/index.d.ts +56 -4
- package/dist/webhooks/index.d.ts.map +1 -1
- package/dist/webhooks/index.js +107 -2
- package/dist/webhooks/index.js.map +1 -1
- package/package.json +5 -1
- package/skills/app-architecture/SKILL.md +23 -2
- package/src/application/index.ts +88 -56
- package/src/domain/entity.ts +61 -13
- package/src/domain/index.ts +8 -7
- package/src/events/index.ts +27 -14
- package/src/flags/index.ts +23 -19
- package/src/idempotency/index.ts +17 -3
- package/src/jobs/index.ts +1022 -19
- package/src/outbox/index.ts +409 -9
- package/src/ports/events.ts +2 -2
- package/src/ports/index.ts +17 -0
- package/src/providers/instrumentation.ts +4 -0
- package/src/providers/provider.ts +11 -2
- package/src/schedules/index.ts +60 -26
- package/src/search/index.ts +3 -1
- package/src/server/hooks/index.ts +10 -0
- package/src/server/hooks/rate-limit.ts +52 -46
- package/src/server/hooks/security.ts +503 -0
- package/src/server/index.ts +8 -0
- package/src/server/instrumentation.ts +25 -5
- package/src/server/providers/loadProviderConfig.ts +19 -2
- package/src/server/request-context.ts +7 -0
- package/src/server/runtime-integrity.ts +322 -0
- package/src/server/server.ts +86 -1
- package/src/server/trusted-proxy.ts +249 -0
- package/src/tasks/index.ts +29 -12
- package/src/tenancy/index.ts +55 -0
- package/src/testing/index.ts +19 -3
- package/src/tracing/execution.ts +37 -0
- package/src/tracing/index.ts +137 -0
- package/src/uploads/client.ts +65 -6
- package/src/uploads/index.ts +713 -76
- package/src/webhooks/index.ts +240 -9
- package/src/domain/events.ts +0 -59
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,120 @@
|
|
|
1
1
|
# @beignet/core
|
|
2
2
|
|
|
3
|
+
## 0.0.33
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 379a351: Add outbox admin ports and CLI tooling to inspect, requeue, purge, and prune durable outbox messages.
|
|
8
|
+
- c909142: Add per-attempt job timeouts, app-owned job execution hooks, and a locks-backed execution lease hook across inline, outbox-inline, BullMQ, and Inngest workers.
|
|
9
|
+
- c514ffc: Document the Next.js cached request-context convention separately from React
|
|
10
|
+
Query prefetching, and update generated agent guidance to use
|
|
11
|
+
`lib/server-context.ts` for shared Server Component request state.
|
|
12
|
+
- ae6d7f9: Document the Next.js server prefetch convention and teach generated agent
|
|
13
|
+
guidance to preserve contract query keys while replacing server query
|
|
14
|
+
functions with direct use-case calls.
|
|
15
|
+
- efe16f4: Add active tracing spans and an OpenTelemetry provider with isolated,
|
|
16
|
+
low-cardinality duration, failure, and provider-operation metrics. Background
|
|
17
|
+
providers resolve lazy contexts inside real spans, and the task CLI now runs
|
|
18
|
+
through the traced task executor.
|
|
19
|
+
- 0c6c0ee: Make generated app test and database scripts package-manager neutral by using
|
|
20
|
+
`tsx`, and refresh package testing docs to avoid Bun-specific snippets.
|
|
21
|
+
- 450ce71: Add opt-in runtime integrity checks for workflow registries, teach the CLI a central listener registry, and document serverless-safe boot checks.
|
|
22
|
+
- 2fe26a4: Add first-class security headers and CSRF server hooks, install the security
|
|
23
|
+
headers baseline in generated apps, and warn when production apps omit it.
|
|
24
|
+
- ab8b288: Refresh package-shipped skills with current tenancy and runtime-integrity conventions.
|
|
25
|
+
- de3e0d2: Tighten tenant-scope enforcement in doctor and generated billing code.
|
|
26
|
+
|
|
27
|
+
`beignet doctor --strict` now detects explicit raw `tenantId` repository
|
|
28
|
+
boundaries in hand-authored Drizzle ports and checks scoped tenant/workspace
|
|
29
|
+
predicates for `tenantScopeId(scope)` drift. The payments generator now uses
|
|
30
|
+
`TenantScope` for billing tenant lookups.
|
|
31
|
+
|
|
32
|
+
- 08e2d3e: Add a branded tenant scope primitive and generate tenant-scoped repositories that accept `TenantScope` instead of raw tenant IDs.
|
|
33
|
+
- 4341860: Add trusted proxy request metadata helpers and wire rate-limit and CSRF hooks to the shared policy.
|
|
34
|
+
- 3b0f288: Add locks-backed unique job declarations and a dispatcher wrapper that suppresses duplicate dispatches for a bounded TTL.
|
|
35
|
+
- 61d9053: Harden uploads with supported content-type signature checks, optional SHA-256 checksums, and app-owned file verification hooks.
|
|
36
|
+
- f263650: Harden generic webhook verification with strict unknown-event defaults and opt-in HMAC timestamp tolerance.
|
|
37
|
+
|
|
38
|
+
## 0.0.32
|
|
39
|
+
|
|
40
|
+
### Patch Changes
|
|
41
|
+
|
|
42
|
+
- 671b986: API coherence: definition kinds, app-bound uploads, honest inline retry, and
|
|
43
|
+
deterministic memory adapters.
|
|
44
|
+
|
|
45
|
+
- `FlagDef` now carries `kind: "flag"` as its definition discriminator, and
|
|
46
|
+
the value type moves to `valueKind` (`FlagEvaluationDetails.kind` is also
|
|
47
|
+
renamed `valueKind`; types `FlagKind` and `FlagKindForValue` are now
|
|
48
|
+
`FlagValueKind` and `FlagValueKindForValue`). `defineWebhook` results carry
|
|
49
|
+
`kind: "webhook"` and `defineSearchIndex` results carry
|
|
50
|
+
`kind: "search-index"`, so every definition subsystem shares the same
|
|
51
|
+
discriminator grammar. The OpenFeature provider and devtools flag panel
|
|
52
|
+
follow the rename.
|
|
53
|
+
- New `createUploads<AppContext>()` in `@beignet/core/uploads` returns an
|
|
54
|
+
app-bound `defineUpload`, matching the jobs/schedules/tasks/notifications/
|
|
55
|
+
listeners factories. The bound builder infers the upload name, metadata
|
|
56
|
+
schema, context, and `onComplete` result without explicit type arguments;
|
|
57
|
+
apps create it once in `lib/uploads.ts`.
|
|
58
|
+
- `createInlineJobDispatcher(...)` now honors a job's declared retry policy:
|
|
59
|
+
failed dispatches retry in-process with the policy's delays (injectable
|
|
60
|
+
`sleep` option for tests), payload validation failures never retry, and
|
|
61
|
+
jobs without a policy run exactly once.
|
|
62
|
+
- `createMemoryOutbox({ id, now })` and
|
|
63
|
+
`createMemoryIdempotencyStore({ now })` accept injectable ID and clock
|
|
64
|
+
factories instead of hardcoding `crypto.randomUUID()` and `new Date()`.
|
|
65
|
+
- The BullMQ provider validates unsupported retry options (`maxDelay`, custom
|
|
66
|
+
`factor`, `jitter`) eagerly at `createBullMQJobWorker(...)` creation instead
|
|
67
|
+
of only at first dispatch or processing.
|
|
68
|
+
|
|
69
|
+
- f759611: Retry policies now run in exactly one layer for outbox-delivered jobs. The
|
|
70
|
+
inline job dispatcher exposes a single-attempt dispatch under a well-known
|
|
71
|
+
symbol; `drainOutbox(...)` detects it and runs the handler once per pass,
|
|
72
|
+
letting the outbox reschedule failures with the job's own policy instead of
|
|
73
|
+
stacking in-process retries (and their real backoff sleeps) inside every
|
|
74
|
+
delivery attempt. Durable providers are unaffected. The inline dispatcher
|
|
75
|
+
also gains a `retry: false` option for callers that own retries themselves,
|
|
76
|
+
and `createTestPorts(...)` now threads its frozen clock and ID generator
|
|
77
|
+
into the memory idempotency store and outbox.
|
|
78
|
+
- f759611: Provider factory options now resolve through one framework-owned rule:
|
|
79
|
+
`ProviderConfigDef` gains an `overrides` map that merges defined values over
|
|
80
|
+
env-derived input before validation, and every first-party provider factory
|
|
81
|
+
uses it instead of hand-rolled schema defaults and setup-time fallbacks. The
|
|
82
|
+
precedence is now uniform — defined factory options win over environment
|
|
83
|
+
variables in all thirteen providers. This flips the previous env-wins
|
|
84
|
+
behavior of `provider-cache-redis`, `provider-locks-redis`, and the storage,
|
|
85
|
+
search, and blob providers; set the env var (or drop the option) if you
|
|
86
|
+
relied on env winning. `installProviderForTest(...)` gains an `env` option
|
|
87
|
+
that resolves config through the same loader, and unreachable missing-config
|
|
88
|
+
guards in the pino and inngest factories are gone.
|
|
89
|
+
- eb680ef: Provider naming now follows one implementation-first order matching the
|
|
90
|
+
factories. `@beignet/provider-redis` is renamed `@beignet/provider-cache-redis`
|
|
91
|
+
(the package fills the cache port; the raw client stays as the
|
|
92
|
+
`ctx.ports.redis` escape hatch) with `redisCacheProvider`,
|
|
93
|
+
`createRedisCacheProvider`, and provider name `cache-redis` matching
|
|
94
|
+
`locks-redis`. Default consts flip to implementation-first:
|
|
95
|
+
`loggerPinoProvider` is now `pinoLoggerProvider`, `mailResendProvider` is now
|
|
96
|
+
`resendMailProvider`, and `mailSmtpProvider` is now `smtpMailProvider`.
|
|
97
|
+
CLI starter templates and the `redis-cache` provider preset wire the new
|
|
98
|
+
names. No aliases are kept.
|
|
99
|
+
- 671b986: Remove the `defineDomainEvent` alias (and the `DomainEventDef`/
|
|
100
|
+
`InferEventPayload` re-exports) from `@beignet/core/domain`. Declare domain
|
|
101
|
+
events with the canonical `defineEvent(name, { payload })` from
|
|
102
|
+
`@beignet/core/events` — the alias returned the exact same `EventDef` and only
|
|
103
|
+
differed by its positional signature. The structural `DomainEventDef` port
|
|
104
|
+
type in `@beignet/core/ports` is unchanged.
|
|
105
|
+
- 671b986: `defineEntity(...).methods((self) => ...)` now types `self` as the entity's
|
|
106
|
+
base instance (validated props plus `with` and `toJSON`) instead of `any`, so
|
|
107
|
+
method bodies are type-checked against the entity's own schema. The new
|
|
108
|
+
`EntityBaseInstance` type is exported from `@beignet/core/domain`.
|
|
109
|
+
- 671b986: Upload failures now throw condition-specific error classes matching the
|
|
110
|
+
framework's class-per-condition convention: `UploadNotFoundError`,
|
|
111
|
+
`InvalidUploadActionError`, `InvalidUploadMetadataError`,
|
|
112
|
+
`InvalidUploadFileError`, `UnauthorizedUploadError`,
|
|
113
|
+
`UploadObjectNotFoundError`, `UploadBodyTooLargeError`, and
|
|
114
|
+
`InvalidUploadBodyError`. `UploadError` remains the shared base class (its
|
|
115
|
+
constructor is now protected), so existing `instanceof UploadError` checks
|
|
116
|
+
and `code`/`status` reads keep working unchanged.
|
|
117
|
+
|
|
3
118
|
## 0.0.31
|
|
4
119
|
|
|
5
120
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -58,7 +58,7 @@ name the framework area they depend on.
|
|
|
58
58
|
| `@beignet/core/events` | Events and listeners |
|
|
59
59
|
| `@beignet/core/flags` | Feature flag definitions, FlagsPort, memory/static adapters, and helpers |
|
|
60
60
|
| `@beignet/core/idempotency` | Retry-safe command, webhook, and job primitives |
|
|
61
|
-
| `@beignet/core/jobs` | Job definitions, retry policies, and inline job dispatch |
|
|
61
|
+
| `@beignet/core/jobs` | Job definitions, retry policies, timeout guards, execution hooks, execution lease helpers, uniqueness guards, and inline job dispatch |
|
|
62
62
|
| `@beignet/core/locks` | Lease-backed LocksPort, memory adapter, memory provider, and helpers |
|
|
63
63
|
| `@beignet/core/mail` | Mail port, memory mailer, and memory mailer provider |
|
|
64
64
|
| `@beignet/core/memo` | Request-scoped memoization for port lookups |
|
|
@@ -72,12 +72,13 @@ name the framework area they depend on.
|
|
|
72
72
|
| `@beignet/core/providers` | Provider lifecycle and instrumentation primitives |
|
|
73
73
|
| `@beignet/core/search` | Search index definitions, SearchPort, memory adapter, memory provider, and helpers |
|
|
74
74
|
| `@beignet/core/schedules` | Schedule primitives |
|
|
75
|
-
| `@beignet/core/server` | Framework-agnostic server runtime and hook helpers |
|
|
75
|
+
| `@beignet/core/server` | Framework-agnostic server runtime, security headers, CSRF, and hook helpers |
|
|
76
76
|
| `@beignet/core/server-only` | Static lint marker for modules that must stay out of client bundles |
|
|
77
77
|
| `@beignet/core/tasks` | Operational task definitions and inline task execution |
|
|
78
|
+
| `@beignet/core/tenancy` | Branded tenant scope helpers for repository boundaries |
|
|
78
79
|
| `@beignet/core/testing` | Test context factories, memory port fixtures, provider install helper, factories, seeds, and database harnesses |
|
|
79
80
|
| `@beignet/core/tracing` | Dependency-free W3C trace context primitives |
|
|
80
|
-
| `@beignet/core/uploads` | Upload definitions, router, signer port, and test signer |
|
|
81
|
+
| `@beignet/core/uploads` | Upload definitions (`createUploads<AppContext>()` app-bound builder), router, signer port, and test signer |
|
|
81
82
|
| `@beignet/core/uploads/client` | Browser upload client for server and direct uploads |
|
|
82
83
|
| `@beignet/core/webhooks` | Inbound webhook definitions, verifiers, memory test verifier, and HMAC verifier |
|
|
83
84
|
|
|
@@ -98,10 +99,100 @@ Jobs, outbox delivery, and schedule runners use the same terms:
|
|
|
98
99
|
- `attempts` in a retry policy is the maximum total attempts, including the
|
|
99
100
|
first try.
|
|
100
101
|
- `backoff` is the delay before the next retry.
|
|
102
|
+
- `timeout` is the maximum execution window for one handler attempt.
|
|
103
|
+
- `hook` is app-owned behavior that wraps one handler attempt.
|
|
104
|
+
- `execution lease` is a TTL-backed lock around one handler attempt for a
|
|
105
|
+
logical job key.
|
|
101
106
|
- `terminal failure` means the work should not be retried automatically.
|
|
102
107
|
- `dead letter` is a durable terminal delivery state, currently owned by the
|
|
103
108
|
outbox.
|
|
104
109
|
|
|
110
|
+
Jobs may also declare dispatch-time uniqueness and execution leases:
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
import {
|
|
114
|
+
createJobExecutionLeaseHook,
|
|
115
|
+
createInlineJobDispatcher,
|
|
116
|
+
createJobs,
|
|
117
|
+
createUniqueJobDispatcher,
|
|
118
|
+
type JobDef,
|
|
119
|
+
retry,
|
|
120
|
+
} from "@beignet/core/jobs";
|
|
121
|
+
import type { LocksPort } from "@beignet/core/locks";
|
|
122
|
+
import { z } from "zod";
|
|
123
|
+
|
|
124
|
+
type AppContext = {
|
|
125
|
+
ports: {
|
|
126
|
+
billing: {
|
|
127
|
+
syncAccount(
|
|
128
|
+
accountId: string,
|
|
129
|
+
options?: { signal?: AbortSignal },
|
|
130
|
+
): Promise<void>;
|
|
131
|
+
};
|
|
132
|
+
locks: LocksPort;
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
const { defineJob } = createJobs<AppContext>();
|
|
137
|
+
|
|
138
|
+
const syncAccountPayloadSchema = z.object({
|
|
139
|
+
accountId: z.string().min(1),
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
const syncAccountExecutionLease = createJobExecutionLeaseHook<
|
|
143
|
+
JobDef<"billing.sync-account", typeof syncAccountPayloadSchema, AppContext>,
|
|
144
|
+
AppContext
|
|
145
|
+
>({
|
|
146
|
+
locks: ({ ctx }) => ctx.ports.locks,
|
|
147
|
+
key: ({ payload }) => payload.accountId,
|
|
148
|
+
ttl: "5m",
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
export const SyncAccountJob = defineJob("billing.sync-account", {
|
|
152
|
+
payload: syncAccountPayloadSchema,
|
|
153
|
+
unique: ({ payload }) => ({
|
|
154
|
+
key: payload.accountId,
|
|
155
|
+
ttl: "10m",
|
|
156
|
+
}),
|
|
157
|
+
timeout: "30s",
|
|
158
|
+
retry: retry.exponential({ attempts: 3 }),
|
|
159
|
+
hooks: [syncAccountExecutionLease],
|
|
160
|
+
async handle({ payload, ctx, signal }) {
|
|
161
|
+
await ctx.ports.billing.syncAccount(payload.accountId, { signal });
|
|
162
|
+
},
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
export function createJobsPort(ctx: AppContext) {
|
|
166
|
+
return createUniqueJobDispatcher({
|
|
167
|
+
jobs: createInlineJobDispatcher<AppContext>({ ctx }),
|
|
168
|
+
locks: ctx.ports.locks,
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
`unique` suppresses duplicate dispatches while the resolved lock key's TTL is
|
|
174
|
+
active. It does not replace handler idempotency: providers may still execute a
|
|
175
|
+
queued job more than once after a worker crash or retry.
|
|
176
|
+
|
|
177
|
+
`timeout` bounds each handler attempt. When the timeout expires, Beignet throws
|
|
178
|
+
`JobTimeoutError`, aborts the handler's `signal`, and lets the job retry policy
|
|
179
|
+
decide whether the timeout should retry.
|
|
180
|
+
|
|
181
|
+
`hooks` wrap each handler attempt when the job runs through a Beignet
|
|
182
|
+
dispatcher or worker helper. Runner-level hooks, such as
|
|
183
|
+
`createInlineJobDispatcher({ hooks })`, wrap job-local hooks. Hook failures are
|
|
184
|
+
classified by the same retry policy as handler failures. When a runner can
|
|
185
|
+
report attempt metadata, hooks receive Beignet's one-based `attempt` and
|
|
186
|
+
`maxAttempts` values. Direct `job.handle(...)` calls bypass hooks; use
|
|
187
|
+
`runJobHandler(...)` or a dispatcher when a test needs hook behavior.
|
|
188
|
+
|
|
189
|
+
`createJobExecutionLeaseHook(...)` is the first built-in hook helper. It
|
|
190
|
+
acquires a TTL-backed `LocksPort` lease for one handler attempt, then releases
|
|
191
|
+
best effort in `finally`. It does not start renewal loops, so serverless
|
|
192
|
+
entrypoints can use it with a shared locks provider; the TTL remains the safety
|
|
193
|
+
boundary if the runtime terminates early. Unavailable leases skip by default,
|
|
194
|
+
or can throw `JobExecutionLeaseUnavailableError` for retry classification.
|
|
195
|
+
|
|
105
196
|
Schedules do not own retry policies. They can carry provider attempt metadata
|
|
106
197
|
through `ScheduleRunContext.attempt`, then dispatch jobs or outbox messages when
|
|
107
198
|
the work needs Beignet-managed retry and dead-letter behavior.
|
|
@@ -215,6 +306,8 @@ import {
|
|
|
215
306
|
type EntitlementDecisionObserver,
|
|
216
307
|
requireEntitlement,
|
|
217
308
|
} from "@beignet/core/entitlements";
|
|
309
|
+
import { createTenant } from "@beignet/core/ports";
|
|
310
|
+
import { createTenantScope } from "@beignet/core/tenancy";
|
|
218
311
|
|
|
219
312
|
function createBillingEntitlements(
|
|
220
313
|
billing: BillingRepository,
|
|
@@ -222,7 +315,10 @@ function createBillingEntitlements(
|
|
|
222
315
|
) {
|
|
223
316
|
return createEntitlements({
|
|
224
317
|
async inspect(input) {
|
|
225
|
-
|
|
318
|
+
if (input.subject.type !== "tenant") return false;
|
|
319
|
+
const account = await billing.findByTenantScope(
|
|
320
|
+
createTenantScope(createTenant(input.subject.id)),
|
|
321
|
+
);
|
|
226
322
|
return account?.status === "active";
|
|
227
323
|
},
|
|
228
324
|
onDecision: recordDecision,
|
|
@@ -353,6 +449,56 @@ Provider adapters may require query fields to be declared in the index
|
|
|
353
449
|
metadata. For Meilisearch, `filters` and `facets` must use
|
|
354
450
|
`filterableAttributes`, and `sort` must use `sortableAttributes`.
|
|
355
451
|
|
|
452
|
+
## Uploads
|
|
453
|
+
|
|
454
|
+
Use `@beignet/core/uploads` for typed file workflows above `StoragePort`.
|
|
455
|
+
Upload definitions own metadata validation, authorization, storage keys, file
|
|
456
|
+
constraints, direct-upload signing, and completion hooks.
|
|
457
|
+
|
|
458
|
+
```typescript
|
|
459
|
+
import { createUploads } from "@beignet/core/uploads";
|
|
460
|
+
import { z } from "zod";
|
|
461
|
+
|
|
462
|
+
const { defineUpload } = createUploads<AppContext>();
|
|
463
|
+
|
|
464
|
+
export const issueAttachmentUpload = defineUpload("issues.attachment", {
|
|
465
|
+
metadata: z.object({ issueKey: z.string() }),
|
|
466
|
+
file: {
|
|
467
|
+
contentTypes: ["application/pdf", "text/plain"],
|
|
468
|
+
maxSizeBytes: 5 * 1024 * 1024,
|
|
469
|
+
checksum: { algorithm: "sha256" },
|
|
470
|
+
},
|
|
471
|
+
authorize({ ctx }) {
|
|
472
|
+
return ctx.actor.type === "user";
|
|
473
|
+
},
|
|
474
|
+
key({ metadata, uploadId }) {
|
|
475
|
+
return `issues/${metadata.issueKey}/attachments/${uploadId}`;
|
|
476
|
+
},
|
|
477
|
+
async verifyFile({ ctx, file }) {
|
|
478
|
+
const scan = await ctx.ports.fileScanner.scanObject(file.key);
|
|
479
|
+
|
|
480
|
+
return scan.clean
|
|
481
|
+
? true
|
|
482
|
+
: { valid: false, reason: "Upload did not pass scanning." };
|
|
483
|
+
},
|
|
484
|
+
async onComplete({ ctx, files }) {
|
|
485
|
+
await ctx.ports.issueAttachments.create({
|
|
486
|
+
id: files[0]!.uploadId,
|
|
487
|
+
key: files[0]!.key,
|
|
488
|
+
});
|
|
489
|
+
},
|
|
490
|
+
});
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
For supported media types, uploads verify the declared content type against the
|
|
494
|
+
file signature before completion. Set `contentTypeVerification: false` only for
|
|
495
|
+
workflows that intentionally accept mismatched supported file types. Direct
|
|
496
|
+
uploads can require a SHA-256 checksum with `checksum: { algorithm: "sha256" }`;
|
|
497
|
+
browser clients need a client-safe manifest so `@beignet/core/uploads/client`
|
|
498
|
+
can compute the digest before `prepare`. Use `verifyFile(...)` for app-owned
|
|
499
|
+
scanning, moderation, and quarantine decisions that run after the object exists
|
|
500
|
+
in storage and before `onComplete(...)`.
|
|
501
|
+
|
|
356
502
|
## Webhooks
|
|
357
503
|
|
|
358
504
|
Use `@beignet/core/webhooks` for provider-neutral inbound webhook definitions,
|
|
@@ -378,6 +524,10 @@ export const issueWebhook = defineWebhook("issues.provider", {
|
|
|
378
524
|
secret: process.env.PROVIDER_WEBHOOK_SECRET ?? "",
|
|
379
525
|
signatureHeader: "x-provider-signature",
|
|
380
526
|
signaturePrefix: "sha256=",
|
|
527
|
+
timestamp: {
|
|
528
|
+
header: "x-provider-timestamp",
|
|
529
|
+
toleranceSec: 300,
|
|
530
|
+
},
|
|
381
531
|
}),
|
|
382
532
|
});
|
|
383
533
|
```
|
|
@@ -399,6 +549,13 @@ direction. Attach provider verifiers at the route boundary through the
|
|
|
399
549
|
(`createHmacWebhookVerifier(...)`, `createMemoryWebhookVerifier(...)`) and for
|
|
400
550
|
tests.
|
|
401
551
|
|
|
552
|
+
Generic webhook catalogs reject verified event types that are not declared in
|
|
553
|
+
`events` by default. Set `allowUnknownEvents: true` on
|
|
554
|
+
`createWebhookRoute(...)` or `verifyWebhook(...)` only for broad provider
|
|
555
|
+
endpoints that intentionally acknowledge valid events the app does not handle.
|
|
556
|
+
When a generic HMAC provider signs a timestamp header or payload field, pass
|
|
557
|
+
`timestamp` to reject replayed deliveries outside the configured tolerance.
|
|
558
|
+
|
|
402
559
|
## Provider metadata
|
|
403
560
|
|
|
404
561
|
Reusable provider packages should declare static metadata in `package.json`
|
|
@@ -578,6 +735,45 @@ path with an unregistered method receives a framework-owned `405
|
|
|
578
735
|
METHOD_NOT_ALLOWED` response with an `Allow` header listing the registered
|
|
579
736
|
methods; `HEAD` is intentionally not served by `GET` handlers.
|
|
580
737
|
|
|
738
|
+
### Runtime integrity
|
|
739
|
+
|
|
740
|
+
Workflow artifacts are explicit too. Use `createRuntimeIntegrity(...)` when an
|
|
741
|
+
app should fail startup if a listener, schedule, task, or outbox event/job is
|
|
742
|
+
listed in the app manifest but missing from the runtime registries:
|
|
743
|
+
|
|
744
|
+
```ts
|
|
745
|
+
import {
|
|
746
|
+
createRuntimeIntegrity,
|
|
747
|
+
defineRuntimeManifest,
|
|
748
|
+
defineRuntimeRegistries,
|
|
749
|
+
} from "@beignet/core/server";
|
|
750
|
+
import { postEvents } from "@/features/posts/domain/events";
|
|
751
|
+
import { postJobs } from "@/features/posts/jobs";
|
|
752
|
+
import { postListeners } from "@/features/posts/listeners";
|
|
753
|
+
import { listeners } from "@/server/listeners";
|
|
754
|
+
import { outboxRegistry } from "@/server/outbox";
|
|
755
|
+
|
|
756
|
+
export const runtimeIntegrity = createRuntimeIntegrity({
|
|
757
|
+
manifest: defineRuntimeManifest({
|
|
758
|
+
listeners: [...postListeners],
|
|
759
|
+
outbox: {
|
|
760
|
+
events: [...postEvents],
|
|
761
|
+
jobs: [...postJobs],
|
|
762
|
+
},
|
|
763
|
+
}),
|
|
764
|
+
registries: defineRuntimeRegistries({
|
|
765
|
+
listeners,
|
|
766
|
+
outbox: outboxRegistry,
|
|
767
|
+
}),
|
|
768
|
+
});
|
|
769
|
+
```
|
|
770
|
+
|
|
771
|
+
Pass `integrity: runtimeIntegrity` to `createServer(...)` or
|
|
772
|
+
`createNextServer(...)`. The check is pure and serverless-safe: it compares
|
|
773
|
+
imported definitions and registries in memory, without filesystem scanning,
|
|
774
|
+
provider calls, database access, worker startup, or background loops. Use
|
|
775
|
+
`mode: "warn"` to log findings without failing boot.
|
|
776
|
+
|
|
581
777
|
Contract path templates intentionally support concrete segments and
|
|
582
778
|
single-segment params such as `:id` and `[id]`. Framework or platform
|
|
583
779
|
catch-all route files can expose a central Beignet handler, but individual
|
|
@@ -785,7 +981,7 @@ The `service` factory powers two server entrypoints:
|
|
|
785
981
|
|
|
786
982
|
- `server.createServiceContext(...)` returns the built context and enters the
|
|
787
983
|
ambient correlation frame for the rest of the caller's async execution. Use
|
|
788
|
-
it from long-lived runtimes only: servers, workers, and
|
|
984
|
+
it from long-lived runtimes only: servers, workers, and test runners.
|
|
789
985
|
- `server.runServiceContext(...)` builds the same context and runs a callback
|
|
790
986
|
inside a scoped ambient frame, returning the callback's result. Use it from
|
|
791
987
|
plain scripts such as seeds and one-off maintenance work — the
|
|
@@ -807,6 +1003,34 @@ Both entrypoints require `context.service` in the blueprint, generate fresh
|
|
|
807
1003
|
`tenant` on the ambient request context so audit and instrumentation wrappers
|
|
808
1004
|
observe them at record time.
|
|
809
1005
|
|
|
1006
|
+
### Tenant scopes
|
|
1007
|
+
|
|
1008
|
+
Use `@beignet/core/tenancy` when a repository method should be scoped to the
|
|
1009
|
+
current tenant without accepting arbitrary tenant IDs from callers:
|
|
1010
|
+
|
|
1011
|
+
```ts
|
|
1012
|
+
import {
|
|
1013
|
+
requireTenantScope,
|
|
1014
|
+
tenantScopeId,
|
|
1015
|
+
type TenantScope,
|
|
1016
|
+
} from "@beignet/core/tenancy";
|
|
1017
|
+
|
|
1018
|
+
export interface TodoRepository {
|
|
1019
|
+
create(input: CreateTodoInput, scope: TenantScope): Promise<Todo>;
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
const scope = requireTenantScope(ctx);
|
|
1023
|
+
await ctx.ports.todos.create(input, scope);
|
|
1024
|
+
|
|
1025
|
+
const tenantId = tenantScopeId(scope); // adapter boundary
|
|
1026
|
+
```
|
|
1027
|
+
|
|
1028
|
+
Apps still own tenant resolution and tenant data modeling. `TenantScope` only
|
|
1029
|
+
brands the already-resolved `ctx.tenant` value for app-facing repository
|
|
1030
|
+
boundaries. `beignet doctor --strict` checks generated tenant-scoped Drizzle
|
|
1031
|
+
repositories, explicit raw `tenantId` repository boundaries, and scoped
|
|
1032
|
+
`tenantId`/`workspaceId` predicates as a conservative drift detector.
|
|
1033
|
+
|
|
810
1034
|
### Testing providers
|
|
811
1035
|
|
|
812
1036
|
Use `installProviderForTest(...)` to run provider setup against test ports
|
|
@@ -816,7 +1040,7 @@ without hand-rolling setup, port merge, and lifecycle plumbing:
|
|
|
816
1040
|
import { installProviderForTest } from "@beignet/core/testing";
|
|
817
1041
|
|
|
818
1042
|
const { ports, result, start, stop } = await installProviderForTest(
|
|
819
|
-
|
|
1043
|
+
redisCacheProvider,
|
|
820
1044
|
{
|
|
821
1045
|
ports: { devtools },
|
|
822
1046
|
config: { URL: "redis://localhost:6379" },
|
|
@@ -1113,6 +1337,29 @@ For caching that must survive across requests, use the explicit tier —
|
|
|
1113
1337
|
`ports.cache.remember` with keys that change when the data changes — and see
|
|
1114
1338
|
the request lifecycle docs for context latency budgets.
|
|
1115
1339
|
|
|
1340
|
+
### Trusted proxy request metadata
|
|
1341
|
+
|
|
1342
|
+
Beignet trusts no forwarding headers by default. Use
|
|
1343
|
+
`resolveTrustedRequest(...)` when app code needs external request metadata
|
|
1344
|
+
behind a platform edge or reverse proxy that strips or normalizes forwarding
|
|
1345
|
+
headers before they reach application code:
|
|
1346
|
+
|
|
1347
|
+
```ts
|
|
1348
|
+
import { resolveTrustedRequest } from "@beignet/core/server";
|
|
1349
|
+
|
|
1350
|
+
const requestInfo = resolveTrustedRequest(req, {
|
|
1351
|
+
clientIp: "x-forwarded-for-last",
|
|
1352
|
+
});
|
|
1353
|
+
|
|
1354
|
+
requestInfo.origin; // "https://app.example.com"
|
|
1355
|
+
requestInfo.clientIp; // resolved only when clientIp is configured
|
|
1356
|
+
```
|
|
1357
|
+
|
|
1358
|
+
The same `trustedProxy` policy is accepted by `createRateLimitHooks(...)` for
|
|
1359
|
+
IP-scoped keys and by `createCsrfHooks(...)` for comparing browser origins
|
|
1360
|
+
against the external host and protocol. Configure it only when every request
|
|
1361
|
+
passes through your trusted edge.
|
|
1362
|
+
|
|
1116
1363
|
### Rate limiting
|
|
1117
1364
|
|
|
1118
1365
|
Use `createRateLimitHooks(...)` from `@beignet/core/server` to enforce
|
|
@@ -1131,14 +1378,15 @@ const server = await createServer<AppContext, AppPorts>({
|
|
|
1131
1378
|
- `global` and `ip` scopes run in `onRequest` before parsing and context
|
|
1132
1379
|
creation; `user` scope runs in `beforeHandle` after route hooks have resolved
|
|
1133
1380
|
identity and `ctx.actor` exists.
|
|
1134
|
-
- `ip` scopes require an explicit `
|
|
1135
|
-
fails `createServer(...)`
|
|
1136
|
-
`ip`-scoped rate limit without
|
|
1137
|
-
configuration error for contracts added
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1381
|
+
- `ip` scopes require an explicit `trustedProxy.clientIp`, `ipSource`, or
|
|
1382
|
+
custom `earlyKey`. The hook's `validate` phase fails `createServer(...)`
|
|
1383
|
+
startup when a registered contract declares an `ip`-scoped rate limit without
|
|
1384
|
+
one, and enforcement throws the same configuration error for contracts added
|
|
1385
|
+
later through `server.route(...)`. Prefer
|
|
1386
|
+
`trustedProxy: { clientIp: "x-forwarded-for-last" }` behind a trusted proxy
|
|
1387
|
+
that appends the socket address, `"x-forwarded-for-first"` when a trusted
|
|
1388
|
+
edge normalizes the header, or
|
|
1389
|
+
`trustedProxy: { clientIp: "cf-connecting-ip" }` for platform headers.
|
|
1142
1390
|
- Pass `ipSource: "none"` to explicitly opt out of client-IP resolution:
|
|
1143
1391
|
Beignet then trusts no forwarding headers and all `ip`-scoped traffic
|
|
1144
1392
|
shares one `ip:unknown` bucket.
|
|
@@ -1230,12 +1478,17 @@ import {
|
|
|
1230
1478
|
createOutboxEventRecorder,
|
|
1231
1479
|
defineOutboxRegistry,
|
|
1232
1480
|
drainOutbox,
|
|
1481
|
+
type OutboxAdminPort,
|
|
1233
1482
|
} from "@beignet/core/outbox";
|
|
1234
1483
|
import {
|
|
1484
|
+
createDrizzleSqliteOutboxAdminPort,
|
|
1235
1485
|
createDrizzleSqliteOutboxPort,
|
|
1236
1486
|
createDrizzleSqliteUnitOfWork,
|
|
1237
1487
|
} from "@beignet/provider-db-drizzle/sqlite";
|
|
1238
1488
|
|
|
1489
|
+
const outboxAdmin: OutboxAdminPort =
|
|
1490
|
+
createDrizzleSqliteOutboxAdminPort(db);
|
|
1491
|
+
|
|
1239
1492
|
const uow = createDrizzleSqliteUnitOfWork({
|
|
1240
1493
|
db,
|
|
1241
1494
|
createTransactionPorts: (tx) => {
|
|
@@ -1265,6 +1518,10 @@ await drainOutbox({
|
|
|
1265
1518
|
The outbox is at-least-once delivery. Use idempotent listeners or jobs when a
|
|
1266
1519
|
duplicate delivery would be harmful.
|
|
1267
1520
|
|
|
1521
|
+
Use `OutboxAdminPort` only from operational contexts. It lets `beignet outbox`
|
|
1522
|
+
list, show, requeue, purge dead-lettered rows, and prune delivered rows without
|
|
1523
|
+
exposing those destructive operations to transaction-scoped use cases.
|
|
1524
|
+
|
|
1268
1525
|
### Schedules
|
|
1269
1526
|
|
|
1270
1527
|
Use `@beignet/core/schedules` to define typed schedules and run them
|
|
@@ -1373,6 +1630,27 @@ const writerAuth = createAuthHooks<AppContext>()({
|
|
|
1373
1630
|
});
|
|
1374
1631
|
```
|
|
1375
1632
|
|
|
1633
|
+
Use `createSecurityHeadersHooks(...)` for the default browser response-header
|
|
1634
|
+
baseline. The hook adds common headers such as `X-Content-Type-Options`,
|
|
1635
|
+
`X-Frame-Options`, `Referrer-Policy`, `Permissions-Policy`,
|
|
1636
|
+
`Cross-Origin-Opener-Policy`, and `Cross-Origin-Resource-Policy`; it does not
|
|
1637
|
+
guess your CSP or HSTS policy:
|
|
1638
|
+
|
|
1639
|
+
```ts
|
|
1640
|
+
import { createSecurityHeadersHooks } from "@beignet/core/server";
|
|
1641
|
+
|
|
1642
|
+
const securityHeaders = createSecurityHeadersHooks({
|
|
1643
|
+
contentSecurityPolicy: "default-src 'self'; frame-ancestors 'none'",
|
|
1644
|
+
strictTransportSecurity: {
|
|
1645
|
+
maxAgeSec: 31_536_000,
|
|
1646
|
+
includeSubDomains: true,
|
|
1647
|
+
},
|
|
1648
|
+
});
|
|
1649
|
+
```
|
|
1650
|
+
|
|
1651
|
+
Existing response headers win, so routes that stream files, render HTML, or need
|
|
1652
|
+
a different CSP can set their own policy.
|
|
1653
|
+
|
|
1376
1654
|
Use `createCorsHooks(...)` for app-wide CORS headers. Wildcard origins are
|
|
1377
1655
|
accepted only for non-credentialed requests:
|
|
1378
1656
|
|
|
@@ -1390,6 +1668,31 @@ const browserAppCors = createCorsHooks({
|
|
|
1390
1668
|
apps do not accidentally reflect arbitrary request origins for cookies or
|
|
1391
1669
|
authorization headers.
|
|
1392
1670
|
|
|
1671
|
+
Use `createCsrfHooks(...)` when browser mutations depend on cookies. By default
|
|
1672
|
+
the hook protects unsafe methods by rejecting cross-origin `Origin` or `Referer`
|
|
1673
|
+
headers while still allowing requests that do not carry browser origin headers.
|
|
1674
|
+
Set `allowMissingOrigin: false` and enable token checks for stricter
|
|
1675
|
+
browser-only APIs:
|
|
1676
|
+
|
|
1677
|
+
```ts
|
|
1678
|
+
import { createCsrfHooks } from "@beignet/core/server";
|
|
1679
|
+
|
|
1680
|
+
const csrf = createCsrfHooks({
|
|
1681
|
+
allowMissingOrigin: false,
|
|
1682
|
+
trustedProxy: {},
|
|
1683
|
+
trustedOrigins: ["https://app.example.com"],
|
|
1684
|
+
token: {
|
|
1685
|
+
cookieName: "csrf",
|
|
1686
|
+
headerName: "x-csrf-token",
|
|
1687
|
+
},
|
|
1688
|
+
skip: ({ contract }) => contract.name.startsWith("webhooks."),
|
|
1689
|
+
});
|
|
1690
|
+
```
|
|
1691
|
+
|
|
1692
|
+
Pass `trustedProxy: {}` only when Beignet should compare `Origin` or `Referer`
|
|
1693
|
+
against the external `x-forwarded-host` and `x-forwarded-proto` values written
|
|
1694
|
+
by your trusted edge.
|
|
1695
|
+
|
|
1393
1696
|
### HTTP adapter boundary
|
|
1394
1697
|
|
|
1395
1698
|
`@beignet/core/server` is framework-neutral. It owns route matching, hooks,
|
|
@@ -1471,15 +1774,37 @@ Service contexts created with `server.createServiceContext(...)` receive fresh
|
|
|
1471
1774
|
sets its own `requestId`, headers and recorded events use it.
|
|
1472
1775
|
|
|
1473
1776
|
Trace primitives live in `@beignet/core/tracing` (`TraceContext`,
|
|
1474
|
-
`
|
|
1475
|
-
`
|
|
1476
|
-
dependency-free so app context
|
|
1777
|
+
`TracingPort`, `TraceOperation`, `TraceSpan`, `createTraceContext`,
|
|
1778
|
+
`createChildTraceContext`, `parseTraceparent`, `createTraceparent`,
|
|
1779
|
+
`createTraceId`, `createSpanId`). The module is dependency-free so app context
|
|
1780
|
+
types can be imported from client bundles.
|
|
1781
|
+
|
|
1782
|
+
When final ports include `ports.tracing`, requests execute inside an active
|
|
1783
|
+
`beignet.request <contract>` span. Incoming `traceparent` and `tracestate`
|
|
1784
|
+
continue the trace; if the host already established an active span, Beignet's
|
|
1785
|
+
request span becomes its child. Use cases, listeners, job handlers, schedule
|
|
1786
|
+
handlers, and task handlers create nested active spans through the same port.
|
|
1787
|
+
Install `@beignet/provider-tracing-opentelemetry` to adapt this port to an
|
|
1788
|
+
app-owned OpenTelemetry SDK and emit baseline duration, error, and provider
|
|
1789
|
+
operation metrics.
|
|
1790
|
+
|
|
1791
|
+
Listener, job, schedule, and task runners accept both a lazy `ctx` factory and
|
|
1792
|
+
an explicit `tracing` port. Provider-backed runtimes should pass the installed
|
|
1793
|
+
port so Beignet starts the workflow span before resolving
|
|
1794
|
+
`server.createServiceContext(...)`; the resulting context then inherits the
|
|
1795
|
+
real active span instead of treating local correlation IDs as a remote parent.
|
|
1796
|
+
|
|
1797
|
+
For custom `TraceOperation` values, `attributes` are span-only. Use
|
|
1798
|
+
`metricAttributes` only for bounded operation dimensions such as a contract,
|
|
1799
|
+
use-case, job, schedule, or task name. Never add request, actor, tenant, or
|
|
1800
|
+
payload values to metric attributes.
|
|
1477
1801
|
|
|
1478
1802
|
Use cases created with `createUseCase(...)` are instrumented by default. Each
|
|
1479
|
-
run resolves the instrumentation port from `ctx.ports
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
out
|
|
1803
|
+
run resolves the instrumentation port from `ctx.ports` and records `usecase`
|
|
1804
|
+
lifecycle events plus correlated `error` events for failures. When a tracing
|
|
1805
|
+
port is installed, it also creates an active child span. Pass
|
|
1806
|
+
`instrumentation: false` to opt out of instrumentation events; tracing is
|
|
1807
|
+
controlled by whether the app installs `ports.tracing`.
|
|
1483
1808
|
|
|
1484
1809
|
`createInstrumentedAuditLog({ audit, instrumentation })` from
|
|
1485
1810
|
`@beignet/core/ports` writes durable audit entries first and mirrors sanitized
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/application/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/application/index.ts"],"names":[],"mappings":"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"}
|