Skip to content

feat: improve setup and infrastructure workflows - #12

Merged
ryzenate1 merged 1 commit into
mainfrom
mvp-v6
Sep 30, 2026
Merged

ryzenate1 merged 1 commit into
mainfrom
mvp-v6

Conversation

@ryzenate1

@ryzenate1 ryzenate1 commented Sep 30, 2026 •

Copy link
Copy Markdown
Owner

CodeAnt-AI Description

Expand setup, security, node visibility, and certificate administration workflows

What Changed

  • Setup can now skip optional organization, node, email, backup, and domain sections, with skipped values cleared, validated, and reported for later completion
  • Setup status reminds administrators about unfinished organization, node, and email configuration
  • Password creation, reset, and change flows now enforce and display the 12-character mixed-character password policy
  • Node lists and details show runtime state, version, address, and accurate last-heartbeat information, including clear mock-runtime warnings
  • Certificate administration supports domain-bound custom certificate imports, Let's Encrypt attachment, default ACME account selection, DNS account deletion, and API response envelopes
  • Login allows legitimate multi-step sign-in flows while retaining per-account failed-attempt protection; user responses no longer expose password hashes or TOTP secrets
  • Admin monitoring, discovery, firewall, traffic, procedures, and reconciliation views refresh automatically; empty and failed runtime reads now explain whether data is unavailable or genuinely absent
  • Local development starts without seeded demo administrators or nodes, requiring the setup flow

Impact

✅ Faster first-time setup
✅ Clearer node heartbeat and runtime status
✅ Stronger password protection
✅ Safer user and login responses
✅ Fewer stale admin views

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

@codeant-ai

codeant-ai Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

🤖 CodeAnt AI — Review Status

Status Commit Started (UTC) Finished (UTC)
✅ Reviewed your PR 4905ee2 Sep 30, 2026 · 15:01 15:05

@codeant-ai

codeant-ai Bot commented Sep 30, 2026

Copy link
Copy Markdown

Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@coderabbitai

coderabbitai Bot commented Sep 30, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: ab22e50d-206b-4edd-b257-f38803bc8bad

  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


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.

@codeant-ai codeant-ai Bot added the size:XXL This PR changes 1000+ lines, ignoring generated files label Sep 30, 2026
@ryzenate1
ryzenate1 merged commit be4043e into main Sep 30, 2026
6 of 7 checks passed
saving={updateMut.isPending}
/>
)}
{renderConfirm()}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: renderConfirm() is already rendered above, so this second call creates two identical open confirmation dialogs with competing overlays and focus traps.

Assessment: 🟠 Major · 🔁 Occurrence: Sometimes · 🏷️ Logic error

Use CodeAnt Skill Fix in Cursor Fix in VSCode Claude

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** forge/web/components/database/managed-database-view.tsx
**Line:** 495:495
**Comment:**
	*Logic Error: `renderConfirm()` is already rendered above, so this second call creates two identical open confirmation dialogs with competing overlays and focus traps.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

Comment thread lang/de.json
Comment on lines +597 to +599
"skip": "TODO-i18n: Skip",
"skipped": "TODO-i18n: Skipped",
"setUpLater": "TODO-i18n: Set up later",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: German users see literal TODO-i18n: text for every newly added setup label and status message instead of usable translations.

Assessment: 🟠 Major · 🔁 Occurrence: Often · 🏷️ Code quality

Use CodeAnt Skill Fix in Cursor Fix in VSCode Claude

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** lang/de.json
**Line:** 597:599
**Comment:**
	*Code Quality: German users see literal `TODO-i18n:` text for every newly added setup label and status message instead of usable translations.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

Comment thread lang/es.json
Comment on lines +597 to +599
"skip": "TODO-i18n: Skip",
"skipped": "TODO-i18n: Skipped",
"setUpLater": "TODO-i18n: Set up later",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: Spanish users see literal TODO-i18n: text for every newly added setup label and status message instead of usable translations.

Assessment: 🟠 Major · 🔁 Occurrence: Often · 🏷️ Code quality

Use CodeAnt Skill Fix in Cursor Fix in VSCode Claude

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** lang/es.json
**Line:** 597:599
**Comment:**
	*Code Quality: Spanish users see literal `TODO-i18n:` text for every newly added setup label and status message instead of usable translations.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

Comment thread lang/fr.json
Comment on lines +597 to +599
"skip": "TODO-i18n: Skip",
"skipped": "TODO-i18n: Skipped",
"setUpLater": "TODO-i18n: Set up later",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: French users see literal TODO-i18n: text for every newly added setup label and status message instead of usable translations.

Assessment: 🟠 Major · 🔁 Occurrence: Often · 🏷️ Code quality

Use CodeAnt Skill Fix in Cursor Fix in VSCode Claude

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** lang/fr.json
**Line:** 597:599
**Comment:**
	*Code Quality: French users see literal `TODO-i18n:` text for every newly added setup label and status message instead of usable translations.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

Comment thread docs/acme-letsencrypt.md
Comment on lines +72 to +74
curl -s -b "$COOKIE" -X POST $API/acme/accounts \
-H 'Content-Type: application/json' \
-d '{"email":"admin@example.com","caUrl":"https://acme-staging-v02.api.letsencrypt.org/directory"}'

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: The documented mutating request sends only the session cookie, not the required CSRF cookie and X-CSRF-Token header, so the API rejects it with 403.

Assessment: 🟠 Major · 🔁 Occurrence: Often · 🏷️ Api mismatch

Use CodeAnt Skill Fix in Cursor Fix in VSCode Claude

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** docs/acme-letsencrypt.md
**Line:** 72:74
**Comment:**
	*Api Mismatch: The documented mutating request sends only the session cookie, not the required CSRF cookie and `X-CSRF-Token` header, so the API rejects it with 403.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

Comment on lines +27 to +32
var setupSkippableSteps = map[string]bool{
"organization": true,
"node": true,
"email": true,
"backup": true,
"domain": true,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: backup and domain are accepted as skipped steps, but pending setup state never tracks them, so skipped sections cannot be surfaced for later completion.

Assessment: 🟠 Major · 🔁 Occurrence: Sometimes · 🏷️ Incomplete implementation

Use CodeAnt Skill Fix in Cursor Fix in VSCode Claude

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** forge/api/internal/http/handlers_setup.go
**Line:** 27:32
**Comment:**
	*Incomplete Implementation: `backup` and `domain` are accepted as skipped steps, but pending setup state never tracks them, so skipped sections cannot be surfaced for later completion.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

Comment thread forge/web/app/page.tsx
const [setupInfo, setSetupInfo] = useState<ApiSetupStatus | null>(null);
const [pendingDismissed, setPendingDismissed] = useState(() => {
try {
return typeof window !== "undefined" && window.localStorage.getItem("forge:setup-pending-dismissed") === "1";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: The dismissal flag is shared by every user and persists after setup changes, so one user can permanently hide pending-setup reminders from other administrators.

Assessment: 🟠 Major · 🔁 Occurrence: Sometimes · 🏷️ Stale reference

Use CodeAnt Skill Fix in Cursor Fix in VSCode Claude

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** forge/web/app/page.tsx
**Line:** 44:44
**Comment:**
	*Stale Reference: The dismissal flag is shared by every user and persists after setup changes, so one user can permanently hide pending-setup reminders from other administrators.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

<div className="rounded-xl border border-line bg-overlay-subtle px-4 py-2 text-xs leading-5 text-text-subtle">
<span className="font-semibold text-text">Beacons</span> is the product term for <span className="font-mono text-[11px]">store.go:129 Node</span> — API alias <code className="font-mono">GET /beacons</code> → <code className="font-mono">GET /nodes</code> compat kept. Click a row for the 8-tab workspace (Overview/Metrics/Workloads/Networking/Storage/Capabilities/Placement/Config).
<span className="ml-2 font-mono text-[11px] text-text-muted">{nodes.length} total · {healthy} healthy · 8-tab detail → /admin/nodes/[id]</span>
<span className="ml-2 font-mono text-[11px] text-text-muted">{nodes.length} total · {healthy} healthy{degraded > 0 ? ` · ${degraded} degraded (mock runtime)` : ""} · 8-tab detail → /admin/nodes/[id]</span>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: This text labels every degraded node as using a mock runtime, although degraded state can result from other health conditions and does not establish mock runtime usage.

Assessment: 🟠 Major · 🔁 Occurrence: Sometimes · 🏷️ Incorrect condition logic

Use CodeAnt Skill Fix in Cursor Fix in VSCode Claude

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** forge/web/components/admin/AdminNodes.tsx
**Line:** 100:100
**Comment:**
	*Incorrect Condition Logic: This text labels every degraded node as using a mock runtime, although degraded state can result from other health conditions and does not establish mock runtime usage.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

const provider = (node.runtimeProvider || node.schedulerType || "docker").toLowerCase();
const status = (node.runtimeStatus || "").toLowerCase();
const signal = `${node.dockerStatus ?? ""} ${node.heartbeatError ?? ""}`.toLowerCase();
const mock = status === "error" || signal.includes("unavailable") || signal.includes("mock");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: Every runtime error is labeled mock, including real production runtime outages, causing the UI to misrepresent unavailable Docker nodes as intentionally mocked.

Assessment: 🟠 Major · 🔁 Occurrence: Sometimes · 🏷️ Incorrect condition logic

Use CodeAnt Skill Fix in Cursor Fix in VSCode Claude

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** forge/web/lib/admin/node-display.ts
**Line:** 26:26
**Comment:**
	*Incorrect Condition Logic: Every runtime error is labeled `mock`, including real production runtime outages, causing the UI to misrepresent unavailable Docker nodes as intentionally mocked.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

onCancel={() => setModal(false)}
onConfirm={() => createMut.mutate()}
disabled={email.trim() === "" || password.length < 8 || createMut.isPending}
disabled={email.trim() === "" || !isPasswordValid(password) || createMut.isPending}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: The browser counts Unicode characters differently from the backend's byte length, so some valid Unicode passwords cannot be submitted.

Assessment: 🟠 Major · 🔁 Occurrence: Sometimes · 🏷️ Api mismatch

Use CodeAnt Skill Fix in Cursor Fix in VSCode Claude

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** forge/web/components/admin/AdminUsers.tsx
**Line:** 366:366
**Comment:**
	*Api Mismatch: The browser counts Unicode characters differently from the backend's byte length, so some valid Unicode passwords cannot be submitted.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

Comment on lines +401 to 403
if err == nil && count >= loginMaxAttempts {
return fiber.NewError(fiber.StatusTooManyRequests, "too many login attempts; try again later")
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: Ten failed attempts for any normalized email block that account for five minutes, allowing unauthenticated attackers to deny the account's legitimate logins.

Assessment: 🟠 Major · 🔁 Occurrence: Sometimes · 🏷️ Security

Use CodeAnt Skill Fix in Cursor Fix in VSCode Claude

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** forge/api/internal/http/server.go
**Line:** 401:403
**Comment:**
	*Security: Ten failed attempts for any normalized email block that account for five minutes, allowing unauthenticated attackers to deny the account's legitimate logins.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

Comment on lines +16 to +20
type SetupPendingState struct {
Organization bool `json:"organization"`
Node bool `json:"node"`
Email bool `json:"email"`
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: SetupPendingState omits backup and domain, so skipped backup or domain configuration can never appear in the post-setup reminder.

Assessment: 🟠 Major · 🔁 Occurrence: Sometimes · 🏷️ Api mismatch

Use CodeAnt Skill Fix in Cursor Fix in VSCode Claude

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** forge/api/internal/store/store_setup.go
**Line:** 16:20
**Comment:**
	*Api Mismatch: `SetupPendingState` omits backup and domain, so skipped backup or domain configuration can never appear in the post-setup reminder.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

// PUT /domains/:id { certType: "letsencrypt" } provisions via the Caddy
// TLS manager; custom PEM binding is done at upload time through POST
// /certificates with a domainId (see upload modal).
return attachCertificateToDomain(attachForm.domainId.trim(), { certType: "letsencrypt", autoRenew: true, https: true });

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: The attach request ignores both certId and mode, so the modal always enables Let's Encrypt instead of attaching the selected certificate or requested certificate type.

Assessment: 🟠 Major · 🔁 Occurrence: Sometimes · 🏷️ Incorrect variable usage

Use CodeAnt Skill Fix in Cursor Fix in VSCode Claude

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** forge/web/app/admin/certificates/page.tsx
**Line:** 110:110
**Comment:**
	*Incorrect Variable Usage: The attach request ignores both `certId` and `mode`, so the modal always enables Let's Encrypt instead of attaching the selected certificate or requested certificate type.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

Comment on lines +161 to +163
for (const id of ids) {
if (!next.includes(id)) next.push(id);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: Once a step is skipped, its ID is never removed; returning with Back and completing that step still sends it as skipped, so the backend discards the entered values.

Assessment: 🟠 Major · 🔁 Occurrence: Sometimes · 🏷️ Stale reference

Use CodeAnt Skill Fix in Cursor Fix in VSCode Claude

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** forge/web/app/setup/page.tsx
**Line:** 161:163
**Comment:**
	*Stale Reference: Once a step is skipped, its ID is never removed; returning with Back and completing that step still sends it as skipped, so the backend discards the entered values.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎


export function evaluatePassword(password: string): PasswordEvaluation {
return {
minLength: password.length >= 12,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: JavaScript counts UTF-16 code units, while the backend checks UTF-8 bytes, so valid multibyte passwords can be rejected by the setup form.

Assessment: 🟠 Major · 🔁 Occurrence: Rarely · 🏷️ Type error

Use CodeAnt Skill Fix in Cursor Fix in VSCode Claude

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** forge/web/components/ui/password-requirements.tsx
**Line:** 22:22
**Comment:**
	*Type Error: JavaScript counts UTF-16 code units, while the backend checks UTF-8 bytes, so valid multibyte passwords can be rejected by the setup form.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

@codeant-ai

codeant-ai Bot commented Sep 30, 2026

Copy link
Copy Markdown

CodeAnt Nitpicks

6 code suggestions

1. This table says production automatically places stacks, contradicting the preceding requirement that nodeId is mandatory and missing it causes scheduler failure.

Logic error · docs/website-hosting.md:151


2. Skipping backup resets backupDriver to local, while the backend clears it; the completion screen therefore falsely reports local backups after skipping.

Logic error · forge/web/app/setup/page.tsx:150


3. The Japanese locale exposes literal TODO-i18n markers for setup actions and status messages, so Japanese users see unfinished English placeholder text.

Code quality · lang/ja.json:601


4. The Portuguese locale exposes literal TODO-i18n markers for setup actions and status messages, so Portuguese users see unfinished English placeholder text.

Code quality · lang/pt.json:601


5. The Russian locale exposes literal TODO-i18n markers for setup actions and status messages, so Russian users see unfinished English placeholder text.

Code quality · lang/ru.json:601


6. The Chinese locale exposes literal TODO-i18n markers for setup actions and status messages, so Chinese users see unfinished English placeholder text.

Code quality · lang/zh.json:601

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

Labels

size:XXL This PR changes 1000+ lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant