Skip to content

feat(auth): prompt to protect resources during auth generation#22

Merged
adnaan merged 4 commits intomainfrom
feature/auth-protect-resources
Jan 1, 2026
Merged

feat(auth): prompt to protect resources during auth generation#22
adnaan merged 4 commits intomainfrom
feature/auth-protect-resources

Conversation

@adnaan
Copy link
Copy Markdown
Contributor

@adnaan adnaan commented Dec 31, 2025

Summary

  • Adds interactive prompt after lvt gen auth to select which resources should be protected
  • Wraps selected resource handlers with authController.RequireAuth() in main.go
  • Adds authController creation if not already present

Changes

  • commands/auth.go: Add interactive prompt to select resources after auth generation
  • internal/generator/auth.go: Add ProtectResources() function to update main.go
  • internal/generator/auth_test.go: Add comprehensive tests for resource protection

How it works

After auth generation completes, if there are existing resources (from .lvtresources), the CLI prompts:

🔒 Resource Protection
Would you like to protect any resources with authentication?
(Users will need to log in to access protected resources)

  1. Posts (/posts)
  2. Comments (/comments)

Enter your selection:
  - Numbers separated by commas (e.g., 1,2,3)
  - 'all' to protect all resources
  - 'none' to skip (you can protect resources later)

Your choice: all

Protecting 2 resource(s)...
✅ Resources protected!
   - Posts (/posts)
   - Comments (/comments)

Test plan

  • Run TestProtectResources_WrapsHandlers - verifies handlers are wrapped
  • Run TestProtectResources_Idempotent - ensures no duplicates on re-run
  • Run TestProtectResources_AddsAuthController - verifies authController creation
  • Run TestProtectResources_NoMainGo - handles missing main.go gracefully
  • Manual test: Create app, add resources, run lvt gen auth with "all"

🤖 Generated with Claude Code

When running `lvt gen auth`, users are now prompted to select which
existing resources should be protected with authentication. This makes
it easier to set up auth protection without manual code modifications.

Changes:
- Add interactive prompt after auth generation to show available resources
- Allow selection by numbers, 'all', or 'none'
- Add ProtectResources() function to wrap handlers with RequireAuth
- Add authController creation if not already present in main.go
- Ensure idempotent behavior (no duplicates on re-run)
- Add comprehensive tests for resource protection feature

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings December 31, 2025 15:12
@claude
Copy link
Copy Markdown

claude bot commented Dec 31, 2025

Code Review - PR #22

I've reviewed the changes for adding interactive resource protection during auth generation. Overall, this is a well-implemented feature with good test coverage. Below are my findings:


✅ Strengths

  1. Excellent Test Coverage: The PR includes comprehensive tests covering:

    • Handler wrapping (commands/auth.go:616-689)
    • Idempotency (commands/auth.go:691-750)
    • Auth controller insertion (commands/auth.go:752-811)
    • Error handling for missing main.go (commands/auth.go:813-830)
  2. User Experience: The interactive prompt is well-designed with clear instructions and multiple input options (all/none/comma-separated numbers).

  3. Idempotency: The implementation correctly handles re-running protection without duplicating middleware (internal/generator/auth.go:668-672).

  4. Safe Defaults: Auth and Home resources are correctly excluded from the protection prompt (commands/auth.go:123).


🔍 Issues & Concerns

1. Potential Regex Escaping Issue (Medium Priority)

File: internal/generator/auth.go:665

The regex pattern uses regexp.QuoteMeta on the path, but paths with special regex characters might still cause issues:

pattern := fmt.Sprintf(`http\.Handle\("%s"\s*,\s*%s\.Handler\(queries\)\)`, regexp.QuoteMeta(path), regexp.QuoteMeta(packageName))

Issue: If a path contains characters that are both valid URL characters AND regex metacharacters (e.g., /posts/{id}), the current approach may not handle them correctly after QuoteMeta.

Recommendation: Add a test case for paths with special characters:

resources := []ResourceEntry{
    {Name: "Posts", Path: "/posts/{id}", Type: "resource"},
}

2. Silent Failure on Invalid Selections (Low Priority)

File: commands/auth.go:166-170

When users enter invalid selections, the code prints warnings but continues:

fmt.Printf("⚠️  Invalid selection: %d (out of range)\n", num)

Issue: If a user enters "1,99" for 2 resources, only resource 1 is protected, but the user might not notice the warning.

Recommendation: Consider collecting all errors and showing a summary, or asking the user to re-enter if any selections are invalid.

3. Hardcoded nil Parameters (Low Priority)

File: internal/generator/auth.go:652

authController := auth.NewUserController(queries, nil, "")

Issue: The hardcoded nil and empty string suggest these parameters might need configuration later. This could be confusing for users who manually inspect the generated code.

Recommendation: Add a comment explaining what these parameters are for, or consider if they should be configurable.

4. No Validation for Empty Resource Selection (Minor)

File: commands/auth.go:174-186

Issue: The code only processes resources if len(selectedResources) > 0, which is correct, but it provides no feedback when the user makes invalid selections that result in an empty list.

Recommendation: If parsing resulted in warnings but no valid selections, inform the user explicitly.


🎯 Best Practices & Code Quality

Positive

  • ✅ Good use of string manipulation with strings.TrimSpace and strings.ToLower
  • ✅ Proper error handling with wrapped errors using fmt.Errorf with %w
  • ✅ Clear variable naming throughout
  • ✅ Good separation of concerns (commands/auth.go handles UI, internal/generator handles logic)

Minor Improvements

  • The ProtectResources function is ~73 lines (internal/generator/auth.go:612-685). Consider extracting the "add auth controller" logic into a separate helper function for better readability.

🔒 Security Considerations

No security concerns identified. The code:

  • Does not execute user input
  • Properly escapes regex patterns
  • Only modifies local files under the project directory

⚡ Performance Considerations

No performance concerns. The operations are:

  • File I/O bound (reading/writing main.go)
  • Run only during code generation (not runtime)
  • Handle small amounts of data

📝 Documentation & UX

Positive:

  • ✅ Clear prompt messages guide users effectively
  • ✅ Good function documentation with example transformations (internal/generator/auth.go:602-611)
  • ✅ Updated "Next steps" instructions (commands/auth.go:190-198)

Suggestions:

  • Consider adding a note in the PR description or docs about what happens if users want to protect resources added AFTER running lvt gen auth. (Do they need to manually edit main.go, or can they re-run the command?)

🧪 Testing

Test Coverage: Excellent ✅

Suggested Additional Tests:

  1. Test with resource paths containing special characters (e.g., /api/v1/posts)
  2. Test with mixed case resource names
  3. Test behavior when main.go has unconventional formatting (multiple spaces, tabs, etc.)
  4. Test when auth routes are in a different order

📋 Summary

This is a high-quality PR with strong test coverage and good user experience design. The implementation is sound, with only minor issues that are mostly edge cases.

Recommended Action: ✅ Approve with minor suggestions

The identified issues are not blockers and can be addressed in follow-up PRs if needed. The core functionality is solid and well-tested.


Priority of Issues

  1. 🔴 High: None
  2. 🟡 Medium: Regex escaping for special path characters (test: Verify CI workflow #1)
  3. 🟢 Low: Silent failure on invalid selections (docs: Verify CI is working on main #2), hardcoded nil parameters (Add Claude Code skills for lvt CLI #3)
  4. Minor: User feedback improvements (fix(lvt): improve auth templates and lvt-plan skill #4)

Great work! 🎉

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds an interactive prompt during lvt gen auth to allow users to select which existing resources should be protected with authentication. After auth generation completes, if resources exist in .lvtresources, the CLI prompts the user to select resources to protect, then automatically wraps the selected handlers with authController.RequireAuth() middleware in main.go.

Key changes:

  • Interactive resource selection prompt after auth generation with support for "all", "none", or comma-separated numbers
  • Automatic wrapping of selected resource handlers with authentication middleware in main.go
  • Comprehensive test coverage including idempotency, authController creation, and error handling

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
commands/auth.go Adds interactive prompt after auth generation to select resources for protection, filters out Auth and Home, handles user input parsing
internal/generator/auth.go Implements ProtectResources() function to modify main.go by adding authController and wrapping handlers with RequireAuth middleware
internal/generator/auth_test.go Adds 4 comprehensive test cases covering handler wrapping, idempotency, authController creation, and missing main.go error handling

Comment thread internal/generator/auth.go Outdated
//
// Before: http.Handle("/posts", posts.Handler(queries))
// After: http.Handle("/posts", authController.RequireAuth(posts.Handler(queries)))
func ProtectResources(projectRoot, moduleName string, resources []ResourceEntry) error {
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

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

The moduleName parameter is declared but never used in the function body. Consider removing this unused parameter from the function signature.

Suggested change
func ProtectResources(projectRoot, moduleName string, resources []ResourceEntry) error {
func ProtectResources(projectRoot, _ string, resources []ResourceEntry) error {

Copilot uses AI. Check for mistakes.
Comment thread internal/generator/auth.go Outdated
Comment on lines +668 to +670
// Check if already wrapped
wrappedPattern := fmt.Sprintf(`authController\.RequireAuth\(%s\.Handler\(queries\)\)`, regexp.QuoteMeta(packageName))
if strings.Contains(mainContent, wrappedPattern) {
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

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

The check for whether a handler is already wrapped only looks for the exact pattern with authController.RequireAuth. However, if someone uses a different variable name for the auth controller (e.g., ac or ctrl), this check will fail and potentially wrap the handler twice. Consider making the idempotency check more robust by using a regex pattern that looks for any variable name followed by .RequireAuth(packageName.Handler(queries)).

Suggested change
// Check if already wrapped
wrappedPattern := fmt.Sprintf(`authController\.RequireAuth\(%s\.Handler\(queries\)\)`, regexp.QuoteMeta(packageName))
if strings.Contains(mainContent, wrappedPattern) {
// Check if already wrapped (any controller variable, e.g., authController, ac, ctrl)
wrappedPattern := fmt.Sprintf(`\w+\.RequireAuth\(\s*%s\.Handler\(queries\)\s*\)`, regexp.QuoteMeta(packageName))
wrappedRe := regexp.MustCompile(wrappedPattern)
if wrappedRe.MatchString(mainContent) {

Copilot uses AI. Check for mistakes.
mainContent = mainContent[:lastAuthRouteEnd+1] + authControllerCode + mainContent[lastAuthRouteEnd+1:]
}
}

Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

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

When no auth routes are found (lastAuthRouteEnd remains 0), the authController creation code is silently skipped. This could lead to a situation where the function attempts to wrap handlers with authController.RequireAuth() but the authController variable doesn't exist, resulting in invalid Go code. Consider returning an error if no auth routes are found, or logging a warning to help with debugging.

Suggested change
// Ensure we don't generate code that references a missing authController
if len(resources) > 0 && !strings.Contains(mainContent, "authController :=") {
return fmt.Errorf("cannot protect resources: authController not found and auth routes not detected in main.go")
}

Copilot uses AI. Check for mistakes.
Comment thread internal/generator/auth.go Outdated
mainContent := string(content)

// Add auth controller creation if not present
if !strings.Contains(mainContent, "authController :=") {
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

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

The check authController := uses := which only matches short variable declarations. If the authController is declared differently (e.g., var authController = ... or authController = ...), this check will fail and create a duplicate declaration. Consider using a more flexible pattern such as checking for authController followed by any of :=, =, or searching for auth.NewUserController.

Suggested change
if !strings.Contains(mainContent, "authController :=") {
authControllerDeclRe := regexp.MustCompile(`authController\s*(?::=|=)`)
if !authControllerDeclRe.MatchString(mainContent) && !strings.Contains(mainContent, "auth.NewUserController(") {

Copilot uses AI. Check for mistakes.
When protecting resources, the auth controller now uses a console email
sender by default instead of nil. This ensures magic links work out of
the box in development mode (links are printed to server logs).

Changes:
- Add email package import when creating auth controller
- Configure NewConsoleEmailSender() by default
- Set baseURL from PORT environment variable
- Update tests to expect email sender configuration

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@claude
Copy link
Copy Markdown

claude bot commented Dec 31, 2025

Pull Request Review: Resource Protection During Auth Generation

Summary

This PR adds an interactive prompt after lvt gen auth to allow users to select which existing resources should be protected with authentication. The implementation wraps selected resource handlers with authController.RequireAuth() middleware in main.go.

Code Quality: ✅ Excellent

Strengths

  1. Well-tested: Comprehensive test coverage with 4 distinct test cases covering:

    • Basic wrapping functionality
    • Idempotency (prevents duplicates)
    • Auth controller creation
    • Error handling (missing main.go)
  2. Clean separation of concerns: The ProtectResources() function in internal/generator/auth.go is focused and does one thing well.

  3. Good user experience: Clear, helpful prompts with multiple input options (numbers, all, none).

  4. Follows existing patterns: Uses findMainGo(), ReadResources(), and other established utility functions consistently.

  5. Proper error handling: Graceful degradation when resources cannot be read or protected.

Potential Issues & Suggestions

🔴 Critical: Missing Function Reference

Location: internal/generator/auth.go:668

baseURL := "http://localhost:" + getPort()

Issue: The getPort() function is called but not defined in this file. It appears to be a template function that exists in generated main.go files (see internal/kits/system/multi/templates/app/main.go.tmpl:104).

Impact: This will cause a compilation error in the generated main.go if getPort() does not already exist.

Recommendation: Before inserting the auth controller code, check if getPort() exists in main.go. If not, either:

  1. Generate the getPort() function as part of the auth controller setup, OR
  2. Use a hardcoded port like "http://localhost:8080" with a comment explaining users should update it

🟡 Medium: Regex Pattern Robustness

Location: internal/generator/auth.go:682-683

Issue: The regex pattern assumes a specific formatting style. If users format their code differently (e.g., with extra whitespace, line breaks, or different variable names), the pattern will not match.

Recommendation: Consider a more flexible approach or document the formatting requirements. Alternatively, use AST parsing for more robust code modification.

🟡 Medium: Import Insertion Logic

Location: internal/generator/auth.go:631-638

Issue: This assumes a multi-line import block with import (. Single-line imports like import "fmt" will not be handled.

Recommendation: Check for both formats or add a comment explaining the assumption.

🟢 Minor: User Input Validation

Location: commands/auth.go:159-171

The input parsing for comma-separated numbers is well done, but consider:

  1. Trimming duplicates: If a user enters "1,1,2", they will get duplicate resources.
  2. Empty selections: If parsing fails for all inputs, selectedResources will be empty but no clear message is shown.

Performance Considerations: ✅ Good

  • String operations are efficient for small files (main.go is typically small)
  • No unnecessary file reads or writes
  • Regex compilation could be optimized by pre-compiling, but negligible for this use case

Security Concerns: ✅ Good

  1. No injection vulnerabilities: Uses regexp.QuoteMeta() to safely escape user input in regex patterns
  2. File permissions: Uses 0644 for file writes (appropriate)
  3. No command execution: All operations are file I/O based
  4. Input validation: Validates resource selections before processing

Test Coverage: ✅ Excellent

Four comprehensive tests covering:

  • ✅ Basic functionality
  • ✅ Idempotency
  • ✅ Auth controller creation
  • ✅ Error handling

Recommendations Summary

Must Fix (Before Merge)

  1. Handle missing getPort() function - This will cause compilation errors

Should Fix (High Priority)

  1. Improve regex robustness or document formatting assumptions
  2. Handle single-line import statements

Nice to Have (Low Priority)

  1. Add duplicate prevention in user input
  2. Add test for missing getPort()
  3. Add test for formatting variations

Overall Assessment: ⭐⭐⭐⭐ (4/5)

This is a well-implemented feature with excellent test coverage and good user experience. The main concern is the getPort() function reference that could cause compilation errors. Once that is addressed, this will be production-ready.

The code follows the repository conventions, is well-tested, and provides a valuable feature that improves the auth generation workflow.


Reviewed by: Claude Code Agent
Review Date: 2025-12-31

- Remove unused moduleName parameter (use _ instead)
- Make authController declaration check more robust with regex
  to handle both := and = declarations
- Add error when no auth routes found to prevent invalid code
- Make idempotency check more robust to handle any controller
  variable name with .RequireAuth()
- Add test for no auth routes error case

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@claude
Copy link
Copy Markdown

claude bot commented Jan 1, 2026

PR Review: Resource Protection Feature

Overview

This PR adds interactive resource protection during auth generation, allowing users to select which resources should require authentication. The implementation is well-structured with comprehensive test coverage.


✅ Strengths

  1. Excellent Test Coverage

    • Four comprehensive test cases covering the main scenarios
    • Tests for idempotency, error handling, and edge cases
    • Well-named test functions that clearly describe what they test
  2. User Experience

    • Clear, interactive prompts with helpful instructions
    • Good error handling with fallback messages
    • Filters out Auth and Home resources appropriately
  3. Code Safety

    • Idempotent operations (can run multiple times safely)
    • Regex patterns properly escape user input with regexp.QuoteMeta
    • Validates auth routes exist before adding controller

🔍 Issues & Recommendations

1. Unused Parameter in ProtectResources

// internal/generator/auth.go:612
func ProtectResources(projectRoot, _ string, resources []ResourceEntry) error {

The second parameter (module name) is unused. Either:

  • Remove it if not needed
  • Use it for better error messages or validation

2. Input Validation Edge Cases

// commands/auth.go:162-170
if num, err := strconv.Atoi(part); err == nil {
    if num >= 1 && num <= len(protectableResources) {
        selectedResources = append(selectedResources, protectableResources[num-1])
    } else {
        fmt.Printf("⚠️  Invalid selection: %d (out of range)\n", num)
    }
}

Issue: Invalid selections print warnings but don't prevent execution. Users might think their invalid choices were accepted.

Recommendation: Track if any invalid selections occurred and ask user to re-enter, or at least show a summary before proceeding.

3. Potential Duplicate Resources

// commands/auth.go:159-171
for _, part := range parts {
    part = strings.TrimSpace(part)
    if num, err := strconv.Atoi(part); err == nil {
        if num >= 1 && num <= len(protectableResources) {
            selectedResources = append(selectedResources, protectableResources[num-1])
        }
    }
}

Issue: If user enters "1,1,2", resource 1 will be added twice. The regex check in ProtectResources prevents double-wrapping, but it's still wasteful.

Recommendation: Use a map or check for duplicates before appending.

4. Regex Pattern Fragility

// internal/generator/auth.go:687-688
pattern := fmt.Sprintf(`http\.Handle("%s"\s*,\s*%s\.Handler\(queries\)\)`, 
    regexp.QuoteMeta(path), regexp.QuoteMeta(packageName))

Issue: This pattern is very specific and will fail if:

  • Code is formatted differently (extra spaces, line breaks)
  • Handler is called with different variable name (not queries)
  • Handler uses method chaining or other patterns

Recommendation: Consider using AST parsing (go/ast) for more robust code modification, or document the expected format clearly.

5. Missing Import Error Handling

// internal/generator/auth.go:629-641
emailImport := `"github.com/livetemplate/lvt/pkg/email"`
if !strings.Contains(mainContent, emailImport) {
    importStart := strings.Index(mainContent, "import (")
    if importStart != -1 {
        importEndRel := strings.Index(mainContent[importStart:], "\n)")
        if importEndRel != -1 {
            insertPos := importStart + importEndRel
            mainContent = mainContent[:insertPos] + "\n\n\t" + emailImport + mainContent[insertPos:]
        }
    }
}

Issue: Silently fails if import block isn't found. This could lead to compilation errors.

Recommendation: Return an error if import injection fails.

6. Hard-coded Port Assumption

// internal/generator/auth.go:674
baseURL := "http://localhost:" + getPort()

Issue: Assumes getPort() function exists in main.go. Test doesn't verify this.

Recommendation: Add a test case that verifies the generated code compiles, or at least document this requirement.

7. Test Coverage Gaps

Missing test cases for:

  • User enters mixed valid/invalid input ("1,99,2")
  • Empty resource list after filtering
  • main.go with unusual formatting
  • Concurrent resource protection calls (if applicable)

🛡️ Security Considerations

Good: Uses regexp.QuoteMeta to prevent injection
Good: Validates input ranges before array access
⚠️ Minor: No sanitization of resource names/paths from .lvtresources file (assuming it's trusted)


⚡ Performance Considerations

  • Multiple string operations on large main.go files could be slow
  • Consider compiling regex patterns once and reusing them
  • File I/O is done synchronously; acceptable for CLI tool

🎯 Style & Best Practices

Good: Follows Go naming conventions
Good: Clear comments explaining complex logic
Good: Error messages are user-friendly
⚠️ Minor: Some functions are quite long (ProtectResources is 95 lines); consider extracting helper functions


📋 Suggested Changes Priority

High Priority:

  1. Fix unused parameter warning (moduleName)
  2. Handle import injection failures
  3. Add duplicate detection for user input

Medium Priority:
4. Improve input validation with retry logic
5. Add test for unusual main.go formatting
6. Document assumptions about main.go structure

Low Priority:
7. Consider AST-based code modification for robustness
8. Extract smaller functions from ProtectResources
9. Add integration test that verifies generated code compiles


✨ Overall Assessment

This is a solid PR that adds valuable functionality with good test coverage. The interactive UX is well-designed, and the code is generally safe and idempotent. The main concerns are around edge case handling and the fragility of string-based code modification.

Recommendation: Approve with minor changes (address high-priority items).

Great work on the comprehensive tests! 🎉

- Add error when import block is missing (fixes silent failure)
- Use fallback port 8080 when getPort() function doesn't exist
  (prevents compilation errors in custom main.go files)
- Prevent duplicate resource selections with seen map
- Add tests for missing import block, getPort() fallback, and
  getPort() usage when available

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@claude
Copy link
Copy Markdown

claude bot commented Jan 1, 2026

Pull Request Review - PR #22

Overview

This PR adds an interactive feature to protect resources with authentication after running lvt gen auth. The implementation is well-thought-out with comprehensive test coverage and good error handling.

✅ Strengths

Code Quality

  1. Excellent test coverage - 7 comprehensive test cases covering:

    • Happy path (wrapping handlers)
    • Idempotency (no duplicate wrapping)
    • Edge cases (missing files, missing auth routes, missing import blocks)
    • Fallback behavior (port configuration)
  2. Good error handling - Graceful degradation with helpful error messages

    • Warns users when resources can't be read
    • Provides manual fallback instructions when auto-protection fails
    • Validates input and provides clear error messages
  3. Idempotent design - The ProtectResources function can be run multiple times safely:

    • Checks for existing authController declarations
    • Skips already-wrapped handlers
    • Prevents duplicate resource selections with seen map
  4. User experience - Excellent UX with:

    • Clear prompts and instructions
    • Multiple input formats (numbers, "all", "none")
    • Good visual feedback with emojis and structured output

Best Practices

  • Follows Go conventions and project style
  • Good use of regex for robust pattern matching
  • Comprehensive documentation in godoc format
  • Follows conventional commit message format

🔍 Observations & Suggestions

1. Input Validation Enhancement

Location: commands/auth.go:163-175

The duplicate prevention works well, but consider providing feedback when duplicates are detected:

if !seen[num] {
    seen[num] = true
    selectedResources = append(selectedResources, protectableResources[num-1])
} else {
    // Optional: inform user about duplicate
    // fmt.Printf("ℹ️  Skipping duplicate selection: %d\n", num)
}

Priority: Low (current behavior is acceptable)

2. Regex Pattern Robustness

Location: internal/generator/auth.go:697-698

The regex pattern assumes specific whitespace patterns. Consider making it more flexible:

// Current pattern is fine, but could be more flexible with \s*
pattern := fmt.Sprintf(`http\.Handle\("%s"\s*,\s*%s\.Handler\(queries\)\)`, ...)
// Could become:
pattern := fmt.Sprintf(`http\.Handle\(\s*"%s"\s*,\s*%s\.Handler\(\s*queries\s*\)\s*\)`, ...)

Priority: Low (current pattern handles typical generated code well)

3. String Manipulation Complexity

Location: internal/generator/auth.go:631-642

The import insertion uses string index manipulation. While it works, consider using go/ast package for more robust Go code modifications. However, for this specific use case, the current approach is acceptable and avoids the complexity of AST manipulation.

Priority: Low (premature optimization - current approach works well)

4. Port Detection Logic

Location: internal/generator/auth.go:673-677

The port detection with getPort() function is smart, but the fallback comment could be more actionable:

baseURLCode = `baseURL := "http://localhost:8080" // TODO: Update if your PORT differs`

Priority: Low (current comment is clear enough)

5. Error Context

Location: internal/generator/auth.go:668

Excellent error message! This helps users understand what went wrong and what to do:

return fmt.Errorf("no auth routes found in main.go - ensure auth was generated before protecting resources")

🐛 Potential Issues

None Found

No bugs detected. The code handles edge cases well and includes proper validation.

🔒 Security Considerations

✅ Good Security Practices

  1. Authentication by default - Encourages developers to protect resources
  2. No hardcoded credentials - Uses email sender abstraction
  3. Proper middleware pattern - RequireAuth wrapper is the correct approach

Note on File Permissions

Location: internal/generator/auth.go:712

File is written with 0644 permissions, which is standard and appropriate for Go source files.

⚡ Performance Considerations

Efficient Implementation

  1. Single file read/write - Minimizes I/O operations
  2. Regex compilation - Could cache compiled regexes, but for a CLI command run once, the current approach is fine
  3. Linear search - For auth route patterns is acceptable given small number of patterns

Minor Optimization Opportunity

Location: internal/generator/auth.go:656-664

Consider compiling regex patterns once:

// Pre-compile common patterns
var authControllerDeclRe = regexp.MustCompile(`authController\s*(?::=|=)`)

// Use in function
if !authControllerDeclRe.MatchString(mainContent) { ... }

Priority: Low (premature optimization for CLI command)

📋 Test Coverage Assessment

Excellent Coverage

The test suite covers all critical paths:

  • ✅ Basic functionality (wrapping handlers)
  • ✅ Idempotency (re-running protection)
  • ✅ Controller creation
  • ✅ Missing file handling
  • ✅ Missing auth routes error
  • ✅ Missing import block error
  • ✅ Port detection fallback
  • ✅ getPort() function detection

Test Quality

  • Tests use proper table-driven approach where appropriate
  • Good use of temp directories for isolation
  • Clear test names that describe what they verify
  • Proper cleanup with t.TempDir()

📚 Documentation

Good Documentation

  1. Godoc comments - Clear function documentation with examples
  2. Code comments - Explain non-obvious logic
  3. PR description - Excellent summary with examples
  4. User-facing messages - Clear instructions in the CLI output

Suggestion

Consider adding a brief usage example in the generator package documentation or README for developers who want to understand the resource protection feature.

🎯 Overall Assessment

Rating: ⭐⭐⭐⭐⭐ (5/5)

This is a high-quality PR that:

  • Solves a real UX problem (manual auth wiring)
  • Has excellent test coverage (7 test cases)
  • Follows Go and project conventions
  • Handles edge cases gracefully
  • Provides good user feedback
  • Is well-documented

Recommendation: ✅ APPROVE

The code is production-ready and demonstrates strong engineering practices. The suggestions above are minor improvements that could be addressed in future iterations if desired, but they don't block this PR.

📝 Minor Suggestions for Future Consideration

  1. Consider extracting the interactive prompt logic into a reusable helper (if this pattern appears elsewhere)
  2. Could add a --protect-resources flag for non-interactive usage (CI/CD scenarios)
  3. Consider logging the modifications to main.go for debugging

Great work! 🎉


Review generated by Claude Code PR Review

@adnaan adnaan merged commit e85fe5e into main Jan 1, 2026
2 checks passed
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.

2 participants