Repository: open-condo-software/condo
Pull request #6184: feat(condo): DOMA-11617 add runtime stats for condo app
Author: login: AleX83Xpert
Labels: name: ✋🙂 Review please
description: Comments are resolved, take a look, please
Created: 2025-05-16T04:38:47Z | Merged: 2025-05-16T16:03:15Z



<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Introduced real-time tracking of active HTTP requests, categorized by type.
  - Added a new endpoint at "/.well-known/runtime-stats" to display current runtime request statistics in JSON format.
- **Chores**
  - Exported the default health check URL constant for easier configuration.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->


Diff:
diff --git a/.helm b/.helm
index 2121f382922..92e6bc19190 160000
--- a/.helm
+++ b/.helm
@@ -1 +1 @@
-Subproject commit 2121f382922b2d700a403620cb68b048615df2fd
+Subproject commit 92e6bc1919031860aa44dc2cf244c88d01ccd7dc
diff --git a/apps/condo/index.js b/apps/condo/index.js
index 43027eaffe0..c238987c701 100644
--- a/apps/condo/index.js
+++ b/apps/condo/index.js
@@ -12,14 +12,15 @@ const { AdapterCache } = require('@open-condo/keystone/adapterCache')
 const { GQLError, GQLErrorCode: { FORBIDDEN } } = require('@open-condo/keystone/errors')
 const FileAdapter = require('@open-condo/keystone/fileAdapter/fileAdapter')
 const {
+    DEFAULT_HEALTHCHECK_URL,
     HealthCheck,
     getRedisHealthCheck,
     getPostgresHealthCheck,
     getPfxCertificateHealthCheck,
 } = require('@open-condo/keystone/healthCheck')
 const { prepareKeystone } = require('@open-condo/keystone/KSv5v6/v5/prepareKeystone')
+const { getLogger } = require('@open-condo/keystone/logging')
 const { RequestCache } = require('@open-condo/keystone/requestCache')
-const { getXRemoteApp, getXRemoteClient, getXRemoteVersion, getAppName } = require('@open-condo/keystone/tracingUtils')
 const { getWebhookModels } = require('@open-condo/webhooks/schema')
 const { getWebhookTasks } = require('@open-condo/webhooks/tasks')
 
@@ -38,6 +39,8 @@ dayjs.extend(isBetween)
 const IS_BUILD_PHASE = conf.PHASE === 'build'
 const SENTRY_CONFIG = conf.SENTRY_CONFIG ? JSON.parse(conf.SENTRY_CONFIG) : {}
 
+const logger = getLogger('condo-index')
+
 // TODO(zuch): DOMA-2990: add FILE_FIELD_ADAPTER to env during build phase
 if (IS_BUILD_PHASE) {
     process.env.FILE_FIELD_ADAPTER = 'local' // Test
@@ -143,6 +146,89 @@ const apps = () => {
 
 /** @type {(app: import('express').Application) => void} */
 const extendExpressApp = (app) => {
+    const runtimeStats = {
+        activeRequestsIds: new Set(),
+        activeRequestsCountByType: {
+            graphql: 0,
+            api: 0,
+            oidc: 0,
+            wellKnown: 0,
+            healthCheck: 0,
+            other: 0,
+        },
+        totalRequestsCount: 0,
+        totalRequestsByTarget: {},
+    }
+
+    app.use(function runtimeStatsMiddleware (req, res, next) {
+        try {
+            const url = new URL(`${conf['SERVER_URL']}${req.url}`).pathname
+            const method = (req.method || 'get').toLowerCase()
+
+            // According to ADR35
+            const possibleXTargetValues = (conf['POSSIBLE_X_TARGET_VALUES'] || '').split(',')
+            const xTargetHeader = req.headers['x-target']
+
+            const xTarget = possibleXTargetValues.includes(xTargetHeader) ? xTargetHeader : 'other'
+
+            const isPost = method === 'post'
+
+            const isAdminApiUrl = url === '/admin/api'
+            const isApiUrl = url.startsWith('/api')
+            const isOidcUrl = url.startsWith('/oidc')
+            const isWellKnownUrl = url.startsWith('/.well-known')
+            const isHealthCheckUrl = url.startsWith(DEFAULT_HEALTHCHECK_URL)
+
+            /** @type {'api' | 'graphql' | 'oidc' | 'wellKnown' | 'healthCheck' | 'other'} */
+            let requestType = 'other'
+
+            if (isPost && isAdminApiUrl) {
+                requestType = 'graphql'
+            } else if (isApiUrl) {
+                requestType = 'api'
+            } else if (isOidcUrl) {
+                requestType = 'oidc'
+            } else if (isWellKnownUrl) {
+                requestType = 'wellKnown'
+            } else if (isHealthCheckUrl) {
+                requestType = 'healthCheck'
+            }
+
+            if (requestType) {
+                runtimeStats.activeRequestsIds.add(req.id)
+                runtimeStats.activeRequestsCountByType[requestType] = (runtimeStats.activeRequestsCountByType[requestType] || 0) + 1
+                runtimeStats.totalRequestsCount = (runtimeStats.totalRequestsCount || 0) + 1
+                runtimeStats.totalRequestsByTarget[xTarget] = (runtimeStats.totalRequestsByTarget[xTarget] || 0) + 1
+            }
+
+            res.on('close', () => {
+                if (requestType) {
+                    runtimeStats.activeRequestsIds.delete(req.id)
+                    runtimeStats.activeRequestsCountByType[requestType] = Math.max(0, runtimeStats.activeRequestsCountByType[requestType] - 1)
+                }
+            })
+        } catch (error) {
+            logger.error({ msg: 'runtimeStatsMiddleware error', error, data: { url: req.url, method: req.method } })
+        }
+
+        next()
+    })
+
+    app.get('/.well-known/runtime-stats', (req, res) => {
+        const token = req.query['token']
+        const accessToken = conf['RUNTIME_STATS_ACCESS_TOKEN']
+        if (!!accessToken && accessToken === token) {
+            res.json({
+                activeRequestsCount: runtimeStats.activeRequestsIds.size,
+                activeRequestsCountByType: runtimeStats.activeRequestsCountByType,
+                totalRequestsCount: runtimeStats.totalRequestsCount,
+                totalRequestsCountByTarget: runtimeStats.totalRequestsByTarget,
+            })
+        } else {
+            res.status(403).send()
+        }
+    })
+
     app.get('/.well-known/change-password', function (req, res) {
         res.redirect('/auth/forgot')
     })
diff --git a/packages/keystone/healthCheck.js b/packages/keystone/healthCheck.js
index 807068c0344..388a9f401aa 100644
--- a/packages/keystone/healthCheck.js
+++ b/packages/keystone/healthCheck.js
@@ -356,4 +356,5 @@ module.exports = {
     getCertificateHealthCheck,
     getIntegrationHealthCheck,
     STATUS_ENUM,
+    DEFAULT_HEALTHCHECK_URL,
 }


Reviews:
user: login: coderabbitai[bot]
body: **Actionable comments posted: 3**

<details>
<summary>🧹 Nitpick comments (1)</summary><blockquote>

<details>
<summary>apps/condo/index.js (1)</summary><blockquote>

`155-183`: **Consider adding rate limiting to the middleware**

The middleware tracks every request without any rate limiting or sampling, which could affect performance under high load.


Consider adding rate limiting or sampling logic to reduce the performance impact under high traffic. You could:
1. Sample only a percentage of requests
2. Skip tracking for certain paths (like static assets)
3. Implement rate limiting to control how frequently stats are updated

This would ensure the middleware has minimal performance impact on the application.

</blockquote></details>

</blockquote></details>

<details>
<summary>📜 Review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: CHILL**
**Plan: Pro**
**Cache: Disabled due to data retention organization setting**
**Knowledge Base: Disabled due to data retention organization setting**


<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between a0b1c96335494c606dfb1d78f1d9a308880beb37 and 5e2e1fc084d1695f121cc7c151b161ad31e7dd61.

</details>

<details>
<summary>📒 Files selected for processing (1)</summary>

* `apps/condo/index.js` (1 hunks)

</details>

<details>
<summary>⏰ Context from checks skipped due to timeout of 90000ms (5)</summary>

* GitHub Check: Build open-source part (ubuntu-22.04, 16.x, 3.13)
* GitHub Check: Build open-source part (windows-latest, 16.x, 3.13)
* GitHub Check: Semgrep vulnerabilities check
* GitHub Check: Check dependencies integrity (16.x)
* GitHub Check: Lint source code (16.x)

</details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-16T04:42:21Z
user: login: SavelevMatthew
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-16T05:01:40Z
user: login: SavelevMatthew
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-16T05:03:33Z
user: login: SavelevMatthew
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-16T05:09:34Z
user: login: SavelevMatthew
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-16T05:11:09Z
user: login: AleX83Xpert
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-16T05:12:58Z
user: login: SavelevMatthew
body: Why not just simple shape like this? Why all IDs needed?
```
{
  "oidc": 2,
  "graphql": 10,
  "other": 3,
  "total": 15
}
```
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-16T05:13:47Z
user: login: SavelevMatthew
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-16T05:16:20Z
user: login: pahaz
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-16T05:44:39Z
user: login: pahaz
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-16T05:50:08Z
user: login: AleX83Xpert
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-16T05:57:17Z
user: login: AleX83Xpert
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-16T06:01:04Z
user: login: AleX83Xpert
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-16T06:02:19Z
user: login: pahaz
state: APPROVED
author_association: MEMBER
submitted_at: 2025-05-16T06:04:50Z
user: login: SavelevMatthew
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-16T06:15:44Z
user: login: SavelevMatthew
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-16T06:17:37Z
user: login: AleX83Xpert
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-16T06:34:53Z
user: login: AleX83Xpert
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-16T06:35:27Z
user: login: coderabbitai[bot]
body: **Actionable comments posted: 1**

<details>
<summary>♻️ Duplicate comments (5)</summary><blockquote>

<details>
<summary>apps/condo/index.js (5)</summary><blockquote>

`162-167`: **Consider using path-based matching for API URLs instead of raw URL comparison**

Using an exact equality check (`url === '/admin/api'`) might not match requests with query parameters like `/admin/api?query=...`. Consider using a path-based approach or checking if the URL starts with the path instead.


```diff
-const isAdminApiUrl = url === '/admin/api'
+const isAdminApiUrl = url.startsWith('/admin/api') && (url === '/admin/api' || url.includes('?'))
```

This aligns with the previous comment from SavelevMatthew about parsing exact paths.

---

`147-154`: **Consider the multi-instance deployment implications of in-memory runtime stats**

The `runtimeStats` object is stored in memory, which means:
1. Data is lost on server restart
2. In a multi-instance deployment, each instance will maintain its own separate stats
3. There's no upper bound on the size of the `activeRequestsIds` Set

If you need consistent stats across restarts or multiple instances, consider using a shared cache like Redis. If the current approach is sufficient for your use case, add a comment explaining this limitation.

---

`183-186`: _🛠️ Refactor suggestion_

**Remove redundant check and add req.id validation**

The `if (requestType)` check is unnecessary since `requestType` is always initialized to 'other' and never set to a falsy value. However, you should validate that `req.id` exists before using it to prevent potential runtime errors.



```diff
-if (requestType) {
+if (req.id) {
    runtimeStats.activeRequestsIds.add(req.id)
    runtimeStats.activeRequestsCountByType[requestType] = (runtimeStats.activeRequestsCountByType[requestType] || 0) + 1
+} else {
+    console.warn('Request ID is missing, cannot track request in runtime stats')
}
```

---

`189-192`: _🛠️ Refactor suggestion_

**Apply the same req.id validation in the close handler**

Similar to the previous comment, the close handler should also validate that `req.id` exists before using it.



```diff
res.on('close', () => {
-    if (requestType) {
+    if (req.id) {
        runtimeStats.activeRequestsIds.delete(req.id)
        runtimeStats.activeRequestsCountByType[requestType] = Math.max(0, runtimeStats.activeRequestsCountByType[requestType] - 1)
    }
})
```

---

`198-203`: _🛠️ Refactor suggestion_

**Add authentication to the runtime stats endpoint**

The runtime stats endpoint is publicly accessible without any authentication. This could expose sensitive information about server activity. Consider adding authentication middleware to restrict access to admin users only.



```diff
-app.get('/.well-known/runtime-stats', (req, res) => {
+app.get('/.well-known/runtime-stats', 
+// TODO: add or reuse an authentication middleware here
+(req, res, next) => {
+    if (!req.user?.isAdmin) {
+        return res.status(403).send('Forbidden')
+    }
+    next()
+},
+(req, res) => {
    res.json({
        activeRequestsCount: runtimeStats.activeRequestsIds.size,
        activeRequestsCountByType: runtimeStats.activeRequestsCountByType,
    })
})
```

</blockquote></details>

</blockquote></details>

<details>
<summary>📜 Review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: CHILL**
**Plan: Pro**
**Cache: Disabled due to data retention organization setting**
**Knowledge Base: Disabled due to data retention organization setting**


<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 5e2e1fc084d1695f121cc7c151b161ad31e7dd61 and 085318d6c79992e351c738df1090a05029f4429b.

</details>

<details>
<summary>📒 Files selected for processing (1)</summary>

* `apps/condo/index.js` (2 hunks)

</details>

<details>
<summary>🧰 Additional context used</summary>

<details>
<summary>🧬 Code Graph Analysis (1)</summary>

<details>
<summary>apps/condo/index.js (1)</summary><blockquote>

<details>
<summary>packages/keystone/healthCheck.js (1)</summary>

* `DEFAULT_HEALTHCHECK_URL` (95-95)

</details>

</blockquote></details>

</details>

</details>

<details>
<summary>⏰ Context from checks skipped due to timeout of 90000ms (5)</summary>

* GitHub Check: Build open-source part (windows-latest, 16.x, 3.13)
* GitHub Check: Build open-source part (ubuntu-22.04, 16.x, 3.13)
* GitHub Check: Semgrep vulnerabilities check
* GitHub Check: Check dependencies integrity (16.x)
* GitHub Check: Lint source code (16.x)

</details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-16T06:36:53Z
user: login: AleX83Xpert
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-16T06:37:15Z
user: login: SavelevMatthew
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-16T06:55:46Z
user: login: AleX83Xpert
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-16T07:24:03Z
user: login: SavelevMatthew
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-16T11:59:16Z
user: login: SavelevMatthew
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-16T12:00:14Z
user: login: AleX83Xpert
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-16T12:01:25Z
user: login: SavelevMatthew
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-16T12:01:51Z
user: login: AleX83Xpert
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-16T12:02:21Z
user: login: SavelevMatthew
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-16T12:03:35Z
user: login: AleX83Xpert
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-16T12:13:11Z
user: login: AleX83Xpert
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-16T12:20:59Z
user: login: coderabbitai[bot]
body: **Actionable comments posted: 1**

<details>
<summary>♻️ Duplicate comments (1)</summary><blockquote>

<details>
<summary>apps/condo/index.js (1)</summary><blockquote>

`212-217`: _🛠️ Refactor suggestion_

**Inconsistent conditions between request tracking and cleanup**

The request response handler should use the same condition as when adding the request to ensure proper cleanup.


```diff
res.on('close', () => {
-    if (requestType) {
+    if (req.id) {
        runtimeStats.activeRequestsIds.delete(req.id)
        runtimeStats.activeRequestsCountByType[requestType] = Math.max(0, runtimeStats.activeRequestsCountByType[requestType] - 1)
    }
})
```

</blockquote></details>

</blockquote></details>

<details>
<summary>🧹 Nitpick comments (4)</summary><blockquote>

<details>
<summary>apps/condo/index.js (4)</summary><blockquote>

`149-161`: **Consider initialization of the `totalRequestsByTarget` object with known values**

While you've correctly initialized all types in `activeRequestsCountByType`, the `totalRequestsByTarget` object is initialized as an empty object. To maintain consistency and prevent potential issues when accessing properties, consider initializing it with all known target values from your `possibleXTargetValues` array.


```diff
const runtimeStats = {
    activeRequestsIds: new Set(),
    activeRequestsCountByType: {
        graphql: 0,
        api: 0,
        oidc: 0,
        wellKnown: 0,
        healthCheck: 0,
        other: 0,
    },
    totalRequestsCount: 0,
-    totalRequestsByTarget: {},
+    totalRequestsByTarget: {
+        billing: 0,
+        'resident-app': 0,
+        'technique-app': 0,
+        'cc-app': 0,
+        'condo-restapi-app': 0,
+        'condo-app': 0,
+        smarthome: 0,
+        other: 0,
+    },
}
```

---

`179-180`: **Add comment explaining the 'other' fallback value for x-target header**

Add a comment to explain why a fallback value of 'other' is used for the x-target header when it's not in the allowed list.


```diff
const xTargetHeader = req.headers['x-target']

-const xTarget = possibleXTargetValues.includes(xTargetHeader) ? xTargetHeader : 'other'
+// Use 'other' category for requests with missing or invalid x-target header
+const xTarget = possibleXTargetValues.includes(xTargetHeader) ? xTargetHeader : 'other'
```

---

`207-209`: **Redundant null checks in counter increments**

Since you've properly initialized the counter objects, the `|| 0` fallbacks are unnecessary:


```diff
runtimeStats.activeRequestsIds.add(req.id)
-runtimeStats.activeRequestsCountByType[requestType] = (runtimeStats.activeRequestsCountByType[requestType] || 0) + 1
-runtimeStats.totalRequestsCount = (runtimeStats.totalRequestsCount || 0) + 1
+runtimeStats.activeRequestsCountByType[requestType] += 1
+runtimeStats.totalRequestsCount += 1
runtimeStats.totalRequestsByTarget[xTarget] = (runtimeStats.totalRequestsByTarget[xTarget] || 0) + 1
```

Keep the null check for `totalRequestsByTarget` if you decide not to pre-initialize that object as suggested earlier.

---

`190-203`: **Extract request type detection into a separate function**

The request type determination logic is complex and would be more maintainable if extracted into a separate function.


```diff
+/**
+ * Determines the type of request based on URL and method
+ * @param {string} url - Request URL path
+ * @param {string} method - HTTP method
+ * @returns {'api' | 'graphql' | 'oidc' | 'wellKnown' | 'healthCheck' | 'other'} The request type
+ */
+function getRequestType(url, method) {
+    const isPost = method === 'post'
+    const isAdminApiUrl = url === '/admin/api'
+    const isApiUrl = url.startsWith('/api')
+    const isOidcUrl = url.startsWith('/oidc')
+    const isWellKnownUrl = url.startsWith('/.well-known')
+    const isHealthCheckUrl = url.startsWith(DEFAULT_HEALTHCHECK_URL)
+    
+    if (isPost && isAdminApiUrl) return 'graphql'
+    if (isApiUrl) return 'api'
+    if (isOidcUrl) return 'oidc'
+    if (isWellKnownUrl) return 'wellKnown'
+    if (isHealthCheckUrl) return 'healthCheck'
+    return 'other'
+}

app.use(function runtimeStatsMiddleware (req, res, next) {
    try {
        const url = new URL(`${conf['SERVER_URL']}${req.url}`).pathname
        const method = (req.method || 'get').toLowerCase()

        // According to ADR35
        const possibleXTargetValues = [
            'billing',
            'resident-app',
            'technique-app',
            'cc-app',
            'condo-restapi-app',
            'condo-app',
            'smarthome',
        ]
        const xTargetHeader = req.headers['x-target']

        const xTarget = possibleXTargetValues.includes(xTargetHeader) ? xTargetHeader : 'other'

-        const isPost = method === 'post'
-
-        const isAdminApiUrl = url === '/admin/api'
-        const isApiUrl = url.startsWith('/api')
-        const isOidcUrl = url.startsWith('/oidc')
-        const isWellKnownUrl = url.startsWith('/.well-known')
-        const isHealthCheckUrl = url.startsWith(DEFAULT_HEALTHCHECK_URL)
-
-        /** @type {'api' | 'graphql' | 'oidc' | 'wellKnown' | 'healthCheck' | 'other'} */
-        let requestType = 'other'
-
-        if (isPost && isAdminApiUrl) {
-            requestType = 'graphql'
-        } else if (isApiUrl) {
-            requestType = 'api'
-        } else if (isOidcUrl) {
-            requestType = 'oidc'
-        } else if (isWellKnownUrl) {
-            requestType = 'wellKnown'
-        } else if (isHealthCheckUrl) {
-            requestType = 'healthCheck'
-        }
+        const requestType = getRequestType(url, method)
```

</blockquote></details>

</blockquote></details>

<details>
<summary>📜 Review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: CHILL**
**Plan: Pro**
**Cache: Disabled due to data retention organization setting**
**Knowledge Base: Disabled due to data retention organization setting**


<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between e0258c425469254fad5d40bc275e90bacced8c32 and 10dbef1c56936f2622f70d2281ee1c220ec55d68.

</details>

<details>
<summary>📒 Files selected for processing (3)</summary>

* `.helm` (1 hunks)
* `apps/condo/index.js` (3 hunks)
* `packages/keystone/healthCheck.js` (1 hunks)

</details>

<details>
<summary>🚧 Files skipped from review as they are similar to previous changes (2)</summary>

* packages/keystone/healthCheck.js
* .helm

</details>

<details>
<summary>🧰 Additional context used</summary>

<details>
<summary>🧬 Code Graph Analysis (1)</summary>

<details>
<summary>apps/condo/index.js (1)</summary><blockquote>

<details>
<summary>packages/keystone/healthCheck.js (4)</summary>

* `require` (84-84)
* `require` (91-91)
* `require` (93-93)
* `DEFAULT_HEALTHCHECK_URL` (95-95)

</details>

</blockquote></details>

</details>

</details>

<details>
<summary>⏰ Context from checks skipped due to timeout of 90000ms (5)</summary>

* GitHub Check: Build open-source part (windows-latest, 16.x, 3.13)
* GitHub Check: Build open-source part (ubuntu-22.04, 16.x, 3.13)
* GitHub Check: Semgrep vulnerabilities check
* GitHub Check: Check dependencies integrity (16.x)
* GitHub Check: Build Docker Image

</details>

<details>
<summary>🔇 Additional comments (1)</summary><blockquote>

<details>
<summary>apps/condo/index.js (1)</summary>

`225-238`: <details>
<summary>❓ Verification inconclusive</summary>

**Enhance runtime stats endpoint security and input validation**

The current implementation only uses a token for authentication. Consider adding more robust security measures and proper input validation:


```diff
app.get('/.well-known/runtime-stats', (req, res) => {
    const token = req.query['token']
    const accessToken = conf['RUNTIME_STATS_ACCESS_TOKEN']
-    if (!!accessToken && accessToken === token) {
+    
+    // Validate token is provided and matches configured token
+    if (!accessToken || !token) {
+        logger.warn({ msg: 'Missing runtime stats access token' })
+        return res.status(403).send('Forbidden')
+    }
+    
+    if (accessToken === token) {
        res.json({
            activeRequestsCount: runtimeStats.activeRequestsIds.size,
            activeRequestsCountByType: runtimeStats.activeRequestsCountByType,
            totalRequestsCount: runtimeStats.totalRequestsCount,
            totalRequestsCountByTarget: runtimeStats.totalRequestsByTarget,
        })
    } else {
-        res.status(403).send()
+        logger.warn({ msg: 'Invalid runtime stats access token' })
+        res.status(403).send('Forbidden')
    }
})
```


Consider implementing a more robust authentication mechanism such as:
- Restricting access to specific IP addresses
- Adding rate limiting to prevent brute force attacks
- Implementing token expiration and rotation

---

🏁 Script executed:

```shell
#!/bin/bash
# Search for examples of similar security patterns in the codebase
echo "Searching for security patterns for endpoints..."
rg -A 5 -B 5 "(app\.get|app\.post).*?token" --glob "*.js" | grep -v "runtime-stats"
```

Length of output: 190

---



</details>

**Enhance runtime-stats endpoint security and input validation**

The `/​.well-known/runtime-stats` route should explicitly check for a provided token, log missing/invalid attempts, and return a clear 403 response. For stronger protection, consider IP whitelisting, rate limiting, and token expiration/rotation.

Suggested diff:
```diff
 app.get('/.well-known/runtime-stats', (req, res) => {
-    const token = req.query['token']
-    const accessToken = conf['RUNTIME_STATS_ACCESS_TOKEN']
-    if (!!accessToken && accessToken === token) {
+    const token = req.query.token
+    const accessToken = conf.RUNTIME_STATS_ACCESS_TOKEN
+
+    // Reject if no token configured or none provided
+    if (!accessToken || !token) {
+        logger.warn({ msg: 'Missing runtime-stats access token' })
+        return res.status(403).send('Forbidden')
+    }
+
+    // Validate token match
+    if (accessToken === token) {
         res.json({
             activeRequestsCount: runtimeStats.activeRequestsIds.size,
             activeRequestsCountByType: runtimeStats.activeRequestsCountByType,
             totalRequestsCount: runtimeStats.totalRequestsCount,
             totalRequestsCountByTarget: runtimeStats.totalRequestsByTarget,
         })
     } else {
-        res.status(403).send()
+        logger.warn({ msg: 'Invalid runtime-stats access token' })
+        res.status(403).send('Forbidden')
     }
 })
```

Key recommendations:
- Add IP address restrictions for trusted callers.
- Introduce rate limiting to mitigate brute-force attempts.
- Implement token expiration and automatic rotation.

I couldn’t find other token-protected endpoints in the codebase—please verify consistency and ensure these security enhancements are applied uniformly.

</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-16T13:34:12Z
user: login: SavelevMatthew
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-16T14:30:58Z
user: login: AleX83Xpert
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-16T15:32:28Z
user: login: SavelevMatthew
state: APPROVED
author_association: MEMBER
submitted_at: 2025-05-16T16:00:45Z
user: login: reactpro
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-16T16:01:57Z
user: login: dlastskii
state: APPROVED
author_association: NONE
submitted_at: 2025-05-16T16:02:46Z

Review comments:
diff_hunk: @@ -143,6 +143,53 @@ const apps = () => {
 
 /** @type {(app: import('express').Application) => void} */
 const extendExpressApp = (app) => {
+    const runtimeStats = {
+        activeRequestsIds: new Set(),
+        activeRequestsCountByType: {
+            graphql: 0,
+            oidc: 0,
+            other: 0,
+        },
+    }
+
+    app.use(function runtimeStatsMiddleware (req, res, next) {
+        const url = req.url
+        const method = (req.method || 'get').toLowerCase()
+
+        const isPost = method === 'post'
+
+        const isAdminApi = url.startsWith('/admin/api')
+        const isOidc = url.startsWith('/oidc')
+
+        /** @type {'graphql' | 'oidc' | 'other'} */
+        let requestType = 'other'
+
+        if (isPost && isAdminApi) requestType = 'graphql'
+        if (isOidc) requestType = 'oidc'
+
+        if (requestType) {
+            runtimeStats.activeRequestsIds.add(req.id)
+            runtimeStats.activeRequestsCountByType[requestType] = (runtimeStats.activeRequestsCountByType[requestType] || 0) + 1
+        }
+
+        res.on('close', () => {
+            if (requestType) {
+                runtimeStats.activeRequestsIds.delete(req.id)
+                runtimeStats.activeRequestsCountByType[requestType] = Math.max(0, runtimeStats.activeRequestsCountByType[requestType] - 1)
+            }
+        })
+
+        next()
+    })
path: apps/condo/index.js
user: login: coderabbitai[bot]
body: _🛠️ Refactor suggestion_

**Simplify conditions and add req.id validation**

The middleware has a few issues that should be addressed:

1. The `if (requestType)` check is unnecessary since `requestType` is always initialized to 'other' and never set to a falsy value
2. There's no validation to ensure `req.id` exists before using it


```diff
app.use(function runtimeStatsMiddleware (req, res, next) {
    const url = req.url
    const method = (req.method || 'get').toLowerCase()

    const isPost = method === 'post'

    const isAdminApi = url.startsWith('/admin/api')
    const isOidc = url.startsWith('/oidc')

    /** @type {'graphql' | 'oidc' | 'other'} */
    let requestType = 'other'

    if (isPost && isAdminApi) requestType = 'graphql'
    if (isOidc) requestType = 'oidc'

-    if (requestType) {
+    if (req.id) {
        runtimeStats.activeRequestsIds.add(req.id)
        runtimeStats.activeRequestsCountByType[requestType] = (runtimeStats.activeRequestsCountByType[requestType] || 0) + 1
+    } else {
+        console.warn('Request ID is missing, cannot track request in runtime stats')
    }

    res.on('close', () => {
-        if (requestType) {
+        if (req.id) {
            runtimeStats.activeRequestsIds.delete(req.id)
            runtimeStats.activeRequestsCountByType[requestType] = Math.max(0, runtimeStats.activeRequestsCountByType[requestType] - 1)
        }
    })

    next()
})
```


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

```suggestion
    app.use(function runtimeStatsMiddleware (req, res, next) {
        const url = req.url
        const method = (req.method || 'get').toLowerCase()

        const isPost = method === 'post'

        const isAdminApi = url.startsWith('/admin/api')
        const isOidc = url.startsWith('/oidc')

        /** @type {'graphql' | 'oidc' | 'other'} */
        let requestType = 'other'

        if (isPost && isAdminApi) requestType = 'graphql'
        if (isOidc) requestType = 'oidc'

        if (req.id) {
            runtimeStats.activeRequestsIds.add(req.id)
            runtimeStats.activeRequestsCountByType[requestType] = (runtimeStats.activeRequestsCountByType[requestType] || 0) + 1
        } else {
            console.warn('Request ID is missing, cannot track request in runtime stats')
        }

        res.on('close', () => {
            if (req.id) {
                runtimeStats.activeRequestsIds.delete(req.id)
                runtimeStats.activeRequestsCountByType[requestType] = Math.max(0, runtimeStats.activeRequestsCountByType[requestType] - 1)
            }
        })

        next()
    })
```

</details>

<!-- suggestion_end -->

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
In apps/condo/index.js between lines 155 and 183, remove the redundant checks
for requestType since it is always a non-falsy string. Add a validation to
ensure req.id exists before adding or deleting it from
runtimeStats.activeRequestsIds to prevent potential runtime errors. Adjust the
logic to only update runtimeStats if req.id is present.
```

</details>

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-05-16T04:42:20Z
author_association: CONTRIBUTOR
diff_hunk: @@ -143,6 +143,53 @@ const apps = () => {
 
 /** @type {(app: import('express').Application) => void} */
 const extendExpressApp = (app) => {
+    const runtimeStats = {
+        activeRequestsIds: new Set(),
+        activeRequestsCountByType: {
+            graphql: 0,
+            oidc: 0,
+            other: 0,
+        },
+    }
+
+    app.use(function runtimeStatsMiddleware (req, res, next) {
+        const url = req.url
+        const method = (req.method || 'get').toLowerCase()
+
+        const isPost = method === 'post'
+
+        const isAdminApi = url.startsWith('/admin/api')
+        const isOidc = url.startsWith('/oidc')
+
+        /** @type {'graphql' | 'oidc' | 'other'} */
+        let requestType = 'other'
+
+        if (isPost && isAdminApi) requestType = 'graphql'
+        if (isOidc) requestType = 'oidc'
+
+        if (requestType) {
+            runtimeStats.activeRequestsIds.add(req.id)
+            runtimeStats.activeRequestsCountByType[requestType] = (runtimeStats.activeRequestsCountByType[requestType] || 0) + 1
+        }
+
+        res.on('close', () => {
+            if (requestType) {
+                runtimeStats.activeRequestsIds.delete(req.id)
+                runtimeStats.activeRequestsCountByType[requestType] = Math.max(0, runtimeStats.activeRequestsCountByType[requestType] - 1)
+            }
+        })
+
+        next()
+    })
+
+    app.get('/.well-known/runtime-stats', (req, res) => {
+        res.json({
+            activeRequestsIds: Array.from(runtimeStats.activeRequestsIds.keys()),
+            activeRequestsCount: runtimeStats.activeRequestsIds.size,
+            activeRequestsCountByType: runtimeStats.activeRequestsCountByType,
+        })
+    })
path: apps/condo/index.js
user: login: coderabbitai[bot]
body: _💡 Verification agent_

<details>
<summary>🧩 Analysis chain</summary>

**Add authentication to the runtime stats endpoint and fix Set conversion**

The current implementation has two issues:

1. The runtime stats endpoint is publicly accessible without authentication, which could expose sensitive information about server activity
2. `Array.from(runtimeStats.activeRequestsIds.keys())` is incorrect for Sets as they don't have separate keys and values like Maps


```diff
-app.get('/.well-known/runtime-stats', (req, res) => {
+app.get('/.well-known/runtime-stats', (req, res) => {
+    // Consider adding authentication here
+    // Example: if (!req.user || !req.user.isAdmin) return res.status(403).send('Forbidden')
+
    res.json({
-        activeRequestsIds: Array.from(runtimeStats.activeRequestsIds.keys()),
+        activeRequestsIds: Array.from(runtimeStats.activeRequestsIds),
        activeRequestsCount: runtimeStats.activeRequestsIds.size,
        activeRequestsCountByType: runtimeStats.activeRequestsCountByType,
    })
})
```


Let's check if the application already has an authentication middleware that could be leveraged:

---

🏁 Script executed:

```shell
#!/bin/bash
# Look for auth middleware patterns in the codebase
echo "Searching for authentication middleware patterns..."
rg -A 3 -B 3 "app\.(get|use)\([^)]+isAuth" --glob "*.js"
rg -A 3 -B 3 "req\.(user|isAuthenticated)" --glob "*.js"
```

Length of output: 9078

---

I’d like to inspect the surrounding code in apps/condo/index.js to confirm whether any authentication middleware is applied before this route.

---

🏁 Script executed:

```shell
#!/bin/bash
set -e

echo "Locate runtime-stats endpoint:"
rg -n "/\\.well-known/runtime-stats" apps/condo/index.js

echo
echo "Show lines 160–220 of apps/condo/index.js for context:"
sed -n '160,220p' apps/condo/index.js
```

Length of output: 2500

---



</details>

**Secure and simplify the runtime-stats endpoint**

Add authentication to restrict access to admin users, and simplify the Set-to-array conversion:

```diff
-app.get('/.well-known/runtime-stats', (req, res) => {
+app.get(
+  '/.well-known/runtime-stats',
+  // TODO: add or reuse an authentication middleware here
+  (req, res, next) => {
+    if (!req.user?.isAdmin) {
+      return res.status(403).send('Forbidden')
+    }
+    next()
+  },
+  (req, res) => {
     res.json({
-      activeRequestsIds: Array.from(runtimeStats.activeRequestsIds.keys()),
+      activeRequestsIds: Array.from(runtimeStats.activeRequestsIds),
       activeRequestsCount: runtimeStats.activeRequestsIds.size,
       activeRequestsCountByType: runtimeStats.activeRequestsCountByType,
     })
```

- Ensure `req.user.isAdmin` (or your chosen admin flag) is set by your auth layer.
- You can also extract this into a shared `requireAdmin` middleware for reuse.



<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

```suggestion
    app.get(
      '/.well-known/runtime-stats',
      // TODO: add or reuse an authentication middleware here
      (req, res, next) => {
        if (!req.user?.isAdmin) {
          return res.status(403).send('Forbidden')
        }
        next()
      },
      (req, res) => {
        res.json({
          activeRequestsIds: Array.from(runtimeStats.activeRequestsIds),
          activeRequestsCount: runtimeStats.activeRequestsIds.size,
          activeRequestsCountByType: runtimeStats.activeRequestsCountByType,
        })
      }
    )
```

</details>

<!-- suggestion_end -->

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
In apps/condo/index.js around lines 185 to 191, the runtime stats endpoint is
publicly accessible and exposes sensitive data, and the conversion of the Set to
an array is incorrect. Fix this by adding authentication middleware that checks
if req.user.isAdmin is true before allowing access to the endpoint, restricting
it to admin users only. Also, replace
Array.from(runtimeStats.activeRequestsIds.keys()) with
Array.from(runtimeStats.activeRequestsIds) to correctly convert the Set to an
array. Optionally, create a reusable requireAdmin middleware to enforce this
check consistently.
```

</details>

<!-- This is an auto-generated comment by CodeRabbit -->

✅ Addressed in commits 83c0dbd to 10dbef1
created_at: 2025-05-16T04:42:20Z
author_association: CONTRIBUTOR
diff_hunk: @@ -143,6 +143,53 @@ const apps = () => {
 
 /** @type {(app: import('express').Application) => void} */
 const extendExpressApp = (app) => {
+    const runtimeStats = {
+        activeRequestsIds: new Set(),
+        activeRequestsCountByType: {
+            graphql: 0,
+            oidc: 0,
+            other: 0,
+        },
+    }
+
+    app.use(function runtimeStatsMiddleware (req, res, next) {
+        const url = req.url
+        const method = (req.method || 'get').toLowerCase()
+
+        const isPost = method === 'post'
+
+        const isAdminApi = url.startsWith('/admin/api')
path: apps/condo/index.js
user: login: SavelevMatthew
body: ```suggestion
        const isGraphql = url.startsWith('/admin/api')
```
created_at: 2025-05-16T05:01:39Z
author_association: MEMBER
diff_hunk: @@ -143,6 +143,53 @@ const apps = () => {
 
 /** @type {(app: import('express').Application) => void} */
 const extendExpressApp = (app) => {
+    const runtimeStats = {
+        activeRequestsIds: new Set(),
+        activeRequestsCountByType: {
+            graphql: 0,
+            oidc: 0,
+            other: 0,
+        },
+    }
+
+    app.use(function runtimeStatsMiddleware (req, res, next) {
+        const url = req.url
+        const method = (req.method || 'get').toLowerCase()
+
+        const isPost = method === 'post'
+
+        const isAdminApi = url.startsWith('/admin/api')
path: apps/condo/index.js
user: login: SavelevMatthew
body: Should we also parse exact path here? Like:
```
const url = new URL(req.url)

 const isGraphql = url.pathname === '/admin/api' 
```
created_at: 2025-05-16T05:03:33Z
author_association: MEMBER
diff_hunk: @@ -143,6 +143,53 @@ const apps = () => {
 
 /** @type {(app: import('express').Application) => void} */
 const extendExpressApp = (app) => {
+    const runtimeStats = {
+        activeRequestsIds: new Set(),
+        activeRequestsCountByType: {
+            graphql: 0,
+            oidc: 0,
+            other: 0,
+        },
+    }
+
+    app.use(function runtimeStatsMiddleware (req, res, next) {
+        const url = req.url
+        const method = (req.method || 'get').toLowerCase()
+
+        const isPost = method === 'post'
+
+        const isAdminApi = url.startsWith('/admin/api')
+        const isOidc = url.startsWith('/oidc')
+
+        /** @type {'graphql' | 'oidc' | 'other'} */
+        let requestType = 'other'
+
+        if (isPost && isAdminApi) requestType = 'graphql'
+        if (isOidc) requestType = 'oidc'
+
+        if (requestType) {
+            runtimeStats.activeRequestsIds.add(req.id)
+            runtimeStats.activeRequestsCountByType[requestType] = (runtimeStats.activeRequestsCountByType[requestType] || 0) + 1
+        }
+
+        res.on('close', () => {
+            if (requestType) {
+                runtimeStats.activeRequestsIds.delete(req.id)
+                runtimeStats.activeRequestsCountByType[requestType] = Math.max(0, runtimeStats.activeRequestsCountByType[requestType] - 1)
+            }
+        })
+
+        next()
+    })
+
+    app.get('/.well-known/runtime-stats', (req, res) => {
+        res.json({
+            activeRequestsIds: Array.from(runtimeStats.activeRequestsIds.keys()),
path: apps/condo/index.js
user: login: SavelevMatthew
body: Why do you need all ids here?
created_at: 2025-05-16T05:09:34Z
author_association: MEMBER
diff_hunk: @@ -143,6 +143,53 @@ const apps = () => {
 
 /** @type {(app: import('express').Application) => void} */
 const extendExpressApp = (app) => {
+    const runtimeStats = {
+        activeRequestsIds: new Set(),
+        activeRequestsCountByType: {
+            graphql: 0,
+            oidc: 0,
+            other: 0,
+        },
+    }
+
+    app.use(function runtimeStatsMiddleware (req, res, next) {
+        const url = req.url
+        const method = (req.method || 'get').toLowerCase()
+
+        const isPost = method === 'post'
+
+        const isAdminApi = url.startsWith('/admin/api')
+        const isOidc = url.startsWith('/oidc')
+
+        /** @type {'graphql' | 'oidc' | 'other'} */
+        let requestType = 'other'
+
+        if (isPost && isAdminApi) requestType = 'graphql'
+        if (isOidc) requestType = 'oidc'
+
+        if (requestType) {
+            runtimeStats.activeRequestsIds.add(req.id)
+            runtimeStats.activeRequestsCountByType[requestType] = (runtimeStats.activeRequestsCountByType[requestType] || 0) + 1
+        }
+
+        res.on('close', () => {
+            if (requestType) {
+                runtimeStats.activeRequestsIds.delete(req.id)
+                runtimeStats.activeRequestsCountByType[requestType] = Math.max(0, runtimeStats.activeRequestsCountByType[requestType] - 1)
+            }
+        })
+
+        next()
+    })
+
+    app.get('/.well-known/runtime-stats', (req, res) => {
+        res.json({
+            activeRequestsIds: Array.from(runtimeStats.activeRequestsIds.keys()),
+            activeRequestsCount: runtimeStats.activeRequestsIds.size,
path: apps/condo/index.js
user: login: SavelevMatthew
body: is req.id always defined? Otherwise it can lead to incorrect counts
created_at: 2025-05-16T05:11:09Z
author_association: MEMBER
diff_hunk: @@ -143,6 +143,53 @@ const apps = () => {
 
 /** @type {(app: import('express').Application) => void} */
 const extendExpressApp = (app) => {
+    const runtimeStats = {
+        activeRequestsIds: new Set(),
+        activeRequestsCountByType: {
+            graphql: 0,
+            oidc: 0,
+            other: 0,
+        },
+    }
+
+    app.use(function runtimeStatsMiddleware (req, res, next) {
+        const url = req.url
+        const method = (req.method || 'get').toLowerCase()
+
+        const isPost = method === 'post'
+
+        const isAdminApi = url.startsWith('/admin/api')
+        const isOidc = url.startsWith('/oidc')
+
+        /** @type {'graphql' | 'oidc' | 'other'} */
+        let requestType = 'other'
+
+        if (isPost && isAdminApi) requestType = 'graphql'
+        if (isOidc) requestType = 'oidc'
+
+        if (requestType) {
+            runtimeStats.activeRequestsIds.add(req.id)
+            runtimeStats.activeRequestsCountByType[requestType] = (runtimeStats.activeRequestsCountByType[requestType] || 0) + 1
+        }
+
+        res.on('close', () => {
+            if (requestType) {
+                runtimeStats.activeRequestsIds.delete(req.id)
+                runtimeStats.activeRequestsCountByType[requestType] = Math.max(0, runtimeStats.activeRequestsCountByType[requestType] - 1)
+            }
+        })
+
+        next()
+    })
+
+    app.get('/.well-known/runtime-stats', (req, res) => {
+        res.json({
+            activeRequestsIds: Array.from(runtimeStats.activeRequestsIds.keys()),
path: apps/condo/index.js
user: login: AleX83Xpert
body: Why not. Looks useful for investigations.
created_at: 2025-05-16T05:12:58Z
author_association: MEMBER
diff_hunk: @@ -143,6 +143,53 @@ const apps = () => {
 
 /** @type {(app: import('express').Application) => void} */
 const extendExpressApp = (app) => {
+    const runtimeStats = {
+        activeRequestsIds: new Set(),
+        activeRequestsCountByType: {
+            graphql: 0,
+            oidc: 0,
+            other: 0,
+        },
+    }
+
+    app.use(function runtimeStatsMiddleware (req, res, next) {
+        const url = req.url
+        const method = (req.method || 'get').toLowerCase()
+
+        const isPost = method === 'post'
+
+        const isAdminApi = url.startsWith('/admin/api')
+        const isOidc = url.startsWith('/oidc')
+
+        /** @type {'graphql' | 'oidc' | 'other'} */
+        let requestType = 'other'
+
+        if (isPost && isAdminApi) requestType = 'graphql'
+        if (isOidc) requestType = 'oidc'
+
+        if (requestType) {
+            runtimeStats.activeRequestsIds.add(req.id)
+            runtimeStats.activeRequestsCountByType[requestType] = (runtimeStats.activeRequestsCountByType[requestType] || 0) + 1
+        }
+
+        res.on('close', () => {
+            if (requestType) {
+                runtimeStats.activeRequestsIds.delete(req.id)
+                runtimeStats.activeRequestsCountByType[requestType] = Math.max(0, runtimeStats.activeRequestsCountByType[requestType] - 1)
+            }
+        })
+
+        next()
+    })
+
+    app.get('/.well-known/runtime-stats', (req, res) => {
+        res.json({
+            activeRequestsIds: Array.from(runtimeStats.activeRequestsIds.keys()),
path: apps/condo/index.js
user: login: SavelevMatthew
body: Who should use it? I have no real scenario on my mind, since you're not logging it anywhere. And you will not investigate anything  manually, since its expiring like each 200 ms?
created_at: 2025-05-16T05:16:20Z
author_association: MEMBER
diff_hunk: @@ -143,6 +143,53 @@ const apps = () => {
 
 /** @type {(app: import('express').Application) => void} */
 const extendExpressApp = (app) => {
+    const runtimeStats = {
+        activeRequestsIds: new Set(),
+        activeRequestsCountByType: {
+            graphql: 0,
+            oidc: 0,
+            other: 0,
+        },
+    }
+
+    app.use(function runtimeStatsMiddleware (req, res, next) {
+        const url = req.url
+        const method = (req.method || 'get').toLowerCase()
+
+        const isPost = method === 'post'
+
+        const isAdminApi = url.startsWith('/admin/api')
+        const isOidc = url.startsWith('/oidc')
+
+        /** @type {'graphql' | 'oidc' | 'other'} */
+        let requestType = 'other'
+
+        if (isPost && isAdminApi) requestType = 'graphql'
+        if (isOidc) requestType = 'oidc'
path: apps/condo/index.js
user: login: pahaz
body: Add “well-known” group and “health-check” group
created_at: 2025-05-16T05:44:39Z
author_association: MEMBER
diff_hunk: @@ -143,6 +143,53 @@ const apps = () => {
 
 /** @type {(app: import('express').Application) => void} */
 const extendExpressApp = (app) => {
+    const runtimeStats = {
+        activeRequestsIds: new Set(),
+        activeRequestsCountByType: {
+            graphql: 0,
+            oidc: 0,
+            other: 0,
+        },
+    }
+
+    app.use(function runtimeStatsMiddleware (req, res, next) {
+        const url = req.url
+        const method = (req.method || 'get').toLowerCase()
+
+        const isPost = method === 'post'
+
+        const isAdminApi = url.startsWith('/admin/api')
+        const isOidc = url.startsWith('/oidc')
+
+        /** @type {'graphql' | 'oidc' | 'other'} */
+        let requestType = 'other'
+
+        if (isPost && isAdminApi) requestType = 'graphql'
+        if (isOidc) requestType = 'oidc'
path: apps/condo/index.js
user: login: pahaz
body: And also: https://github.com/open-condo-software/condo/blob/main/apps/condo/index.js#L134

/api/version /api/files /api/auth … may be something others

It’s ok to extract “files” and “others-api” group by /api prefix.
created_at: 2025-05-16T05:50:08Z
author_association: MEMBER
diff_hunk: @@ -143,6 +143,53 @@ const apps = () => {
 
 /** @type {(app: import('express').Application) => void} */
 const extendExpressApp = (app) => {
+    const runtimeStats = {
+        activeRequestsIds: new Set(),
+        activeRequestsCountByType: {
+            graphql: 0,
+            oidc: 0,
+            other: 0,
+        },
+    }
+
+    app.use(function runtimeStatsMiddleware (req, res, next) {
+        const url = req.url
+        const method = (req.method || 'get').toLowerCase()
+
+        const isPost = method === 'post'
+
+        const isAdminApi = url.startsWith('/admin/api')
path: apps/condo/index.js
user: login: AleX83Xpert
body: I think no. What is the profit?
created_at: 2025-05-16T05:57:17Z
author_association: MEMBER
diff_hunk: @@ -143,6 +143,53 @@ const apps = () => {
 
 /** @type {(app: import('express').Application) => void} */
 const extendExpressApp = (app) => {
+    const runtimeStats = {
+        activeRequestsIds: new Set(),
+        activeRequestsCountByType: {
+            graphql: 0,
+            oidc: 0,
+            other: 0,
+        },
+    }
+
+    app.use(function runtimeStatsMiddleware (req, res, next) {
+        const url = req.url
+        const method = (req.method || 'get').toLowerCase()
+
+        const isPost = method === 'post'
+
+        const isAdminApi = url.startsWith('/admin/api')
+        const isOidc = url.startsWith('/oidc')
+
+        /** @type {'graphql' | 'oidc' | 'other'} */
+        let requestType = 'other'
+
+        if (isPost && isAdminApi) requestType = 'graphql'
+        if (isOidc) requestType = 'oidc'
+
+        if (requestType) {
+            runtimeStats.activeRequestsIds.add(req.id)
+            runtimeStats.activeRequestsCountByType[requestType] = (runtimeStats.activeRequestsCountByType[requestType] || 0) + 1
+        }
+
+        res.on('close', () => {
+            if (requestType) {
+                runtimeStats.activeRequestsIds.delete(req.id)
+                runtimeStats.activeRequestsCountByType[requestType] = Math.max(0, runtimeStats.activeRequestsCountByType[requestType] - 1)
+            }
+        })
+
+        next()
+    })
+
+    app.get('/.well-known/runtime-stats', (req, res) => {
+        res.json({
+            activeRequestsIds: Array.from(runtimeStats.activeRequestsIds.keys()),
path: apps/condo/index.js
user: login: AleX83Xpert
body: Ok, I removed this field. I will add it if needed in the future.
created_at: 2025-05-16T06:01:04Z
author_association: MEMBER
diff_hunk: @@ -143,6 +143,53 @@ const apps = () => {
 
 /** @type {(app: import('express').Application) => void} */
 const extendExpressApp = (app) => {
+    const runtimeStats = {
+        activeRequestsIds: new Set(),
+        activeRequestsCountByType: {
+            graphql: 0,
+            oidc: 0,
+            other: 0,
+        },
+    }
+
+    app.use(function runtimeStatsMiddleware (req, res, next) {
+        const url = req.url
+        const method = (req.method || 'get').toLowerCase()
+
+        const isPost = method === 'post'
+
+        const isAdminApi = url.startsWith('/admin/api')
+        const isOidc = url.startsWith('/oidc')
+
+        /** @type {'graphql' | 'oidc' | 'other'} */
+        let requestType = 'other'
+
+        if (isPost && isAdminApi) requestType = 'graphql'
+        if (isOidc) requestType = 'oidc'
+
+        if (requestType) {
+            runtimeStats.activeRequestsIds.add(req.id)
+            runtimeStats.activeRequestsCountByType[requestType] = (runtimeStats.activeRequestsCountByType[requestType] || 0) + 1
+        }
+
+        res.on('close', () => {
+            if (requestType) {
+                runtimeStats.activeRequestsIds.delete(req.id)
+                runtimeStats.activeRequestsCountByType[requestType] = Math.max(0, runtimeStats.activeRequestsCountByType[requestType] - 1)
+            }
+        })
+
+        next()
+    })
+
+    app.get('/.well-known/runtime-stats', (req, res) => {
+        res.json({
+            activeRequestsIds: Array.from(runtimeStats.activeRequestsIds.keys()),
+            activeRequestsCount: runtimeStats.activeRequestsIds.size,
path: apps/condo/index.js
user: login: AleX83Xpert
body: Looks like [yes](https://github.com/open-condo-software/condo/blob/a42d776f1a4e5885b22d1f247dbe604f3e8dd340/packages/keystone/KSv5v6/v5/prepareKeystone.js#L264).
created_at: 2025-05-16T06:02:19Z
author_association: MEMBER
diff_hunk: @@ -143,6 +143,53 @@ const apps = () => {
 
 /** @type {(app: import('express').Application) => void} */
 const extendExpressApp = (app) => {
+    const runtimeStats = {
+        activeRequestsIds: new Set(),
+        activeRequestsCountByType: {
+            graphql: 0,
+            oidc: 0,
+            other: 0,
+        },
+    }
+
+    app.use(function runtimeStatsMiddleware (req, res, next) {
+        const url = req.url
+        const method = (req.method || 'get').toLowerCase()
+
+        const isPost = method === 'post'
+
+        const isAdminApi = url.startsWith('/admin/api')
path: apps/condo/index.js
user: login: SavelevMatthew
body: Because some weird request can affect your stat

Like request to `/admin/api/something/resolving/404`
created_at: 2025-05-16T06:15:44Z
author_association: MEMBER
diff_hunk: @@ -143,6 +143,53 @@ const apps = () => {
 
 /** @type {(app: import('express').Application) => void} */
 const extendExpressApp = (app) => {
+    const runtimeStats = {
+        activeRequestsIds: new Set(),
+        activeRequestsCountByType: {
+            graphql: 0,
+            oidc: 0,
+            other: 0,
+        },
+    }
+
+    app.use(function runtimeStatsMiddleware (req, res, next) {
+        const url = req.url
+        const method = (req.method || 'get').toLowerCase()
+
+        const isPost = method === 'post'
+
+        const isAdminApi = url.startsWith('/admin/api')
path: apps/condo/index.js
user: login: SavelevMatthew
body: And since your target is to separately monitor amount of GQL requests, you want to separate specific endpoint, so other routes will count not as gql, but as others instead 
created_at: 2025-05-16T06:17:37Z
author_association: MEMBER
diff_hunk: @@ -143,6 +143,53 @@ const apps = () => {
 
 /** @type {(app: import('express').Application) => void} */
 const extendExpressApp = (app) => {
+    const runtimeStats = {
+        activeRequestsIds: new Set(),
+        activeRequestsCountByType: {
+            graphql: 0,
+            oidc: 0,
+            other: 0,
+        },
+    }
+
+    app.use(function runtimeStatsMiddleware (req, res, next) {
+        const url = req.url
+        const method = (req.method || 'get').toLowerCase()
+
+        const isPost = method === 'post'
+
+        const isAdminApi = url.startsWith('/admin/api')
+        const isOidc = url.startsWith('/oidc')
+
+        /** @type {'graphql' | 'oidc' | 'other'} */
+        let requestType = 'other'
+
+        if (isPost && isAdminApi) requestType = 'graphql'
+        if (isOidc) requestType = 'oidc'
path: apps/condo/index.js
user: login: AleX83Xpert
body: A new group `api` was added
created_at: 2025-05-16T06:34:53Z
author_association: MEMBER
diff_hunk: @@ -143,6 +143,53 @@ const apps = () => {
 
 /** @type {(app: import('express').Application) => void} */
 const extendExpressApp = (app) => {
+    const runtimeStats = {
+        activeRequestsIds: new Set(),
+        activeRequestsCountByType: {
+            graphql: 0,
+            oidc: 0,
+            other: 0,
+        },
+    }
+
+    app.use(function runtimeStatsMiddleware (req, res, next) {
+        const url = req.url
+        const method = (req.method || 'get').toLowerCase()
+
+        const isPost = method === 'post'
+
+        const isAdminApi = url.startsWith('/admin/api')
+        const isOidc = url.startsWith('/oidc')
+
+        /** @type {'graphql' | 'oidc' | 'other'} */
+        let requestType = 'other'
+
+        if (isPost && isAdminApi) requestType = 'graphql'
+        if (isOidc) requestType = 'oidc'
path: apps/condo/index.js
user: login: AleX83Xpert
body: `wellKnown` and `healthCheck` groups too
created_at: 2025-05-16T06:35:27Z
author_association: MEMBER
diff_hunk: @@ -143,6 +144,64 @@ const apps = () => {
 
 /** @type {(app: import('express').Application) => void} */
 const extendExpressApp = (app) => {
+    const runtimeStats = {
+        activeRequestsIds: new Set(),
+        activeRequestsCountByType: {
+            graphql: 0,
+            oidc: 0,
+            other: 0,
+        },
+    }
path: apps/condo/index.js
user: login: coderabbitai[bot]
body: _🛠️ Refactor suggestion_

**Consider initializing all request types in the activeRequestsCountByType object**

The `runtimeStats` object only initializes counts for `graphql`, `oidc`, and `other`, but the middleware uses additional types like `api`, `wellKnown`, and `healthCheck`. You should initialize all types to avoid potential issues when accessing properties that don't exist yet.


```diff
const runtimeStats = {
    activeRequestsIds: new Set(),
    activeRequestsCountByType: {
        graphql: 0,
        oidc: 0,
+       api: 0,
+       wellKnown: 0,
+       healthCheck: 0,
        other: 0,
    },
}
```


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

```suggestion
    const runtimeStats = {
        activeRequestsIds: new Set(),
        activeRequestsCountByType: {
            graphql: 0,
            oidc: 0,
            api: 0,
            wellKnown: 0,
            healthCheck: 0,
            other: 0,
        },
    }
```

</details>

<!-- suggestion_end -->

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
In apps/condo/index.js around lines 147 to 154, the activeRequestsCountByType
object only initializes counts for graphql, oidc, and other, but the middleware
also uses api, wellKnown, and healthCheck types. To fix this, add these missing
types to the activeRequestsCountByType object and initialize their counts to 0
to ensure all request types are accounted for and avoid undefined property
access.
```

</details>

<!-- This is an auto-generated comment by CodeRabbit -->

✅ Addressed in commit 8a32fe1
created_at: 2025-05-16T06:36:53Z
author_association: CONTRIBUTOR
diff_hunk: @@ -143,6 +143,53 @@ const apps = () => {
 
 /** @type {(app: import('express').Application) => void} */
 const extendExpressApp = (app) => {
+    const runtimeStats = {
+        activeRequestsIds: new Set(),
+        activeRequestsCountByType: {
+            graphql: 0,
+            oidc: 0,
+            other: 0,
+        },
+    }
+
+    app.use(function runtimeStatsMiddleware (req, res, next) {
+        const url = req.url
+        const method = (req.method || 'get').toLowerCase()
+
+        const isPost = method === 'post'
+
+        const isAdminApi = url.startsWith('/admin/api')
path: apps/condo/index.js
user: login: AleX83Xpert
body: > 

`isAdminApi` is about the URL itself.
created_at: 2025-05-16T06:37:15Z
author_association: MEMBER
diff_hunk: @@ -143,6 +144,64 @@ const apps = () => {
 
 /** @type {(app: import('express').Application) => void} */
 const extendExpressApp = (app) => {
+    const runtimeStats = {
+        activeRequestsIds: new Set(),
+        activeRequestsCountByType: {
+            graphql: 0,
+            oidc: 0,
+            other: 0,
+        },
+    }
+
+    app.use(function runtimeStatsMiddleware (req, res, next) {
+        const url = req.url
+        const method = (req.method || 'get').toLowerCase()
+
+        const isPost = method === 'post'
+
+        const isAdminApiUrl = url === '/admin/api'
path: apps/condo/index.js
user: login: SavelevMatthew
body: This one will not work in case like `/admin/api?deleted=true` as far as I remember, since req.url contains query params
<img width="805" alt="image" src="https://github.com/user-attachments/assets/ab7acacc-672b-4fbd-aeda-73e53ffa12f0" />


Consider using (new URL + pathname) option as I mentioned before 
created_at: 2025-05-16T06:55:46Z
author_association: MEMBER
diff_hunk: @@ -143,6 +144,64 @@ const apps = () => {
 
 /** @type {(app: import('express').Application) => void} */
 const extendExpressApp = (app) => {
+    const runtimeStats = {
+        activeRequestsIds: new Set(),
+        activeRequestsCountByType: {
+            graphql: 0,
+            oidc: 0,
+            other: 0,
+        },
+    }
+
+    app.use(function runtimeStatsMiddleware (req, res, next) {
+        const url = req.url
+        const method = (req.method || 'get').toLowerCase()
+
+        const isPost = method === 'post'
+
+        const isAdminApiUrl = url === '/admin/api'
path: apps/condo/index.js
user: login: AleX83Xpert
body: Done
created_at: 2025-05-16T07:24:03Z
author_association: MEMBER
diff_hunk: @@ -38,6 +39,8 @@ dayjs.extend(isBetween)
 const IS_BUILD_PHASE = conf.PHASE === 'build'
 const SENTRY_CONFIG = conf.SENTRY_CONFIG ? JSON.parse(conf.SENTRY_CONFIG) : {}
 
+const logger = getLogger('condo-index')
path: apps/condo/index.js
user: login: SavelevMatthew
body: Maybe we should call it more specific? Like, 'runtime-stats'?
created_at: 2025-05-16T11:59:16Z
author_association: MEMBER
diff_hunk: @@ -143,6 +146,84 @@ const apps = () => {
 
 /** @type {(app: import('express').Application) => void} */
 const extendExpressApp = (app) => {
+    const runtimeStats = {
+        activeRequestsIds: new Set(),
+        activeRequestsCountByType: {
+            graphql: 0,
+            api: 0,
+            oidc: 0,
+            wellKnown: 0,
+            healthCheck: 0,
+            other: 0,
+        },
+        totalRequestsCount: 0,
+        totalRequestsByTarget: {},
path: apps/condo/index.js
user: login: SavelevMatthew
body: Should we compute total by type? I thought we agreed to count it as well?
created_at: 2025-05-16T12:00:14Z
author_association: MEMBER
diff_hunk: @@ -38,6 +39,8 @@ dayjs.extend(isBetween)
 const IS_BUILD_PHASE = conf.PHASE === 'build'
 const SENTRY_CONFIG = conf.SENTRY_CONFIG ? JSON.parse(conf.SENTRY_CONFIG) : {}
 
+const logger = getLogger('condo-index')
path: apps/condo/index.js
user: login: AleX83Xpert
body: ¯\\\_(ツ)_/¯
I've named it according to place where it calling
created_at: 2025-05-16T12:01:25Z
author_association: MEMBER
diff_hunk: @@ -143,6 +146,84 @@ const apps = () => {
 
 /** @type {(app: import('express').Application) => void} */
 const extendExpressApp = (app) => {
+    const runtimeStats = {
+        activeRequestsIds: new Set(),
+        activeRequestsCountByType: {
+            graphql: 0,
+            api: 0,
+            oidc: 0,
+            wellKnown: 0,
+            healthCheck: 0,
+            other: 0,
+        },
+        totalRequestsCount: 0,
+        totalRequestsByTarget: {},
+    }
+
+    app.use(function runtimeStatsMiddleware (req, res, next) {
+        try {
+            const url = new URL(`${conf['SERVER_URL']}${req.url}`).pathname
+            const method = (req.method || 'get').toLowerCase()
+            const xTargetHeader = req.headers['x-target'] || 'other'
path: apps/condo/index.js
user: login: SavelevMatthew
body: You should sanitise this!!!

Otherwise I can brute-force values and memory leak
created_at: 2025-05-16T12:01:51Z
author_association: MEMBER
diff_hunk: @@ -143,6 +146,84 @@ const apps = () => {
 
 /** @type {(app: import('express').Application) => void} */
 const extendExpressApp = (app) => {
+    const runtimeStats = {
+        activeRequestsIds: new Set(),
+        activeRequestsCountByType: {
+            graphql: 0,
+            api: 0,
+            oidc: 0,
+            wellKnown: 0,
+            healthCheck: 0,
+            other: 0,
+        },
+        totalRequestsCount: 0,
+        totalRequestsByTarget: {},
path: apps/condo/index.js
user: login: AleX83Xpert
body: Yes, we've discussed it. Total and total by types.
created_at: 2025-05-16T12:02:21Z
author_association: MEMBER
diff_hunk: @@ -143,6 +146,84 @@ const apps = () => {
 
 /** @type {(app: import('express').Application) => void} */
 const extendExpressApp = (app) => {
+    const runtimeStats = {
+        activeRequestsIds: new Set(),
+        activeRequestsCountByType: {
+            graphql: 0,
+            api: 0,
+            oidc: 0,
+            wellKnown: 0,
+            healthCheck: 0,
+            other: 0,
+        },
+        totalRequestsCount: 0,
+        totalRequestsByTarget: {},
+    }
+
+    app.use(function runtimeStatsMiddleware (req, res, next) {
+        try {
+            const url = new URL(`${conf['SERVER_URL']}${req.url}`).pathname
+            const method = (req.method || 'get').toLowerCase()
+            const xTargetHeader = req.headers['x-target'] || 'other'
+
+            const isPost = method === 'post'
+
+            const isAdminApiUrl = url === '/admin/api'
path: apps/condo/index.js
user: login: SavelevMatthew
body: Should we separate this logic, to something like `getRequestType`
created_at: 2025-05-16T12:03:35Z
author_association: MEMBER
diff_hunk: @@ -143,6 +146,84 @@ const apps = () => {
 
 /** @type {(app: import('express').Application) => void} */
 const extendExpressApp = (app) => {
+    const runtimeStats = {
+        activeRequestsIds: new Set(),
+        activeRequestsCountByType: {
+            graphql: 0,
+            api: 0,
+            oidc: 0,
+            wellKnown: 0,
+            healthCheck: 0,
+            other: 0,
+        },
+        totalRequestsCount: 0,
+        totalRequestsByTarget: {},
+    }
+
+    app.use(function runtimeStatsMiddleware (req, res, next) {
+        try {
+            const url = new URL(`${conf['SERVER_URL']}${req.url}`).pathname
+            const method = (req.method || 'get').toLowerCase()
+            const xTargetHeader = req.headers['x-target'] || 'other'
path: apps/condo/index.js
user: login: AleX83Xpert
body: Done
created_at: 2025-05-16T12:13:10Z
author_association: MEMBER
diff_hunk: @@ -143,6 +146,84 @@ const apps = () => {
 
 /** @type {(app: import('express').Application) => void} */
 const extendExpressApp = (app) => {
+    const runtimeStats = {
+        activeRequestsIds: new Set(),
+        activeRequestsCountByType: {
+            graphql: 0,
+            api: 0,
+            oidc: 0,
+            wellKnown: 0,
+            healthCheck: 0,
+            other: 0,
+        },
+        totalRequestsCount: 0,
+        totalRequestsByTarget: {},
+    }
+
+    app.use(function runtimeStatsMiddleware (req, res, next) {
+        try {
+            const url = new URL(`${conf['SERVER_URL']}${req.url}`).pathname
+            const method = (req.method || 'get').toLowerCase()
+            const xTargetHeader = req.headers['x-target'] || 'other'
+
+            const isPost = method === 'post'
+
+            const isAdminApiUrl = url === '/admin/api'
path: apps/condo/index.js
user: login: AleX83Xpert
body: It is a small function. I've decided keep all code within middleware function.
created_at: 2025-05-16T12:20:59Z
author_association: MEMBER
diff_hunk: @@ -143,6 +146,97 @@ const apps = () => {
 
 /** @type {(app: import('express').Application) => void} */
 const extendExpressApp = (app) => {
+    const runtimeStats = {
+        activeRequestsIds: new Set(),
+        activeRequestsCountByType: {
+            graphql: 0,
+            api: 0,
+            oidc: 0,
+            wellKnown: 0,
+            healthCheck: 0,
+            other: 0,
+        },
+        totalRequestsCount: 0,
+        totalRequestsByTarget: {},
+    }
+
+    app.use(function runtimeStatsMiddleware (req, res, next) {
+        try {
+            const url = new URL(`${conf['SERVER_URL']}${req.url}`).pathname
+            const method = (req.method || 'get').toLowerCase()
+
+            // According to ADR35
+            const possibleXTargetValues = [
+                'billing',
+                'resident-app',
+                'technique-app',
+                'cc-app',
+                'condo-restapi-app',
+                'condo-app',
+                'smarthome',
+            ]
+            const xTargetHeader = req.headers['x-target']
+
+            const xTarget = possibleXTargetValues.includes(xTargetHeader) ? xTargetHeader : 'other'
+
+            const isPost = method === 'post'
+
+            const isAdminApiUrl = url === '/admin/api'
+            const isApiUrl = url.startsWith('/api')
+            const isOidcUrl = url.startsWith('/oidc')
+            const isWellKnownUrl = url.startsWith('/.well-known')
+            const isHealthCheckUrl = url.startsWith(DEFAULT_HEALTHCHECK_URL)
+
+            /** @type {'api' | 'graphql' | 'oidc' | 'wellKnown' | 'healthCheck' | 'other'} */
+            let requestType = 'other'
+
+            if (isPost && isAdminApiUrl) {
+                requestType = 'graphql'
+            } else if (isApiUrl) {
+                requestType = 'api'
+            } else if (isOidcUrl) {
+                requestType = 'oidc'
+            } else if (isWellKnownUrl) {
+                requestType = 'wellKnown'
+            } else if (isHealthCheckUrl) {
+                requestType = 'healthCheck'
+            }
+
+            if (requestType) {
+                runtimeStats.activeRequestsIds.add(req.id)
+                runtimeStats.activeRequestsCountByType[requestType] = (runtimeStats.activeRequestsCountByType[requestType] || 0) + 1
+                runtimeStats.totalRequestsCount = (runtimeStats.totalRequestsCount || 0) + 1
+                runtimeStats.totalRequestsByTarget[xTarget] = (runtimeStats.totalRequestsByTarget[xTarget] || 0) + 1
+            }
path: apps/condo/index.js
user: login: coderabbitai[bot]
body: _🛠️ Refactor suggestion_

**Redundant check and potential runtime error with req.id**

Two issues in this section:

1. The `if (requestType)` check is unnecessary since `requestType` is always assigned and defaults to 'other'
2. There's no validation to ensure `req.id` exists before using it


```diff
-if (requestType) {
+if (req.id) {
    runtimeStats.activeRequestsIds.add(req.id)
    runtimeStats.activeRequestsCountByType[requestType] = (runtimeStats.activeRequestsCountByType[requestType] || 0) + 1
    runtimeStats.totalRequestsCount = (runtimeStats.totalRequestsCount || 0) + 1
    runtimeStats.totalRequestsByTarget[xTarget] = (runtimeStats.totalRequestsByTarget[xTarget] || 0) + 1
+} else {
+    logger.warn({ msg: 'Request without ID', data: { url: req.url, method: req.method } })
}
```


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

```suggestion
            if (req.id) {
                runtimeStats.activeRequestsIds.add(req.id)
                runtimeStats.activeRequestsCountByType[requestType] = (runtimeStats.activeRequestsCountByType[requestType] || 0) + 1
                runtimeStats.totalRequestsCount = (runtimeStats.totalRequestsCount || 0) + 1
                runtimeStats.totalRequestsByTarget[xTarget] = (runtimeStats.totalRequestsByTarget[xTarget] || 0) + 1
            } else {
                logger.warn({ msg: 'Request without ID', data: { url: req.url, method: req.method } })
            }
```

</details>

<!-- suggestion_end -->

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
In apps/condo/index.js around lines 204 to 210, remove the redundant if
(requestType) check since requestType always has a default value. Add a
validation to check if req.id exists before adding it to
runtimeStats.activeRequestsIds to prevent potential runtime errors. Ensure the
code safely handles cases where req.id might be undefined or null.
```

</details>

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-05-16T13:34:11Z
author_association: CONTRIBUTOR
diff_hunk: @@ -143,6 +146,97 @@ const apps = () => {
 
 /** @type {(app: import('express').Application) => void} */
 const extendExpressApp = (app) => {
+    const runtimeStats = {
+        activeRequestsIds: new Set(),
+        activeRequestsCountByType: {
+            graphql: 0,
+            api: 0,
+            oidc: 0,
+            wellKnown: 0,
+            healthCheck: 0,
+            other: 0,
+        },
+        totalRequestsCount: 0,
+        totalRequestsByTarget: {},
+    }
+
+    app.use(function runtimeStatsMiddleware (req, res, next) {
+        try {
+            const url = new URL(`${conf['SERVER_URL']}${req.url}`).pathname
+            const method = (req.method || 'get').toLowerCase()
+
+            // According to ADR35
+            const possibleXTargetValues = [
path: apps/condo/index.js
user: login: SavelevMatthew
body: take it from env, dont hard-code it
created_at: 2025-05-16T14:30:57Z
author_association: MEMBER
diff_hunk: @@ -143,6 +146,97 @@ const apps = () => {
 
 /** @type {(app: import('express').Application) => void} */
 const extendExpressApp = (app) => {
+    const runtimeStats = {
+        activeRequestsIds: new Set(),
+        activeRequestsCountByType: {
+            graphql: 0,
+            api: 0,
+            oidc: 0,
+            wellKnown: 0,
+            healthCheck: 0,
+            other: 0,
+        },
+        totalRequestsCount: 0,
+        totalRequestsByTarget: {},
+    }
+
+    app.use(function runtimeStatsMiddleware (req, res, next) {
+        try {
+            const url = new URL(`${conf['SERVER_URL']}${req.url}`).pathname
+            const method = (req.method || 'get').toLowerCase()
+
+            // According to ADR35
+            const possibleXTargetValues = [
path: apps/condo/index.js
user: login: AleX83Xpert
body: moved to envs
created_at: 2025-05-16T15:32:28Z
author_association: MEMBER

PR comments:
user: login: coderabbitai[bot]
created_at: 2025-05-16T04:38:55Z
body: <!-- This is an auto-generated comment: summarize by coderabbit.ai -->
<!-- walkthrough_start -->

"""
## Walkthrough

A middleware was introduced to the Express application to monitor active HTTP requests, categorizing them into six types: "graphql," "api," "oidc," "wellKnown," "healthCheck," and "other." It tracks request IDs and counts per type. A new GET endpoint, "/.well-known/runtime-stats," exposes these runtime statistics as JSON, showing active requests and their classifications. Additionally, the constant `DEFAULT_HEALTHCHECK_URL` was exported from the health check module.

## Changes

| File(s)                      | Change Summary                                                                                                                     |
|-----------------------------|-----------------------------------------------------------------------------------------------------------------------------------|
| apps/condo/index.js          | Added middleware to track and categorize active HTTP requests into six types; introduced a GET endpoint for runtime stats as JSON. |
| packages/keystone/healthCheck.js | Exported the `DEFAULT_HEALTHCHECK_URL` constant for external use.                                                                 |
| .helm                       | Updated subproject reference commit hash.                                                                                        |

## Sequence Diagram(s)

```mermaid
sequenceDiagram
    participant Client
    participant ExpressApp
    participant Middleware
    participant RuntimeStatsEndpoint

    Client->>ExpressApp: HTTP Request (any path)
    ExpressApp->>Middleware: Pass request through tracking middleware
    Middleware->>Middleware: Categorize & track request (graphql/api/oidc/wellKnown/healthCheck/other)
    Middleware->>ExpressApp: Pass request to next handler
    ExpressApp-->>Client: Response sent
    Middleware->>Middleware: Remove request from tracking on response close

    Client->>RuntimeStatsEndpoint: GET /.well-known/runtime-stats
    RuntimeStatsEndpoint->>Middleware: Retrieve current request stats
    RuntimeStatsEndpoint-->>Client: Respond with JSON stats
```

## Poem

> In the condo where requests abound,  
> A rabbit tracks them, all around.  
> GraphQL, API, or OIDC,  
> WellKnown, health checks, and others we see.  
> Counting each hop with care and cheer,  
> Stats revealed for all to peer!  
> 🐇📊✨
"""

<!-- walkthrough_end -->


---

<details>
<summary>📜 Recent review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: CHILL**
**Plan: Pro**
**Cache: Disabled due to data retention organization setting**
**Knowledge Base: Disabled due to data retention organization setting**


<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 18c41c8c90a84884d8c2b8f73577d5ddf397e276 and e5389a1ca315feca474d639d069cb9fd6d355575.

</details>

<details>
<summary>📒 Files selected for processing (1)</summary>

* `.helm` (1 hunks)

</details>

<details>
<summary>🚧 Files skipped from review as they are similar to previous changes (1)</summary>

* .helm

</details>

<details>
<summary>⏰ Context from checks skipped due to timeout of 90000ms (6)</summary>

* GitHub Check: Build open-source part (windows-latest, 16.x, 3.13)
* GitHub Check: Build open-source part (ubuntu-22.04, 16.x, 3.13)
* GitHub Check: Check dependencies integrity (16.x)
* GitHub Check: Semgrep vulnerabilities check
* GitHub Check: Lint source code (16.x)
* GitHub Check: Build Docker Image

</details>

</details>
<!-- internal state start -->


<!-- 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 -->

<!-- internal state end -->
<!-- tips_start -->

---

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

<details>
<summary>❤️ Share</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)
- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

</details>

<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=open-condo-software/condo&utm_content=6184):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Explain this complex logic.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai explain this code block.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and explain its main purpose.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

### Support

Need help? Create a ticket on our [support page](https://www.coderabbit.ai/contact-us/support) for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai generate sequence diagram` to generate a sequence diagram of the changes in this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### CodeRabbit Configuration File (`.coderabbit.yaml`)

- You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository.
- Please see the [configuration documentation](https://docs.coderabbit.ai/guides/configure-coderabbit) for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: `# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json`

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->
author_association: CONTRIBUTOR
user: login: AleX83Xpert
created_at: 2025-05-16T06:04:05Z
body: > Why not just simple shape like this? Why all IDs needed?
> 
> ```
> {
>   "oidc": 2,
>   "graphql": 10,
>   "other": 3,
>   "total": 15
> }
> ```

I do not want to mix separated values with summarized values.
author_association: MEMBER
user: login: sonarqubecloud[bot]
created_at: 2025-05-16T15:46:41Z
body: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=open-condo-software_condo&pullRequest=6184) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 New issues](https://sonarcloud.io/project/issues?id=open-condo-software_condo&pullRequest=6184&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=open-condo-software_condo&pullRequest=6184&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=open-condo-software_condo&pullRequest=6184&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=open-condo-software_condo&pullRequest=6184&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=open-condo-software_condo&pullRequest=6184&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=open-condo-software_condo&pullRequest=6184)


author_association: NONE