Skip to content

Conversation

@sosweetham
Copy link
Member

@sosweetham sosweetham commented Nov 29, 2025

Description of change

Issue Number

Type of change

  • Breaking (any change that would cause existing functionality to not work as expected)
  • New (a change which implements a new feature)
  • Update (a change which updates existing functionality)
  • Fix (a change which fixes an issue)
  • Docs (changes to the documentation)
  • Chore (refactoring, build scripts or anything else that isn't user-facing)

How the change has been tested

Change checklist

  • I have ensured that the CI Checks pass locally
  • I have removed any unnecessary logic
  • My code is well documented
  • I have signed my commits
  • My code follows the pattern of the application
  • I have self reviewed my code

Summary by CodeRabbit

  • New Features

    • Loki log aggregation added for centralized logs
    • eVault health status, details, and per-eVault logs accessible via UI and API
    • Unified eVault identifiers for simpler selection and navigation
  • Infrastructure

    • eVault discovery moved to registry-driven approach
    • Neo4j startup reliability improved with PID cleanup and stricter healthchecks
    • Multi-database initialization script added
  • Chores

    • New environment variables and helper script to obtain platform token
    • Removed legacy pod-level diagnostics in favor of registry-based views

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 29, 2025

Walkthrough

Refactors control-panel from Kubernetes (kubectl/pod) discovery to a registry-driven model, adds Loki log aggregation and environment entries, replaces pod-centric API routes with registry-based endpoints, updates services (registry, loki, evault), and adjusts UI pages/components and dev tooling/configuration accordingly.

Changes

Cohort / File(s) Summary
Environment & Tooling
\.env.example`, `db/init-multiple-databases.sh`, `dev-docker-compose.yaml`, `svelte.config.js`, `vite.config.ts`, `scripts/get-eid-wallet-token.sh``
Added PUBLIC_EID_WALLET_TOKEN and Loki-related env entries; new DB init script to create multiple Postgres DBs; added Loki service and Neo4j PID-cleanup/healthcheck to docker-compose; set env.dir/envPrefix for monorepo; added script to obtain eid-wallet token.
Registry platform server
\platforms/registry/src/index.ts`, `platforms/registry/src/services/HealthCheckService.ts`, `platforms/registry/src/services/VaultService.ts``
Minor formatting, logging, and debug additions; CORS/dotenv usage; type-only imports in VaultService and small signature spacing normalizations.
Control Panel — Services
\infrastructure/control-panel/src/lib/services/registry.ts`, `.../evaultService.ts`, `.../loki.ts``
New/updated RegistryService with getEVaults() and improved getPlatforms(); evaultService methods repurposed to use evaultId (getEVaultLogs, getEVaultDetails); new LokiService.getEVaultLogs with multi-pattern queries, deduplication, sorting, and limit.
Control Panel — API (added)
\infrastructure/control-panel/src/routes/api/evaults/[evaultId]/details/+server.ts`, `.../logs/+server.ts``
New GET routes: details (health check + registry metadata) and logs (fetch via LokiService) resolving evault by evaultId or ename with error handling.
Control Panel — API (migrated)
\infrastructure/control-panel/src/routes/api/evaults/+server.ts`**`
Replaced kubectl-based discovery with registryService.getEVaults(); EVault shape changed to id, name, ename, uri, evault, status, serviceUrl; status derived via /health checks.
Control Panel — API (removed)
\infrastructure/control-panel/src/routes/api/evaults/[namespace]/[pod]/details/+server.ts`, `.../[namespace]/[pod]/logs/+server.ts`, `.../[namespace]/[pod]/metrics/+server.ts``
Removed pod-centric kubectl-based route handlers for details, logs, and metrics.
Control Panel — UI Components & Pages
\infrastructure/control-panel/src/lib/components/EVaultList.svelte`, `.../src/routes/+page.svelte`, `.../src/routes/monitoring/+page.svelte`, `.../src/routes/evaults/[evaultId]/+page.svelte``
UI updated to use composite identifiers (evault, ename, id), show URI-centric fields, change labels/status text, remove age/metrics where applicable, adapt navigation and selection logic to evaultId-based flows, and display details/logs from new endpoints.
Control Panel — Config
\infrastructure/control-panel/svelte.config.js`, `infrastructure/control-panel/vite.config.ts``
Added env.dir/envPrefix to load monorepo root env and expose PUBLIC_ client vars; minor formatting changes.
eID Wallet
\infrastructure/eid-wallet/src/lib/global/controllers/evault.ts`, `.../onboarding/+page.svelte``
Reordered env imports and adjusted header assignment style; added console.debug logs during onboarding.
eVault Core & Misc
\infrastructure/evault-core/src/core/http/server.ts``, other minor files
Formatting/typing reorganizations with no functional changes.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant UI as Control Panel UI
    participant API as Control-Panel API
    participant Registry as RegistryService
    participant Health as HealthCheck (/health)
    participant Loki as LokiService
    participant EVault as eVault Instance

    User->>UI: Open eVault list
    UI->>API: GET /api/evaults
    API->>Registry: getEVaults()
    Registry-->>API: RegistryVault[] 

    loop per eVault
      API->>Health: GET {evault.uri}/health (2s timeout)
      Health->>EVault: /health
      EVault-->>Health: 200/timeout/error
      Health-->>API: Healthy/Unhealthy/Unreachable
    end
    API-->>UI: EVault[] (with status, uri, id)

    User->>UI: View eVault details/logs
    UI->>API: GET /api/evaults/{evaultId}/details
    API->>Registry: getEVaults() -> find evault
    API-->>UI: details (ename, evault, uri, healthStatus)

    UI->>API: GET /api/evaults/{evaultId}/logs?tail=100
    API->>Registry: getEVaults() -> find evault
    API->>Loki: getEVaultLogs(evaultId, ename, limit, start, end)
    Loki->>Loki: run multiple query patterns, dedupe & sort
    Loki-->>API: logs[]
    API-->>UI: logs
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

  • Areas needing extra attention:
    • RegistryService.getEVaults() and getPlatforms() logic and URL/name inference.
    • API migration in routes/api/evaults/+server.ts: health-check concurrency, timeout handling, and response shape changes.
    • LokiService.getEVaultLogs: query fallback behavior, deduplication correctness, and sorting/limit enforcement.
    • UI changes that map identifiers across components (+page.svelte, EVaultList.svelte, monitoring and evault detail pages) to ensure selection, navigation, and session persistence remain consistent.

Possibly related PRs

  • #334 — Changes to evaultService.ts (log/metrics methods): directly related; signatures were renamed/repurposed in this diff.
  • #464 — eID wallet environment/token work: adds/uses PUBLIC_EID_WALLET_TOKEN and token-fetching flows connected to the new script and env entries.
  • #327 — EVaultList UI adjustments: touches the same component (EVaultList.svelte) and related selection/display logic.

Suggested labels

evault-refactor

Suggested reviewers

  • coodos
  • xPathin

Poem

🐰 I hopped through registries at dawn,

Loki fetched logs before the yawn;
No more pods to chase or pry,
IDs align, health checks fly,
A nibble, a hop — the panel's reborn!

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings, 1 inconclusive)
Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description consists entirely of an unfilled template with no concrete details about changes, testing, type of change, or any items checked off. Fill out the template with: issue number, selected type of change, specific description of what was refactored and why, testing methodology, and check off applicable checklist items.
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title 'refactor:control-panel' is vague and overly generic, using a format that doesn't clearly convey the scope or impact of changes beyond referencing one component. Provide a more descriptive title that explains the main change, such as 'refactor: migrate control-panel eVault discovery from Kubernetes to registry-based lookup'.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor/control-panel-infrastructure

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@sosweetham sosweetham marked this pull request as ready for review November 29, 2025 09:37
@sosweetham sosweetham requested a review from coodos as a code owner November 29, 2025 09:37
Comment on lines +129 to +156
// Return fallback platforms if registry is unavailable
return [
{
name: "Blabsy",
url: "http://192.168.0.235:4444",
status: "Active",
uptime: "24h",
},
{
name: "Pictique",
url: "http://192.168.0.235:1111",
status: "Active",
uptime: "24h",
},
{
name: "Group Charter",
url: "http://192.168.0.235:5555",
status: "Active",
uptime: "24h",
},
{
name: "Cerberus",
url: "http://192.168.0.235:6666",
status: "Active",
uptime: "24h",
},
];
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bad, coz these URL's are 99.9% wrong. We should just fail.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ya I saw it as the platform loaded these for me and i was like wtf, but I have just preserved them cuz they were already there and i have no idea why @coodos had them :P

But I wouldnt mind handling it separately outside this pr's scope

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (5)
infrastructure/eid-wallet/src/routes/(auth)/onboarding/+page.svelte (1)

201-212: Remove or conditionally gate debug logs containing sensitive data before production release.

Lines 201 and 212 contain unconditional console.log statements that will execute in all environments, including production. Line 212 specifically logs provisionRes.data, which contains security-sensitive identity tokens (uri, w3id) and should never be exposed to browser console in production. Line 201 logs registryEntropy, which is a security token.

The vite.config.js has no log stripping or environment-based filtering configured, meaning these logs will persist in production builds.

Option 1: Remove the logs entirely

             const registryEntropy = entropyRes.data.token;
-            console.log("Registry entropy:", registryEntropy);

             const provisionRes = await axios.post(
                 new URL("/provision", PUBLIC_PROVISIONER_URL).toString(),
@@ -210,7 +209,6 @@
                     publicKey: await getApplicationPublicKey(),
                 },
             );
-            console.log("Provision response:", provisionRes.data);

             if (!provisionRes.data?.success) {

Option 2: Conditionally gate on debug flag

+            const DEBUG = false; // or read from environment
             const registryEntropy = entropyRes.data.token;
-            console.log("Registry entropy:", registryEntropy);
+            if (DEBUG) console.log("Registry entropy:", registryEntropy);

             const provisionRes = await axios.post(
                 new URL("/provision", PUBLIC_PROVISIONER_URL).toString(),
@@ -210,7 +208,7 @@
                     publicKey: await getApplicationPublicKey(),
                 },
             );
-            console.log("Provision response:", provisionRes.data);
+            if (DEBUG) console.log("Provision response:", provisionRes.data);

             if (!provisionRes.data?.success) {
platforms/registry/src/index.ts (1)

34-39: Fix CORS misconfiguration: origin: "*" with credentials: true.

Browsers block requests when CORS is configured with both origin: "*" and credentials: true. This combination is invalid per the CORS specification and will cause authentication/cookie-based requests to fail.

Apply this diff to fix the configuration:

 server.register(cors, {
-    origin: "*",
+    origin: process.env.ALLOWED_ORIGINS?.split(",") || ["http://localhost:3000"],
     methods: ["GET", "POST", "OPTIONS"],
     allowedHeaders: ["Content-Type", "Authorization"],
     credentials: true,
 });

Alternatively, if you don't need credentials, remove the credentials option:

 server.register(cors, {
     origin: "*",
     methods: ["GET", "POST", "OPTIONS"],
     allowedHeaders: ["Content-Type", "Authorization"],
-    credentials: true,
 });
infrastructure/control-panel/src/routes/+page.svelte (3)

200-206: Bug: evaultId property does not exist on EVault type.

The EVault interface defines id, evault, and ename fields, but evaultId is not a valid property. This will cause the sessionStorage to store undefined values.

Apply this diff to fix the property reference:

 		// Store selections immediately in sessionStorage
 		const selectedEVaultData = selectedEVaults
-			.map((id) => evaults.find((e) => e.evaultId === id))
+			.map((id) => evaults.find((e) => (e.evault || e.ename || e.id) === id))
 			.filter(Boolean);
 		sessionStorage.setItem('selectedEVaults', JSON.stringify(selectedEVaultData));

249-256: Bug: Same evaultId property issue in goToMonitoring.

Consistent with the previous issue, this references the non-existent evaultId property.

Apply this diff:

 	function goToMonitoring() {
 		const selectedEVaultData = selectedEVaults
-			.map((id) => evaults.find((e) => e.evaultId === id))
+			.map((id) => evaults.find((e) => (e.evault || e.ename || e.id) === id))
 			.filter(Boolean);

286-311: Dead code: mappedData uses obsolete EVault fields.

This mapping block references evault.age and evault.ip, which no longer exist in the EVault interface. The mappedData variable appears to be unused—the table uses mappedEVaultsData() instead.

Consider removing this dead code block entirely, or update it to use the correct fields if it's needed elsewhere:

 			try {
-				const mapped = evaults.map((evault) => {
-					const mapped = {
-						eName: {
-							type: 'text',
-							value: evault.evault || evault.ename || evault.id,
-							className:
-								'cursor-pointer text-blue-600 hover:text-blue-800 hover:underline'
-						},
-						Uptime: {
-							type: 'text',
-							value: evault.age
-						},
-						IP: {
-							type: 'text',
-							value: evault.ip
-						},
-						URI: {
-							type: 'link',
-							value: evault.serviceUrl || 'N/A',
-							link: evault.serviceUrl || '#',
-							external: true
-						}
-					};
-					return mapped;
-				});
-
-				mappedData = mapped;
-				console.log('✅ Data mapped successfully:', mappedData.length, 'items');
+				console.log('✅ eVaults loaded successfully:', evaults.length, 'items');
🧹 Nitpick comments (16)
db/init-multiple-databases.sh (1)

20-20: Unconventional whitespace trimming; consider Bash parameter expansion instead.

Using echo "$db" | xargs for trimming is non-idiomatic and introduces a subprocess. Bash offers built-in parameter expansion that is more efficient and doesn't require external tools.

- db=$(echo "$db" | xargs)
+ db="${db##*( )}"  # Remove leading whitespace
+ db="${db%%*( )}"  # Remove trailing whitespace

Or use a more portable approach with sed or awk if targeting older Bash versions. This also improves robustness in minimal container environments where xargs may not be available.

platforms/registry/src/services/VaultService.ts (1)

7-32: CRUD methods remain straightforward repository wrappers

create, findAll, findOne, findByEname, update, and delete all delegate directly to serviceRepository with clear, conventional TypeORM usage. The updatefindOne pattern is appropriate when you need the updated entity, and there are no obvious edge‑case or correctness issues here.

If your project style allows, you could optionally simplify return await this.serviceRepository... to just return this.serviceRepository... in these methods, since they immediately return the promise, but this is purely stylistic and fine as-is.

platforms/registry/src/services/HealthCheckService.ts (3)

9-38: Confirm health vs reachability semantics in isUriHealthy

With validateStatus: (status) => status < 500, this method returns true for any HTTP status below 500 (including 3xx and 4xx); only 5xx or network/timeout errors produce false. If you intend this to model reachability that’s fine, but the name isUriHealthy and the log message “Health check passed” suggest stricter semantics (e.g., only 2xx/3xx). Consider either:

  • tightening the success condition (e.g., require 2xx) and logging pass/fail accordingly, or
  • renaming/logging it as a reachability check to avoid confusion.

45-68: parseUri is intentionally narrow; consider robustness only if future callers need it

The protocol stripping and cleanUri.split(":") with parts.length === 2 match the documented supported formats (IP:PORT, http://IP:PORT, https://IP:PORT). This will deliberately reject URIs that include paths, queries, or hostnames. That’s fine given the comment, but if future inputs may include /whois or DNS hostnames, consider switching to the built‑in URL parser for more robust extraction of host and port.


73-78: IPv4-only IP validation is acceptable but limited

The regex correctly validates dotted‑quad IPv4 addresses. Just be aware this will reject IPv6 literals and DNS hostnames; if those ever need to be supported, you’ll need a broader validation strategy.

infrastructure/evault-core/src/core/http/server.ts (2)

23-28: Consider stronger typing for the evault parameter.

The evault parameter is typed as any. While this works, a more specific type would improve maintainability and catch potential issues at compile time.

 export async function registerHttpRoutes(
     server: FastifyInstance,
-    evault: any, // EVault instance to access publicKey
+    evault: { publicKey?: string }, // EVault instance - define a proper interface if more properties are needed
     provisioningService?: ProvisioningService,
     dbService?: DbService,
 ): Promise<void> {

295-298: Consider using jose.JWTPayload return type.

The return type Promise<any | null> could leverage the jose library's type for better type safety.

     async function validateToken(
         authHeader: string | null,
-    ): Promise<any | null> {
+    ): Promise<jose.JWTPayload | null> {
.env.example (1)

74-79: LGTM - New environment variables for Loki and eid-wallet token.

The additions align with the PR's Loki service integration and token-based authentication. Consider adding a section comment for the Loki variables for consistency with other grouped configurations (e.g., # Loki Configuration).

 LOAD_TEST_USER_COUNT=6

 PUBLIC_EID_WALLET_TOKEN=obtained-from-post-registry-service-/platforms/certification

+# Loki Configuration
 LOKI_URL=http://localhost:3100
 LOKI_USERNAME=admin
 LOKI_PASSWORD=admin
scripts/get-eid-wallet-token.sh (1)

45-47: Remove trailing blank lines.

The file has extra blank lines at the end which can be cleaned up.

 echo "$TOKEN"
-
-
-
infrastructure/control-panel/src/lib/services/evaultService.ts (1)

98-115: Consider defining a return type interface for getEVaultDetails.

The Promise<any> return type could be replaced with a specific interface matching the expected response structure for better type safety and IDE support.

+interface EVaultDetails {
+    id: string;
+    w3id: string;
+    uri: string;
+    healthStatus: string;
+    // Add other fields as needed
+}
+
 /**
  * Get details for a specific eVault by evaultId
  */
-static async getEVaultDetails(evaultId: string): Promise<any> {
+static async getEVaultDetails(evaultId: string): Promise<EVaultDetails> {
infrastructure/control-panel/src/lib/services/registry.ts (2)

27-41: Error handling silently returns empty array.

Consider whether silently returning an empty array on error is the desired behavior. Callers won't be able to distinguish between "registry has no vaults" and "registry is unreachable."

If distinguishing these cases matters, consider throwing or returning a result type:

     } catch (error) {
         console.error("Error fetching evaults from registry:", error);
-        return [];
+        throw error; // Let caller decide how to handle
     }

71-115: Extract duplicate name mapping logic.

The platform name mapping logic at lines 81-92 is duplicated at lines 100-113 in the catch block fallback. Consider extracting to a helper function.

+function mapPlatformName(namePart: string): string {
+    const nameMap: Record<string, string> = {
+        pictique: "Pictique",
+        blabsy: "Blabsy",
+        charter: "Group Charter",
+        cerberus: "Cerberus",
+        evoting: "eVoting",
+        dreamsync: "DreamSync",
+        ereputation: "eReputation",
+    };
+    const lower = namePart.toLowerCase();
+    return nameMap[lower] || namePart.charAt(0).toUpperCase() + namePart.slice(1);
+}

Then replace both occurrences with name = mapPlatformName(namePart);

infrastructure/control-panel/src/routes/api/evaults/[evaultId]/logs/+server.ts (1)

6-46: Clean implementation consistent with existing patterns.

The route follows the same evault lookup pattern as the details endpoint and provides appropriate error responses. The structured error responses with logs: [] allow clients to handle errors gracefully.

Consider adding validation for the tail parameter to prevent excessive queries:

 const tail = parseInt(url.searchParams.get('tail') || '100', 10);
+const validatedTail = Math.min(Math.max(tail, 1), 1000); // Clamp between 1-1000
infrastructure/control-panel/src/routes/evaults/[evaultId]/+page.svelte (1)

69-73: Consider null-safe access for evault.uri.

If evault is truthy but uri is undefined/null, this will display undefined. Use optional chaining or a fallback.

 		{#if evault}
 			<p class="text-sm text-gray-500">
-				URI: {evault.uri}
+				URI: {evault.uri || 'N/A'}
 			</p>
 		{/if}
infrastructure/control-panel/src/routes/api/evaults/+server.ts (2)

5-13: Redundant fields in EVault interface.

The interface has redundancy: id duplicates evault, and serviceUrl duplicates uri. If this is for backward compatibility during migration, consider adding a comment. Otherwise, consolidate to reduce confusion.

 export interface EVault {
-	id: string; // evault identifier (evault field from registry)
+	id: string; // evault identifier (evault field from registry) - kept for backward compatibility
 	name: string; // display name (ename or evault)
 	ename: string; // w3id identifier
 	uri: string; // resolved service URI
 	evault: string; // evault identifier
 	status: string; // derived from health check
-	serviceUrl?: string; // same as uri for display
+	serviceUrl?: string; // same as uri - kept for backward compatibility
 }

29-38: Inconsistent status terminology across endpoints.

This endpoint uses Active/Inactive for status, while the details endpoint (/evaults/[evaultId]/details) uses Healthy/Unhealthy/Unreachable for healthStatus. Consider aligning the terminology to avoid confusion in the UI.

The list endpoint could either:

  1. Use Healthy/Unhealthy/Unreachable to match details, or
  2. Keep Active/Inactive but ensure the UI handles both consistently

If keeping both, document the distinction clearly.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7d94cea and d24c4cf.

⛔ Files ignored due to path filters (3)
  • infrastructure/eid-wallet/src-tauri/gen/android/.idea/codeStyles/Project.xml is excluded by !**/gen/**
  • infrastructure/eid-wallet/src-tauri/gen/android/.idea/codeStyles/codeStyleConfig.xml is excluded by !**/gen/**
  • infrastructure/eid-wallet/src-tauri/gen/android/.idea/kotlinc.xml is excluded by !**/gen/**
📒 Files selected for processing (25)
  • .env.example (1 hunks)
  • db/init-multiple-databases.sh (1 hunks)
  • dev-docker-compose.yaml (2 hunks)
  • infrastructure/control-panel/src/lib/components/EVaultList.svelte (4 hunks)
  • infrastructure/control-panel/src/lib/services/evaultService.ts (2 hunks)
  • infrastructure/control-panel/src/lib/services/loki.ts (1 hunks)
  • infrastructure/control-panel/src/lib/services/registry.ts (1 hunks)
  • infrastructure/control-panel/src/routes/+page.svelte (8 hunks)
  • infrastructure/control-panel/src/routes/api/evaults/+server.ts (1 hunks)
  • infrastructure/control-panel/src/routes/api/evaults/[evaultId]/details/+server.ts (1 hunks)
  • infrastructure/control-panel/src/routes/api/evaults/[evaultId]/logs/+server.ts (1 hunks)
  • infrastructure/control-panel/src/routes/api/evaults/[namespace]/[pod]/details/+server.ts (0 hunks)
  • infrastructure/control-panel/src/routes/api/evaults/[namespace]/[pod]/logs/+server.ts (0 hunks)
  • infrastructure/control-panel/src/routes/api/evaults/[namespace]/[pod]/metrics/+server.ts (0 hunks)
  • infrastructure/control-panel/src/routes/evaults/[evaultId]/+page.svelte (5 hunks)
  • infrastructure/control-panel/src/routes/monitoring/+page.svelte (3 hunks)
  • infrastructure/control-panel/svelte.config.js (1 hunks)
  • infrastructure/control-panel/vite.config.ts (1 hunks)
  • infrastructure/eid-wallet/src/lib/global/controllers/evault.ts (2 hunks)
  • infrastructure/eid-wallet/src/routes/(auth)/onboarding/+page.svelte (2 hunks)
  • infrastructure/evault-core/src/core/http/server.ts (3 hunks)
  • platforms/registry/src/index.ts (5 hunks)
  • platforms/registry/src/services/HealthCheckService.ts (4 hunks)
  • platforms/registry/src/services/VaultService.ts (1 hunks)
  • scripts/get-eid-wallet-token.sh (1 hunks)
💤 Files with no reviewable changes (3)
  • infrastructure/control-panel/src/routes/api/evaults/[namespace]/[pod]/metrics/+server.ts
  • infrastructure/control-panel/src/routes/api/evaults/[namespace]/[pod]/details/+server.ts
  • infrastructure/control-panel/src/routes/api/evaults/[namespace]/[pod]/logs/+server.ts
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-11-13T10:34:52.527Z
Learnt from: coodos
Repo: MetaState-Prototype-Project/prototype PR: 415
File: infrastructure/eid-wallet/src/env.d.ts:8-8
Timestamp: 2025-11-13T10:34:52.527Z
Learning: In infrastructure/eid-wallet, PUBLIC_PLATFORM_URL should not be added to .env.example or configured as a static environment variable. The platform URL is extracted dynamically through URI parsing according to the protocol specification, and all fallbacks for platform URL are being removed.

Applied to files:

  • .env.example
  • scripts/get-eid-wallet-token.sh
📚 Learning: 2025-11-21T15:49:12.904Z
Learnt from: coodos
Repo: MetaState-Prototype-Project/prototype PR: 458
File: platforms/eReputation-api/src/services/ReferenceSigningSessionService.ts:60-60
Timestamp: 2025-11-21T15:49:12.904Z
Learning: In platforms/eReputation-api/src/services/ReferenceSigningSessionService.ts, the VITE_EREPUTATION_BASE_URL environment variable intentionally has no fallback value. The service should fail if this environment variable is not set, following a fail-fast design pattern.

Applied to files:

  • infrastructure/control-panel/src/lib/services/registry.ts
🧬 Code graph analysis (6)
infrastructure/control-panel/src/routes/api/evaults/[evaultId]/details/+server.ts (3)
infrastructure/control-panel/src/routes/api/evaults/+server.ts (1)
  • GET (15-58)
infrastructure/control-panel/src/routes/api/evaults/[evaultId]/logs/+server.ts (1)
  • GET (6-46)
infrastructure/control-panel/src/lib/services/registry.ts (1)
  • registryService (160-160)
infrastructure/control-panel/vite.config.ts (1)
infrastructure/eid-wallet/vitest.workspace.js (1)
  • dirname (8-11)
infrastructure/control-panel/src/routes/api/evaults/+server.ts (3)
infrastructure/control-panel/src/routes/api/evaults/[evaultId]/details/+server.ts (1)
  • GET (5-44)
infrastructure/control-panel/src/routes/api/evaults/[evaultId]/logs/+server.ts (1)
  • GET (6-46)
infrastructure/control-panel/src/lib/services/registry.ts (1)
  • registryService (160-160)
infrastructure/control-panel/src/routes/api/evaults/[evaultId]/logs/+server.ts (4)
infrastructure/control-panel/src/routes/api/evaults/+server.ts (1)
  • GET (15-58)
infrastructure/control-panel/src/routes/api/evaults/[evaultId]/details/+server.ts (1)
  • GET (5-44)
infrastructure/control-panel/src/lib/services/registry.ts (1)
  • registryService (160-160)
infrastructure/control-panel/src/lib/services/loki.ts (1)
  • lokiService (213-213)
infrastructure/control-panel/src/lib/services/registry.ts (1)
tests/src/factories/index.ts (1)
  • Platform (1-1)
infrastructure/evault-core/src/core/http/server.ts (1)
infrastructure/evault-core/src/core/http/types.ts (2)
  • TypedRequest (14-16)
  • TypedReply (18-18)
🪛 dotenv-linter (4.0.0)
.env.example

[warning] 79-79: [UnorderedKey] The LOKI_PASSWORD key should go before the LOKI_URL key

(UnorderedKey)

🔇 Additional comments (32)
db/init-multiple-databases.sh (1)

31-33: Verify heredoc syntax and ensure proper error propagation on database creation failure.

The heredoc uses <<-EOSQL correctly to allow indentation. However, ensure that if the CREATE DATABASE statement fails, the error is properly reported. Since set -e is enabled at the top, any non-zero exit from psql should cause the script to exit. Verify that this behavior is intentional and desired (i.e., partial failures should fail the entire initialization).

Test the error propagation by attempting to create a database with an invalid name or when the postgres user lacks permissions, and confirm the script exits with a failure status.

platforms/registry/src/services/VaultService.ts (1)

1-2: Type-only imports align with usage

Repository and Vault are only used in type positions here, so switching to import type cleanly removes unnecessary runtime dependencies with no behavior change, assuming the repository/entity are wired via the DataSource/DI elsewhere.

platforms/registry/src/index.ts (5)

2-4: LGTM: Import additions look good.

The CORS and dotenv imports are properly added, and the dotenv configuration is correctly placed to load environment variables for subsequent usage in the server.

Also applies to: 29-29


13-20: LGTM: Formatting improvement.

The multiline formatting enhances readability without changing functionality.


47-50: LGTM: Improved structured logging.

The multiline object format improves log structure and readability, making it easier to parse errors in log aggregation systems.


133-143: LGTM: Improved array formatting.

The multiline format with trailing commas improves readability and reduces diff noise in future changes.


192-209: LGTM: Improved code formatting.

The multiline formatting of the resolveUri call and added whitespace improve readability without changing functionality.

platforms/registry/src/services/HealthCheckService.ts (2)

1-1: Axios import style change is fine

Switching to double quotes for the axios import is purely stylistic and consistent; no functional impact.


83-87: Port validation logic looks correct and idiomatic

Parsing the port as base‑10 and enforcing the 1–65535 range is appropriate and safely filters out invalid values.

infrastructure/control-panel/svelte.config.js (1)

11-14: LGTM - Environment configuration aligns with monorepo pattern.

The env.dir pointing to the monorepo root (../../) enables consistent environment variable loading across the control-panel, matching the approach in vite.config.ts.

infrastructure/eid-wallet/src/lib/global/controllers/evault.ts (1)

178-180: LGTM - Minor stylistic improvement.

The change from bracket notation (headers["Authorization"]) to dot notation (headers.Authorization) is equivalent and slightly more idiomatic for valid identifier keys.

infrastructure/evault-core/src/core/http/server.ts (1)

365-465: LGTM - Well-structured endpoint with proper validation.

The /public-key endpoint has comprehensive validation for headers, authentication, and body content with appropriate HTTP status codes for each error case.

infrastructure/control-panel/vite.config.ts (2)

7-8: LGTM - Correct ESM __dirname computation.

The pattern correctly derives __dirname from import.meta.url since native __dirname is not available in ESM modules. This is consistent with the monorepo's approach seen in other files.


12-15: LGTM - Environment configuration aligns with monorepo strategy.

Setting envDir to the monorepo root and envPrefix to "PUBLIC_" enables consistent environment variable loading. Server-side variables (like LOKI_*) are loaded automatically while PUBLIC_ prefixed vars are exposed to the client.

infrastructure/control-panel/src/lib/services/evaultService.ts (1)

77-96: LGTM - Clean refactor to evaultId-based API.

The method signature change from (namespace, podName) to (evaultId, tail?) aligns with the registry-driven architecture. The encodeURIComponent usage correctly handles special characters in the evaultId.

dev-docker-compose.yaml (1)

129-141: Neo4j PID cleanup approach looks reasonable.

This is a common workaround for Neo4j container restart issues where stale PID files prevent startup. The redundant cleanup paths ensure coverage across different Neo4j versions.

infrastructure/control-panel/src/lib/services/registry.ts (2)

10-16: Interface definition looks good.

The RegistryVault interface captures the essential fields for registry-based vault discovery. The optional fields originalUri and resolved provide flexibility for different resolution states.


117-123: Hardcoded status and uptime values.

Status is always set to "Active" and uptime to "24h" regardless of actual platform health. If real status/uptime data is needed, consider adding health checks similar to the EVaults API.

Is this intentional placeholder behavior, or should actual health checks be added here?

infrastructure/control-panel/src/routes/monitoring/+page.svelte (2)

103-104: Flexible label derivation handles varying EVault data shapes.

The fallback chain (name || ename || evault || id || 'eVault') accommodates the different field names used across the registry-based and legacy EVault representations.


509-543: Improved EVault matching logic with comprehensive field checks.

The updated matching logic correctly handles the @ prefix in ename fields and checks multiple identifier fields. The debug logging is helpful for troubleshooting.

infrastructure/control-panel/src/lib/services/loki.ts (1)

101-142: Well-structured log aggregation with deduplication.

The method correctly tries multiple query patterns, aggregates results, deduplicates by timestamp+line, and returns the last N entries. The approach handles the varying label formats across different log sources.

One minor note: The catch block at line 126-128 will rarely trigger since queryLogs already catches errors internally and returns an empty array. The try-catch is still valid for unexpected errors, but the log message could be misleading.

infrastructure/control-panel/src/routes/api/evaults/[evaultId]/details/+server.ts (1)

1-44: Clean implementation following established patterns.

The route handler correctly:

  • Fetches eVaults from registry and finds by evault or ename
  • Performs health check with appropriate timeout
  • Returns structured response with healthStatus
  • Handles errors with proper status codes

This aligns well with the sibling logs endpoint pattern.

infrastructure/control-panel/src/lib/components/EVaultList.svelte (3)

140-142: LGTM!

The empty state message correctly reflects the shift from Kubernetes to registry-based discovery.


156-169: Column headers appropriately updated for registry model.

The table headers now reflect the registry-driven EVault structure with eName (w3id) and URI replacing the Kubernetes-specific Namespace and Age columns.


183-207: Robust fallback handling for status and URI display.

The status badge logic correctly handles Active/Inactive states, and the URI rendering provides appropriate fallbacks with a clear message when unavailable.

infrastructure/control-panel/src/routes/+page.svelte (3)

33-41: LGTM!

The search filter appropriately includes the new registry-driven fields (ename, evault, id) with null-safe optional chaining.


71-90: Well-structured table mapping with proper fallbacks.

The mappedEVaultsData correctly maps the new EVault structure with appropriate fallback chains for the eVault ID, eName, and URI fields.


347-355: Correct navigation implementation.

The row click handler properly derives the evaultId using the fallback chain and correctly encodes it for URL navigation.

infrastructure/control-panel/src/routes/evaults/[evaultId]/+page.svelte (3)

14-34: Clean validation and data fetching flow.

The early validation of evaultId and the sequential fetch pattern (get all → find target → fetch details) is well-structured with appropriate error handling.


36-43: Efficient parallel data fetching.

Using Promise.all to fetch logs and details concurrently is the right approach for reducing latency.


155-169: Health status badge styling is intuitive.

The color coding (green for Healthy, yellow for Unhealthy, red for others including Unreachable) provides clear visual feedback for the eVault's health state.

infrastructure/control-panel/src/routes/api/evaults/+server.ts (1)

21-50: Good use of concurrent health checks.

Using Promise.all with individual health checks per vault is efficient. The 2-second timeout prevents slow vaults from blocking the entire response.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
infrastructure/control-panel/src/routes/monitoring/+page.svelte (1)

156-163: The isPaused state is unused — pause button has no effect.

The pause/resume button toggles isPaused (line 640), but the SSE message handler never checks this state. Events will continue to be processed and visualized regardless of the button state.

 		eventSource.onmessage = (event) => {
+			if (isPaused) return;
 			try {
 				const data = JSON.parse(event.data);
 				handleFlowEvent(data);
 			} catch (error) {
 				console.error('Error parsing SSE data:', error);
 			}
 		};
🧹 Nitpick comments (5)
infrastructure/control-panel/src/routes/monitoring/+page.svelte (5)

165-174: Consider exponential backoff for SSE reconnection.

The current reconnection logic uses a fixed 2-second delay. For better resilience against persistent failures (e.g., server down), consider implementing exponential backoff to avoid rapid reconnection attempts that could overwhelm the server when it recovers.

+	let reconnectAttempts = 0;
+	const MAX_RECONNECT_DELAY = 30000;
+
 	function subscribeToEvents() {
+		reconnectAttempts = 0;
 		eventSource = new EventSource('/api/events');
 		// ...
 		eventSource.onerror = (error) => {
 			console.error('SSE connection error:', error);
+			const delay = Math.min(1000 * Math.pow(2, reconnectAttempts), MAX_RECONNECT_DELAY);
+			reconnectAttempts++;
 			setTimeout(() => {
 				if (eventSource) {
 					eventSource.close();
 					subscribeToEvents();
 				}
-			}, 2000);
+			}, delay);
 		};

509-553: Verbose debug logging may impact performance and readability in production.

The per-iteration logging on non-matches (lines 539-549) will produce significant console output when there are many eVaults, making it harder to find relevant debug information. Consider:

  1. Moving the normalize helper outside the findIndex callback to avoid recreating it on each iteration
  2. Reducing the per-iteration logging or gating it behind a debug flag
+	// Helper to normalize IDs by removing @ symbol for comparison
+	const normalize = (id: string | undefined) => id?.replace('@', '') || '';
+
 	function getEvaultIndex(w3id: string): number {
 		console.log('getEvaultIndex called with w3id:', w3id);
-		console.log('selectedEVaults:', selectedEVaults);
 
 		// Strip the @ symbol from w3id if present
 		const cleanW3id = w3id.replace('@', '');
-		console.log('Cleaned w3id:', cleanW3id);
-
-		// Match against ename (w3id), evault, or id fields
-		// Helper to normalize IDs by removing @ symbol for comparison
-		const normalize = (id: string | undefined) => id?.replace('@', '') || '';
 
 		const index = selectedEVaults.findIndex((e, idx) => {
 			// ... matching logic ...
-
-			} else {
-				// Log why it didn't match for debugging
-				console.log(`eVault ${idx} didn't match:`, {
-					eventW3id: w3id,
-					eventCleanW3id: cleanW3id,
-					evaultEname: e.ename,
-					// ... extensive logging ...
-				});
 			}
 
 			return matches;
 		});

722-728: Unused loop index variable.

The loop variable i is declared but never used. Consider removing it to avoid lint warnings.

-				{#each flowMessages as message, i}
+				{#each flowMessages as message}
 					<div class="rounded bg-gray-50 p-2 font-mono text-sm">
 						{message}
 					</div>
 				{/each}

147-151: Pending timeouts are not cancelled on component destruction.

Multiple setTimeout calls throughout the component (lines 236, 266, 269, 273, 305, 309, 359, 400, 431) modify component state after delays. If the component unmounts before these timeouts complete, they may attempt to update stale state. Consider tracking and clearing pending timeouts in onDestroy.

+	let pendingTimeouts: ReturnType<typeof setTimeout>[] = [];
+
+	function safeTimeout(fn: () => void, delay: number) {
+		const id = setTimeout(() => {
+			pendingTimeouts = pendingTimeouts.filter(t => t !== id);
+			fn();
+		}, delay);
+		pendingTimeouts.push(id);
+		return id;
+	}
+
 	onDestroy(() => {
 		if (eventSource) {
 			eventSource.close();
 		}
+		pendingTimeouts.forEach(clearTimeout);
 	});

Then replace setTimeout calls with safeTimeout throughout.


476-499: Inconsistent fallback behavior between getPlatformIndex and getEvaultIndex.

getEvaultIndex correctly returns -1 when no match is found (and the caller handles this), but getPlatformIndex falls back to 0 (line 498), which could silently visualize data flow to the wrong platform. Consider aligning the behavior.

-		return index >= 0 ? index : 0;
+		if (index === -1) {
+			console.log('No matching platform found for:', platformName);
+		}
+		return index;
 	}

Then update handleEvaultSyncEvent to also check for platformIndex === -1 before visualization.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d24c4cf and 74da3f3.

📒 Files selected for processing (2)
  • .env.example (1 hunks)
  • infrastructure/control-panel/src/routes/monitoring/+page.svelte (4 hunks)
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-05-08T09:02:43.311Z
Learnt from: pixel-punk-20
Repo: MetaState-Prototype-Project/prototype PR: 121
File: platforms/metagram/src/stories/Button.svelte:0-0
Timestamp: 2025-05-08T09:02:43.311Z
Learning: The project uses Svelte 5, which uses the new "runes" API including $props() for handling component props instead of the export let syntax from Svelte 3/4.

Applied to files:

  • infrastructure/control-panel/src/routes/monitoring/+page.svelte
📚 Learning: 2025-05-08T09:02:43.311Z
Learnt from: pixel-punk-20
Repo: MetaState-Prototype-Project/prototype PR: 121
File: platforms/metagram/src/stories/Button.svelte:0-0
Timestamp: 2025-05-08T09:02:43.311Z
Learning: The project uses Svelte 5, which introduces the new "runes" API including $props() for handling component props instead of the export let syntax from Svelte 3/4.

Applied to files:

  • infrastructure/control-panel/src/routes/monitoring/+page.svelte
📚 Learning: 2025-11-13T10:34:52.527Z
Learnt from: coodos
Repo: MetaState-Prototype-Project/prototype PR: 415
File: infrastructure/eid-wallet/src/env.d.ts:8-8
Timestamp: 2025-11-13T10:34:52.527Z
Learning: In infrastructure/eid-wallet, PUBLIC_PLATFORM_URL should not be added to .env.example or configured as a static environment variable. The platform URL is extracted dynamically through URI parsing according to the protocol specification, and all fallbacks for platform URL are being removed.

Applied to files:

  • .env.example
🪛 dotenv-linter (4.0.0)
.env.example

[warning] 79-79: [UnorderedKey] The LOKI_PASSWORD key should go before the LOKI_URL key

(UnorderedKey)


[warning] 81-81: [DuplicatedKey] The LOKI_URL key is duplicated

(DuplicatedKey)


[warning] 82-82: [DuplicatedKey] The LOKI_USERNAME key is duplicated

(DuplicatedKey)


[warning] 83-83: [DuplicatedKey] The LOKI_PASSWORD key is duplicated

(DuplicatedKey)


[warning] 83-83: [UnorderedKey] The LOKI_PASSWORD key should go before the LOKI_URL key

(UnorderedKey)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: test
  • GitHub Check: test
  • GitHub Check: test-web3-adapter-integration
  • GitHub Check: build
🔇 Additional comments (3)
infrastructure/control-panel/src/routes/monitoring/+page.svelte (2)

1-31: LGTM!

The imports are well-organized, and the component correctly uses Svelte 5 runes ($state) for reactive state management. The pattern of statically importing Background and Controls while dynamically loading SvelteFlowComponent is appropriate for code splitting.


97-110: LGTM!

The label derivation logic correctly handles the new registry-based data model with appropriate fallback chains (name → ename → evault → id → 'eVault' for labels and uri → serviceUrl → 'Unknown' for sub-labels). This provides good backward compatibility with different data sources.

.env.example (1)

75-75: Good addition for EID wallet token.

The new PUBLIC_EID_WALLET_TOKEN environment variable aligns with the registry-driven authentication model and includes a helpful comment about obtaining the value.

Comment on lines +77 to +83
LOKI_URL=http://localhost:3100
LOKI_USERNAME=admin
LOKI_PASSWORD=admin

LOKI_URL=http://146.190.29.56:3100
LOKI_USERNAME=admin
LOKI_PASSWORD=admin
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# First, find the .env.example file and check its content around the specified lines
fd -name ".env.example" -type f

Repository: MetaState-Prototype-Project/prototype

Length of output: 311


🏁 Script executed:

#!/bin/bash
# Find the .env.example file
fd ".env.example" -type f

Repository: MetaState-Prototype-Project/prototype

Length of output: 251


🏁 Script executed:

#!/bin/bash
# Find the .env.example file
fd ".env.example"

Repository: MetaState-Prototype-Project/prototype

Length of output: 154


🏁 Script executed:

#!/bin/bash
# Check the content of both .env.example files, focusing on lines around 77-83
echo "=== infrastructure/control-panel/.env.example ==="
wc -l infrastructure/control-panel/.env.example
echo ""
echo "Lines 70-90:"
sed -n '70,90p' infrastructure/control-panel/.env.example

echo ""
echo "=== platforms/pictique/.env.example ==="
wc -l platforms/pictique/.env.example
echo ""
echo "Lines 70-90:"
sed -n '70,90p' platforms/pictique/.env.example

Repository: MetaState-Prototype-Project/prototype

Length of output: 277


🏁 Script executed:

#!/bin/bash
# Search for files containing LOKI_URL
echo "=== Files containing LOKI_URL ==="
rg "LOKI_URL" -l

echo ""
echo "=== Context around LOKI_URL matches ==="
rg "LOKI_URL" -B2 -A2

Repository: MetaState-Prototype-Project/prototype

Length of output: 1387


🏁 Script executed:

#!/bin/bash
# Check git diff to see what changed in the PR
echo "=== Git diff for infrastructure/control-panel/.env.example ==="
git diff HEAD infrastructure/control-panel/.env.example

echo ""
echo "=== Full content of infrastructure/control-panel/.env.example ==="
cat -n infrastructure/control-panel/.env.example

Repository: MetaState-Prototype-Project/prototype

Length of output: 443


🏁 Script executed:

#!/bin/bash
# Look for .env files in infrastructure/eid-wallet (mentioned in learnings)
echo "=== Search for .env files in infrastructure/eid-wallet ==="
fd ".env" infrastructure/eid-wallet

echo ""
echo "=== Search for any .env files in infrastructure/ ==="
fd ".env" infrastructure/

echo ""
echo "=== Check git log to see recent changes to .env.example files ==="
git log --oneline infrastructure/control-panel/.env.example | head -10

Repository: MetaState-Prototype-Project/prototype

Length of output: 341


🏁 Script executed:

#!/bin/bash
# Check current branch and git status
echo "=== Current branch info ==="
git branch -v
git log --oneline -5

echo ""
echo "=== Check if there are other .env.example files ==="
find . -name ".env*" -type f

echo ""
echo "=== Search for the IP 146.190.29.56 in the entire codebase ==="
rg "146.190.29.56"

Repository: MetaState-Prototype-Project/prototype

Length of output: 614


🏁 Script executed:

#!/bin/bash
# Check the root .env.example file
echo "=== Root .env.example file ==="
wc -l .env.example

echo ""
echo "=== Lines 70-90 of root .env.example ==="
sed -n '70,90p' .env.example

echo ""
echo "=== Search for LOKI in root .env.example ==="
grep -n "LOKI" .env.example

Repository: MetaState-Prototype-Project/prototype

Length of output: 740


🏁 Script executed:

#!/bin/bash
# Check git diff for root .env.example
echo "=== Git diff for .env.example ==="
git diff HEAD .env.example

echo ""
echo "=== Git log for .env.example ==="
git log --oneline .env.example | head -5

echo ""
echo "=== Full content of .env.example to verify context ==="
cat -n .env.example | tail -20

Repository: MetaState-Prototype-Project/prototype

Length of output: 1012


🏁 Script executed:

#!/bin/bash
# Search for .env file parsing/loading to understand how duplicates are handled
echo "=== Search for dotenv or env loading patterns ==="
rg "dotenv|process\.env|EnvConfig|env\.load" --type=ts --type=js -B2 -A2 | head -60

echo ""
echo "=== Check if .env.example is referenced in package.json or build config ==="
fd "package.json|vite.config|webpack.config|tsconfig" | xargs grep -l "env.example" 2>/dev/null || echo "No references found"

Repository: MetaState-Prototype-Project/prototype

Length of output: 4124


Remove duplicate Loki environment variables from .env.example.

Lines 77–83 contain duplicate LOKI_URL, LOKI_USERNAME, and LOKI_PASSWORD keys. The second set (lines 81–83) will overwrite the first during dotenv parsing, causing the production IP address (146.190.29.56) to be used instead of the localhost development configuration. Additionally, .env.example should contain a single canonical set of example values, not multiple configurations.

Apply this diff to keep only the development configuration:

 LOKI_URL=http://localhost:3100
 LOKI_USERNAME=admin
 LOKI_PASSWORD=admin
-
-LOKI_URL=http://146.190.29.56:3100
-LOKI_USERNAME=admin
-LOKI_PASSWORD=admin

Alternatively, if production configuration reference is needed:

 LOKI_URL=http://localhost:3100
 LOKI_USERNAME=admin
 LOKI_PASSWORD=admin
+
+# Production Loki configuration (use via environment secrets, not this file):
+# LOKI_URL=http://146.190.29.56:3100
+# LOKI_USERNAME=admin
+# LOKI_PASSWORD=admin
📝 Committable suggestion

‼️ 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.

Suggested change
LOKI_URL=http://localhost:3100
LOKI_USERNAME=admin
LOKI_PASSWORD=admin
LOKI_URL=http://146.190.29.56:3100
LOKI_USERNAME=admin
LOKI_PASSWORD=admin
LOKI_URL=http://localhost:3100
LOKI_USERNAME=admin
LOKI_PASSWORD=admin
🧰 Tools
🪛 dotenv-linter (4.0.0)

[warning] 79-79: [UnorderedKey] The LOKI_PASSWORD key should go before the LOKI_URL key

(UnorderedKey)


[warning] 81-81: [DuplicatedKey] The LOKI_URL key is duplicated

(DuplicatedKey)


[warning] 82-82: [DuplicatedKey] The LOKI_USERNAME key is duplicated

(DuplicatedKey)


[warning] 83-83: [DuplicatedKey] The LOKI_PASSWORD key is duplicated

(DuplicatedKey)


[warning] 83-83: [UnorderedKey] The LOKI_PASSWORD key should go before the LOKI_URL key

(UnorderedKey)

🤖 Prompt for AI Agents
In .env.example around lines 77 to 83, there are duplicate
LOKI_URL/LOKI_USERNAME/LOKI_PASSWORD entries; remove the duplicate production
block so only the development configuration (LOKI_URL=http://localhost:3100,
LOKI_USERNAME=admin, LOKI_PASSWORD=admin) remains, deleting the second set (the
146.190.29.56 lines) to ensure a single canonical example and prevent dotenv
from being overwritten by the production IP.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants