@friggframework/devtools 2.0.0--canary.606.7d3473f.0 → 2.0.0--canary.608.ba60ba6.0

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.
@@ -16,14 +16,14 @@
16
16
  "@friggframework/core": "^2.0.0-next.0",
17
17
  "@friggframework/schemas": "^2.0.0-next.0",
18
18
  "@inquirer/prompts": "^5.3.8",
19
- "axios": "^1.7.2",
19
+ "axios": "^1.18.0",
20
20
  "chalk": "^4.1.2",
21
21
  "commander": "^12.1.0",
22
22
  "cross-spawn": "^7.0.3",
23
23
  "dotenv": "^16.4.5",
24
24
  "fs-extra": "^11.2.0",
25
25
  "js-yaml": "^4.1.0",
26
- "lodash": "4.17.21",
26
+ "lodash": "4.18.1",
27
27
  "node-cache": "^5.1.2",
28
28
  "open": "^8.4.2",
29
29
  "osls": "^3.40.1",
@@ -196,6 +196,14 @@ class IntegrationBuilder extends InfrastructureBuilder {
196
196
  );
197
197
  }
198
198
 
199
+ // App-level FIFO queue for dispatch:'queue' events — one per app,
200
+ // independent of per-integration queue ownership.
201
+ this.createUserActionQueue(
202
+ result,
203
+ functionPackageConfig,
204
+ usePrismaLayer
205
+ );
206
+
199
207
  for (const integration of appDefinition.integrations) {
200
208
  const integrationName = integration.Definition.name;
201
209
  const queueDecision = decisions.integrations[integrationName].queue;
@@ -472,6 +480,113 @@ class IntegrationBuilder extends InfrastructureBuilder {
472
480
  console.log(' ✓ Created InternalErrorQueue resource');
473
481
  }
474
482
 
483
+ /**
484
+ * Create the app-level FIFO queue + FIFO DLQ + worker used by integration
485
+ * events declared with `dispatch: 'queue'`.
486
+ *
487
+ * A single queue serves every integration: `MessageGroupId = integrationId`
488
+ * (set by the producer) serializes events per integration while letting
489
+ * distinct integrations process in parallel. Always created, like the
490
+ * InternalErrorQueue — idle cost is ~$0.
491
+ */
492
+ createUserActionQueue(
493
+ result,
494
+ functionPackageConfig,
495
+ usePrismaLayer = true
496
+ ) {
497
+ const queueName =
498
+ '${self:service}-${self:provider.stage}-FriggUserActionQueue.fifo';
499
+ const dlqName =
500
+ '${self:service}-${self:provider.stage}-FriggUserActionDLQ.fifo';
501
+
502
+ result.custom.FriggUserActionQueue = queueName;
503
+ result.custom.FriggUserActionDLQ = dlqName;
504
+
505
+ // A FIFO source queue can only redrive to a FIFO DLQ.
506
+ result.resources.FriggUserActionDLQ = {
507
+ Type: 'AWS::SQS::Queue',
508
+ Properties: {
509
+ QueueName: '${self:custom.FriggUserActionDLQ}',
510
+ FifoQueue: true,
511
+ MessageRetentionPeriod: 1209600, // 14 days
512
+ },
513
+ };
514
+
515
+ // ContentBasedDeduplication is intentionally OMITTED. The producer
516
+ // supplies a unique MessageDeduplicationId per send, so two distinct
517
+ // requests with identical bodies both run — content-based dedup would
518
+ // hash the body and silently drop the second within the 5-min window.
519
+ result.resources.FriggUserActionQueue = {
520
+ Type: 'AWS::SQS::Queue',
521
+ Properties: {
522
+ QueueName: '${self:custom.FriggUserActionQueue}',
523
+ FifoQueue: true,
524
+ MessageRetentionPeriod: 345600, // 4 days
525
+ VisibilityTimeout: 1800, // >= worker timeout (900s)
526
+ RedrivePolicy: {
527
+ maxReceiveCount: 2,
528
+ deadLetterTargetArn: {
529
+ 'Fn::GetAtt': ['FriggUserActionDLQ', 'Arn'],
530
+ },
531
+ },
532
+ },
533
+ };
534
+
535
+ // Expose the queue URL to ALL Lambdas — both the HTTP handlers that
536
+ // produce events and the worker that consumes them.
537
+ result.environment.USER_ACTION_QUEUE_URL = {
538
+ Ref: 'FriggUserActionQueue',
539
+ };
540
+
541
+ // Any message in the FIFO DLQ is a failed eventual event.
542
+ result.resources.FriggUserActionDLQAlarm = {
543
+ Type: 'AWS::CloudWatch::Alarm',
544
+ Properties: {
545
+ AlarmDescription:
546
+ 'Messages in FriggUserActionDLQ — eventual (queued) integration event failures',
547
+ Namespace: 'AWS/SQS',
548
+ MetricName: 'ApproximateNumberOfMessagesVisible',
549
+ Statistic: 'Maximum',
550
+ Threshold: 0,
551
+ ComparisonOperator: 'GreaterThanThreshold',
552
+ EvaluationPeriods: 1,
553
+ Period: 300,
554
+ AlarmActions: [{ Ref: 'InternalErrorBridgeTopic' }],
555
+ Dimensions: [
556
+ {
557
+ Name: 'QueueName',
558
+ Value: {
559
+ 'Fn::GetAtt': ['FriggUserActionDLQ', 'QueueName'],
560
+ },
561
+ },
562
+ ],
563
+ },
564
+ };
565
+
566
+ // Single app-level worker. NO reservedConcurrency: FIFO already
567
+ // serializes per MessageGroupId; capping at 1 would serialize across
568
+ // ALL integrations and kill cross-integration parallelism.
569
+ result.functions.userActionQueueWorker = {
570
+ handler:
571
+ 'node_modules/@friggframework/core/handlers/workers/user-action-worker.userActionQueueWorker',
572
+ skipEsbuild: true,
573
+ package: functionPackageConfig,
574
+ ...(usePrismaLayer && { layers: [{ Ref: 'PrismaLambdaLayer' }] }),
575
+ timeout: 900,
576
+ events: [
577
+ {
578
+ sqs: {
579
+ arn: { 'Fn::GetAtt': ['FriggUserActionQueue', 'Arn'] },
580
+ batchSize: 1,
581
+ functionResponseType: 'ReportBatchItemFailures',
582
+ },
583
+ },
584
+ ],
585
+ };
586
+
587
+ console.log(' ✓ Created FriggUserActionQueue (.fifo) + DLQ + worker');
588
+ }
589
+
475
590
  /**
476
591
  * Use external InternalErrorQueue
477
592
  */