package mysql import ( "context" "database/sql" "errors" "strings" "hyapp/pkg/appcode" "hyapp/pkg/xerr" "hyapp/services/wallet-service/internal/domain/ledger" ) type walletPolicyInstance struct { InstanceCode string TemplateCode string TemplateVersion string RegionID int64 HostPointAsset string HostPointRatioPPM int64 PointsPerUSD int64 WithdrawFeeBPS int64 } func (r *Repository) resolveActiveWalletPolicy(ctx context.Context, tx *sql.Tx, appCode string, regionID int64, nowMS int64) (walletPolicyInstance, bool, error) { appCode = appcode.Normalize(appCode) if regionID < 0 { return walletPolicyInstance{}, false, xerr.New(xerr.InvalidArgument, "region_id is invalid") } row := tx.QueryRowContext(ctx, ` SELECT instance_code, template_code, template_version, region_id, host_point_asset_type, host_point_ratio_ppm, points_per_usd, withdraw_fee_bps FROM wallet_policy_instances WHERE app_code = ? AND region_id IN (?, 0) AND status = 'active' AND effective_from_ms <= ? AND (effective_to_ms = 0 OR effective_to_ms > ?) ORDER BY CASE WHEN region_id = ? THEN 0 ELSE 1 END, published_at_ms DESC, instance_code DESC LIMIT 1`, appCode, regionID, nowMS, nowMS, regionID, ) var item walletPolicyInstance if err := row.Scan(&item.InstanceCode, &item.TemplateCode, &item.TemplateVersion, &item.RegionID, &item.HostPointAsset, &item.HostPointRatioPPM, &item.PointsPerUSD, &item.WithdrawFeeBPS); err != nil { if errors.Is(err, sql.ErrNoRows) { return walletPolicyInstance{}, false, nil } return walletPolicyInstance{}, false, err } item.HostPointAsset = strings.ToUpper(strings.TrimSpace(item.HostPointAsset)) if item.HostPointAsset == "" { item.HostPointAsset = ledger.AssetPoint } if item.HostPointAsset != ledger.AssetPoint || item.HostPointRatioPPM <= 0 || item.HostPointRatioPPM > 1_000_000 || item.PointsPerUSD <= 0 || item.WithdrawFeeBPS < 0 || item.WithdrawFeeBPS > 10_000 { return walletPolicyInstance{}, false, xerr.New(xerr.InvalidArgument, "wallet policy instance is invalid") } return item, true, nil }