Skip to content

[devices] SIM cards info support#229

Draft
capcom6 wants to merge 2 commits intomasterfrom
devices/sim-cards-info
Draft

[devices] SIM cards info support#229
capcom6 wants to merge 2 commits intomasterfrom
devices/sim-cards-info

Conversation

@capcom6
Copy link
Copy Markdown
Member

@capcom6 capcom6 commented May 7, 2026

Summary by CodeRabbit

Release Notes

  • New Features

    • SIM card details are now tracked and displayed with device information.
  • Chores

    • Internal infrastructure improvements and dependency updates to enhance system reliability and maintainability.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 7, 2026

Warning

Rate limit exceeded

@capcom6 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 48 minutes and 53 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: db6bc272-cb8d-4195-aa82-ed9e7cbbc786

📥 Commits

Reviewing files that changed from the base of the PR and between 15ad054 and e8f35fd.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (36)
  • go.mod
  • internal/sms-gateway/handlers/converters/devices.go
  • internal/sms-gateway/handlers/converters/devices_test.go
  • internal/sms-gateway/handlers/devices/3rdparty.go
  • internal/sms-gateway/handlers/events/mobile.go
  • internal/sms-gateway/handlers/messages/3rdparty.go
  • internal/sms-gateway/handlers/messages/mobile.go
  • internal/sms-gateway/handlers/middlewares/deviceauth/deviceauth.go
  • internal/sms-gateway/handlers/mobile.go
  • internal/sms-gateway/handlers/settings/mobile.go
  • internal/sms-gateway/handlers/webhooks/3rdparty.go
  • internal/sms-gateway/handlers/webhooks/mobile.go
  • internal/sms-gateway/jwt/metrics.go
  • internal/sms-gateway/models/migration.go
  • internal/sms-gateway/models/migrations/mysql/20260507035019_device_sim_cards.sql
  • internal/sms-gateway/models/models.go
  • internal/sms-gateway/models/models_test.go
  • internal/sms-gateway/models/module.go
  • internal/sms-gateway/modules/auth/service.go
  • internal/sms-gateway/modules/devices/cache.go
  • internal/sms-gateway/modules/devices/domain.go
  • internal/sms-gateway/modules/devices/models.go
  • internal/sms-gateway/modules/devices/module.go
  • internal/sms-gateway/modules/devices/repository.go
  • internal/sms-gateway/modules/devices/service.go
  • internal/sms-gateway/modules/events/metrics.go
  • internal/sms-gateway/modules/events/service.go
  • internal/sms-gateway/modules/messages/models.go
  • internal/sms-gateway/modules/messages/service.go
  • internal/sms-gateway/modules/push/metrics.go
  • internal/sms-gateway/modules/sse/metrics.go
  • internal/sms-gateway/modules/webhooks/models.go
  • internal/sms-gateway/modules/webhooks/service.go
  • internal/sms-gateway/online/metrics.go
  • internal/sms-gateway/openapi/docs.go
  • internal/worker/executor/metrics.go
📝 Walkthrough

Walkthrough

The PR refactors device management by introducing a new devices module with domain models, context-aware repository and service layers, and SIM card support. It migrates the entire codebase from models.Device to devices.Device, updates handlers and middlewares to use the new types, and centralizes metrics namespace/subsystem constants across multiple modules.

Changes

Device Module Migration & Integration

Layer / File(s) Summary
Domain Models & Data Schema
internal/sms-gateway/modules/devices/domain.go, internal/sms-gateway/modules/devices/models.go, internal/sms-gateway/models/migrations/mysql/20260507035019_device_sim_cards.sql, go.mod
New devices module introduces domain types (Device, DeviceInfo, DeviceUpdate, SimCard) and GORM persistence (DeviceModel) with SIM card JSON storage. SQL migration adds sim_cards column. Dependency android-sms-gateway/client-go updated to v1.12.7-0.20260506065831-72a3c7972539.
Persistence Layer
internal/sms-gateway/modules/devices/cache.go, internal/sms-gateway/modules/devices/repository.go
Cache retargeted to store devices.Device instead of models.Device. Repository refactored to be context-aware with new/updated methods: Select(ctx, ...), Get(ctx, ...), Insert(ctx, DeviceInput), Update(ctx, id, DeviceUpdate), Remove(ctx, ...), GetByToken(ctx, token), SetLastSeen(ctx, ...), Cleanup(ctx, ...). Error wrapping added for all DB operations.
Service Layer
internal/sms-gateway/modules/devices/service.go, internal/sms-gateway/modules/auth/service.go
Device service made context-aware: Insert, Select, Exists, Get, GetAny, GetByToken, Update, Remove now take context.Context. Auth service updated: RegisterDevice(ctx, userID, DeviceInfo) replaces old signature, AuthorizeDevice(ctx, token) returns *devices.Device, online-tracking goroutine uses background context. UpdatePushToken removed from service.
Database Migration Registration
internal/sms-gateway/models/migration.go, internal/sms-gateway/models/models.go, internal/sms-gateway/models/module.go, internal/sms-gateway/modules/devices/module.go
Old Migrate(db) function and related imports removed from models. New SoftDeletableModel struct added to models (embedding TimedModel with DeletedAt). Devices module registers migration via db.RegisterMigration(Migrate) in init(). Models module switches from RegisterMigration(Migrate) to RegisterGoose(migrations).
Handler Middleware & Injection
internal/sms-gateway/handlers/middlewares/deviceauth/deviceauth.go, internal/sms-gateway/handlers/converters/devices.go
Device auth middleware updated: New() calls authSvc.AuthorizeDevice(c.Context(), token), stores dereferenced *devices.Device in locals. GetDevice() and WithDevice() signatures updated to use devices.Device. New converter helper mapSimCards maps []devices.SimCard to []smsgateway.SimCard. DeviceToDTO now accepts devices.Device and populates SimCards field.
HTTP Handler Updates
internal/sms-gateway/handlers/devices/3rdparty.go, internal/sms-gateway/handlers/events/mobile.go, internal/sms-gateway/handlers/messages/mobile.go, internal/sms-gateway/handlers/messages/3rdparty.go, internal/sms-gateway/handlers/mobile.go, internal/sms-gateway/handlers/settings/mobile.go, internal/sms-gateway/handlers/webhooks/mobile.go, internal/sms-gateway/handlers/webhooks/3rdparty.go
All mobile/3rdparty device handlers updated to use devices.Device parameter type. Device context passed into service calls: Select(c.Context(), ...), GetAny(c.Context(), ...), Remove(c.Context(), ...). Device registration (postDevice) refactored to use devices.DeviceInfo payload. Device patching uses devices.DeviceUpdate with SimCards mapping. Settings controller no longer stores devicesSvc. Webhook service methods now receive context.Context. Device selection uses lo.Map converter.
Messages & Related Modules
internal/sms-gateway/modules/messages/models.go, internal/sms-gateway/modules/messages/service.go, internal/sms-gateway/modules/events/service.go, internal/sms-gateway/modules/webhooks/models.go, internal/sms-gateway/modules/webhooks/service.go
Messages model's device relationship updated from models.Device to devices.DeviceModel. Messages service UpdateState and Enqueue methods accept devices.Device. Events service processEvent made context-aware, passing context to deviceSvc.Select(ctx, ...). Webhooks model references devices.DeviceModel. Webhooks service Replace(ctx, userID, webhook) now context-aware and validates device ownership via Exists(ctx, ...). Inbox export handler body type switched from MessagesExportRequest to InboxRefreshRequest.
Metrics Refactoring
internal/sms-gateway/jwt/metrics.go, internal/sms-gateway/modules/events/metrics.go, internal/sms-gateway/modules/push/metrics.go, internal/sms-gateway/modules/sse/metrics.go, internal/sms-gateway/online/metrics.go, internal/worker/executor/metrics.go
Prometheus metric namespace/subsystem constants centralized via package-level metricsNamespace and metricsSubsystem declarations; all metric registrations updated to use shared constants instead of inline literals. Metric names, help text, labels, and behavior unchanged.
OpenAPI & Testing
internal/sms-gateway/openapi/docs.go, internal/sms-gateway/handlers/converters/devices_test.go, internal/sms-gateway/models/models_test.go
OpenAPI schema updated: smsgateway.Device includes simCards property, smsgateway.SimCard definition added with carrier/ICCID/phone/slot fields. InboxRefreshRequest schema added with messageTypes and triggerWebhooks fields. /3rdparty/v1/messages/inbox/export endpoint now references InboxRefreshRequest. Converter test refactored to use devices.Device fixtures and verify SIM card conversion. Old TestDevice_IsEmpty removed from models test suite.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

codex

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title '[devices] SIM cards info support' directly reflects the main change: adding SIM card information support to the devices module throughout the codebase.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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


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

Caution

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

⚠️ Outside diff range comments (1)
internal/sms-gateway/handlers/messages/3rdparty.go (1)

253-253: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Stale OpenAPI annotation — body type mismatch.

The @Param annotation still references smsgateway.MessagesExportRequest, but the handler now parses smsgateway.InboxRefreshRequest (line 263). The generated OpenAPI spec will document the wrong request schema.

📝 Proposed fix
-//	`@Param`			request	body		smsgateway.MessagesExportRequest	true	"Export inbox request"
+//	`@Param`			request	body		smsgateway.InboxRefreshRequest		true	"Export inbox request"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/sms-gateway/handlers/messages/3rdparty.go` at line 253, The OpenAPI
`@Param` annotation is stale: it declares the request body as
smsgateway.MessagesExportRequest while the handler actually parses
smsgateway.InboxRefreshRequest; update the annotation line that currently
contains "@Param request body smsgateway.MessagesExportRequest" to reference
"smsgateway.InboxRefreshRequest" (or remove the `@Param` if the handler no longer
accepts a body) so the generated OpenAPI schema matches the handler's parsed
type (see the handler parsing of smsgateway.InboxRefreshRequest).
🧹 Nitpick comments (6)
internal/sms-gateway/modules/devices/models.go (1)

24-24: 💤 Low value

Consider specifying an explicit JSON column type for SimCards

Without a type tag, GORM's JSON serializer falls back to longtext on MySQL instead of a proper json column. If structured queries or JSON-specific indexing are ever needed, the column type should be specified explicitly.

♻️ Proposed improvement
-    SimCards []simCardModel `gorm:"serializer:json"`
+    SimCards []simCardModel `gorm:"serializer:json;type:json"`
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/sms-gateway/modules/devices/models.go` at line 24, The SimCards
field on the device model is using GORM's JSON serializer but lacks an explicit
column type, causing MySQL to default to longtext; update the struct tag on
SimCards (the SimCards []simCardModel field in models.go) to include a type
declaration for JSON (e.g., add type:json in the gorm tag) so the column is
created as a native JSON type and supports JSON queries/indexing.
internal/sms-gateway/handlers/converters/devices_test.go (1)

14-74: ⚡ Quick win

Missing test coverage for SIM card conversion — the primary feature of this PR

All three test cases use an empty DeviceUpdate{} (no SimCards), so the devices.SimCard → smsgateway.SimCard conversion path in the converter is completely untested. At minimum, add a case with one or more populated SIM cards and verify the output DTO matches.

♻️ Suggested additional test case
+        {
+            name: "device with sim cards",
+            device: devices.Device{
+                DeviceInput: devices.DeviceInput{
+                    DeviceInfo: devices.DeviceInfo{
+                        DeviceUpdate: devices.DeviceUpdate{
+                            SimCards: []devices.SimCard{
+                                {
+                                    SlotIndex:   0,
+                                    SimNumber:   1,
+                                    PhoneNumber: lo.ToPtr("+79990001234"),
+                                    CarrierName: lo.ToPtr("Carrier"),
+                                    ICCID:       lo.ToPtr("8901260000000000000"),
+                                },
+                            },
+                        },
+                    },
+                    ID: "test-id",
+                },
+            },
+            expected: smsgateway.Device{
+                ID: "test-id",
+                SimCards: []smsgateway.SimCard{
+                    {
+                        SlotIndex:   0,
+                        SimNumber:   1,
+                        PhoneNumber: lo.ToPtr("+79990001234"),
+                        CarrierName: lo.ToPtr("Carrier"),
+                        ICCID:       lo.ToPtr("8901260000000000000"),
+                    },
+                },
+            },
+        },
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/sms-gateway/handlers/converters/devices_test.go` around lines 14 -
74, TestDeviceToDTO currently never exercises the devices.SimCard →
smsgateway.SimCard path; add a new case in the tests slice inside
TestDeviceToDTO that constructs a devices.Device whose DeviceUpdate contains one
or more populated devices.SimCard entries (with fields like ICCID, MSISDN,
Provider, Status, CreatedAt/UpdatedAt) and set the expected smsgateway.Device to
include the corresponding smsgateway.SimCard entries, then call
converters.DeviceToDTO and assert equality; ensure you reference the existing
TestDeviceToDTO test, the converters.DeviceToDTO function, and the
devices.SimCard / smsgateway.SimCard types so the mapping of each field
(including nil/empty edge cases) is validated.
internal/sms-gateway/handlers/settings/mobile.go (1)

16-17: ⚡ Quick win

Remove unused devicesSvc dependency from MobileController

devicesSvc is injected and stored but never referenced in the get() method. Since the Device object is passed directly to the handler, the service dependency is redundant and can be removed from the struct field, constructor parameter, and assignment.

Constructor refactor
func NewMobileController(
	settingsSvc *settings.Service,
	logger *zap.Logger,
	validator *validator.Validate,
) *MobileController {
	return &MobileController{
		Handler: base.Handler{
			Logger:    logger,
			Validator: validator,
		},
		settingsSvc: settingsSvc,
	}
}

Also applies to: 20-33

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/sms-gateway/handlers/settings/mobile.go` around lines 16 - 17, The
MobileController currently stores an unused devicesSvc dependency; remove the
devicesSvc field from the MobileController struct, remove the devicesSvc
parameter from NewMobileController, and delete any assignment of devicesSvc in
the constructor so only settingsSvc, Logger and Validator remain; ensure the
get() handler signature and implementation (get()) continue to accept the Device
object directly and compile after removing references to devicesSvc.
internal/sms-gateway/modules/events/service.go (1)

120-120: ⚡ Quick win

Local variable devices shadows the imported package devices.

While harmless now (all package-level references appear before the assignment), this is a refactoring hazard — any future code added after line 120 that tries to reference the package will fail to compile or silently refer to the wrong thing.

♻️ Proposed fix
-	devices, err := s.deviceSvc.Select(ctx, wrapper.UserID, filters...)
+	devList, err := s.deviceSvc.Select(ctx, wrapper.UserID, filters...)
 	if err != nil {
 		...
 	}

-	if len(devices) == 0 {
+	if len(devList) == 0 {
 		...
 	}

-	for _, device := range devices {
+	for _, device := range devList {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/sms-gateway/modules/events/service.go` at line 120, The local
variable name "devices" in the assignment from s.deviceSvc.Select(ctx,
wrapper.UserID, filters...) shadows the imported package "devices"; rename the
local variable to a non-conflicting identifier (e.g., deviceList or
fetchedDevices) wherever s.deviceSvc.Select is called to avoid shadowing the
package and update any subsequent references to that variable accordingly so
future code can still reference the devices package without ambiguity.
internal/sms-gateway/modules/devices/domain.go (2)

11-11: ⚡ Quick win

AuthToken in DeviceInput is a sensitive credential — guard against accidental serialization.

DeviceInput (and by embedding, Device) carries AuthToken string. If a Device or DeviceInput value is ever accidentally passed to a JSON encoder, the token will leak. The DTO converter today manually picks fields, but there's no structural guard.

Consider annotating AuthToken with json:"-" to make accidental serialization safe by default.

🛡️ Proposed fix
 type DeviceInput struct {
 	DeviceInfo

 	ID     string
 	UserID string

-	AuthToken string
+	AuthToken string `json:"-"`
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/sms-gateway/modules/devices/domain.go` at line 11, DeviceInput (and
by embedding Device) contains the sensitive AuthToken string which can leak if
the struct is ever JSON-encoded; update the AuthToken field definition to forbid
JSON serialization (e.g., add the struct tag json:"-") so accidental encoding
won't include the token, and apply the same tag to any embedded Device AuthToken
field if present to ensure the credential is protected by default.

38-44: ⚡ Quick win

SlotIndex and SimNumber have ambiguous semantics.

SimCard has both SlotIndex int and SimNumber int. It's unclear what distinguishes them — is SlotIndex zero-based and SimNumber one-based? Is one the physical slot and the other a logical SIM index? Without documentation or at minimum distinct naming, this will be confusing to both implementors and API consumers.

Consider adding Go doc comments clarifying the meaning and range of each field.

📝 Example doc addition
 type SimCard struct {
+	// SlotIndex is the zero-based index of the physical SIM slot (0, 1, ...).
 	SlotIndex   int
+	// SimNumber is the one-based subscription number used internally by the device.
 	SimNumber   int
 	PhoneNumber *string
 	CarrierName *string
 	ICCID       *string
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/sms-gateway/modules/devices/domain.go` around lines 38 - 44, The
SlotIndex and SimNumber fields in the SimCard struct are ambiguous; add Go doc
comments above the SimCard type and above each field (SlotIndex and SimNumber)
that clearly states their semantics and valid ranges (e.g., whether SlotIndex is
zero-based physical slot, SimNumber is one-based logical SIM id, or vice versa),
what each represents (physical slot vs logical SIM index), and any constraints
(min/max or nil handling for PhoneNumber/ICCID), using the exact symbol names
SimCard, SlotIndex, and SimNumber so readers and API consumers understand the
distinction.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/sms-gateway/handlers/mobile.go`:
- Around line 198-209: The current call to h.devicesSvc.Update builds
devices.DeviceUpdate using lo.EmptyableToPtr(req.PushToken) and
lo.Map(req.SimCards, ...), which drops whether the client actually sent those
fields and causes unintended destructive updates; change the construction so you
only set PushToken and SimCards on devices.DeviceUpdate when the corresponding
request fields were present: check req.PushToken presence (preserve nil vs empty
vs value) and only assign PushToken when present, and likewise only assign
SimCards when req.SimCards is present (map to []devices.SimCard only in that
branch), leaving those fields unset on DeviceUpdate otherwise so
devicesSvc.Update can decide not to modify them. Reference symbols:
h.devicesSvc.Update, devices.DeviceUpdate, req.PushToken, req.SimCards,
lo.EmptyableToPtr, lo.Map.

In `@internal/sms-gateway/modules/auth/service.go`:
- Around line 99-103: The background goroutine that calls s.onlineSvc.SetOnline
is incorrectly deriving a timeout context from the handler-scoped ctx (which may
be a fasthttp RequestCtx) causing unsafe retention of request-scoped state;
change the context creation inside the goroutine from context.WithTimeout(ctx,
timeout) to use a non-request context (e.g.,
context.WithTimeout(context.Background(), timeout) or a server-level context
like s.ctx/s.shutdownCtx) so the goroutine does not capture the handler
RequestCtx, keep the same timeout/cancel pattern and still call
s.onlineSvc.SetOnline(subCtx, id).

In `@internal/sms-gateway/modules/devices/domain.go`:
- Around line 34-36: The IsEmpty method currently uses a pointer receiver and
checks for nil, which breaks calls on value-typed devices; change the receiver
to a value receiver on Device (i.e., func (d Device) IsEmpty() bool) and
simplify the body to only check d.ID == "" (remove the nil check), so existing
handlers that accept devices.Device by value can call device.IsEmpty() without
compilation errors.

In `@internal/sms-gateway/modules/devices/models.go`:
- Line 102: The error string currently uses "models migration failed" which is
misleading for this module; update the error message to use the module name
"devices" (e.g., change the fmt.Errorf call in the migration function in
internal/sms-gateway/modules/devices/models.go so it returns "devices migration
failed: %w" instead of "models migration failed: %w") so logs consistently
identify the devices module (look for the migration function that returns
fmt.Errorf in this file).

In `@internal/sms-gateway/modules/devices/service.go`:
- Around line 133-135: The Update method currently writes through to the
repository but does not clear the in-memory cache used by GetByToken, so callers
may see stale device data; modify Service.Update to, after calling
s.devices.Update(ctx, id, device), invalidate the cache entries that GetByToken
uses (e.g., delete the cache key(s) for the device token and/or device id), by
either calling the existing cache delete method (the same cache used in
GetByToken) or by adding a small helper like invalidateDeviceCache(id) that
removes those keys; ensure the invalidation occurs only after a successful
update and covers all keys GetByToken may have stored.

In `@internal/sms-gateway/modules/webhooks/models.go`:
- Around line 25-26: The DeviceID struct tag uses type:varchar(21) which
conflicts with the migration that defines the column as char(21); update the
DeviceID field's gorm tag to use type:char(21) (retain the json tag and index)
so the struct matches the actual DB column, e.g. modify the DeviceID field
definition and keep the existing Device relationship (Device
*devices.DeviceModel and its gorm
foreignKey:DeviceID;constraint:OnDelete:CASCADE) unchanged.

In `@internal/sms-gateway/openapi/docs.go`:
- Around line 2271-2295: Update the SimCard struct in
internal/sms-gateway/modules/devices/domain.go by adding validation tags to the
non-pointer integer fields so OpenAPI marks them required and constrained: add
`validate:"required"` to SlotIndex and to SimNumber, and add bounds to SimNumber
as `validate:"required,min=1,max=3"` (or equivalent combined tag) so the
generated schema reflects mandatory presence and the 1–3 range.

---

Outside diff comments:
In `@internal/sms-gateway/handlers/messages/3rdparty.go`:
- Line 253: The OpenAPI `@Param` annotation is stale: it declares the request body
as smsgateway.MessagesExportRequest while the handler actually parses
smsgateway.InboxRefreshRequest; update the annotation line that currently
contains "@Param request body smsgateway.MessagesExportRequest" to reference
"smsgateway.InboxRefreshRequest" (or remove the `@Param` if the handler no longer
accepts a body) so the generated OpenAPI schema matches the handler's parsed
type (see the handler parsing of smsgateway.InboxRefreshRequest).

---

Nitpick comments:
In `@internal/sms-gateway/handlers/converters/devices_test.go`:
- Around line 14-74: TestDeviceToDTO currently never exercises the
devices.SimCard → smsgateway.SimCard path; add a new case in the tests slice
inside TestDeviceToDTO that constructs a devices.Device whose DeviceUpdate
contains one or more populated devices.SimCard entries (with fields like ICCID,
MSISDN, Provider, Status, CreatedAt/UpdatedAt) and set the expected
smsgateway.Device to include the corresponding smsgateway.SimCard entries, then
call converters.DeviceToDTO and assert equality; ensure you reference the
existing TestDeviceToDTO test, the converters.DeviceToDTO function, and the
devices.SimCard / smsgateway.SimCard types so the mapping of each field
(including nil/empty edge cases) is validated.

In `@internal/sms-gateway/handlers/settings/mobile.go`:
- Around line 16-17: The MobileController currently stores an unused devicesSvc
dependency; remove the devicesSvc field from the MobileController struct, remove
the devicesSvc parameter from NewMobileController, and delete any assignment of
devicesSvc in the constructor so only settingsSvc, Logger and Validator remain;
ensure the get() handler signature and implementation (get()) continue to accept
the Device object directly and compile after removing references to devicesSvc.

In `@internal/sms-gateway/modules/devices/domain.go`:
- Line 11: DeviceInput (and by embedding Device) contains the sensitive
AuthToken string which can leak if the struct is ever JSON-encoded; update the
AuthToken field definition to forbid JSON serialization (e.g., add the struct
tag json:"-") so accidental encoding won't include the token, and apply the same
tag to any embedded Device AuthToken field if present to ensure the credential
is protected by default.
- Around line 38-44: The SlotIndex and SimNumber fields in the SimCard struct
are ambiguous; add Go doc comments above the SimCard type and above each field
(SlotIndex and SimNumber) that clearly states their semantics and valid ranges
(e.g., whether SlotIndex is zero-based physical slot, SimNumber is one-based
logical SIM id, or vice versa), what each represents (physical slot vs logical
SIM index), and any constraints (min/max or nil handling for PhoneNumber/ICCID),
using the exact symbol names SimCard, SlotIndex, and SimNumber so readers and
API consumers understand the distinction.

In `@internal/sms-gateway/modules/devices/models.go`:
- Line 24: The SimCards field on the device model is using GORM's JSON
serializer but lacks an explicit column type, causing MySQL to default to
longtext; update the struct tag on SimCards (the SimCards []simCardModel field
in models.go) to include a type declaration for JSON (e.g., add type:json in the
gorm tag) so the column is created as a native JSON type and supports JSON
queries/indexing.

In `@internal/sms-gateway/modules/events/service.go`:
- Line 120: The local variable name "devices" in the assignment from
s.deviceSvc.Select(ctx, wrapper.UserID, filters...) shadows the imported package
"devices"; rename the local variable to a non-conflicting identifier (e.g.,
deviceList or fetchedDevices) wherever s.deviceSvc.Select is called to avoid
shadowing the package and update any subsequent references to that variable
accordingly so future code can still reference the devices package without
ambiguity.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 75cc8804-2390-438f-b267-1f233554478c

📥 Commits

Reviewing files that changed from the base of the PR and between b83f22f and 0955da9.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (37)
  • go.mod
  • internal/config/config.go
  • internal/sms-gateway/handlers/converters/devices.go
  • internal/sms-gateway/handlers/converters/devices_test.go
  • internal/sms-gateway/handlers/devices/3rdparty.go
  • internal/sms-gateway/handlers/events/mobile.go
  • internal/sms-gateway/handlers/messages/3rdparty.go
  • internal/sms-gateway/handlers/messages/mobile.go
  • internal/sms-gateway/handlers/middlewares/deviceauth/deviceauth.go
  • internal/sms-gateway/handlers/mobile.go
  • internal/sms-gateway/handlers/settings/mobile.go
  • internal/sms-gateway/handlers/webhooks/3rdparty.go
  • internal/sms-gateway/handlers/webhooks/mobile.go
  • internal/sms-gateway/jwt/metrics.go
  • internal/sms-gateway/models/migration.go
  • internal/sms-gateway/models/models.go
  • internal/sms-gateway/models/models_test.go
  • internal/sms-gateway/models/module.go
  • internal/sms-gateway/modules/auth/service.go
  • internal/sms-gateway/modules/devices/cache.go
  • internal/sms-gateway/modules/devices/domain.go
  • internal/sms-gateway/modules/devices/models.go
  • internal/sms-gateway/modules/devices/module.go
  • internal/sms-gateway/modules/devices/repository.go
  • internal/sms-gateway/modules/devices/service.go
  • internal/sms-gateway/modules/events/metrics.go
  • internal/sms-gateway/modules/events/service.go
  • internal/sms-gateway/modules/messages/models.go
  • internal/sms-gateway/modules/messages/service.go
  • internal/sms-gateway/modules/push/metrics.go
  • internal/sms-gateway/modules/sse/metrics.go
  • internal/sms-gateway/modules/webhooks/models.go
  • internal/sms-gateway/modules/webhooks/service.go
  • internal/sms-gateway/online/metrics.go
  • internal/sms-gateway/openapi/docs.go
  • internal/worker/config/config.go
  • internal/worker/executor/metrics.go
💤 Files with no reviewable changes (4)
  • internal/sms-gateway/models/models.go
  • internal/sms-gateway/models/migration.go
  • internal/sms-gateway/models/models_test.go
  • internal/sms-gateway/models/module.go

Comment thread internal/sms-gateway/handlers/mobile.go
Comment thread internal/sms-gateway/modules/auth/service.go
Comment thread internal/sms-gateway/modules/devices/domain.go Outdated
Comment thread internal/sms-gateway/modules/devices/models.go Outdated
Comment thread internal/sms-gateway/modules/devices/service.go
Comment thread internal/sms-gateway/modules/webhooks/models.go
Comment thread internal/sms-gateway/openapi/docs.go
@capcom6 capcom6 force-pushed the devices/sim-cards-info branch from 0955da9 to 15ad054 Compare May 7, 2026 04:07
@coderabbitai coderabbitai Bot added the codex label May 7, 2026
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.

Caution

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

⚠️ Outside diff range comments (1)
internal/sms-gateway/handlers/messages/3rdparty.go (1)

264-274: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

messageTypes and triggerWebhooks from InboxRefreshRequest are silently ignored.

The OpenAPI schema documents both messageTypes and triggerWebhooks as valid request fields, but the handler parses them into InboxRefreshRequest without forwarding them to inboxSvc.Refresh(). The Refresh() method signature only accepts userID, deviceID, since, and until—the two new fields are never passed. Clients relying on triggerWebhooks: false to suppress webhook delivery or messageTypes to filter re-exported messages will experience unexpected behavior with no error surfaced.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/sms-gateway/handlers/messages/3rdparty.go` around lines 264 - 274,
postInboxExport currently parses messageTypes and triggerWebhooks from
InboxRefreshRequest but does not forward them to inboxSvc.Refresh; update the
handler and service call so those fields are honored: modify the call in
postInboxExport to pass req.MessageTypes and req.TriggerWebhooks (e.g., extend
inboxSvc.Refresh signature to Refresh(userID string, deviceID *string, since,
until time.Time, messageTypes []smsgateway.MessageType, triggerWebhooks *bool)
or create a single options/params struct and pass req into it), then update the
inboxSvc.Refresh implementation signature (and all callers) to accept and apply
those new parameters so webhook suppression and message type filtering work as
documented.
🧹 Nitpick comments (1)
internal/sms-gateway/handlers/converters/devices_test.go (1)

66-98: ⚡ Quick win

SlotIndex: 0 is a zero-value and may mask a mapping omission.

Both the input and expected fixture use SlotIndex: 0, which is the Go zero value for int. If the converter accidentally omits this field, the test still passes because the uninitialized field would also be 0. Use a non-zero value (e.g., 1) to confirm the field is actually being mapped.

🛠️ Proposed fix
 SimCards: []devices.SimCard{
     {
-        SlotIndex:   0,
+        SlotIndex:   1,
         SimNumber:   1,
 SimCards: []smsgateway.SimCard{
     {
-        SlotIndex:   0,
+        SlotIndex:   1,
         SimNumber:   1,
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/sms-gateway/handlers/converters/devices_test.go` around lines 66 -
98, The test uses SlotIndex: 0 which can hide mapping bugs; update the table
case named "device with sim cards" so the input devices.SimCard and the expected
smsgateway.SimCard both use a non-zero SlotIndex (e.g., 1) instead of 0 to
ensure the converter actually maps SlotIndex in the conversion logic (look for
the test case in devices_test.go and the structs devices.Device/devices.SimCard
and smsgateway.SimCard to update).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@internal/sms-gateway/handlers/messages/3rdparty.go`:
- Around line 264-274: postInboxExport currently parses messageTypes and
triggerWebhooks from InboxRefreshRequest but does not forward them to
inboxSvc.Refresh; update the handler and service call so those fields are
honored: modify the call in postInboxExport to pass req.MessageTypes and
req.TriggerWebhooks (e.g., extend inboxSvc.Refresh signature to Refresh(userID
string, deviceID *string, since, until time.Time, messageTypes
[]smsgateway.MessageType, triggerWebhooks *bool) or create a single
options/params struct and pass req into it), then update the inboxSvc.Refresh
implementation signature (and all callers) to accept and apply those new
parameters so webhook suppression and message type filtering work as documented.

---

Nitpick comments:
In `@internal/sms-gateway/handlers/converters/devices_test.go`:
- Around line 66-98: The test uses SlotIndex: 0 which can hide mapping bugs;
update the table case named "device with sim cards" so the input devices.SimCard
and the expected smsgateway.SimCard both use a non-zero SlotIndex (e.g., 1)
instead of 0 to ensure the converter actually maps SlotIndex in the conversion
logic (look for the test case in devices_test.go and the structs
devices.Device/devices.SimCard and smsgateway.SimCard to update).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ccaebd13-02a5-4cc8-b538-13fd922c85dd

📥 Commits

Reviewing files that changed from the base of the PR and between 0955da9 and 15ad054.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (36)
  • go.mod
  • internal/sms-gateway/handlers/converters/devices.go
  • internal/sms-gateway/handlers/converters/devices_test.go
  • internal/sms-gateway/handlers/devices/3rdparty.go
  • internal/sms-gateway/handlers/events/mobile.go
  • internal/sms-gateway/handlers/messages/3rdparty.go
  • internal/sms-gateway/handlers/messages/mobile.go
  • internal/sms-gateway/handlers/middlewares/deviceauth/deviceauth.go
  • internal/sms-gateway/handlers/mobile.go
  • internal/sms-gateway/handlers/settings/mobile.go
  • internal/sms-gateway/handlers/webhooks/3rdparty.go
  • internal/sms-gateway/handlers/webhooks/mobile.go
  • internal/sms-gateway/jwt/metrics.go
  • internal/sms-gateway/models/migration.go
  • internal/sms-gateway/models/migrations/mysql/20260507035019_device_sim_cards.sql
  • internal/sms-gateway/models/models.go
  • internal/sms-gateway/models/models_test.go
  • internal/sms-gateway/models/module.go
  • internal/sms-gateway/modules/auth/service.go
  • internal/sms-gateway/modules/devices/cache.go
  • internal/sms-gateway/modules/devices/domain.go
  • internal/sms-gateway/modules/devices/models.go
  • internal/sms-gateway/modules/devices/module.go
  • internal/sms-gateway/modules/devices/repository.go
  • internal/sms-gateway/modules/devices/service.go
  • internal/sms-gateway/modules/events/metrics.go
  • internal/sms-gateway/modules/events/service.go
  • internal/sms-gateway/modules/messages/models.go
  • internal/sms-gateway/modules/messages/service.go
  • internal/sms-gateway/modules/push/metrics.go
  • internal/sms-gateway/modules/sse/metrics.go
  • internal/sms-gateway/modules/webhooks/models.go
  • internal/sms-gateway/modules/webhooks/service.go
  • internal/sms-gateway/online/metrics.go
  • internal/sms-gateway/openapi/docs.go
  • internal/worker/executor/metrics.go
💤 Files with no reviewable changes (4)
  • internal/sms-gateway/models/models_test.go
  • internal/sms-gateway/models/module.go
  • internal/sms-gateway/models/migration.go
  • internal/sms-gateway/models/models.go
✅ Files skipped from review due to trivial changes (4)
  • go.mod
  • internal/sms-gateway/jwt/metrics.go
  • internal/sms-gateway/models/migrations/mysql/20260507035019_device_sim_cards.sql
  • internal/worker/executor/metrics.go
🚧 Files skipped from review as they are similar to previous changes (19)
  • internal/sms-gateway/handlers/events/mobile.go
  • internal/sms-gateway/modules/devices/module.go
  • internal/sms-gateway/modules/sse/metrics.go
  • internal/sms-gateway/handlers/webhooks/3rdparty.go
  • internal/sms-gateway/handlers/webhooks/mobile.go
  • internal/sms-gateway/handlers/devices/3rdparty.go
  • internal/sms-gateway/modules/webhooks/models.go
  • internal/sms-gateway/modules/events/metrics.go
  • internal/sms-gateway/handlers/mobile.go
  • internal/sms-gateway/handlers/messages/mobile.go
  • internal/sms-gateway/handlers/converters/devices.go
  • internal/sms-gateway/modules/devices/domain.go
  • internal/sms-gateway/modules/devices/models.go
  • internal/sms-gateway/modules/push/metrics.go
  • internal/sms-gateway/modules/auth/service.go
  • internal/sms-gateway/modules/messages/service.go
  • internal/sms-gateway/online/metrics.go
  • internal/sms-gateway/modules/devices/cache.go
  • internal/sms-gateway/modules/devices/repository.go

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 7, 2026

🤖 Pull request artifacts

Platform File
🐳 Docker GitHub Container Registry
🍎 Darwin arm64 server_Darwin_arm64.tar.gz
🍎 Darwin x86_64 server_Darwin_x86_64.tar.gz
🐧 Linux arm64 server_Linux_arm64.tar.gz
🐧 Linux i386 server_Linux_i386.tar.gz
🐧 Linux x86_64 server_Linux_x86_64.tar.gz
🪟 Windows arm64 server_Windows_arm64.zip
🪟 Windows i386 server_Windows_i386.zip
🪟 Windows x86_64 server_Windows_x86_64.zip

@capcom6 capcom6 force-pushed the devices/sim-cards-info branch from 15ad054 to 7d176aa Compare May 7, 2026 06:34
@capcom6 capcom6 force-pushed the devices/sim-cards-info branch from 86a1c57 to 8971974 Compare May 8, 2026 05:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant