Skip to content

Commit e698c0a

Browse files
cpcloudclaude
andcommitted
feat(cli): format phone numbers in show vendors output
Table output uses FormatPhoneNumber with vendor locale fallback. JSON output preserves raw phone values for machine consumption. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 86b4795 commit e698c0a

2 files changed

Lines changed: 33 additions & 4 deletions

File tree

cmd/micasa/show.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ import (
1212
"text/tabwriter"
1313
"time"
1414

15+
"github.com/micasa-dev/micasa/internal/config"
1516
"github.com/micasa-dev/micasa/internal/data"
17+
"github.com/micasa-dev/micasa/internal/locale"
1618
"github.com/spf13/cobra"
1719
"gorm.io/gorm"
1820
)
@@ -447,7 +449,13 @@ var vendorCols = []showCol[data.Vendor]{
447449
{"NAME", func(v data.Vendor) string { return fmtStr(v.Name) }},
448450
{"CONTACT", func(v data.Vendor) string { return fmtStr(v.ContactName) }},
449451
{"EMAIL", func(v data.Vendor) string { return fmtStr(v.Email) }},
450-
{"PHONE", func(v data.Vendor) string { return fmtStr(v.Phone) }},
452+
{"PHONE", func(v data.Vendor) string {
453+
region := strings.ToUpper(config.DetectCountry())
454+
if v.Locale != "" {
455+
region = strings.ToUpper(v.Locale)
456+
}
457+
return fmtStr(locale.FormatPhoneNumber(v.Phone, region))
458+
}},
451459
{"WEBSITE", func(v data.Vendor) string { return fmtStr(v.Website) }},
452460
}
453461

cmd/micasa/show_test.go

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,14 +169,16 @@ func TestShowProjectsJSON(t *testing.T) {
169169
}
170170

171171
func TestShowVendorsText(t *testing.T) {
172-
t.Parallel()
172+
// Not parallel: t.Setenv modifies process-global state.
173+
// LC_ALL has highest precedence in DetectCountry().
174+
t.Setenv("LC_ALL", "en_US.UTF-8")
173175
store := newTestStoreWithMigration(t)
174176

175177
require.NoError(t, store.CreateVendor(&data.Vendor{
176178
Name: "Acme Plumbing",
177179
ContactName: "John Doe",
178180
Email: "john@acme.com",
179-
Phone: "555-1234",
181+
Phone: "5551234567",
180182
}))
181183

182184
var buf bytes.Buffer
@@ -187,7 +189,7 @@ func TestShowVendorsText(t *testing.T) {
187189
assert.Contains(t, out, "Acme Plumbing")
188190
assert.Contains(t, out, "John Doe")
189191
assert.Contains(t, out, "john@acme.com")
190-
assert.Contains(t, out, "555-1234")
192+
assert.Contains(t, out, "(555) 123-4567")
191193
}
192194

193195
func TestShowVendorsJSON(t *testing.T) {
@@ -210,6 +212,25 @@ func TestShowVendorsJSON(t *testing.T) {
210212
assert.NotEmpty(t, result[0]["id"])
211213
}
212214

215+
func TestShowVendorsJSONPhoneRaw(t *testing.T) {
216+
t.Parallel()
217+
store := newTestStoreWithMigration(t)
218+
219+
require.NoError(t, store.CreateVendor(&data.Vendor{
220+
Name: "Raw Phone Co",
221+
Phone: "5551234567",
222+
}))
223+
224+
var buf bytes.Buffer
225+
require.NoError(t, runShow(&buf, store, "vendors", true, false))
226+
227+
var result []map[string]any
228+
require.NoError(t, json.Unmarshal(buf.Bytes(), &result))
229+
require.Len(t, result, 1)
230+
assert.Equal(t, "5551234567", result[0]["phone"],
231+
"JSON output must carry raw phone, not formatted")
232+
}
233+
213234
func TestShowAppliancesText(t *testing.T) {
214235
t.Parallel()
215236
store := newTestStoreWithMigration(t)

0 commit comments

Comments
 (0)