---
phase: 04-code-quality
plan: 01
type: execute
wave: 1
depends_on: []
files_modified:
  - internal/api/client.go
  - cmd/common.go
  - cmd/start.go
  - cmd/submit.go
  - cmd/reset.go
autonomous: true
requirements: [QUAL-01]

must_haves:
  truths:
    - "internal/api/client.go contains no function whose sole body is 'return OtherFunc(args...)'"
    - "cmd/start.go function vars point directly to the canonical api.* names"
    - "cmd/submit.go function vars point directly to the canonical api.* names"
    - "cmd/reset.go calls api.ResetChallenge (canonical) not api.ResetChallengeProgress"
    - "cmd/common.go calls api.GetChallengeBySlug not api.GetChallenge"
    - "task test:unit passes with no changes to test expectations"
  artifacts:
    - path: "internal/api/client.go"
      provides: "Canonical API functions only, no alias wrappers"
    - path: "cmd/start.go"
      provides: "Function vars pointing to canonical names"
    - path: "cmd/submit.go"
      provides: "Function vars pointing to canonical names; SendSubmit logic inlined or replaced"
    - path: "cmd/reset.go"
      provides: "Direct call to api.ResetChallenge"
    - path: "cmd/common.go"
      provides: "Direct call to api.GetChallengeBySlug"
  key_links:
    - from: "cmd/start.go"
      to: "api.GetChallengeBySlug"
      via: "apiGetChallenge function var"
      pattern: "apiGetChallenge\\s*=\\s*api\\.GetChallengeBySlug"
    - from: "cmd/submit.go"
      to: "api.SubmitChallenge"
      via: "direct call or inlined SendSubmit logic"
      pattern: "api\\.SubmitChallenge"
---

<objective>
Remove the six backward-compatibility alias functions from internal/api/client.go and update every caller in cmd/ to use the canonical function names.

Purpose: Eliminate the double layer of indirection that makes it hard to understand which API operation a caller is actually invoking. Every alias is a dead abstraction.
Output: internal/api/client.go with no alias wrappers; all cmd/ files calling canonical names directly.
</objective>

<execution_context>
@/Users/paul/.claude/get-shit-done/workflows/execute-plan.md
@/Users/paul/.claude/get-shit-done/templates/summary.md
</execution_context>

<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md

@internal/api/client.go
@cmd/common.go
@cmd/start.go
@cmd/submit.go
@cmd/reset.go
</context>

<interfaces>
<!-- Current alias map — executor must delete these six functions and update callers accordingly. -->

Aliases to delete from internal/api/client.go:
```go
// DELETE: GetUserProfile → GetProfile
func GetUserProfile(ctx context.Context) (*UserProfile, error) { return GetProfile(ctx) }

// DELETE: GetChallenge → GetChallengeBySlug
func GetChallenge(ctx context.Context, slug string) (*ChallengeEntity, error) {
    return GetChallengeBySlug(ctx, slug)
}

// DELETE: GetChallengeProgress → GetChallengeStatus
func GetChallengeProgress(ctx context.Context, slug string) (*ChallengeStatusResponse, error) {
    return GetChallengeStatus(ctx, slug)
}

// DELETE: StartChallenge → StartChallengeWithResponse (error-only wrapper)
func StartChallenge(ctx context.Context, slug string) error {
    _, err := StartChallengeWithResponse(ctx, slug)
    return err
}

// DELETE: SendSubmit — wraps SubmitChallenge with ObjectiveResult conversion
func SendSubmit(ctx context.Context, challengeSlug string, results []ObjectiveResult) error { ... }

// DELETE: ResetChallengeProgress → ResetChallenge (error-only wrapper)
func ResetChallengeProgress(ctx context.Context, slugOrID string) error { ... }
```

Canonical functions that remain:
```go
func GetProfile(ctx context.Context) (*UserProfile, error)
func GetChallengeBySlug(ctx context.Context, slug string) (*ChallengeEntity, error)
func GetChallengeStatus(ctx context.Context, slug string) (*ChallengeStatusResponse, error)
func StartChallengeWithResponse(ctx context.Context, slug string) (*ChallengeStartResponse, error)
func SubmitChallenge(ctx context.Context, slug string, req ChallengeSubmitRequest) (*ChallengeSubmitResponse, error)
func ResetChallenge(ctx context.Context, slug string) (*ChallengeResetResponse, error)
```

Current callers using aliases (must be updated):
- cmd/start.go:16  apiGetChallenge         = api.GetChallenge       → api.GetChallengeBySlug
- cmd/start.go:17  apiGetChallengeProgress = api.GetChallengeProgress → api.GetChallengeStatus
- cmd/start.go:18  apiStartChallenge       = api.StartChallenge     → api.StartChallengeWithResponse
- cmd/submit.go:14 apiGetChallengeForSubmit = api.GetChallenge      → api.GetChallengeBySlug
- cmd/submit.go:15 apiGetProgressForSubmit  = api.GetChallengeProgress → api.GetChallengeStatus
- cmd/submit.go:158,167  api.SendSubmit(...)  → inline logic using api.SubmitChallenge
- cmd/reset.go:43  api.ResetChallengeProgress(...)  → api.ResetChallenge(...) with error extraction
- cmd/common.go:34 api.GetChallenge(...)   → api.GetChallengeBySlug(...)

Note: cmd/start.go var apiStartChallenge had type func(ctx, slug) error.
StartChallengeWithResponse returns (*ChallengeStartResponse, error). Update the var type and ignore the response (or keep inline call — the start command does not use the response fields).
</interfaces>

<tasks>

<task type="auto">
  <name>Task 1: Delete alias functions from internal/api/client.go</name>
  <files>internal/api/client.go</files>
  <action>
Delete the following six functions entirely from internal/api/client.go:
1. GetUserProfile (lines ~77-79)
2. GetChallenge (lines ~222-225)
3. GetChallengeProgress (lines ~227-230)
4. StartChallenge (lines ~170-174)
5. SendSubmit (lines ~232-251)
6. ResetChallengeProgress (lines ~366-378)

Do NOT change any canonical functions (GetProfile, GetChallengeBySlug, GetChallengeStatus, StartChallengeWithResponse, SubmitChallenge, ResetChallenge).

After deletion, run `go build ./internal/api/...` to confirm the package compiles. Expected: build errors in cmd/ (callers not yet updated) but the api package itself must compile cleanly.
  </action>
  <verify>
    <automated>cd /Users/paul/Workspace/kubeasy/kubeasy-cli && go build ./internal/api/...</automated>
  </verify>
  <done>internal/api/client.go has no function whose sole body delegates to another function in the same file. `go build ./internal/api/...` exits 0.</done>
</task>

<task type="auto">
  <name>Task 2: Update cmd/ callers to canonical names</name>
  <files>cmd/common.go, cmd/start.go, cmd/submit.go, cmd/reset.go</files>
  <action>
Update each caller as follows:

**cmd/common.go line ~34:**
```go
// Before:
challenge, err := api.GetChallenge(context.Background(), slug)
// After:
challenge, err := api.GetChallengeBySlug(context.Background(), slug)
```

**cmd/start.go lines ~16-18:**
```go
// Before:
apiGetChallenge         = api.GetChallenge
apiGetChallengeProgress = api.GetChallengeProgress
apiStartChallenge       = api.StartChallenge
// After:
apiGetChallenge         = api.GetChallengeBySlug
apiGetChallengeProgress = api.GetChallengeStatus
apiStartChallenge       = api.StartChallengeWithResponse
```

The var `apiStartChallenge` currently has type `func(context.Context, string) error`.
Change its type to `func(context.Context, string) (*api.ChallengeStartResponse, error)` and update the call site at ~line 112 to discard the response:
```go
_, err = apiStartChallenge(cmd.Context(), challengeSlug)
return err
```

**cmd/submit.go lines ~14-15:**
```go
// Before:
apiGetChallengeForSubmit = api.GetChallenge
apiGetProgressForSubmit  = api.GetChallengeProgress
// After:
apiGetChallengeForSubmit = api.GetChallengeBySlug
apiGetProgressForSubmit  = api.GetChallengeStatus
```

**cmd/submit.go lines ~158 and ~167 (two call sites for api.SendSubmit):**
Replace each `api.SendSubmit(cmd.Context(), challengeSlug, apiResults)` with an inline call that preserves the same behavior:
```go
submitReq := api.ChallengeSubmitRequest{Results: apiResults}
submitResult, err := api.SubmitChallenge(cmd.Context(), challengeSlug, submitReq)
if err != nil {
    return err
}
if !submitResult.Success {
    if submitResult.Message != nil {
        return fmt.Errorf("submission failed: %s", *submitResult.Message)
    }
    return fmt.Errorf("submission failed")
}
```
Note: apiResults in submit.go is `[]api.ObjectiveResult`. ChallengeSubmitRequest.Results is also `[]ObjectiveResult` — direct assignment, no conversion needed.

**cmd/reset.go line ~43:**
Replace `api.ResetChallengeProgress(cmd.Context(), challengeSlug)` with:
```go
result, err := api.ResetChallenge(cmd.Context(), challengeSlug)
if err != nil {
    return err
}
if !result.Success {
    return fmt.Errorf("reset failed: %s", result.Message)
}
return nil
```

After all edits: `go build ./cmd/... ./...` must pass with zero errors.
  </action>
  <verify>
    <automated>cd /Users/paul/Workspace/kubeasy/kubeasy-cli && go build ./... && task test:unit</automated>
  </verify>
  <done>
`go build ./...` exits 0. `task test:unit` passes. No reference to GetChallenge, GetChallengeProgress, StartChallenge, SendSubmit, ResetChallengeProgress, or GetUserProfile remains in any file outside of internal/api/client.go (which has already deleted them).
  </done>
</task>

</tasks>

<verification>
```bash
cd /Users/paul/Workspace/kubeasy/kubeasy-cli

# No alias names remain anywhere
grep -rn "api\.GetChallenge\b\|api\.GetChallengeProgress\|api\.StartChallenge\b\|api\.SendSubmit\|api\.ResetChallengeProgress\|api\.GetUserProfile" . --include="*.go"
# Expected: zero matches

# No alias function bodies remain in client.go
grep -n "GetUserProfile\|func GetChallenge\b\|func GetChallengeProgress\|func StartChallenge\b\|func SendSubmit\|func ResetChallengeProgress" internal/api/client.go
# Expected: zero matches

# Full build and tests pass
go build ./...
task test:unit
```
</verification>

<success_criteria>
- internal/api/client.go has no alias functions (zero backward-compat wrappers)
- All callers in cmd/ use canonical function names: GetChallengeBySlug, GetChallengeStatus, StartChallengeWithResponse, SubmitChallenge, ResetChallenge
- `go build ./...` exits 0
- `task test:unit` passes with no test changes needed
</success_criteria>

<output>
After completion, create `.planning/phases/04-code-quality/04-01-SUMMARY.md`
</output>
