feat(service): P5.4 outbound sandbox sink + rate limit + inspector read endpoints
OutboundService: idempotent commands, per-(channelType,target) rate-limit bucket, sandbox send (no network) + delivery attempts. POST /v1/adapters/:type/send + GET inbound/outbound (session-auth). 55 tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,7 @@ import { IIOS_EVENTS, type CloudEvent } from '@insignia/iios-contracts';
|
||||
import { signedFixture, emailFixture } from '@insignia/iios-adapter-sdk';
|
||||
import { AdapterRegistry } from './adapter.registry';
|
||||
import { InboundService } from './inbound.service';
|
||||
import { OutboundService } from './outbound.service';
|
||||
import { RawEventProjector } from './raw-event.projector';
|
||||
import { IngestService } from '../interactions/ingest.service';
|
||||
import { ActorResolver } from '../identity/actor.resolver';
|
||||
@@ -73,3 +74,34 @@ describe('Adapter inbound (P5)', () => {
|
||||
expect(await prisma.iiosInteraction.count()).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Adapter outbound (P5)', () => {
|
||||
const outbound = (limit?: number): OutboundService => {
|
||||
const s = new OutboundService(asService, registry());
|
||||
if (limit) s.limit = limit;
|
||||
return s;
|
||||
};
|
||||
|
||||
it('send → command SENT + one delivery attempt (sandbox, no network)', async () => {
|
||||
const cmd = await outbound().send('WEBHOOK', 'user@x', { text: 'hi' }, 'ob-1');
|
||||
expect(cmd.status).toBe('SENT');
|
||||
expect(cmd.providerRef).toContain('sim-');
|
||||
expect(await prisma.iiosDeliveryAttempt.count({ where: { commandId: cmd.id } })).toBe(1);
|
||||
});
|
||||
|
||||
it('rate limit: exceeding the window → RATE_LIMITED', async () => {
|
||||
const svc = outbound(2);
|
||||
await svc.send('WEBHOOK', 't', {}, 'a');
|
||||
await svc.send('WEBHOOK', 't', {}, 'b');
|
||||
const third = await svc.send('WEBHOOK', 't', {}, 'c');
|
||||
expect(third.status).toBe('RATE_LIMITED');
|
||||
});
|
||||
|
||||
it('idempotent: same key twice → one command', async () => {
|
||||
const svc = outbound();
|
||||
const a = await svc.send('WEBHOOK', 't2', {}, 'k');
|
||||
const b = await svc.send('WEBHOOK', 't2', {}, 'k');
|
||||
expect(b.id).toBe(a.id);
|
||||
expect(await prisma.iiosOutboundCommand.count()).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user