vert-core 1.0.14 → 1.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +39 -0
- data/lib/vert/concerns/multi_tenant.rb +65 -11
- data/lib/vert/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c81e24d685ccd2412787e971650108ad2d507fea03121aecf9f74f442cdeee29
|
|
4
|
+
data.tar.gz: 6da8dfb2a6d8fcc3ed751a0d04958446e392417c4ed33d2a60ed4a5cbf870236
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d9c5b091cb5a213aa0b14cc27f31817617096d89ceb58bd74f327c56a422b7f17cd57681ad4a9f4cc010ce42b9002807ac6ae34bce5dae84e5ced185b62265db
|
|
7
|
+
data.tar.gz: 1ffaaf2ae131b78aa452abccf4ccacebaf454c594e8b9bff6d6b458c13c498ce06e5936df5bb8502f5945cf3f69e9f59d03ad71caf455e133529bac4de5d56b1
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,44 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.0.15] - 2026-05-24
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- `Vert::Concerns::MultiTenant.multi_tenant_options(include_system_records: true)` — opt-in para que o `default_scope` inclua registros com `tenant_id IS NULL` (system records visíveis globalmente). Útil para `Role`, `Plan`, `Permission` catálogo e outros modelos com registros "globais" compartilhados entre tenants.
|
|
8
|
+
- Quando ativado, o scope vira `WHERE tenant_id = ? OR tenant_id IS NULL`.
|
|
9
|
+
- Quando ativado, `tenant_id` deixa de ser obrigatório na validação.
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- **Bug crítico latente** — sem a opção `include_system_records`, o `default_scope` do `MultiTenant` escondia silenciosamente todos os registros com `tenant_id NULL` durante requests autenticadas. Isso quebrava qualquer associação `belongs_to` para system records (ex: `User#role` apontando para system role) retornando nil mesmo com `role_id` presente. Consequência: TODAS as Pundit policies que checavam `user.role` retornavam 403 mesmo para Proprietário do tenant.
|
|
14
|
+
- Workaround anterior (sem essa release): `Role.unscoped.find_by(id:)` em cada chamada.
|
|
15
|
+
- Com 1.0.15: declarar `multi_tenant_options include_system_records: true` no model e remover workarounds.
|
|
16
|
+
|
|
17
|
+
### Migration guide
|
|
18
|
+
|
|
19
|
+
```ruby
|
|
20
|
+
# Antes (workaround):
|
|
21
|
+
class User < ApplicationRecord
|
|
22
|
+
belongs_to :role, optional: true
|
|
23
|
+
|
|
24
|
+
def role
|
|
25
|
+
return super if association(:role).loaded?
|
|
26
|
+
@role_with_fallback ||= Role.unscoped.find_by(id: role_id)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Depois (vert-core 1.0.15):
|
|
31
|
+
class Role < ApplicationRecord
|
|
32
|
+
include Vert::Concerns::MultiTenant
|
|
33
|
+
multi_tenant_options include_system_records: true # ← novo
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
class User < ApplicationRecord
|
|
37
|
+
belongs_to :role, optional: true
|
|
38
|
+
# Sem override — agora `user.role` carrega normalmente
|
|
39
|
+
end
|
|
40
|
+
```
|
|
41
|
+
|
|
3
42
|
## [1.0.14] - 2026-05-24
|
|
4
43
|
|
|
5
44
|
### Added
|
|
@@ -2,22 +2,55 @@
|
|
|
2
2
|
|
|
3
3
|
module Vert
|
|
4
4
|
module Concerns
|
|
5
|
+
# MultiTenant
|
|
6
|
+
# -----------
|
|
7
|
+
# Adiciona escopo automático por `tenant_id` baseado em `Vert::Current.tenant_id`.
|
|
8
|
+
#
|
|
9
|
+
# ## Uso básico
|
|
10
|
+
# class Order < ApplicationRecord
|
|
11
|
+
# include Vert::Concerns::MultiTenant
|
|
12
|
+
# end
|
|
13
|
+
#
|
|
14
|
+
# ## System records (tenant_id NULL)
|
|
15
|
+
#
|
|
16
|
+
# Alguns modelos têm registros "globais" que devem ser visíveis em todos
|
|
17
|
+
# os tenants — ex: `Role` system, `Plan`, `Permission` catálogo. Esses
|
|
18
|
+
# registros são identificados por `tenant_id IS NULL`.
|
|
19
|
+
#
|
|
20
|
+
# Por default, o `default_scope` filtra `where(tenant_id = current)`, o que
|
|
21
|
+
# exclui esses registros silenciosamente quando há tenant ativo. Para
|
|
22
|
+
# incluí-los, use o opt-in:
|
|
23
|
+
#
|
|
24
|
+
# class Role < ApplicationRecord
|
|
25
|
+
# include Vert::Concerns::MultiTenant
|
|
26
|
+
# multi_tenant_options include_system_records: true
|
|
27
|
+
# end
|
|
28
|
+
#
|
|
29
|
+
# Com essa opção, o default_scope passa a ser:
|
|
30
|
+
# where("tenant_id = ? OR tenant_id IS NULL", Vert::Current.tenant_id)
|
|
31
|
+
#
|
|
32
|
+
# Aplica-se também à validação: `tenant_id` deixa de ser obrigatório.
|
|
33
|
+
#
|
|
34
|
+
# ## Bypass manual
|
|
35
|
+
#
|
|
36
|
+
# Para queries específicas que precisam ignorar o escopo:
|
|
37
|
+
#
|
|
38
|
+
# Order.unscoped.where(id: external_id)
|
|
39
|
+
# Order.unscoped_for_tenant(other_tenant_id).find(id)
|
|
5
40
|
module MultiTenant
|
|
6
41
|
extend ActiveSupport::Concern
|
|
7
42
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
default_scope
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
43
|
+
class_methods do
|
|
44
|
+
# Configura comportamento do MultiTenant. Aceita:
|
|
45
|
+
# - include_system_records: true → default_scope inclui tenant_id NULL
|
|
46
|
+
def multi_tenant_options(include_system_records: false)
|
|
47
|
+
@multi_tenant_include_system_records = include_system_records
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def multi_tenant_include_system_records?
|
|
51
|
+
@multi_tenant_include_system_records == true
|
|
16
52
|
end
|
|
17
|
-
before_validation :set_tenant_id, on: :create
|
|
18
|
-
end
|
|
19
53
|
|
|
20
|
-
class_methods do
|
|
21
54
|
def unscoped_for_tenant(tenant_id)
|
|
22
55
|
unscoped.where(tenant_id: tenant_id)
|
|
23
56
|
end
|
|
@@ -31,9 +64,30 @@ module Vert
|
|
|
31
64
|
end
|
|
32
65
|
end
|
|
33
66
|
|
|
67
|
+
included do
|
|
68
|
+
validates :tenant_id, presence: true, if: :require_tenant_id?
|
|
69
|
+
|
|
70
|
+
default_scope do
|
|
71
|
+
current_tenant = Vert::Current.tenant_id
|
|
72
|
+
if current_tenant.present?
|
|
73
|
+
if multi_tenant_include_system_records?
|
|
74
|
+
where("#{table_name}.tenant_id = ? OR #{table_name}.tenant_id IS NULL", current_tenant)
|
|
75
|
+
else
|
|
76
|
+
where(tenant_id: current_tenant)
|
|
77
|
+
end
|
|
78
|
+
else
|
|
79
|
+
all
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
before_validation :set_tenant_id, on: :create
|
|
84
|
+
end
|
|
85
|
+
|
|
34
86
|
private
|
|
35
87
|
|
|
36
88
|
def require_tenant_id?
|
|
89
|
+
return false if self.class.multi_tenant_include_system_records?
|
|
90
|
+
|
|
37
91
|
true
|
|
38
92
|
end
|
|
39
93
|
|
data/lib/vert/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: vert-core
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.
|
|
4
|
+
version: 1.0.15
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Vert Team
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-05-
|
|
10
|
+
date: 2026-05-25 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: activesupport
|