@fjall/components-infrastructure 12.4.0 → 13.0.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.
package/dist/lib/app.d.ts CHANGED
@@ -117,6 +117,12 @@ export declare class App extends CdkApp {
117
117
  getName(): string;
118
118
  static getApp(name?: string, options?: IAppOptions): App;
119
119
  static getInstance(name?: string, options?: IAppOptions): App;
120
+ /**
121
+ * Whether the singleton App has been initialised. Lets patterns consult the
122
+ * instance for defaults without materialising it (and its manifest
123
+ * collector) as a side effect in bare-synth contexts.
124
+ */
125
+ static hasInstance(): boolean;
120
126
  static resetForTesting(): void;
121
127
  /**
122
128
  * Retrieve a stack by key. If the stack does not exist, it will be created.
package/dist/lib/app.js CHANGED
@@ -169,6 +169,14 @@ export class App extends CdkApp {
169
169
  }
170
170
  return App.instance;
171
171
  }
172
+ /**
173
+ * Whether the singleton App has been initialised. Lets patterns consult the
174
+ * instance for defaults without materialising it (and its manifest
175
+ * collector) as a side effect in bare-synth contexts.
176
+ */
177
+ static hasInstance() {
178
+ return App.instance !== null;
179
+ }
172
180
  static resetForTesting() {
173
181
  App.instance = null;
174
182
  // App-scoped synth state resets with the App singleton — the DNS
@@ -437,6 +437,8 @@ export class ClickHouseDatabase extends Construct {
437
437
  }
438
438
  const resolvedAlertsTopic = resolveAlertsTopic(this, "AlertsTopic", props.alertsTopic);
439
439
  const alarmsDisabled = props.alarms === false;
440
+ const applicationId = props.applicationId ??
441
+ (App.hasInstance() ? App.getInstance().getName() : undefined);
440
442
  const alarmThresholds = typeof props.alarms === "object" ? props.alarms : {};
441
443
  validateClickHouseAlarmThresholds(alarmThresholds);
442
444
  const serverTuning = deriveClickHouseServerTuning(instanceType);
@@ -449,9 +451,7 @@ export class ClickHouseDatabase extends Construct {
449
451
  ...(resolvedAlertsTopic !== undefined && {
450
452
  alertsTopic: resolvedAlertsTopic
451
453
  }),
452
- ...(props.applicationId !== undefined && {
453
- applicationId: props.applicationId
454
- }),
454
+ ...(applicationId !== undefined && { applicationId }),
455
455
  cluster: {
456
456
  loadBalancer: false,
457
457
  securityGroup,
@@ -639,9 +639,7 @@ export class ClickHouseDatabase extends Construct {
639
639
  asgName,
640
640
  alarmTopic: resolvedAlertsTopic,
641
641
  config: alarmThresholds,
642
- ...(props.applicationId !== undefined && {
643
- applicationId: props.applicationId
644
- }),
642
+ ...(applicationId !== undefined && { applicationId }),
645
643
  ...(backupTaskLogGroup !== undefined && { backupTaskLogGroup })
646
644
  });
647
645
  }
@@ -163,7 +163,8 @@ export class ComputeFactory {
163
163
  if (computeProps.type === "ecs") {
164
164
  computeProps = {
165
165
  ...computeProps,
166
- appName: computeProps.appName ?? app.getName()
166
+ appName: computeProps.appName ?? app.getName(),
167
+ applicationId: computeProps.applicationId ?? app.getName()
167
168
  };
168
169
  }
169
170
  // Create specific compute class based on type discriminator
@@ -993,7 +993,8 @@ export class EcsCompute extends Construct {
993
993
  cluster,
994
994
  services,
995
995
  alertsTopic: resolvedAlertsTopic,
996
- applicationId: props.applicationId,
996
+ applicationId: props.applicationId ??
997
+ (App.hasInstance() ? App.getInstance().getName() : undefined),
997
998
  ...(props.taskStopWatchdog === false && { taskStopWatchdog: false })
998
999
  };
999
1000
  this.ecsCluster = new EcsCluster(this, `${id}Ecs`, ecsProps);
@@ -176,13 +176,15 @@ export class DatabaseFactory {
176
176
  if (props.type === "ClickHouse") {
177
177
  const clickhouseProps = {
178
178
  ...props,
179
- vpc: props.vpc ?? app.getVpc()
179
+ vpc: props.vpc ?? app.getVpc(),
180
+ applicationId: props.applicationId ?? app.getName()
180
181
  };
181
182
  return new ClickHouseDatabase(scope, id, clickhouseProps);
182
183
  }
183
184
  const databaseProps = {
184
185
  ...props,
185
- vpc: props.vpc ?? app.getVpc()
186
+ vpc: props.vpc ?? app.getVpc(),
187
+ applicationId: props.applicationId ?? app.getName()
186
188
  };
187
189
  validateDatabaseProps(databaseProps);
188
190
  return new RelationalDatabase(scope, id, databaseProps);
@@ -307,10 +307,13 @@ export class MessagingFactory {
307
307
  * Implementation of the build method.
308
308
  */
309
309
  static build(id, props) {
310
- return (_app, scope) => {
310
+ return (app, scope) => {
311
311
  switch (props.type) {
312
312
  case "queue":
313
- return new QueueMessaging(scope, id, props);
313
+ return new QueueMessaging(scope, id, {
314
+ ...props,
315
+ applicationId: props.applicationId ?? app.getName()
316
+ });
314
317
  case "topic":
315
318
  return new TopicMessaging(scope, id, props);
316
319
  case "eventBus":
@@ -3,8 +3,19 @@ import type { Alarm, AlarmBase } from "aws-cdk-lib/aws-cloudwatch";
3
3
  import type { SnsAction } from "aws-cdk-lib/aws-cloudwatch-actions";
4
4
  /**
5
5
  * Tag key for mapping CloudWatch alarms to Fjall applications.
6
- * Cross-system contract: the webhook at webapp/app/routes/api/internal/alarm-webhook.ts
7
- * extracts this tag from alarm descriptions and dimensions.
6
+ *
7
+ * Value contract: the tag value is the fjall application NAME — every
8
+ * alarm-bearing factory branch defaults it to `app.getName()`, which equals
9
+ * the webapp's `Application.fjallName` (the byte-stable deploy identity), not
10
+ * a database id. The webapp resolves it to the owning application record at
11
+ * alarm-webhook ingress.
12
+ *
13
+ * Cross-system contract: the webhook at
14
+ * webapp/app/routes/api/internal/alarm-webhook.ts extracts this tag from
15
+ * alarm descriptions and dimensions via the mirror constant
16
+ * `APPLICATION_ID_TAG_KEY` at
17
+ * webapp/app/.server/services/alarms/alarmMapper.ts — the two literals must
18
+ * stay byte-identical.
8
19
  */
9
20
  export declare const APPLICATION_ID_TAG_KEY = "fjall:applicationId";
10
21
  export declare const ALARM_DEFAULTS: {
@@ -1,8 +1,19 @@
1
1
  import { Duration, Tags } from "aws-cdk-lib";
2
2
  /**
3
3
  * Tag key for mapping CloudWatch alarms to Fjall applications.
4
- * Cross-system contract: the webhook at webapp/app/routes/api/internal/alarm-webhook.ts
5
- * extracts this tag from alarm descriptions and dimensions.
4
+ *
5
+ * Value contract: the tag value is the fjall application NAME — every
6
+ * alarm-bearing factory branch defaults it to `app.getName()`, which equals
7
+ * the webapp's `Application.fjallName` (the byte-stable deploy identity), not
8
+ * a database id. The webapp resolves it to the owning application record at
9
+ * alarm-webhook ingress.
10
+ *
11
+ * Cross-system contract: the webhook at
12
+ * webapp/app/routes/api/internal/alarm-webhook.ts extracts this tag from
13
+ * alarm descriptions and dimensions via the mirror constant
14
+ * `APPLICATION_ID_TAG_KEY` at
15
+ * webapp/app/.server/services/alarms/alarmMapper.ts — the two literals must
16
+ * stay byte-identical.
6
17
  */
7
18
  export const APPLICATION_ID_TAG_KEY = "fjall:applicationId";
8
19
  export const ALARM_DEFAULTS = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fjall/components-infrastructure",
3
- "version": "12.4.0",
3
+ "version": "13.0.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/fjall-tech/fjall.git",
@@ -80,8 +80,8 @@
80
80
  },
81
81
  "dependencies": {
82
82
  "@aws-sdk/client-organizations": "^3.1098.0",
83
- "@fjall/generator": "^12.4.0",
84
- "@fjall/util": "^12.4.0",
83
+ "@fjall/generator": "^13.0.0",
84
+ "@fjall/util": "^13.0.0",
85
85
  "constructs": "^10.7.2"
86
86
  },
87
87
  "overrides": {