Skip to content

[feature/49] :: renamed package names and other adjustments#50

Merged
wellfernandes merged 30 commits intodevelopfrom
feature/49-refactor-package-names
Oct 28, 2025
Merged

[feature/49] :: renamed package names and other adjustments#50
wellfernandes merged 30 commits intodevelopfrom
feature/49-refactor-package-names

Conversation

@wellfernandes
Copy link
Copy Markdown
Member

@wellfernandes wellfernandes commented Oct 18, 2025

  • fixed the way mocai is instantiated
  • added constructors
  • updated the main readme and the pt readme

Summary by CodeRabbit

  • New Features

    • New formatting flag when creating the mocker to produce formatted mock data.
    • Mocker now returns a fully-initialized, immutable instance per language.
  • Refactor

    • Access patterns changed from method calls to direct properties across the mocker and entities.
    • Entity generation unified under explicit constructors; several legacy generators removed or reshaped.
  • Documentation

    • Examples and READMEs updated to show the new initialization, immutability, and property-style API; some example programs removed.
  • Bug Fixes

    • Improved consistency and stability of generated entities.

@wellfernandes wellfernandes self-assigned this Oct 18, 2025
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Oct 18, 2025

Walkthrough

NewMocker now takes (lang string, isFormatted bool) and returns a fully initialized Mocker with public entity fields. Many package-level generators were converted into constructors and receiver-based generate methods; multiple types and return shapes changed between pointers and values; some files/packages were renamed, deleted, or relocated.

Changes

Cohort / File(s) Summary
Docs & Examples
README.md, docs/localization/pt/README-PT.md, examples/mocker/main.go, examples/specific/main.go
Update docs and examples to mocai.NewMocker(lang, isFormatted) and field-style access (e.g., m.Address.Street); change error handling to log.Fatal; remove examples/specific/main.go.
Mocker core
pkg/mocai/mocker.go
NewMocker(lang string)NewMocker(lang string, isFormatted bool); Mocker becomes a struct with public fields (Address, Certificate, Company, Gender, NationalID, Person, Phone, VoteRegistration) and is fully initialized in NewMocker; per-field accessor methods removed; imports/aliases adjusted.
Entity constructors & generators (grouped)
pkg/mocai/entities/... (address, phone, person, company, certificate, cpf, gender, vote_registration/voteregistration, national_id/nationalid, voteregistration/, nationalid/)
Add exported constructors NewX(...) and convert many package-level GenerateX functions into receiver methods generateX; change field types and return shapes between pointers and values (e.g., BrazilianCertificates, BrazilianCompany, CPF, RG); update callers to use new constructors and methods; adjust error propagation.
Package renames, removals & errors
pkg/mocai/entities/national_id/*pkg/mocai/entities/nationalid/*, pkg/mocai/entities/vote_registration/*pkg/mocai/entities/voteregistration/*, deleted old generator files, moved/added error defs
Rename packages and relocate generators; delete legacy top-level generator files (national_id and vote_registration old files); remove some old exported errors and add/move new error declarations (e.g., ErrToConvertDigit in nationalid countries).

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant NewMocker as NewMocker(lang,isFormatted)
    participant Constructor as NewX()
    participant Gen as (x).generateX

    rect rgb(245,250,245)
    Note over Client,NewMocker: NewMocker constructs and populates all entity fields
    Client->>NewMocker: call NewMocker(lang,isFormatted)
    NewMocker->>Constructor: NewAddress(), NewPhone(), NewPerson(isFormatted), NewCertificate(isFormatted), ...
    Constructor->>Gen: (entity).generateX(isFormatted)
    Gen-->>Constructor: entity / error
    Constructor-->>NewMocker: initialized entity / propagate error
    NewMocker-->>Client: *Mocker with fields (m.Address, m.Person, m.Phone, ...)
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

enhancement

Suggested reviewers

  • DODOSUBI
  • BertBR
  • rluders

Poem

🐰 I hopped through code with a curious twitch,

NewMocker blooms fields in a single stitch.
Constructors sprout and generators play,
I nibble bugs softly and bounce away.
Hooray for fresh fields — carrot cake today!

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title mentions "renamed package names," which is indeed present in the changeset (national_id → nationalid, vote_registration → voteregistration, plus file reorganizations). However, the primary objectives stated in the PR description are to fix the way mocai is instantiated, add constructors, and update documentation. The package renaming, while significant, is a secondary implementation detail supporting these main goals. The phrase "other adjustments" is somewhat vague and doesn't convey the substantive API changes (NewMocker signature modification, field vs. method access patterns, type refactoring) that are the core of this change. The title thus refers to a real aspect of the changeset but fails to capture its primary focus.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/49-refactor-package-names

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 and usage tips.

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: 10

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (5)
pkg/mocai/entities/nationalid/countries/brazilian_national_id.go (3)

46-47: Use per‑call RNG; current globalRand is not goroutine‑safe.

Avoid data races by using a local RNG instance.

Apply:

- base := globalRand.Intn(100000000)
+ rng := rand.New(rand.NewSource(time.Now().UnixNano()))
+ base := rng.Intn(100000000)

51-57: Invalid range 8 loop — won’t compile.

Replace with a classic index loop.

Apply:

-for i := range 8 {
+for i := 0; i < 8; i++ {

60-66: Second invalid range 8 loop; and minor typo.

Fix the loop; consider renaming wheights -> weights.

Apply:

-// wheights from right to left: 9, 8, 7, 6, 5, 4, 3, 2
-wheights := []int{2, 3, 4, 5, 6, 7, 8, 9}
+// weights from right to left: 9, 8, 7, 6, 5, 4, 3, 2
+weights := []int{2, 3, 4, 5, 6, 7, 8, 9}
 ...
-for i := range 8 {
-  sum += d[7-i] * wheights[i]
+for i := 0; i < 8; i++ {
+  sum += d[7-i] * weights[i]
pkg/mocai/entities/person/generator.go (2)

37-44: Strengthen data validation; current len checks miss empty datasets.

strings.Split on an empty string yields [""] (len=1), so the early guards won’t trigger; empty picks are only caught later with a generic error. Filter empties up front.

Minimal change:

-	firstNamesMale := strings.Split(translations.Get(lang, "person_first_name_male"), ",")
-	firstNamesFemale := strings.Split(translations.Get(lang, "person_first_name_female"), ",")
-	lastNames := strings.Split(translations.Get(lang, "person_last_name"), ",")
+	firstNamesMale := parseList(translations.Get(lang, "person_first_name_male"))
+	firstNamesFemale := parseList(translations.Get(lang, "person_first_name_female"))
+	lastNames := parseList(translations.Get(lang, "person_last_name"))

-	if len(firstNamesMale) == 0 || len(firstNamesFemale) == 0 {
+	if len(firstNamesMale) == 0 || len(firstNamesFemale) == 0 {
 		return Person{}, ErrNoFirstNames
 	}
-	if len(lastNames) == 0 {
+	if len(lastNames) == 0 {
 		return Person{}, ErrNoLastNames
 	}

Add helper (outside this hunk):

// trims entries, removes empties
func parseList(s string) []string {
	items := strings.Split(s, ",")
	out := make([]string, 0, len(items))
	for _, it := range items {
		if t := strings.TrimSpace(it); t != "" {
			out = append(out, t)
		}
	}
	return out
}

Also applies to: 46-48, 61-65


51-55: Unseeded math/rand yields deterministic people.

rand.Intn here uses the default global RNG (seed=1), so names/ages repeat each run. Other files use a seeded RNG. Align to a seeded source.

Option A (local to package):

// at top-level in this file:
var rng = rand.New(rand.NewSource(time.Now().UnixNano()))
// use rng.Intn(...)

Option B: centralize a shared RNG utility and reuse across entities.

Also applies to: 72-72

🧹 Nitpick comments (13)
pkg/mocai/entities/cpf/generator.go (1)

16-16: Avoid unnecessary pointer allocation.

Creating a temporary pointer (&CPF{}) just to call the method is inefficient. Since generateCPF is an internal method, consider making it a package-level function instead.

-	c, err := (&CPF{}).generateCPF(isFormatted)
+	c, err := generateCPF(isFormatted)

Then update the method signature:

-func (c *CPF) generateCPF(formatted bool) (string, error) {
+func generateCPF(formatted bool) (string, error) {
pkg/mocai/entities/address/generator.go (1)

28-28: Avoid unnecessary pointer allocation.

Creating a temporary pointer (&Address{}) just to call the method is inefficient. Consider making generateAddress a package-level function.

-	addr, err := (&Address{}).generateAddress()
+	addr, err := generateAddress()
pkg/mocai/entities/nationalid/generator.go (2)

13-17: Constructor swallows errors; method can’t fail as written.

countries.NewRG(formatted) returns a value and hides errors; your generateNationalID returns (NationalID, error) but never fails, and NewNationalId returns zero value on “error”. Pick one:

  • Option A (simplify): remove error from generateNationalID and the constructor.
  • Option B (propagate): make countries.NewRG return (RG, error) and bubble it up.

Option A:

-func (n *NationalID) generateNationalID(formatted bool) (NationalID, error) {
-  rg := countries.NewRG(formatted)
-  return NationalID{BrazilianRG: rg}, nil
-}
+func (n *NationalID) generateNationalID(formatted bool) NationalID {
+  rg := countries.NewRG(formatted)
+  return NationalID{BrazilianRG: rg}
+}
- n, err := (&NationalID{}).generateNationalID(isFormatted)
- if err != nil {
-   return NationalID{}
- }
- return n
+ return (&NationalID{}).generateNationalID(isFormatted)

Also applies to: 23-26


20-23: Doc/receiver nits.

  • Comment should start with the function name (“generateNationalID ...”), not “GenerateNationalID”.
  • The receiver isn’t used; consider a package‑level helper or a value receiver.
pkg/mocai/entities/gender/gender.go (1)

9-12: Add String() for ergonomics.

Enable fmt printing and JSON friendliness by exposing the string form.

Add:

func (g Gender) String() string { return string(g.gender) }
pkg/mocai/entities/voteregistration/generator.go (1)

10-17: Inconsistent error handling; unreachable error path.

countries.NewBrazilianVoteRegistration returns a value, so generateVoteRegistration can’t fail; NewVoteRegistration swallows errors anyway. Either:

  • Make countries.NewBrazilianVoteRegistration return (BrazilianVoteRegistration, error) and propagate, or
  • Remove error from generateVoteRegistration and simplify the constructor.

Also, start the doc with the actual name (“generateVoteRegistration ...”).

Example (simplify):

-func (v *VoteRegistration) generateVoteRegistration(isFormatted bool) (VoteRegistration, error) {
-  brazilianVoteRegistration := countries.NewBrazilianVoteRegistration(isFormatted)
-  return VoteRegistration{BrazilianVoteRegistration: brazilianVoteRegistration}, nil
-}
+func (v *VoteRegistration) generateVoteRegistration(isFormatted bool) VoteRegistration {
+  bvr := countries.NewBrazilianVoteRegistration(isFormatted)
+  return VoteRegistration{BrazilianVoteRegistration: bvr}
+}
- vr, err := (&VoteRegistration{}).generateVoteRegistration(isFormatted)
- if err != nil {
-   return VoteRegistration{}
- }
- return vr
+ return (&VoteRegistration{}).generateVoteRegistration(isFormatted)

Also applies to: 19-26

pkg/mocai/entities/person/generator.go (2)

56-60: Avoid shadowing imported packages (gender, cpf).

Local vars named the same as packages reduce readability and risk compile errors if reused. Rename locals.

Apply:

-	// Generate a random gender
-	gender := gender.NewGender()
+	// Generate a random gender
+	g := gender.NewGender()

-	// Generate a random CPF without a mask
-	cpf := cpf.NewCPF(isFormatted)
+	// Generate a random CPF
+	c := cpf.NewCPF(isFormatted)

And in the return literal:

-		Gender:          gender,
+		Gender:          g,
-		CPF:             cpf.Number,
+		CPF:             c.Number,

63-64: Preserve error identity: use %w when wrapping.

Using %s discards ErrGeneratingPerson type info.

- return Person{}, fmt.Errorf("%s: missing required data (firstNameMale: %s, firstNameFemale: %s, lastName: %s)",
-			ErrGeneratingPerson, firstNameMale, firstNameFemale, lastName)
+ return Person{}, fmt.Errorf("%w: missing required data (firstNameMale: %q, firstNameFemale: %q, lastName: %q)",
+			ErrGeneratingPerson, firstNameMale, firstNameFemale, lastName)
pkg/mocai/mocker.go (2)

38-39: Go naming: use “ID”, not “Id”.

NewNationalId should be NewNationalID for Go conventions, and the same for type/field names if applicable.

- NationalID:       nationalid.NewNationalId(isFormatted),
+ NationalID:       nationalid.NewNationalID(isFormatted),

Please confirm the function/type names in pkg/mocai/entities/nationalid to align consistently.


46-53: Simplify SetLanguage; avoid redundant branching.

-func (m *Mocker) SetLanguage(lang string) error {
-	err := translations.SetLanguage(lang)
-	if err != nil {
-		return err
-	}
-	return err
-}
+func (m *Mocker) SetLanguage(lang string) error {
+	return translations.SetLanguage(lang)
+}
pkg/mocai/entities/certificate/generator.go (1)

12-19: Value semantics + constructor look good.

Clean switch to value returns and internal generator; error paths return zero-value with err. API is consistent with other entities.

Minor: unify parameter naming (“isFormatted” vs “formatted”) across packages for consistency.

Also applies to: 24-31

pkg/mocai/entities/voteregistration/countries/brazilian_vote_registration.go (1)

74-82: Domain check: allow “000” for Section/Zone?

randomInt3Digits returns 000..999; if “000” is invalid, clamp to 001..999.

If needed:

-func randomInt3Digits() string {
-	return fmt.Sprintf("%03d", globalRand.Intn(1000))
-}
+func randomInt3Digits() string {
+	n := globalRand.Intn(999) + 1 // 001..999
+	return fmt.Sprintf("%03d", n)
+}

Please confirm the valid ranges for Brazilian Section/Zone.

Also applies to: 16-19, 34-36

pkg/mocai/entities/certificate/countries/brazilian_certificates.go (1)

91-92: Simplify redundant negative number validations.

The negative number checks are unreachable since generateRandomNumber(min, max) with positive arguments cannot return negative values. The function uses rand.Intn(max-min+1) + min, which always produces a result ≥ min.

Consider removing these redundant checks to simplify the code:

 vitalRecordsOffice := generateRandomNumber(100000, 899999)
-if vitalRecordsOffice < 0 {
-	return BaseCertificate{}, ErrInvalidVitalRecordsOffice
-}

Apply similar changes for bookNumber, pageNumber, and termNumber checks.

Also applies to: 109-110, 115-116, 121-122

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 920442f and a651c27.

📒 Files selected for processing (23)
  • README.md (1 hunks)
  • docs/localization/pt/README-PT.md (1 hunks)
  • examples/mocker/main.go (1 hunks)
  • examples/specific/main.go (0 hunks)
  • pkg/mocai/entities/address/generator.go (3 hunks)
  • pkg/mocai/entities/certificate/countries/brazilian_certificates.go (5 hunks)
  • pkg/mocai/entities/certificate/generator.go (1 hunks)
  • pkg/mocai/entities/company/countries/brazilian_company.go (2 hunks)
  • pkg/mocai/entities/company/generator.go (1 hunks)
  • pkg/mocai/entities/cpf/generator.go (1 hunks)
  • pkg/mocai/entities/gender/errors.go (1 hunks)
  • pkg/mocai/entities/gender/gender.go (1 hunks)
  • pkg/mocai/entities/national_id/countries/errors.go (0 hunks)
  • pkg/mocai/entities/national_id/generator.go (0 hunks)
  • pkg/mocai/entities/nationalid/countries/brazilian_national_id.go (1 hunks)
  • pkg/mocai/entities/nationalid/countries/errors.go (1 hunks)
  • pkg/mocai/entities/nationalid/generator.go (1 hunks)
  • pkg/mocai/entities/person/generator.go (3 hunks)
  • pkg/mocai/entities/phone/generator.go (1 hunks)
  • pkg/mocai/entities/vote_registration/generator.go (0 hunks)
  • pkg/mocai/entities/voteregistration/countries/brazilian_vote_registration.go (2 hunks)
  • pkg/mocai/entities/voteregistration/generator.go (1 hunks)
  • pkg/mocai/mocker.go (1 hunks)
💤 Files with no reviewable changes (4)
  • examples/specific/main.go
  • pkg/mocai/entities/national_id/generator.go
  • pkg/mocai/entities/national_id/countries/errors.go
  • pkg/mocai/entities/vote_registration/generator.go
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-03-11T21:56:28.660Z
Learnt from: BertBR
PR: brazzcore/mocai#31
File: pkg/mocai/entities/company/brazil/generator.go:42-43
Timestamp: 2025-03-11T21:56:28.660Z
Learning: In the mocai project, the constant `ERROR_GENERATING_BRAZILIAN_COMPANY` is defined in the `pkg/mocai/entities/company/brazil/errors.go` file and is accessible from other files in the same `company` package, such as `generator.go`.

Applied to files:

  • pkg/mocai/entities/company/countries/brazilian_company.go
  • pkg/mocai/entities/company/generator.go
🧬 Code graph analysis (16)
README.md (2)
examples/specific/main.go (1)
  • main (17-96)
pkg/mocai/translations/pt_br.go (1)
  • init (13-33)
pkg/mocai/mocker.go (9)
pkg/mocai/entities/address/generator.go (2)
  • Address (12-19)
  • NewAddress (27-33)
pkg/mocai/entities/certificate/generator.go (2)
  • Certificate (8-10)
  • NewCertificate (13-19)
pkg/mocai/entities/company/generator.go (2)
  • Company (6-8)
  • NewCompany (11-17)
pkg/mocai/entities/gender/gender.go (2)
  • Gender (9-11)
  • NewGender (28-34)
pkg/mocai/entities/nationalid/generator.go (2)
  • NationalID (7-9)
  • NewNationalId (12-18)
pkg/mocai/entities/person/generator.go (2)
  • Person (14-21)
  • NewPerson (23-29)
pkg/mocai/entities/phone/generator.go (2)
  • Phone (12-15)
  • NewPhone (18-24)
pkg/mocai/entities/voteregistration/generator.go (2)
  • VoteRegistration (6-8)
  • NewVoteRegistration (11-17)
pkg/mocai/translations/translations.go (1)
  • SetLanguage (35-44)
pkg/mocai/entities/company/countries/brazilian_company.go (3)
pkg/mocai/translations/translations.go (2)
  • GetLanguage (47-51)
  • Get (54-67)
pkg/mocai/entities/company/countries/errors.go (3)
  • ErrNoCompanyNamesAvailable (11-11)
  • ErrGeneratingBrazilianCompany (9-9)
  • ErrGeneratingCNPJ (10-10)
pkg/mocai/entities/company/countries/generator_test.go (2)
  • TestGenerateCompany (9-18)
  • TestIfCompanyHasAValidCNPJ (20-29)
pkg/mocai/entities/nationalid/countries/brazilian_national_id.go (1)
pkg/mocai/entities/national_id/generator.go (1)
  • GenerateNationalID (12-19)
pkg/mocai/entities/nationalid/generator.go (3)
pkg/mocai/entities/nationalid/countries/brazilian_national_id.go (2)
  • RG (12-16)
  • NewRG (18-24)
pkg/mocai/entities/national_id/generator.go (1)
  • GenerateNationalID (12-19)
pkg/mocai/entities/national_id/countries/brazilian_national_id.go (1)
  • GenerateBrazilianNationalID (19-33)
pkg/mocai/entities/phone/generator.go (1)
examples/specific/main.go (1)
  • main (17-96)
pkg/mocai/entities/voteregistration/generator.go (3)
pkg/mocai/entities/voteregistration/countries/brazilian_vote_registration.go (2)
  • BrazilianVoteRegistration (15-19)
  • NewBrazilianVoteRegistration (22-28)
pkg/mocai/entities/vote_registration/countries/brazilian_vote_registration.go (1)
  • GenerateBrazilianVoteRegistration (24-63)
examples/specific/main.go (1)
  • main (17-96)
pkg/mocai/entities/company/generator.go (2)
pkg/mocai/entities/company/countries/brazilian_company.go (2)
  • BrazilianCompany (14-17)
  • GenerateBrazilianCompany (21-56)
pkg/mocai/entities/company/countries/generator_test.go (2)
  • TestGenerateCompany (9-18)
  • TestIfCompanyHasAValidCNPJ (20-29)
pkg/mocai/entities/voteregistration/countries/brazilian_vote_registration.go (2)
pkg/mocai/entities/voteregistration/countries/errors.go (1)
  • ErrInvalidVoteRegistration (9-9)
pkg/mocai/entities/vote_registration/generator.go (1)
  • GenerateVoteRegistration (13-20)
pkg/mocai/entities/cpf/generator.go (1)
pkg/mocai/entities/cpf/validator.go (1)
  • ValidateCPF (10-51)
pkg/mocai/entities/person/generator.go (4)
pkg/mocai/entities/gender/gender.go (2)
  • Gender (9-11)
  • NewGender (28-34)
pkg/mocai/entities/cpf/generator.go (2)
  • CPF (10-12)
  • NewCPF (15-21)
pkg/mocai/entities/person/errors.go (3)
  • ErrNoFirstNames (10-10)
  • ErrNoLastNames (11-11)
  • ErrGeneratingPerson (9-9)
examples/specific/main.go (1)
  • main (17-96)
pkg/mocai/entities/certificate/countries/brazilian_certificates.go (1)
pkg/mocai/entities/certificate/countries/errors.go (6)
  • ErrInvalidVitalRecordsOffice (10-10)
  • ErrInvalidBookNumber (14-14)
  • ErrInvalidPageNumber (15-15)
  • ErrInvalidTermNumber (16-16)
  • ErrInvalidNumberWithoutCheckDigits (17-17)
  • ErrInvalidCertificate (9-9)
examples/mocker/main.go (3)
pkg/mocai/mocker.go (1)
  • NewMocker (27-44)
pkg/mocai/entities/address/generator.go (1)
  • Address (12-19)
pkg/mocai/translations/pt_br.go (1)
  • init (13-33)
pkg/mocai/entities/certificate/generator.go (1)
pkg/mocai/entities/certificate/countries/brazilian_certificates.go (2)
  • BrazilianCertificates (49-53)
  • GenerateBrazilianCertificates (58-81)
docs/localization/pt/README-PT.md (2)
pkg/mocai/translations/pt_br.go (1)
  • init (13-33)
examples/specific/main.go (1)
  • main (17-96)
pkg/mocai/entities/gender/gender.go (3)
pkg/mocai/translations/translations.go (2)
  • GetLanguage (47-51)
  • Get (54-67)
pkg/mocai/entities/gender/errors.go (1)
  • ErrNoGenders (9-9)
examples/specific/main.go (1)
  • main (17-96)
🪛 LanguageTool
docs/localization/pt/README-PT.md

[uncategorized] ~52-~52: Sinal de pontuação isolado.
Context: ...de comoo usar a biblioteca: - mocker/: Exemplo usando um ponto de entrada prin...

(UNLIKELY_OPENING_PUNCTUATION)

🔇 Additional comments (13)
pkg/mocai/entities/nationalid/countries/errors.go (1)

1-7: LGTM!

The error variable follows standard Go conventions with a clear, descriptive message.

pkg/mocai/entities/gender/errors.go (1)

9-10: LGTM!

The new error variable follows Go conventions and provides clear error messaging.

docs/localization/pt/README-PT.md (1)

40-46: LGTM!

Documentation correctly reflects the new API with the isFormatted parameter and property-style access pattern.

README.md (1)

42-48: LGTM!

Documentation accurately reflects the refactored API with the new constructor signature and direct field access pattern.

pkg/mocai/entities/company/countries/brazilian_company.go (1)

21-55: LGTM!

The refactoring from pointer to value return type is well-executed. All error paths correctly return BrazilianCompany{} with an error, maintaining proper error propagation to callers. This is the correct pattern for this refactoring.

pkg/mocai/entities/nationalid/countries/brazilian_national_id.go (1)

60-66: Weight order is correct; code properly implements 9–2 left-to-right.

The code correctly applies weights 9,8,7,6,5,4,3,2 left-to-right via reverse indexing. Official São Paulo RG (SSP‑SP) documentation specifies modulo‑11 with weights 9,8,7,6,5,4,3,2 applied left-to-right (leftmost digit ×9, next ×8, …, rightmost of the 8 ×2), which matches the implementation. The wheights array [2,3,4,5,6,7,8,9] accessed via d[7-i] achieves this sequence in the correct direction.

pkg/mocai/entities/person/generator.go (1)

23-29: Constructor swallows errors; confirm this API change is intentional.

NewPerson returns zero-value on failure, making failures silent at call sites (e.g., mocai.NewMocker). If unintended, return (Person, error) or expose a diagnostics hook.

If silent fallback is desired, consider a Health() on Mocker to surface which fields defaulted.

pkg/mocai/entities/company/generator.go (1)

10-17: Solid refactor to values; generator wiring is correct.

Constructor + internal generator pattern is consistent; error propagation is correct; final value return is idiomatic.

Also applies to: 20-27

pkg/mocai/entities/voteregistration/countries/brazilian_vote_registration.go (2)

21-28: Constructor returns zero-value on error; confirm behavior.

NewBrazilianVoteRegistration swallows errors. Aligns with other constructors but hides failures; confirm this is desired.

Would you prefer returning (BrazilianVoteRegistration, error) here?


84-103: Error symbols verified and used correctly.

All three error symbols (ErrInvalidVoteRegistration, ErrInvalidCheckDigit1, ErrInvalidCheckDigit2) are properly defined in errors.go, exported (capitalized), and used consistently throughout brazilian_vote_registration.go. The code is correct as written.

pkg/mocai/entities/certificate/countries/brazilian_certificates.go (3)

50-52: LGTM: Value types are appropriate here.

The change from pointer to value types for the certificate fields is well-suited for these small structs and eliminates nil-checking concerns.


58-81: LGTM: Consistent value-based return pattern.

The function correctly returns values instead of pointers, with proper zero-value returns on error paths. The implementation is clean and error handling is appropriate.


162-173: LGTM: Certificate generation functions are consistent.

All three certificate generation functions follow the same clean pattern with proper error handling and value-based returns.

Also applies to: 176-187, 190-201

Comment on lines +11 to +18
// NewNationalId creates a new NationalID entity with a generated Brazilian national ID [RG].
func NewNationalId(isFormatted bool) NationalID {
n, err := (&NationalID{}).generateNationalID(isFormatted)
if err != nil {
return NationalID{}
}
return n
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

🧩 Analysis chain

Rename to NewNationalID (Go acronym convention).

Public API should use “ID”, not “Id”. Rename the constructor to NewNationalID and update call sites.

Apply:

-// NewNationalId creates a new NationalID entity with a generated Brazilian national ID [RG].
-func NewNationalId(isFormatted bool) NationalID {
+// NewNationalID creates a new NationalID entity with a generated Brazilian national ID (RG).
+func NewNationalID(isFormatted bool) NationalID {

Run to find/update usages:


🏁 Script executed:

#!/bin/bash
rg -nP '\bNewNationalId\s*\(' -C3

Length of output: 1102


Rename NewNationalId to NewNationalID (Go acronym convention).

Go convention uses "ID" for the acronym, not "Id". Update the constructor and its call site:

  • pkg/mocai/entities/nationalid/generator.go:12 — rename function definition
  • pkg/mocai/mocker.go:38 — update call site
-// NewNationalId creates a new NationalID entity with a generated Brazilian national ID [RG].
-func NewNationalId(isFormatted bool) NationalID {
+// NewNationalID creates a new NationalID entity with a generated Brazilian national ID (RG).
+func NewNationalID(isFormatted bool) NationalID {
-		NationalID:       nationalid.NewNationalId(isFormatted),
+		NationalID:       nationalid.NewNationalID(isFormatted),
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// NewNationalId creates a new NationalID entity with a generated Brazilian national ID [RG].
func NewNationalId(isFormatted bool) NationalID {
n, err := (&NationalID{}).generateNationalID(isFormatted)
if err != nil {
return NationalID{}
}
return n
}
// NewNationalID creates a new NationalID entity with a generated Brazilian national ID (RG).
func NewNationalID(isFormatted bool) NationalID {
n, err := (&NationalID{}).generateNationalID(isFormatted)
if err != nil {
return NationalID{}
}
return n
}
🤖 Prompt for AI Agents
In pkg/mocai/entities/nationalid/generator.go around lines 11–18, the exported
constructor is named NewNationalId which violates Go acronym conventions; rename
the function to NewNationalID and update its documentation/comment accordingly,
then update the call site in pkg/mocai/mocker.go at line 38 to use
NewNationalID; after renaming, run a quick build or go vet to catch any
remaining references and update imports/usages across the repo as necessary.

Comment on lines +30 to +33
// GenerateBrazilianVoteRegistration generates a valid Brazilian vote registration number.
// If formatted is true, the Brazilian vote registration number will be returned in the format XXX XXX XXX.
// If formatted is false, the Brazilian vote registration number will be returned as a plain string.
func GenerateBrazilianVoteRegistration(formatted bool) (*BrazilianVoteRegistration, error) {
func (b *BrazilianVoteRegistration) generateBrazilianVoteRegistration(formatted bool) (BrazilianVoteRegistration, error) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Docs mismatch: format is 4‑4‑4, not 3‑3‑3.

Comment says “XXX XXX XXX” but code formats “XXXX XXXX XXXX”.

-// If formatted is true, the Brazilian vote registration number will be returned in the format XXX XXX XXX.
+// If formatted is true, the Brazilian vote registration number will be returned in the format XXXX XXXX XXXX.

Also applies to: 63-65

🤖 Prompt for AI Agents
In pkg/mocai/entities/voteregistration/countries/brazilian_vote_registration.go
around lines 30-33 (and also update the similar comments at 63-65), the doc
comment incorrectly states the formatted pattern as "XXX XXX XXX" (3-3-3) while
the implementation uses a 4-4-4 pattern; update the comment text to reflect the
correct format "XXXX XXXX XXXX" (4-4-4) and any explanatory text to match that
formatting.

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: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
pkg/mocai/entities/address/generator.go (1)

37-46: Guard against missing translations; translations.Get returns the key when not found.

When a key is absent, Get(lang, key) returns key (e.g., "address_street"), so current checks pass and you emit bogus values. Validate raw values before Split.

@@
- // Get the list of streets, cities, states, and ZIP codes
- streets := strings.Split(translations.Get(lang, "address_street"), ",")
- cities := strings.Split(translations.Get(lang, "address_city"), ",")
- states := strings.Split(translations.Get(lang, "address_state"), ",")
- uf := translations.Get(lang, "address_uf")
- zips := strings.Split(translations.Get(lang, "address_zip"), ",")
+ // Fetch raw strings and validate presence (Get returns key if missing)
+ rawStreets := translations.Get(lang, "address_street")
+ rawCities  := translations.Get(lang, "address_city")
+ rawStates  := translations.Get(lang, "address_state")
+ uf         := translations.Get(lang, "address_uf")
+ rawZips    := translations.Get(lang, "address_zip")
+
+ if rawStreets == "address_street" { return nil, ErrNoStreets }
+ if rawCities  == "address_city"   { return nil, ErrNoCities }
+ if rawStates  == "address_state"  { return nil, ErrNoStates }
+ if uf         == "address_uf"     { return nil, ErrNoUFs }
+ if rawZips    == "address_zip"    { return nil, ErrNoZips }
+
+ streets := strings.Split(rawStreets, ",")
+ cities  := strings.Split(rawCities, ",")
+ states  := strings.Split(rawStates, ",")
+ zips    := strings.Split(rawZips, ",")

As per coding guidelines.

Also applies to: 60-69

♻️ Duplicate comments (3)
pkg/mocai/entities/gender/gender.go (1)

38-46: Normalize translation and bound to allowed set; add missing-translation guard.

translations.Get returns the key when missing, so the empty-string check never triggers. Normalize and default or error out.

@@
-import (
-  "fmt"
-  "github.com/brazzcore/mocai/pkg/mocai/translations"
-)
+import (
+  "fmt"
+  "strings"
+  "github.com/brazzcore/mocai/pkg/mocai/translations"
+)
@@
-func (g *Gender) generateRandomGender() (*Gender, error) {
-  lang := translations.GetLanguage()
-  genderStr := translations.Get(lang, "gender")
-
-  if genderStr == "" {
-    return nil, fmt.Errorf("%s for: %s", ErrNoGenders, lang)
-  }
-  return &Gender{Identity: Identity(genderStr)}, nil
-}
+func (g *Gender) generateRandomGender() (*Gender, error) {
+  lang := translations.GetLanguage()
+  s := strings.ToLower(strings.TrimSpace(translations.Get(lang, "gender")))
+  if s == "gender" {
+    return nil, fmt.Errorf("%s for: %s", ErrNoGenders, lang)
+  }
+  switch s {
+  case "male", "female", "non-binary", "genderfluid", "agender", "two-spirit", "other":
+    return &Gender{Identity: Identity(s)}, nil
+  default:
+    return &Gender{Identity: Other}, nil
+  }
+}
pkg/mocai/mocker.go (2)

53-56: Acronym casing: Id → ID (duplicate of prior feedback).

Consider renaming NewNationalId to NewNationalID across the repo for Go conventions.


86-93: Return nil on success (duplicate of prior feedback).

SetLanguage returns err even when it must be nil; return nil explicitly.

 func (m *Mocker) SetLanguage(lang string) error {
     err := translations.SetLanguage(lang)
     if err != nil {
         return err
     }
-    return err
+    return nil
 }
🧹 Nitpick comments (7)
pkg/mocai/entities/address/generator.go (1)

73-86: Use a locally seeded RNG and avoid house number 0.

  • Seed a local rand.Rand for variability (consistent with CPF).
  • Return numbers in 1..9999 (not 0..9998).
@@
- // Choose random values
- street := streets[rand.Intn(len(streets))]
- city := cities[rand.Intn(len(cities))]
- state := states[rand.Intn(len(states))]
- zip := zips[rand.Intn(len(zips))]
+ // Choose random values using a local RNG
+ src := rand.NewSource(time.Now().UnixNano())
+ r   := rand.New(src)
+ street := streets[r.Intn(len(streets))]
+ city   := cities[r.Intn(len(cities))]
+ state  := states[r.Intn(len(states))]
+ zip    := zips[r.Intn(len(zips))]
@@
-   Number: rand.Intn(9999),
+   Number: r.Intn(9999) + 1,

And import time:

-import (
+import (
   "fmt"
   "math/rand"
   "strings"
+  "time"
docs/localization/pt/README-PT.md (1)

50-53: Minor style nit (optional):

Consider removing the colon at the end of the sentence or adding a blank line before the bullet to silence linters that flag “isolated punctuation.” Not required.

pkg/mocai/entities/cpf/generator.go (1)

44-45: Build cpfNumber without fmt/Fields/Trim for clarity and speed.

Use strings.Builder to avoid allocations and bracket/trim hacks.

- cpfNumber := strings.Trim(strings.Join(strings.Fields(fmt.Sprint(digits)), ""), "[]")
+ var b strings.Builder
+ b.Grow(11)
+ for _, d := range digits {
+   b.WriteByte(byte('0' + d))
+ }
+ cpfNumber := b.String()
pkg/mocai/entities/certificate/generator.go (1)

24-30: Minor: receiver unused and comment capitalization.

generateCertificate doesn’t use the receiver; make it a package‑private helper or populate c in-place. Also fix the preceding comment to match the unexported name (“generateCertificate”).

-// GenerateCertificate generates all certificates available.
+// generateCertificate generates all certificates available.
pkg/mocai/entities/person/generator.go (2)

55-66: Avoid shadowing imported package names.

Variables named gender and cpf shadow their imported packages, hurting readability and tooling. Rename locals.

-    gender, err := gender.NewGender()
+    g, err := gender.NewGender()
 ...
-    cpf, err := cpf.NewCPF(isFormatted)
+    docCPF, err := cpf.NewCPF(isFormatted)
 ...
-        Gender:          gender,
+        Gender:          g,
-        CPF:             cpf,
+        CPF:             docCPF,

61-66: Comment drift.

“Generate a random CPF without a mask” is outdated now that isFormatted is honored. Update the comment.

-// Generate a random CPF without a mask
+// Generate a random CPF respecting isFormatted
pkg/mocai/mocker.go (1)

33-71: Rename locals to avoid shadowing package imports.

address, certificate, company, gender, nationalID, person, phone, voteRegistration shadow imports. Prefer short, distinct names.

- address, err := address.NewAddress()
+ addr, err := address.NewAddress()
 ...
- certificate, err := certificate.NewCertificate(isFormatted)
+ cert, err := certificate.NewCertificate(isFormatted)
 ...
- company, err := company.NewCompany(isFormatted)
+ comp, err := company.NewCompany(isFormatted)
 ...
- gender, err := gender.NewGender()
+ g, err := gender.NewGender()
 ...
- nationalID, err := nationalid.NewNationalId(isFormatted)
+ nid, err := nationalid.NewNationalId(isFormatted)
 ...
- person, err := person.NewPerson(isFormatted)
+ p, err := person.NewPerson(isFormatted)
 ...
- phone, err := phone.NewPhone()
+ ph, err := phone.NewPhone()
 ...
- voteRegistration, err := voteregistration.NewVoteRegistration(isFormatted)
+ vr, err := voteregistration.NewVoteRegistration(isFormatted)
 ...
-        Address:          address,
-        Certificate:      certificate,
-        Company:          company,
-        Gender:           gender,
-        NationalID:       nationalID,
-        Person:           person,
-        Phone:            phone,
-        VoteRegistration: voteRegistration,
+        Address:          addr,
+        Certificate:      cert,
+        Company:          comp,
+        Gender:           g,
+        NationalID:       nid,
+        Person:           p,
+        Phone:            ph,
+        VoteRegistration: vr,
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a651c27 and 33b1fa5.

📒 Files selected for processing (12)
  • README.md (1 hunks)
  • docs/localization/pt/README-PT.md (1 hunks)
  • pkg/mocai/entities/address/generator.go (2 hunks)
  • pkg/mocai/entities/certificate/generator.go (1 hunks)
  • pkg/mocai/entities/company/generator.go (1 hunks)
  • pkg/mocai/entities/cpf/generator.go (2 hunks)
  • pkg/mocai/entities/gender/gender.go (1 hunks)
  • pkg/mocai/entities/nationalid/generator.go (1 hunks)
  • pkg/mocai/entities/person/generator.go (3 hunks)
  • pkg/mocai/entities/phone/generator.go (1 hunks)
  • pkg/mocai/entities/voteregistration/generator.go (1 hunks)
  • pkg/mocai/mocker.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • pkg/mocai/entities/phone/generator.go
  • pkg/mocai/entities/nationalid/generator.go
  • pkg/mocai/entities/company/generator.go
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-18T03:32:17.181Z
Learnt from: wellfernandes
PR: brazzcore/mocai#50
File: pkg/mocai/entities/cpf/generator.go:14-21
Timestamp: 2025-10-18T03:32:17.181Z
Learning: In the mocai Go codebase, constructor functions like NewCPF, NewPerson, NewAddress, etc. in pkg/mocai/entities/* are designed to return zero values (e.g., CPF{}, Person{}, Address{}) on generation errors without propagating the error to callers. This is an intentional design choice.

Applied to files:

  • pkg/mocai/entities/cpf/generator.go
  • pkg/mocai/entities/address/generator.go
  • pkg/mocai/entities/person/generator.go
  • pkg/mocai/mocker.go
🧬 Code graph analysis (6)
pkg/mocai/entities/cpf/generator.go (1)
pkg/mocai/entities/cpf/errors.go (1)
  • ErrInvalidCPF (6-6)
pkg/mocai/entities/certificate/generator.go (1)
pkg/mocai/entities/certificate/countries/brazilian_certificates.go (1)
  • BrazilianCertificates (49-53)
pkg/mocai/entities/gender/gender.go (2)
pkg/mocai/translations/translations.go (2)
  • GetLanguage (47-51)
  • Get (54-67)
pkg/mocai/entities/gender/errors.go (1)
  • ErrNoGenders (9-9)
pkg/mocai/entities/voteregistration/generator.go (1)
pkg/mocai/entities/voteregistration/countries/brazilian_vote_registration.go (2)
  • BrazilianVoteRegistration (15-19)
  • NewBrazilianVoteRegistration (22-28)
pkg/mocai/entities/person/generator.go (2)
pkg/mocai/entities/cpf/generator.go (2)
  • CPF (10-12)
  • NewCPF (15-21)
pkg/mocai/entities/gender/gender.go (1)
  • NewGender (29-35)
pkg/mocai/mocker.go (9)
pkg/mocai/entities/address/generator.go (2)
  • Address (12-19)
  • NewAddress (27-33)
pkg/mocai/entities/certificate/generator.go (2)
  • Certificate (8-10)
  • NewCertificate (13-19)
pkg/mocai/entities/company/generator.go (2)
  • Company (6-8)
  • NewCompany (11-17)
pkg/mocai/entities/gender/gender.go (2)
  • Gender (10-12)
  • NewGender (29-35)
pkg/mocai/entities/nationalid/generator.go (2)
  • NationalID (7-9)
  • NewNationalId (12-18)
pkg/mocai/entities/person/generator.go (2)
  • Person (14-21)
  • NewPerson (23-29)
pkg/mocai/entities/phone/generator.go (2)
  • Phone (12-15)
  • NewPhone (18-24)
pkg/mocai/entities/voteregistration/generator.go (2)
  • VoteRegistration (6-8)
  • NewVoteRegistration (11-17)
pkg/mocai/translations/translations.go (2)
  • SetLanguage (35-44)
  • GetLanguage (47-51)
🪛 LanguageTool
docs/localization/pt/README-PT.md

[uncategorized] ~52-~52: Sinal de pontuação isolado.
Context: ... de como usar a biblioteca: - mocker/: Exemplo usando um ponto de entrada prin...

(UNLIKELY_OPENING_PUNCTUATION)

🔇 Additional comments (9)
docs/localization/pt/README-PT.md (1)

40-47: API usage update looks good.

The NewMocker(lang, isFormatted) example and field access (Address.Street, Phone.Number) align with the refactor.

README.md (1)

42-49: Docs match the new API.

Constructor signature and field-based access are correctly reflected.

pkg/mocai/entities/cpf/generator.go (1)

48-55: Remove redundant length check; constructor pattern appears consistent, but verify PR intent.

The length check on line 49 is indeed redundant. The CPF generation always produces exactly 11 digits (9 random + 2 check digits via append), so the guard can be simplified to a comment:

if formatted {
-   if len(cpfNumber) != 11 {
-     return nil, ErrInvalidCPF
-   }
+   // cpfNumber is guaranteed to have 11 chars from digit generation
    f := cpfNumber[:3] + "." + cpfNumber[3:6] + "." + cpfNumber[6:9] + "-" + cpfNumber[9:]
    return &CPF{Number: f}, nil
}

Regarding the design shift: All examined entity constructors (CPF, Address, Person) already return (*Type, error) with error propagation, indicating the pattern is consistent. However, verify whether this PR introduces that shift or if it's pre-existing from earlier commits, as the actual before/after state of the code in this PR affects whether the refactor aligns with intentional architecture changes.

pkg/mocai/entities/certificate/generator.go (2)

9-10: Struct field switch to value type looks good.

Aligns with countries.BrazilianCertificates now being value fields; avoids nil checks.


12-19: Constructor pattern LGTM.

NewCertificate delegates to an internal generator and propagates errors. Consistent with other entities.

pkg/mocai/entities/person/generator.go (2)

20-21: API change: CPF now a pointer.

Confirm downstream JSON/schema expectations and nil handling where Person is serialized or compared.


78-79: Verify intended age range.

rand.Intn(70)+18 yields ages 18–87. If target is 18–70, use rand.Intn(53)+18. Please confirm.

pkg/mocai/mocker.go (2)

26-83: Constructor now fail‑fasts on init errors — good.

Error propagation across all entity constructors improves debuggability.


95-97: GetLanguage passthrough looks fine.

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: 0

♻️ Duplicate comments (2)
pkg/mocai/entities/voteregistration/countries/brazilian_vote_registration.go (1)

30-33: Docs mismatch: format is 4‑4‑4, not 3‑3‑3.

The comment states "XXX XXX XXX" but line 64 formats as "XXXX XXXX XXXX" (4-4-4).

-// If formatted is true, the Brazilian vote registration number will be returned in the format XXX XXX XXX.
+// If formatted is true, the Brazilian vote registration number will be returned in the format XXXX XXXX XXXX.

Also applies to: 63-65

pkg/mocai/entities/voteregistration/generator.go (1)

19-21: Docs mismatch: format is 4‑4‑4, not 3‑3‑3.

The comment states "XXX XXX XXX" but the actual format (as implemented in the countries package) is "XXXX XXXX XXXX" (4-4-4).

-// If formatted is true, the Brazilian vote registration will be returned in the format XXX XXX XXX.
+// If formatted is true, the Brazilian vote registration will be returned in the format XXXX XXXX XXXX.
🧹 Nitpick comments (2)
pkg/mocai/entities/address/generator.go (2)

26-33: Error handling improved – properly propagates errors now.

The constructor now returns (*Address, error) and correctly propagates errors, resolving the previous concern where errors were silently swallowed. This is a good improvement over the old design.

However, the pattern (&Address{}).generateAddress() is unusual because the generateAddress() method doesn't use its receiver at all (see next comment). Consider either making generateAddress a package-level function or refactoring it to populate the receiver instead of returning a new Address.


37-87: Unused receiver suggests refactoring opportunity.

The generateAddress() method never uses its receiver a. The method creates and returns a new *Address instead of populating the receiver. This pattern makes the receiver unnecessary.

Also, the past issue about returning &Address{} on validation errors has been fixed – the code now correctly returns nil on errors (lines 62, 68). Good improvement!

Consider one of these refactors for better idiomaticity:

Option 1 (preferred): Make it a package-level function since the receiver isn't used:

-func (a *Address) generateAddress() (*Address, error) {
+func generateAddress() (*Address, error) {
 	lang := translations.GetLanguage()
 	// ... rest unchanged

Option 2: Populate the receiver instead of creating a new Address:

-func (a *Address) generateAddress() (*Address, error) {
+func (a *Address) generate() error {
 	lang := translations.GetLanguage()
 	// ... validation logic ...
 	
-	return &Address{
-		Street: street,
-		Number: rand.Intn(9999),
-		City:   city,
-		State:  state,
-		UF:     uf,
-		ZIP:    zip,
-	}, nil
+	a.Street = street
+	a.Number = rand.Intn(9999)
+	a.City = city
+	a.State = state
+	a.UF = uf
+	a.ZIP = zip
+	return nil
 }

Then update NewAddress:

 func NewAddress() (*Address, error) {
-	addr, err := (&Address{}).generateAddress()
+	addr := &Address{}
+	err := addr.generate()
 	if err != nil {
 		return nil, err
 	}
 	return addr, nil
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 33b1fa5 and 798928b.

📒 Files selected for processing (3)
  • pkg/mocai/entities/address/generator.go (1 hunks)
  • pkg/mocai/entities/voteregistration/countries/brazilian_vote_registration.go (1 hunks)
  • pkg/mocai/entities/voteregistration/generator.go (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-18T03:32:17.181Z
Learnt from: wellfernandes
PR: brazzcore/mocai#50
File: pkg/mocai/entities/cpf/generator.go:14-21
Timestamp: 2025-10-18T03:32:17.181Z
Learning: In the mocai Go codebase, constructor functions like NewCPF, NewPerson, NewAddress, etc. in pkg/mocai/entities/* are designed to return zero values (e.g., CPF{}, Person{}, Address{}) on generation errors without propagating the error to callers. This is an intentional design choice.

Applied to files:

  • pkg/mocai/entities/address/generator.go
🧬 Code graph analysis (1)
pkg/mocai/entities/voteregistration/generator.go (1)
pkg/mocai/entities/voteregistration/countries/brazilian_vote_registration.go (2)
  • BrazilianVoteRegistration (15-19)
  • NewBrazilianVoteRegistration (22-28)
🔇 Additional comments (5)
pkg/mocai/entities/voteregistration/countries/brazilian_vote_registration.go (2)

21-28: LGTM! Constructor properly propagates errors.

The new constructor correctly delegates to the internal generator and propagates errors as expected.


10-11: Verify whether NewBrazilianVoteRegistration is called concurrently in practice or intended for concurrent use.

The review's technical concern is valid—math/rand.Rand is indeed not thread-safe. However, no goroutine spawning patterns or concurrent call sites were found in the codebase. No test files exist for the vote registration module to demonstrate concurrent usage.

Before applying synchronization overhead with a mutex or migrating to math/rand/v2, confirm whether this code is actually called from multiple goroutines in production or intended for concurrent use. If yes, the fix is necessary. If no, it may be premature optimization.

pkg/mocai/entities/voteregistration/generator.go (3)

5-8: LGTM! Clean wrapper design.

The struct design is straightforward and follows Go conventions.


10-17: LGTM! Error propagation is correct.

The constructor properly delegates and propagates errors. The past review concern about error handling has been resolved.


22-28: LGTM! Proper error handling and pointer semantics.

The method correctly captures and propagates errors from countries.NewBrazilianVoteRegistration. The pointer dereference on line 27 properly matches the struct field type.

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
pkg/mocai/entities/voteregistration/countries/brazilian_vote_registration.go (1)

11-11: Critical: Race condition on shared random number generator.

globalRand is accessed without synchronization by randomInt and randomInt3Digits, which are called from generateBrazilianVoteRegistration. rand.Rand is not safe for concurrent use, so concurrent calls to NewBrazilianVoteRegistration will trigger data races.

Solution: Use a mutex to protect access:

 var (
+	randMutex  sync.Mutex
 	globalRand = rand.New(rand.NewSource(time.Now().UnixNano()))
 )

Then wrap all globalRand calls:

 func randomInt(min, max int) int {
+	randMutex.Lock()
+	defer randMutex.Unlock()
 	return globalRand.Intn(max-min+1) + min
 }
 
 func randomInt3Digits() string {
+	randMutex.Lock()
+	defer randMutex.Unlock()
 	return fmt.Sprintf("%03d", globalRand.Intn(1000))
 }

Don't forget to import sync at the top of the file.

🧹 Nitpick comments (2)
pkg/mocai/entities/voteregistration/countries/brazilian_vote_registration.go (2)

21-28: Consider simplifying the constructor pattern.

The constructor creates a zero-value BrazilianVoteRegistration solely to invoke generateBrazilianVoteRegistration. Since the receiver is unused in the method (see Line 31), this could be simplified to a direct package-level function call.

If this pattern is required for project-wide consistency, consider documenting the architectural rationale. Otherwise, simplify:

-func NewBrazilianVoteRegistration(isFormatted bool) (*BrazilianVoteRegistration, error) {
-	bvr, err := (&BrazilianVoteRegistration{}).generateBrazilianVoteRegistration(isFormatted)
-	if err != nil {
-		return nil, err
-	}
-	return bvr, nil
-}
+func NewBrazilianVoteRegistration(isFormatted bool) (*BrazilianVoteRegistration, error) {
+	return generateBrazilianVoteRegistration(isFormatted)
+}

And convert generateBrazilianVoteRegistration back to a package-level function (removing the receiver).


31-31: Unused receiver parameter.

The receiver b is never referenced in the method body. The method operates as a pure function, creating and returning a new BrazilianVoteRegistration without accessing receiver state. This suggests it should be a package-level function rather than a method.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 798928b and 26ce805.

📒 Files selected for processing (3)
  • pkg/mocai/entities/nationalid/generator.go (1 hunks)
  • pkg/mocai/entities/voteregistration/countries/brazilian_vote_registration.go (1 hunks)
  • pkg/mocai/mocker.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • pkg/mocai/entities/nationalid/generator.go
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-18T03:32:17.181Z
Learnt from: wellfernandes
PR: brazzcore/mocai#50
File: pkg/mocai/entities/cpf/generator.go:14-21
Timestamp: 2025-10-18T03:32:17.181Z
Learning: In the mocai Go codebase, constructor functions like NewCPF, NewPerson, NewAddress, etc. in pkg/mocai/entities/* are designed to return zero values (e.g., CPF{}, Person{}, Address{}) on generation errors without propagating the error to callers. This is an intentional design choice.

Applied to files:

  • pkg/mocai/mocker.go
🧬 Code graph analysis (1)
pkg/mocai/mocker.go (9)
pkg/mocai/entities/address/generator.go (2)
  • Address (12-19)
  • NewAddress (27-33)
pkg/mocai/entities/certificate/generator.go (2)
  • Certificate (8-10)
  • NewCertificate (13-19)
pkg/mocai/entities/company/generator.go (2)
  • Company (6-8)
  • NewCompany (11-17)
pkg/mocai/entities/gender/gender.go (2)
  • Gender (10-12)
  • NewGender (29-35)
pkg/mocai/entities/nationalid/generator.go (2)
  • NationalID (7-9)
  • NewNationalID (12-18)
pkg/mocai/entities/person/generator.go (2)
  • Person (14-21)
  • NewPerson (23-29)
pkg/mocai/entities/phone/generator.go (2)
  • Phone (12-15)
  • NewPhone (18-24)
pkg/mocai/entities/voteregistration/generator.go (2)
  • VoteRegistration (6-8)
  • NewVoteRegistration (11-17)
pkg/mocai/translations/translations.go (2)
  • SetLanguage (35-44)
  • GetLanguage (47-51)
🔇 Additional comments (4)
pkg/mocai/mocker.go (4)

1-13: LGTM!

The package declaration and imports are clean and properly organized. The naming conventions follow Go standards.


15-24: LGTM!

The public field design enables direct access to entities and follows Go naming conventions correctly (e.g., NationalID with correct acronym capitalization). This is a breaking API change from accessor methods to public fields, but aligns with the PR objectives.


26-84: Well done fixing the error handling!

NewMocker now properly checks and propagates errors from all entity constructors (lines 33-71), addressing the error-swallowing issue flagged in previous reviews. The constructor correctly uses NewNationalID with proper Go naming conventions.


95-97: LGTM!

The GetLanguage method correctly delegates to the translations package and provides convenient access to the current language setting.

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: 0

🧹 Nitpick comments (1)
pkg/mocai/mocker.go (1)

15-28: Consider adding a GetFormatted() method for consistency.

The struct design looks good. All entity fields are properly exposed as public pointers, and the private formatted and lang fields store initialization configuration.

However, lang has a corresponding GetLanguage() method (lines 92-95) while formatted has no getter. For API consistency, consider adding:

// GetFormatted returns whether this Mocker's data was generated with formatting
func (m *Mocker) GetFormatted() bool {
    return m.formatted
}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 26ce805 and 56c88c5.

📒 Files selected for processing (3)
  • README.md (1 hunks)
  • docs/localization/pt/README-PT.md (1 hunks)
  • pkg/mocai/mocker.go (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-18T03:32:17.181Z
Learnt from: wellfernandes
PR: brazzcore/mocai#50
File: pkg/mocai/entities/cpf/generator.go:14-21
Timestamp: 2025-10-18T03:32:17.181Z
Learning: In the mocai Go codebase, constructor functions like NewCPF, NewPerson, NewAddress, etc. in pkg/mocai/entities/* are designed to return zero values (e.g., CPF{}, Person{}, Address{}) on generation errors without propagating the error to callers. This is an intentional design choice.

Applied to files:

  • pkg/mocai/mocker.go
🧬 Code graph analysis (1)
pkg/mocai/mocker.go (9)
pkg/mocai/entities/address/generator.go (2)
  • Address (12-19)
  • NewAddress (27-33)
pkg/mocai/entities/certificate/generator.go (2)
  • Certificate (8-10)
  • NewCertificate (13-19)
pkg/mocai/entities/company/generator.go (2)
  • Company (6-8)
  • NewCompany (11-17)
pkg/mocai/entities/gender/gender.go (2)
  • Gender (10-12)
  • NewGender (29-35)
pkg/mocai/entities/nationalid/generator.go (2)
  • NationalID (7-9)
  • NewNationalID (12-18)
pkg/mocai/entities/person/generator.go (2)
  • Person (14-21)
  • NewPerson (23-29)
pkg/mocai/entities/phone/generator.go (2)
  • Phone (12-15)
  • NewPhone (18-24)
pkg/mocai/entities/voteregistration/generator.go (2)
  • VoteRegistration (6-8)
  • NewVoteRegistration (11-17)
pkg/mocai/translations/translations.go (2)
  • SetLanguage (35-44)
  • GetLanguage (47-51)
🪛 LanguageTool
docs/localization/pt/README-PT.md

[uncategorized] ~61-~61: Sinal de pontuação isolado.
Context: ... de como usar a biblioteca: - mocker/: Exemplo usando um ponto de entrada prin...

(UNLIKELY_OPENING_PUNCTUATION)

🔇 Additional comments (7)
pkg/mocai/mocker.go (3)

3-13: LGTM: Import statements reflect package restructuring.

The updated import paths for nationalid and voteregistration align with Go naming conventions and the broader package refactoring described in the PR objectives.


30-90: Excellent: Previous error-handling concerns have been addressed.

The constructor now properly checks and propagates errors from all entity initialization calls (lines 38-76). Each NewXxx constructor is followed by an error check that returns early on failure, ensuring that NewMocker never returns a partially-initialized Mocker with zero-valued fields.

This resolves the error-swallowing issue flagged in previous reviews.


92-95: LGTM: SetLanguage removal improves API clarity.

The previous SetLanguage method (which had a bug and unclear semantics about whether it would regenerate entities) has been removed. The current design makes language immutable after construction, which aligns well with the documentation stating that users must create a new Mocker instance for different languages.

GetLanguage() provides simple read access to the configured language.

docs/localization/pt/README-PT.md (2)

38-54: LGTM: Code example accurately reflects the new API.

The example correctly demonstrates:

  • The updated NewMocker(lang string, isFormatted bool) signature
  • Proper error handling with log.Fatal(err)
  • Direct field access pattern (ptMocker.Address.Street, ptMocker.Phone.Number)
  • Creating separate instances for different languages

56-66: LGTM: Documentation accurately describes the new API semantics.

The documentation correctly emphasizes:

  • Immutability of each Mocker instance (line 56)
  • The need to create new instances for different languages
  • The updated constructor signature and parameters (line 61)

The static analysis hint about punctuation at line 61 is a false positive—the colon and dash are standard Markdown list formatting.

README.md (2)

41-56: LGTM: Code example accurately demonstrates the new API.

The example correctly shows:

  • The new NewMocker(lang string, isFormatted bool) constructor signature
  • Proper error handling with log.Fatal(err)
  • Direct field access (ptMocker.Address.Street, ptMocker.Phone.Number)
  • Creating separate instances for different languages

Consistent with the Portuguese README and the actual implementation.


58-68: LGTM: Documentation clearly describes API semantics and immutability.

The documentation correctly emphasizes:

  • Each Mocker instance is immutable and language-specific (line 58)
  • Users must create new instances for different languages
  • The updated constructor signature with both lang and isFormatted parameters (line 63)

Consistent with the Portuguese README and the implementation.

Copy link
Copy Markdown
Collaborator

@DODOSUBI DODOSUBI left a comment

Choose a reason for hiding this comment

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

LGTM

@wellfernandes wellfernandes merged commit bb343f1 into develop Oct 28, 2025
2 checks passed
@wellfernandes wellfernandes deleted the feature/49-refactor-package-names branch October 28, 2025 02:37
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