Skip to content

feat: add domain verification status command#192

Merged
yuaanlin merged 4 commits intomainfrom
feat/verification-status
Mar 22, 2026
Merged

feat: add domain verification status command#192
yuaanlin merged 4 commits intomainfrom
feat/verification-status

Conversation

@yuaanlin
Copy link
Copy Markdown
Member

@yuaanlin yuaanlin commented Mar 22, 2026

Summary

  • Add zeabur domain verification status subcommand to check ICANN registrant verification status for a registered domain
  • Show verification status column in zeabur domain list-registered table output

Test plan

  • Run zeabur domain verification status interactively and verify it shows the correct status
  • Run zeabur domain verification status --id <id> non-interactively
  • Run zeabur domain verification status --id <id> --json for JSON output
  • Run zeabur domain list-registered and verify the new "Verification" column appears

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added a command to check ICANN registrant verification status for registered domains, supporting interactive domain selection and direct ID lookup.
    • Domain listings now include a "Verification" column (shows "N/A" when unavailable).
    • Viewing a registered domain (non-JSON) now shows a Registrant Profile table (Name, Email, Phone, Country) when present.
    • Added an interactive command to update registrant contact details with validation and confirmation.

Add `zeabur domain verification status` to check ICANN registrant
verification status. Also show verification status in `domain list-registered`.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 22, 2026

Caution

Review failed

Pull request was closed or merged during review

Walkthrough

Adds two new verification subcommands (status, update-contact), registers status with the verification command tree, extends RegisteredDomain with RegistrantProfile and verification data, and prints registrant profile details in get-registered output when present.

Changes

Cohort / File(s) Summary
Verification commands
internal/cmd/domain/verification/status.go, internal/cmd/domain/verification/update_contact.go, internal/cmd/domain/verification/verification.go
Added status and update-contact Cobra subcommands; verification.go registers newCmdStatus(f) and newCmdUpdateContact(f). status fetches and displays ICANN registrant verification status (supports --id, interactive selection, JSON or table output). update-contact prompts/accepts registrant contact/address fields, pre-fills from existing profile when available, validates required fields, and calls ApiClient.UpdateRegistrantContact.
RegisteredDomain model
pkg/model/registered_domain.go
Added exported field RegistrantProfile *RegistrantProfile and a "Verification" column to Header(); Rows() now populates the verification column from RegistrantVerificationStatus (falls back to "N/A").
Get Registered Domain output
internal/cmd/domain/get-registered/get.go
When domain.RegistrantProfile is non-nil and output is non-JSON, prints an additional "Registrant Profile" table (Name = FirstName + LastName, Email, Phone, Country).

Sequence Diagram

sequenceDiagram
    participant User
    participant CLI
    participant ApiClient
    participant Output

    User->>CLI: run "domain verification status" [--id]
    alt id provided
        CLI->>ApiClient: GetRegisteredDomain(id)
    else no id & interactive
        CLI->>ApiClient: ListRegisteredDomains()
        ApiClient-->>CLI: domain list
        CLI->>User: prompt to select domain
        User-->>CLI: selects domain
        CLI->>ApiClient: GetRegisteredDomain(selectedID)
    else no id & non-interactive
        CLI-->>User: error (id required)
    end
    ApiClient-->>CLI: RegisteredDomain (RegistrantVerificationStatus, RegistrantProfile)
    CLI->>Output: render JSON or table (Domain, Verification Status)
    alt RegistrantProfile present & table mode
        CLI->>Output: render Registrant Profile table
    end
    Output-->>User: display results
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: add domain verification status command' accurately reflects the primary change—adding a new verification status subcommand. It is concise, specific, and directly related to the main objective of the pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/verification-status

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

yuaanlin and others added 2 commits March 22, 2026 17:21
Query the nested registrantProfile field so users can see which
registrant email is associated with a domain.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Allow updating the registrant contact info on a domain via
`zeabur domain verification update-contact`. Changing the email
triggers a new ICANN verification flow. Interactive mode pre-fills
from the current registrant profile.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@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

🧹 Nitpick comments (1)
internal/cmd/domain/verification/update_contact.go (1)

86-153: Consider extracting a helper to reduce duplication.

The prompting logic in lines 86-118 (with pre-fill) and 120-152 (without pre-fill) is nearly identical. You could unify this by extracting default values first, then having a single prompting block.

♻️ Suggested refactor
 	if f.Interactive {
-		// Pre-fill from current registrant profile if available
 		domain, err := f.ApiClient.GetRegisteredDomain(ctx, opts.id)
-		if err == nil && domain.RegistrantProfile != nil {
-			p := domain.RegistrantProfile
-			if opts.firstName == "" {
-				opts.firstName, _ = f.Prompter.Input("First name: ", p.FirstName)
-			}
-			if opts.lastName == "" {
-				opts.lastName, _ = f.Prompter.Input("Last name: ", p.LastName)
-			}
-			if opts.email == "" {
-				opts.email, _ = f.Prompter.Input("Email: ", p.Email)
-			}
-			if opts.phone == "" {
-				opts.phone, _ = f.Prompter.Input("Phone (e.g. +1.5551234567): ", p.Phone)
-			}
-			if opts.address1 == "" {
-				opts.address1, _ = f.Prompter.Input("Address: ", p.Address1)
-			}
-			if opts.address2 == "" {
-				opts.address2, _ = f.Prompter.Input("Address line 2 (optional): ", "")
-			}
-			if opts.city == "" {
-				opts.city, _ = f.Prompter.Input("City: ", p.City)
-			}
-			if opts.state == "" {
-				opts.state, _ = f.Prompter.Input("State/Province: ", p.State)
-			}
-			if opts.country == "" {
-				opts.country, _ = f.Prompter.Input("Country (e.g. US): ", p.Country)
-			}
-			if opts.postalCode == "" {
-				opts.postalCode, _ = f.Prompter.Input("Postal code: ", p.PostalCode)
-			}
-			if opts.organization == "" {
-				opts.organization, _ = f.Prompter.Input("Organization (optional): ", p.Organization)
-			}
-		} else {
-			if opts.firstName == "" {
-				opts.firstName, _ = f.Prompter.Input("First name: ", "")
-			}
-			// ... rest of prompts with empty defaults
+		// Pre-fill defaults from current registrant profile if available
+		var defaults model.RegistrantProfile
+		if err == nil && domain.RegistrantProfile != nil {
+			defaults = *domain.RegistrantProfile
+		}
+		if opts.firstName == "" {
+			opts.firstName, _ = f.Prompter.Input("First name: ", defaults.FirstName)
+		}
+		if opts.lastName == "" {
+			opts.lastName, _ = f.Prompter.Input("Last name: ", defaults.LastName)
+		}
+		// ... continue for other fields
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/cmd/domain/verification/update_contact.go` around lines 86 - 153,
Extract a small helper to remove the duplicated prompting block: create a
function (e.g., promptIfEmpty(prompt string, currentVal string) string) that
calls f.Prompter.Input and returns the chosen value, then replace the two large
branches with logic that first computes default values (use
p.FirstName/p.LastName/... when prefill is true, otherwise empty strings) and
then calls promptIfEmpty for each field (opts.firstName, opts.lastName,
opts.email, opts.phone, opts.address1, opts.address2, opts.city, opts.state,
opts.country, opts.postalCode, opts.organization) so all prompting uses the
single helper and the duplicated input calls to f.Prompter.Input are removed.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@internal/cmd/domain/verification/update_contact.go`:
- Around line 202-205: The note about ICANN verification is printed
unconditionally because opts.email is validated as required; instead capture the
original registrant email before prompts (e.g., store registrant.Email from the
fetched profile into originalEmail) and then compare originalEmail != opts.email
before calling f.Log.Infof("Note: changing the email triggers a new ICANN
verification flow"); update the logic around the f.Log.Infof that currently
follows the "Registrant contact updated successfully" message to only log when
the email changed (or, if storing beforehand is impossible, refetch the
registrant profile after updates and compare the before/after emails to decide
whether to log).

---

Nitpick comments:
In `@internal/cmd/domain/verification/update_contact.go`:
- Around line 86-153: Extract a small helper to remove the duplicated prompting
block: create a function (e.g., promptIfEmpty(prompt string, currentVal string)
string) that calls f.Prompter.Input and returns the chosen value, then replace
the two large branches with logic that first computes default values (use
p.FirstName/p.LastName/... when prefill is true, otherwise empty strings) and
then calls promptIfEmpty for each field (opts.firstName, opts.lastName,
opts.email, opts.phone, opts.address1, opts.address2, opts.city, opts.state,
opts.country, opts.postalCode, opts.organization) so all prompting uses the
single helper and the duplicated input calls to f.Prompter.Input are removed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f1505721-3f29-4644-9bba-a9ccae7c0559

📥 Commits

Reviewing files that changed from the base of the PR and between 5beb41f and 4cb4f05.

📒 Files selected for processing (2)
  • internal/cmd/domain/verification/update_contact.go
  • internal/cmd/domain/verification/verification.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • internal/cmd/domain/verification/verification.go

Comment thread internal/cmd/domain/verification/update_contact.go
Track the original registrant email before prompts and compare
after update to avoid always showing the verification warning.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@yuaanlin yuaanlin merged commit 80a3c0d into main Mar 22, 2026
4 of 5 checks passed
@yuaanlin yuaanlin deleted the feat/verification-status branch March 22, 2026 09:42
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.

1 participant