Plug & Play
Plug & Play is the ZinTrust surface for reusable, composable framework workflows that developers would otherwise rebuild in every service.
The first shipped Plug & Play slice focuses on workflows that already exist across services and need one product-ready contract:
- secure payload decoding
- auth and login orchestration
- notification composition
- context loading
The goal is not to hide application logic. The goal is to provide a stable orchestration layer with:
- consistent API shape
- normalized failure semantics
- reusable adapter registration
- bounded-state runtime behavior
- Node and Cloudflare Workers compatibility
Design Rules
Every Plug & Play feature should follow these runtime rules:
- no unbounded in-memory request caches
- explicit cleanup for retained state
- low-cardinality metrics and structured logs
- request-scoped or invocation-scoped state by default
- adapters provide integration details, core provides orchestration
Available Today
Secure payload decoding
Use plug-and-play-secure-payload for encrypted payload pipelines that decrypt, parse JSON, coerce values, validate schema, and return typed results.
Auth and login orchestration
Use plug-and-play-auth-login for the LoginFlow contract that centralizes account lookup, credential verification, token issuance, and audit hooks without retaining request state after the flow completes.
Notification composer
Use plug-and-play-notification-composer for Notification.compose(...), which coordinates required and best-effort delivery across registered channels without pushing orchestration glue into every service.
Context loader
Use plug-and-play-context-loader for ContextLoader.create(), which centralizes dependency-ordered context assembly and optional batch fan-out loading without pretending every graph collapses to one query.
Context loader
Request-scoped context loading and optional batching is now available through ContextLoader.
Example: secure payload flow
import { Schema, SecurePayload } from '@zintrust/core';
SecurePayload.registerDecryptor('payments', async (raw, context) => {
return context.encryption.decryptString(raw);
});
const schema = Schema.create()
.required('amount')
.number('amount')
.required('currency')
.string('currency');
const payload = await SecurePayload.decode(rawPayload, {
decryptor: 'payments',
context: {
encryption: Encryption.connection('default'),
},
})
.decrypt()
.json()
.coerce({ amount: 'number' })
.validate(schema)
.typed<{ amount: number; currency: string }>();Example: auth and login flow
import { Auth, ErrorFactory, LoginFlow } from '@zintrust/core';
LoginFlow.registerProvider('password', {
identify: async ({ email }) => User.where('email', '=', email).first(),
verify: async (user, { password }) => {
if (!user) {
throw ErrorFactory.createUnauthorizedError('Invalid credentials');
}
const ok = await Auth.compare(password, String(user.password ?? ''));
if (!ok) {
throw ErrorFactory.createUnauthorizedError('Invalid credentials');
}
return {
user,
subject: String(user.id),
claims: {
sub: String(user.id),
email: String(user.email),
},
};
},
});
const result = await LoginFlow.create({
provider: 'password',
context: { requestId: req.getHeader('x-request-id') },
})
// This exact object becomes provider.identify({ email }, context)
.identify({ email })
// This exact object becomes provider.verify(identity, { password }, context)
.verify({ password })
.issue('jwt')
.audit()
.run();
res.json({
token: result.issued,
user: result.verified.user,
});Example: notification compose flow
import { Notification } from '@zintrust/core';
Notification.registerChannel('email', async (payload, context) => {
return context.mailer.send(payload);
});
Notification.registerChannel('push', async (payload, context) => {
return context.pushProvider.send(payload);
});
const result = await Notification.compose({
context: {
mailer: Mail.connection('default'),
pushProvider: Push.connection('primary'),
},
})
.email({ to: 'account@example.com', subject: 'Operation complete', html: '<p>Completed</p>' })
.push({
recipientId: 'account-1',
title: 'Operation complete',
body: 'Your request was successful',
})
.required(['email'])
.bestEffort(['push'])
.send();
if (result.results.some((entry) => entry.channel === 'push' && entry.ok === false)) {
Logger.warn('push delivery failed but email still sent', result.results);
}Example: context loader flow
import { ContextLoader } from '@zintrust/core';
const loader = ContextLoader.create({ mode: 'batch' }).batch(
'profilesByUserId',
async (userIds) => {
const profiles = await Profile.whereIn('user_id', userIds).get();
return new Map(profiles.map((profile) => [String(profile.user_id), profile]));
}
);
const context = await loader
.load('user', async () => User.find(userId))
.load('profile', async ({ user }) => {
const currentUser = user as { id?: string } | null;
return currentUser?.id ? loader.fromBatch('profilesByUserId', currentUser.id) : null;
})
.load('wallet', async ({ user }) => {
const currentUser = user as { id?: string } | null;
return currentUser?.id ? Wallet.where('user_id', '=', currentUser.id).first() : null;
})
.resolve();