bp3-core 0.1.5 → 0.3.0
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/.rubocop.yml +1 -1
- data/.ruby-version +1 -2
- data/CHANGELOG.md +27 -0
- data/CLAUDE.md +119 -0
- data/Gemfile.lock +89 -54
- data/README.md +14 -1
- data/bp3-core.gemspec +3 -2
- data/lib/bp3/core/actions.rb +1 -2
- data/lib/bp3/core/cookies.rb +2 -4
- data/lib/bp3/core/feature_flags.rb +6 -5
- data/lib/bp3/core/system_logs.rb +115 -0
- data/lib/bp3/core/tenantable.rb +29 -13
- data/lib/bp3/core/test.rb +38 -0
- data/lib/bp3/core/version.rb +1 -1
- data/lib/bp3/core.rb +1 -0
- metadata +27 -15
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 76165d42f4b28714655519eeddedc6d08dd0b5bc9a5e919b389f173aa0bf20a0
|
|
4
|
+
data.tar.gz: dba935fa44898891607c50b377cbb4d8636300c7285592838826331cc47d5da6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 548dd80c8000de996d2abe85c4e158b979e9c809957f1403f15519280ee2dcb3c1fa865bf4355bc6fa25d9a6cf19791bc09cf3d6d0a84b7c0a7888cdd4960c21
|
|
7
|
+
data.tar.gz: 6dbc07299dcc22c84643250fd8fe018dc2b8c94de6a30fe303431d61f38438ffa32c897f43132a49d4fa9d75491ceb33cf11e988c9c2a88e21406a7dd33e6abc
|
data/.rubocop.yml
CHANGED
data/.ruby-version
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
ruby-3.
|
|
2
|
-
|
|
1
|
+
ruby-3.4.6
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [0.3.0] - 2026-10-26
|
|
4
|
+
|
|
5
|
+
### Breaking
|
|
6
|
+
- Scope Tenantable by the primary login
|
|
7
|
+
Tenantable default scopes reach as far as the primary login, the request state's
|
|
8
|
+
`current_login` (the least privileged one signed in), rather than as far as any root or admin signed
|
|
9
|
+
in. A root signed in beside a user or an admin no longer reaches every site, and an admin signed in
|
|
10
|
+
beside a user no longer reaches every tenant; with one login signed in, nothing changes
|
|
11
|
+
- Read request state through `Bp3::Core::Rqid.global_request_state_class`
|
|
12
|
+
Tenantable reads the request state through `Bp3::Core::Rqid.global_request_state_class`
|
|
13
|
+
rather than a `GlobalRequestState` constant, so `Bp3::Core::Rqid.global_request_state_class_name`
|
|
14
|
+
must be configured wherever Tenantable is used
|
|
15
|
+
- Add `Bp3::Core::Tenantable.reaches_every_site?`, `.reaches_every_tenant?` and `.global_request_state`
|
|
16
|
+
|
|
17
|
+
### Bug fixes
|
|
18
|
+
|
|
19
|
+
- Fix efon? and cfon?
|
|
20
|
+
Fix `efon?` and `cfon?` returning the default when the flag is explicitly off; `cfon` returns the
|
|
21
|
+
default when the config is not set
|
|
22
|
+
|
|
23
|
+
## [0.2.0] - 2026-01-09
|
|
24
|
+
|
|
25
|
+
- Add bp3-request_state dependency
|
|
26
|
+
- Add SystemLogs concern
|
|
27
|
+
- Update gems
|
|
28
|
+
- Update ruby version to 3.4.6
|
|
29
|
+
|
|
3
30
|
## [0.1.5] - 2024-11-18
|
|
4
31
|
|
|
5
32
|
- Use ruby 3.3.5 and relax gem constraints
|
data/CLAUDE.md
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
bp3-core is a Ruby gem providing core ActiveSupport concerns for BP3 (persuavis/black_phoebe_3), a
|
|
8
|
+
multi-site multi-tenant Rails application. The concerns handle tenancy, request tracking, sequence
|
|
9
|
+
ordering, ransack, feature flags, cookies and system logging, for the application's models and controllers
|
|
10
|
+
and for the other bp3 gems, which mix them into third-party classes (noticed, friendly_id, pg_search,
|
|
11
|
+
ActionText, ActiveStorage, paper_trail, ActiveAdmin, Rails' mailer previews).
|
|
12
|
+
|
|
13
|
+
## Commands
|
|
14
|
+
|
|
15
|
+
The gems run on Ruby 3.4.6 (`.ruby-version`). Prefix commands with `~/.rvm/bin/rvm 3.4.6 do` when the
|
|
16
|
+
shell is not already on it; a missing `rspec` means the wrong Ruby, not a missing bundle.
|
|
17
|
+
|
|
18
|
+
- `bundle exec rake` - specs and RuboCop (the default task)
|
|
19
|
+
- `bundle exec rspec spec/path/to/file_spec.rb[:LINE]` - one file or example
|
|
20
|
+
- `bundle exec rubocop` / `bundle exec rubocop -a`
|
|
21
|
+
- `bin/setup`, `bin/console`, `rake install`, `yard doc`
|
|
22
|
+
|
|
23
|
+
The specs have no database or Rails app: test a concern's decisions through plain Ruby (e.g.
|
|
24
|
+
`Tenantable.reaches_every_site?` with a struct standing in for the request state), and try a change against
|
|
25
|
+
the application by putting this repo's `lib` ahead of the bundled gem. `lib/bp3/core/test.rb` is a plain
|
|
26
|
+
class that stubs `before_action`, `belongs_to` and the like and includes every concern; the gem does not
|
|
27
|
+
require it.
|
|
28
|
+
|
|
29
|
+
## Architecture
|
|
30
|
+
|
|
31
|
+
### Model concerns
|
|
32
|
+
|
|
33
|
+
**Tenantable** (`tenantable.rb`)
|
|
34
|
+
- `configure_tenancy` looks at which of `sites_site_id`, `tenant_id` and `workspaces_workspace_id` the
|
|
35
|
+
table has and only sets up those: `belongs_to` (optional when the column is nullable), `site`/`workspace`
|
|
36
|
+
aliases, `before_validation` callbacks that fill the column from the request state's `either_*_id`, and
|
|
37
|
+
validations that tenant and workspace belong to the record's site
|
|
38
|
+
- Site and tenant get default scopes from the request state's `either_site`/`either_tenant`. How far they
|
|
39
|
+
reach is decided by the primary login, `current_login`, the least privileged one signed in: a root reaches
|
|
40
|
+
every site and an admin every tenant of theirs, but not when a less privileged login is signed in beside
|
|
41
|
+
them -- see `Tenantable.reaches_every_site?` and `.reaches_every_tenant?`
|
|
42
|
+
- Including it calls `connection` to load column metadata, unless `IGNORE_NOTIFICATIONS` is set
|
|
43
|
+
- The gem does not know the application's `GlobalRequestState`, only its parent `Bp3::RequestState::Base`
|
|
44
|
+
(gem bp3-request_state): use that API -- `current_login`, `current_root`, `current_admin`, `either_site`
|
|
45
|
+
and the like -- through `Bp3::Core::Tenantable.global_request_state`, never the constant
|
|
46
|
+
|
|
47
|
+
**Rqid** (`rqid.rb`)
|
|
48
|
+
- `before_create` sets `rqid` from the configured request state class and method
|
|
49
|
+
- optional `belongs_to` `original_request`, `original_response` and `original_visit` on `rqid` (more than
|
|
50
|
+
one record may share an rqid)
|
|
51
|
+
- `Bp3::Core::Rqid.global_request_state_class` is where every bp3 gem gets the request state class
|
|
52
|
+
|
|
53
|
+
**Sqnr** (`sqnr.rb`): `sqnr` (ascending) and `rnqs` (descending) scopes; `use_sqnr_for_ordering` sets
|
|
54
|
+
`implicit_order_column`
|
|
55
|
+
|
|
56
|
+
**Ransackable** (`ransackable.rb`): `ransackable_attributes` (all columns), `ransackable_associations` (all
|
|
57
|
+
associations), `ransackable_scopes` (none), `ransackable_fields` (all three), `ransortable_attributes`,
|
|
58
|
+
minus the global `attribute_exceptions` and `association_exceptions`
|
|
59
|
+
|
|
60
|
+
**Displayable** (`displayable.rb`): `to_dom_id`, `display_name`/`admin_display_name` ("ClassName id"),
|
|
61
|
+
`i18n_key`, and `filtered_attributes`, which masks `Rails.application.config.filter_parameters` (also inside
|
|
62
|
+
`object`/`object_changes` for versions) with `version_filter_mask`; classes override the mask to tell
|
|
63
|
+
sources apart
|
|
64
|
+
|
|
65
|
+
### Controller concerns
|
|
66
|
+
|
|
67
|
+
**Actions** (`actions.rb`): the request pipeline. Prepended before actions, in order: `set_rqid`,
|
|
68
|
+
`check_site`, `check_workspace`, `check_tenant` (each finds or creates the record and stores it in the
|
|
69
|
+
request state); then paper_trail whodunnit, user agent and `Inbound::Request` records (skipped under do not
|
|
70
|
+
track), the maintenance-mode check, and `set_global_request_state` for the logins, locale and view context.
|
|
71
|
+
Also `info_for_paper_trail`, `user_for_paper_trail`, `pundit_user` and `default_url_options` with the
|
|
72
|
+
locale. The order of the prepends matters; do not change it
|
|
73
|
+
|
|
74
|
+
**Cookies** (`cookies.rb`): the `_bp3_visitor` signed cookie that finds or creates the `Users::Visitor`,
|
|
75
|
+
the do-not-track cookie, and migration from the old per-site/tenant cookie name
|
|
76
|
+
|
|
77
|
+
**Settings** (`settings.rb`): `create_request_record_is_on?`, `multi_tenant_is_on?`
|
|
78
|
+
|
|
79
|
+
**FeatureFlags** (`feature_flags.rb`): `efon?` (a `Feature::Enabler`), `cfon?` (a record's `configs`),
|
|
80
|
+
`efcfon?` (either, the config winning when both are set)
|
|
81
|
+
|
|
82
|
+
### Anywhere
|
|
83
|
+
|
|
84
|
+
**SystemLogs** (`system_logs.rb`): `log`, `log_debug`, `log_info`, `log_warn`, `log_error`,
|
|
85
|
+
`log_exception`, as instance methods and on the module itself. Each writes to the Rails log and to the
|
|
86
|
+
configured log and exception classes (`log_to_io:` and `log_to_db:` switch either off); a failing database
|
|
87
|
+
write is logged, not raised
|
|
88
|
+
|
|
89
|
+
### Configuration
|
|
90
|
+
|
|
91
|
+
Set in the application's `config/initializers/bp3-core.rb`; the class names are constantized and cached on
|
|
92
|
+
first use:
|
|
93
|
+
- `Bp3::Core::Rqid.global_request_state_class_name` (`'GlobalRequestState'`) and
|
|
94
|
+
`.global_request_state_method` (`:request_id`)
|
|
95
|
+
- `Bp3::Core::SystemLogs.system_log_name` (`'System::Log'`) and `.system_exception_name`
|
|
96
|
+
(`'System::Exception'`)
|
|
97
|
+
- `Bp3::Core::Ransackable.attribute_exceptions` and `.association_exceptions`
|
|
98
|
+
|
|
99
|
+
The concerns also name application classes directly: `Sites::Site`, `Tenant`, `Workspaces::Workspace`,
|
|
100
|
+
`Users::Visitor`, `Inbound::Request`, `Inbound::UserAgent`, `Feature::Enabler`, `UserContext`,
|
|
101
|
+
`DomainExtractor`.
|
|
102
|
+
|
|
103
|
+
### Dependencies
|
|
104
|
+
|
|
105
|
+
- `activesupport ~> 8.1`, `actionview ~> 8.1`
|
|
106
|
+
- `bp3-request_state ~> 0.1` - `Bp3::RequestState::Base`, the parent of the application's request state
|
|
107
|
+
|
|
108
|
+
## Code Style
|
|
109
|
+
|
|
110
|
+
- RuboCop (`.rubocop.yml`): target Ruby 3.2.2, NewCops, rubocop-rake and rubocop-rspec; AbcSize 26,
|
|
111
|
+
MethodLength 15, ModuleLength 150, BlockLength 66, Cyclomatic/PerceivedComplexity 10; RSpec ExampleLength
|
|
112
|
+
10, MultipleExpectations 4; Style/Documentation off
|
|
113
|
+
- Every file starts with `# frozen_string_literal: true`
|
|
114
|
+
- American English; no trailing whitespace on any added or modified line
|
|
115
|
+
|
|
116
|
+
## Release
|
|
117
|
+
|
|
118
|
+
Bump `lib/bp3/core/version.rb` and add a `CHANGELOG.md` entry. `rake release` tags, pushes and publishes to
|
|
119
|
+
rubygems.org; leave releasing and committing to the user.
|
data/Gemfile.lock
CHANGED
|
@@ -1,109 +1,144 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
bp3-core (0.
|
|
5
|
-
actionview (
|
|
6
|
-
activesupport (
|
|
4
|
+
bp3-core (0.3.0)
|
|
5
|
+
actionview (~> 8.1)
|
|
6
|
+
activesupport (~> 8.1)
|
|
7
|
+
bp3-request_state (~> 0.1)
|
|
7
8
|
|
|
8
9
|
GEM
|
|
9
10
|
remote: https://rubygems.org/
|
|
10
11
|
specs:
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
actionpack (8.1.4)
|
|
13
|
+
actionview (= 8.1.4)
|
|
14
|
+
activesupport (= 8.1.4)
|
|
15
|
+
nokogiri (>= 1.8.5)
|
|
16
|
+
rack (>= 2.2.4)
|
|
17
|
+
rack-session (>= 1.0.1)
|
|
18
|
+
rack-test (>= 0.6.3)
|
|
19
|
+
rails-dom-testing (~> 2.2)
|
|
20
|
+
rails-html-sanitizer (~> 1.6)
|
|
21
|
+
useragent (~> 0.16)
|
|
22
|
+
actionview (8.1.4)
|
|
23
|
+
activesupport (= 8.1.4)
|
|
13
24
|
builder (~> 3.1)
|
|
14
25
|
erubi (~> 1.11)
|
|
15
26
|
rails-dom-testing (~> 2.2)
|
|
16
27
|
rails-html-sanitizer (~> 1.6)
|
|
17
|
-
activesupport (8.
|
|
28
|
+
activesupport (8.1.4)
|
|
18
29
|
base64
|
|
19
|
-
benchmark (>= 0.3)
|
|
20
30
|
bigdecimal
|
|
21
31
|
concurrent-ruby (~> 1.0, >= 1.3.1)
|
|
22
32
|
connection_pool (>= 2.2.5)
|
|
23
33
|
drb
|
|
24
34
|
i18n (>= 1.6, < 2)
|
|
35
|
+
json
|
|
25
36
|
logger (>= 1.4.2)
|
|
26
37
|
minitest (>= 5.1)
|
|
27
38
|
securerandom (>= 0.3)
|
|
28
39
|
tzinfo (~> 2.0, >= 2.0.5)
|
|
29
40
|
uri (>= 0.13.1)
|
|
30
|
-
ast (2.4.
|
|
31
|
-
base64 (0.
|
|
32
|
-
|
|
33
|
-
|
|
41
|
+
ast (2.4.3)
|
|
42
|
+
base64 (0.3.0)
|
|
43
|
+
bigdecimal (4.1.3)
|
|
44
|
+
bp3-request_state (0.1.3)
|
|
45
|
+
actionpack (~> 8.1)
|
|
46
|
+
activesupport (~> 8.1)
|
|
47
|
+
request_store (>= 1.5.1)
|
|
34
48
|
builder (3.3.0)
|
|
35
|
-
concurrent-ruby (1.3.
|
|
36
|
-
connection_pool (
|
|
37
|
-
crass (1.0.
|
|
38
|
-
diff-lcs (1.
|
|
39
|
-
drb (2.2.
|
|
40
|
-
erubi (1.13.
|
|
41
|
-
i18n (1.
|
|
49
|
+
concurrent-ruby (1.3.8)
|
|
50
|
+
connection_pool (3.0.2)
|
|
51
|
+
crass (1.0.8)
|
|
52
|
+
diff-lcs (1.6.2)
|
|
53
|
+
drb (2.2.3)
|
|
54
|
+
erubi (1.13.1)
|
|
55
|
+
i18n (1.15.2)
|
|
42
56
|
concurrent-ruby (~> 1.0)
|
|
43
|
-
json (
|
|
44
|
-
language_server-protocol (3.17.0.
|
|
45
|
-
|
|
46
|
-
|
|
57
|
+
json (3.1.0)
|
|
58
|
+
language_server-protocol (3.17.0.6)
|
|
59
|
+
lint_roller (1.1.0)
|
|
60
|
+
logger (1.7.0)
|
|
61
|
+
loofah (2.25.2)
|
|
47
62
|
crass (~> 1.0.2)
|
|
48
63
|
nokogiri (>= 1.12.0)
|
|
49
|
-
minitest (
|
|
50
|
-
|
|
64
|
+
minitest (6.0.6)
|
|
65
|
+
drb (~> 2.0)
|
|
66
|
+
prism (~> 1.5)
|
|
67
|
+
nokogiri (1.19.4-x86_64-darwin)
|
|
51
68
|
racc (~> 1.4)
|
|
52
|
-
parallel (
|
|
53
|
-
parser (3.3.
|
|
69
|
+
parallel (2.3.0)
|
|
70
|
+
parser (3.3.13.0)
|
|
54
71
|
ast (~> 2.4.1)
|
|
55
72
|
racc
|
|
73
|
+
prism (1.9.0)
|
|
56
74
|
racc (1.8.1)
|
|
57
|
-
|
|
75
|
+
rack (3.2.7)
|
|
76
|
+
rack-session (2.1.2)
|
|
77
|
+
base64 (>= 0.1.0)
|
|
78
|
+
rack (>= 3.0.0)
|
|
79
|
+
rack-test (2.3.0)
|
|
80
|
+
rack (>= 1.3)
|
|
81
|
+
rails-dom-testing (2.3.0)
|
|
58
82
|
activesupport (>= 5.0.0)
|
|
59
83
|
minitest
|
|
60
84
|
nokogiri (>= 1.6)
|
|
61
|
-
rails-html-sanitizer (1.
|
|
62
|
-
loofah (~> 2.
|
|
63
|
-
nokogiri (
|
|
85
|
+
rails-html-sanitizer (1.7.1)
|
|
86
|
+
loofah (~> 2.25, >= 2.25.2)
|
|
87
|
+
nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
|
|
64
88
|
rainbow (3.1.1)
|
|
65
|
-
rake (13.2
|
|
66
|
-
regexp_parser (2.
|
|
67
|
-
|
|
89
|
+
rake (13.4.2)
|
|
90
|
+
regexp_parser (2.13.1)
|
|
91
|
+
request_store (1.7.0)
|
|
92
|
+
rack (>= 1.4)
|
|
93
|
+
rspec (3.13.2)
|
|
68
94
|
rspec-core (~> 3.13.0)
|
|
69
95
|
rspec-expectations (~> 3.13.0)
|
|
70
96
|
rspec-mocks (~> 3.13.0)
|
|
71
|
-
rspec-core (3.13.
|
|
97
|
+
rspec-core (3.13.6)
|
|
72
98
|
rspec-support (~> 3.13.0)
|
|
73
|
-
rspec-expectations (3.13.
|
|
99
|
+
rspec-expectations (3.13.5)
|
|
74
100
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
75
101
|
rspec-support (~> 3.13.0)
|
|
76
|
-
rspec-mocks (3.13.
|
|
102
|
+
rspec-mocks (3.13.8)
|
|
77
103
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
78
104
|
rspec-support (~> 3.13.0)
|
|
79
|
-
rspec-support (3.13.
|
|
80
|
-
rubocop (1.
|
|
81
|
-
json (
|
|
82
|
-
language_server-protocol (
|
|
83
|
-
|
|
105
|
+
rspec-support (3.13.7)
|
|
106
|
+
rubocop (1.92.1)
|
|
107
|
+
json (>= 2.3)
|
|
108
|
+
language_server-protocol (~> 3.17.0.2)
|
|
109
|
+
lint_roller (~> 1.1.0)
|
|
110
|
+
parallel (>= 1.10)
|
|
84
111
|
parser (>= 3.3.0.2)
|
|
85
112
|
rainbow (>= 2.2.2, < 4.0)
|
|
86
|
-
regexp_parser (>= 2.
|
|
87
|
-
rubocop-ast (>= 1.
|
|
113
|
+
regexp_parser (>= 2.11.3, < 3.0)
|
|
114
|
+
rubocop-ast (>= 1.49.0, < 2.0)
|
|
88
115
|
ruby-progressbar (~> 1.7)
|
|
89
|
-
unicode-display_width (>= 2.4.0, <
|
|
90
|
-
rubocop-ast (1.
|
|
91
|
-
parser (>= 3.3.
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
rubocop (
|
|
116
|
+
unicode-display_width (>= 2.4.0, < 4.0)
|
|
117
|
+
rubocop-ast (1.50.0)
|
|
118
|
+
parser (>= 3.3.7.2)
|
|
119
|
+
prism (~> 1.7)
|
|
120
|
+
rubocop-rake (0.7.1)
|
|
121
|
+
lint_roller (~> 1.1)
|
|
122
|
+
rubocop (>= 1.72.1)
|
|
123
|
+
rubocop-rspec (3.10.2)
|
|
124
|
+
lint_roller (~> 1.1)
|
|
125
|
+
regexp_parser (>= 2.0)
|
|
126
|
+
rubocop (~> 1.86, >= 1.86.2)
|
|
96
127
|
ruby-progressbar (1.13.0)
|
|
97
|
-
securerandom (0.
|
|
128
|
+
securerandom (0.4.1)
|
|
98
129
|
tzinfo (2.0.6)
|
|
99
130
|
concurrent-ruby (~> 1.0)
|
|
100
|
-
unicode-display_width (
|
|
101
|
-
|
|
131
|
+
unicode-display_width (3.3.0)
|
|
132
|
+
unicode-emoji (~> 4.3)
|
|
133
|
+
unicode-emoji (4.3.0)
|
|
134
|
+
uri (1.1.2)
|
|
135
|
+
useragent (0.16.11)
|
|
102
136
|
|
|
103
137
|
PLATFORMS
|
|
104
138
|
x86_64-darwin-21
|
|
105
139
|
x86_64-darwin-22
|
|
106
140
|
x86_64-darwin-23
|
|
141
|
+
x86_64-darwin-24
|
|
107
142
|
|
|
108
143
|
DEPENDENCIES
|
|
109
144
|
bp3-core!
|
|
@@ -114,4 +149,4 @@ DEPENDENCIES
|
|
|
114
149
|
rubocop-rspec (>= 2.25)
|
|
115
150
|
|
|
116
151
|
BUNDLED WITH
|
|
117
|
-
2.
|
|
152
|
+
2.7.2
|
data/README.md
CHANGED
|
@@ -61,6 +61,15 @@ To use :sqnr for record ordering for a particular model, use the class macro:
|
|
|
61
61
|
```ruby
|
|
62
62
|
use_sqnr_for_ordering
|
|
63
63
|
```
|
|
64
|
+
In all models that need logging of messages and exceptions to the db, add:
|
|
65
|
+
```ruby
|
|
66
|
+
include Bp3::Core::SystemLogs
|
|
67
|
+
```
|
|
68
|
+
Then in your application's `config/initializers/bp3-core`, add:
|
|
69
|
+
```ruby
|
|
70
|
+
Bp3::Core::SystemLogs.system_log_name = 'System::Log' # any class that exposes a .log_message method
|
|
71
|
+
Bp3::Core::SystemLogs.system_exception_name = 'System::Exception' # any class that exposes a .log_exception method
|
|
72
|
+
```
|
|
64
73
|
In all ActiveRecord models (or their base class) that use site, tenant and/or workspace
|
|
65
74
|
attributes that need to be populated from global state, add:
|
|
66
75
|
```ruby
|
|
@@ -71,7 +80,11 @@ The specific columns expected by `Tenantable` are:
|
|
|
71
80
|
- site: `sites_site_id`
|
|
72
81
|
- tenant: `tenant_id`
|
|
73
82
|
- workspace: `workspaces_workspace_id`
|
|
74
|
-
Tenantable will use reflection to determine which one(s) exist, and will create associations and callbacks accordingly.
|
|
83
|
+
Tenantable will use reflection to determine which one(s) exist, and will create associations and callbacks accordingly.
|
|
84
|
+
|
|
85
|
+
Its default scopes reach as far as the primary login, the request state's `current_login`: a root
|
|
86
|
+
reaches every site and an admin every tenant of their site, unless a less privileged login is signed
|
|
87
|
+
in beside them. It reads the request state through `Bp3::Core::Rqid.global_request_state_class`.
|
|
75
88
|
|
|
76
89
|
## Development
|
|
77
90
|
|
data/bp3-core.gemspec
CHANGED
|
@@ -31,8 +31,9 @@ Gem::Specification.new do |spec|
|
|
|
31
31
|
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
|
32
32
|
spec.require_paths = ['lib']
|
|
33
33
|
|
|
34
|
-
spec.add_dependency 'actionview', '
|
|
35
|
-
spec.add_dependency 'activesupport', '
|
|
34
|
+
spec.add_dependency 'actionview', '~> 8.1'
|
|
35
|
+
spec.add_dependency 'activesupport', '~> 8.1'
|
|
36
|
+
spec.add_dependency 'bp3-request_state', '~> 0.1'
|
|
36
37
|
|
|
37
38
|
spec.add_development_dependency 'rake', '>= 13.0'
|
|
38
39
|
spec.add_development_dependency 'rspec', '>= 3.0'
|
data/lib/bp3/core/actions.rb
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module Bp3
|
|
4
4
|
module Core
|
|
5
|
-
# rubocop:disable Metrics/ModuleLength
|
|
5
|
+
# rubocop:disable-next Metrics/ModuleLength
|
|
6
6
|
module Actions
|
|
7
7
|
extend ActiveSupport::Concern
|
|
8
8
|
|
|
@@ -209,6 +209,5 @@ module Bp3
|
|
|
209
209
|
@grsc ||= Bp3::Core::Rqid.global_request_state_class
|
|
210
210
|
end
|
|
211
211
|
end
|
|
212
|
-
# rubocop:enable Metrics/ModuleLength
|
|
213
212
|
end
|
|
214
213
|
end
|
data/lib/bp3/core/cookies.rb
CHANGED
|
@@ -58,7 +58,7 @@ module Bp3
|
|
|
58
58
|
}
|
|
59
59
|
end
|
|
60
60
|
|
|
61
|
-
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
|
61
|
+
# rubocop:disable-next Metrics/AbcSize, Metrics/MethodLength
|
|
62
62
|
def check_old_visitor_cookie
|
|
63
63
|
cookie_value = cookies.signed[visitor_cookie_name]
|
|
64
64
|
return if cookie_value.blank? && do_not_track
|
|
@@ -85,9 +85,8 @@ module Bp3
|
|
|
85
85
|
"check_visitor_cookie: cookie[#{visitor_cookie_name}]=#{cookies.signed[visitor_cookie_name]}"
|
|
86
86
|
end
|
|
87
87
|
end
|
|
88
|
-
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
|
89
88
|
|
|
90
|
-
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
|
89
|
+
# rubocop:disable-next Metrics/AbcSize, Metrics/MethodLength
|
|
91
90
|
def check_new_visitor_cookie
|
|
92
91
|
cookie_value = cookies.signed[new_visitor_cookie_name]
|
|
93
92
|
return if cookie_value.blank? && do_not_track
|
|
@@ -110,7 +109,6 @@ module Bp3
|
|
|
110
109
|
"check_visitor_cookie: cookie[#{new_visitor_cookie_name}]=#{cookies.signed[new_visitor_cookie_name]}"
|
|
111
110
|
end
|
|
112
111
|
end
|
|
113
|
-
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
|
114
112
|
|
|
115
113
|
def visitor_cookie_name
|
|
116
114
|
@visitor_cookie_name ||= "#{VISITOR_COOKIE_NAME_PREFIX}_#{cookie_site_id}_#{cookie_tenant_id}"
|
|
@@ -24,18 +24,19 @@ module Bp3
|
|
|
24
24
|
Feature::Enabler.on(flag, enablable: ref, default:)
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
+
# An explicit false wins over the default; the default applies only when the flag is not set
|
|
27
28
|
def efon?(flag, ref: nil, default: nil)
|
|
28
|
-
efon(flag, ref:, default:) ||
|
|
29
|
+
efon(flag, ref:, default:) || false
|
|
29
30
|
end
|
|
30
31
|
|
|
31
32
|
def cfon(flag, ref: nil, default: nil)
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
ref.configs&.[](flag)
|
|
33
|
+
value = ref&.configs&.[](flag)
|
|
34
|
+
value.nil? ? default : value
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
+
# An explicit false wins over the default; the default applies only when the config is not set
|
|
37
38
|
def cfon?(flag, ref: nil, default: nil)
|
|
38
|
-
cfon(flag, ref:, default:) ||
|
|
39
|
+
cfon(flag, ref:, default:) || false
|
|
39
40
|
end
|
|
40
41
|
end
|
|
41
42
|
end
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'logger'
|
|
4
|
+
|
|
5
|
+
module Bp3
|
|
6
|
+
module Core
|
|
7
|
+
module SystemLogs
|
|
8
|
+
extend ActiveSupport::Concern
|
|
9
|
+
|
|
10
|
+
SYSTEM_LOG_DEFAULTS = { log_to_db: true, log_to_io: true }.freeze
|
|
11
|
+
|
|
12
|
+
mattr_accessor :system_exception_name, :system_log_name
|
|
13
|
+
|
|
14
|
+
def self.system_exception_class
|
|
15
|
+
@@system_exception_class ||= system_exception_name.constantize # rubocop:disable Style/ClassVars
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.system_log_class
|
|
19
|
+
@@system_log_class ||= system_log_name.constantize # rubocop:disable Style/ClassVars
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Class methods for use in contexts without instance methods
|
|
23
|
+
module ClassMethods
|
|
24
|
+
# rubocop:disable-next Metrics/ParameterLists, Metrics/MethodLength
|
|
25
|
+
def log(level:, key:, message: nil, exception: nil, site: nil, details: {}, **system_log_options)
|
|
26
|
+
system_log_options = SYSTEM_LOG_DEFAULTS.dup.merge(system_log_options)
|
|
27
|
+
record = nil
|
|
28
|
+
if exception
|
|
29
|
+
if system_log_options[:log_to_io]
|
|
30
|
+
rails_logger.debug do
|
|
31
|
+
"SystemLogs, #{level}, #{key}, #{exception.message}"
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
record = exception_logger.log_exception(exception, site:, key:, details:) if system_log_options[:log_to_db]
|
|
35
|
+
end
|
|
36
|
+
return record if (message || '').strip == ''
|
|
37
|
+
|
|
38
|
+
rails_logger.debug { "SystemLogs, #{level}, #{key}, #{message}" } if system_log_options[:log_to_io]
|
|
39
|
+
begin
|
|
40
|
+
system_logger.log_message(level:, key:, message:, details:) if system_log_options[:log_to_db]
|
|
41
|
+
rescue StandardError => e
|
|
42
|
+
rails_logger.error { "SystemLogs.log failed: #{e.message}" }
|
|
43
|
+
nil
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def log_debug(key:, message:, details: {}, **system_log_options)
|
|
48
|
+
log(level: 'debug', key:, message:, details:, **system_log_options)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def log_info(key:, message:, details: {}, **system_log_options)
|
|
52
|
+
log(level: 'info', key:, message:, details:, **system_log_options)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def log_warn(key:, message:, details: {}, **system_log_options)
|
|
56
|
+
log(level: 'warn', key:, message:, details:, **system_log_options)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def log_error(key:, message:, details: {}, **system_log_options)
|
|
60
|
+
log(level: 'error', key:, message:, details:, **system_log_options)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def log_exception(exception, key:, details: {}, **system_log_options)
|
|
64
|
+
if exception.nil?
|
|
65
|
+
rails_logger.error { "SystemLogs, #{key}, nil exception logged" }
|
|
66
|
+
return nil
|
|
67
|
+
end
|
|
68
|
+
log(level: 'exception', key:, exception:, details:, **system_log_options)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def rails_logger
|
|
72
|
+
return Rails.logger if defined?(Rails)
|
|
73
|
+
|
|
74
|
+
::Logger.new($stdout, level: Logger::ERROR)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def system_logger
|
|
78
|
+
::Bp3::Core::SystemLogs.system_log_class
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def exception_logger
|
|
82
|
+
::Bp3::Core::SystemLogs.system_exception_class
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# rubocop:disable-next Metrics/ParameterLists
|
|
87
|
+
def log(level:, key:, message: nil, exception: nil, site: nil, details: {}, **system_log_options)
|
|
88
|
+
SystemLogs.log(level:, key:, message:, exception:, site:, details:, **system_log_options)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def log_debug(key:, message:, details: {}, **system_log_options)
|
|
92
|
+
SystemLogs.log_debug(key:, message:, details:, **system_log_options)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def log_info(key:, message:, details: {}, **system_log_options)
|
|
96
|
+
SystemLogs.log_info(key:, message:, details:, **system_log_options)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def log_warn(key:, message:, details: {}, **system_log_options)
|
|
100
|
+
SystemLogs.log_warn(key:, message:, details:, **system_log_options)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def log_error(key:, message:, details: {}, **system_log_options)
|
|
104
|
+
SystemLogs.log_error(key:, message:, details:, **system_log_options)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def log_exception(exception, key:, details: {}, **system_log_options)
|
|
108
|
+
SystemLogs.log_exception(exception, key:, details:, **system_log_options)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# Extend self to make ClassMethods available directly on SystemLogs module
|
|
112
|
+
extend ClassMethods
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
data/lib/bp3/core/tenantable.rb
CHANGED
|
@@ -5,6 +5,25 @@ module Bp3
|
|
|
5
5
|
module Tenantable
|
|
6
6
|
extend ActiveSupport::Concern
|
|
7
7
|
|
|
8
|
+
# The application's request state, the Bp3::RequestState::Base subclass Bp3::Core::Rqid is
|
|
9
|
+
# configured with
|
|
10
|
+
def self.global_request_state
|
|
11
|
+
Bp3::Core::Rqid.global_request_state_class
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# How far a default scope reaches is decided by the primary login, the request state's
|
|
15
|
+
# current_login: the least privileged one signed in. A root or an admin signed in beside a less
|
|
16
|
+
# privileged login has that login's reach rather than their own.
|
|
17
|
+
def self.reaches_every_site?(state = global_request_state)
|
|
18
|
+
login = state.current_login
|
|
19
|
+
!login.nil? && login == state.current_root
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def self.reaches_every_tenant?(state = global_request_state)
|
|
23
|
+
login = state.current_login
|
|
24
|
+
!login.nil? && (login == state.current_root || login == state.current_admin)
|
|
25
|
+
end
|
|
26
|
+
|
|
8
27
|
included do
|
|
9
28
|
# call connection to make sure the db meta data has been loaded
|
|
10
29
|
ignore_notifications_string = (ENV['IGNORE_NOTIFICATIONS'] || '').strip
|
|
@@ -16,13 +35,13 @@ module Bp3
|
|
|
16
35
|
def set_sites_site_id
|
|
17
36
|
return if sites_site_id || sites_site
|
|
18
37
|
|
|
19
|
-
self.sites_site_id =
|
|
38
|
+
self.sites_site_id = Bp3::Core::Tenantable.global_request_state.either_site_id
|
|
20
39
|
end
|
|
21
40
|
|
|
22
41
|
def set_tenant_id
|
|
23
42
|
return if tenant_id || tenant
|
|
24
43
|
|
|
25
|
-
self.tenant_id =
|
|
44
|
+
self.tenant_id = Bp3::Core::Tenantable.global_request_state.either_tenant_id
|
|
26
45
|
end
|
|
27
46
|
|
|
28
47
|
def tenant_matches_site
|
|
@@ -38,7 +57,7 @@ module Bp3
|
|
|
38
57
|
def set_workspaces_workspace_id
|
|
39
58
|
return if workspaces_workspace_id || workspaces_workspace
|
|
40
59
|
|
|
41
|
-
self.workspaces_workspace_id =
|
|
60
|
+
self.workspaces_workspace_id = Bp3::Core::Tenantable.global_request_state.either_workspace_id
|
|
42
61
|
end
|
|
43
62
|
|
|
44
63
|
def workspaces_workspace_matches_site
|
|
@@ -51,7 +70,6 @@ module Bp3
|
|
|
51
70
|
errors.add(:workspaces_workspace, :must_match_site)
|
|
52
71
|
end
|
|
53
72
|
|
|
54
|
-
# rubocop:disable: Metrics/BlockLength
|
|
55
73
|
class_methods do
|
|
56
74
|
def configure_tenancy(tenancy_configuration = {})
|
|
57
75
|
@tenancy_configuration = default_configuration.merge(tenancy_configuration)
|
|
@@ -76,13 +94,13 @@ module Bp3
|
|
|
76
94
|
before_validation :set_sites_site_id
|
|
77
95
|
|
|
78
96
|
default_scope lambda {
|
|
79
|
-
site =
|
|
80
|
-
site = nil if
|
|
97
|
+
site = Bp3::Core::Tenantable.global_request_state.either_site
|
|
98
|
+
site = nil if Bp3::Core::Tenantable.reaches_every_site?
|
|
81
99
|
where(sites_site_id: site.id) if site
|
|
82
100
|
}
|
|
83
101
|
end
|
|
84
102
|
|
|
85
|
-
# rubocop:disable Metrics/MethodLength
|
|
103
|
+
# rubocop:disable-next Metrics/MethodLength
|
|
86
104
|
def may_belong_to_tenant
|
|
87
105
|
column = columns.detect { |c| c.name == 'tenant_id' }
|
|
88
106
|
return if column.nil?
|
|
@@ -96,10 +114,10 @@ module Bp3
|
|
|
96
114
|
validate :tenant_matches_site
|
|
97
115
|
|
|
98
116
|
default_scope lambda {
|
|
99
|
-
site =
|
|
100
|
-
site = nil if
|
|
101
|
-
tenant =
|
|
102
|
-
tenant = nil if
|
|
117
|
+
site = Bp3::Core::Tenantable.global_request_state.either_site
|
|
118
|
+
site = nil if Bp3::Core::Tenantable.reaches_every_site?
|
|
119
|
+
tenant = Bp3::Core::Tenantable.global_request_state.either_tenant
|
|
120
|
+
tenant = nil if Bp3::Core::Tenantable.reaches_every_tenant?
|
|
103
121
|
if site && tenant # for non admins (i.e. users)
|
|
104
122
|
where(sites_site_id: site.id, tenant_id: tenant.id)
|
|
105
123
|
elsif site # for site admins
|
|
@@ -109,7 +127,6 @@ module Bp3
|
|
|
109
127
|
end
|
|
110
128
|
}
|
|
111
129
|
end
|
|
112
|
-
# rubocop:enable Metrics/MethodLength
|
|
113
130
|
|
|
114
131
|
def may_belong_to_workspace
|
|
115
132
|
column = columns.detect { |c| c.name == 'workspaces_workspace_id' }
|
|
@@ -137,7 +154,6 @@ module Bp3
|
|
|
137
154
|
}
|
|
138
155
|
end
|
|
139
156
|
end
|
|
140
|
-
# rubocop:disable: Metrics/BlockLength
|
|
141
157
|
end
|
|
142
158
|
end
|
|
143
159
|
end
|
data/lib/bp3/core/test.rb
CHANGED
|
@@ -4,6 +4,40 @@ module Bp3
|
|
|
4
4
|
module Core
|
|
5
5
|
# Bp3::Core::Test provides a convenience class for testing Bp3::Core
|
|
6
6
|
class Test
|
|
7
|
+
class SystemLogger
|
|
8
|
+
@log_count = 0
|
|
9
|
+
|
|
10
|
+
def self.log_message(level:, key:, message:, details:)
|
|
11
|
+
puts "Test:SystemLogger: #{level} #{key} #{message} #{details}"
|
|
12
|
+
add_count
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.add_count
|
|
16
|
+
@log_count += 1
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
class << self
|
|
20
|
+
attr_reader :log_count
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
class ExceptionLogger
|
|
25
|
+
@log_count = 0
|
|
26
|
+
|
|
27
|
+
def self.log_exception(exception, site:, key:, details:)
|
|
28
|
+
puts "Test:ExceptionLogger: #{site&.display_name} #{key} #{exception.message} #{details}"
|
|
29
|
+
add_count
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def self.add_count
|
|
33
|
+
@log_count += 1
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
class << self
|
|
37
|
+
attr_reader :log_count
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
7
41
|
# to test Ransackable
|
|
8
42
|
include Ransackable
|
|
9
43
|
|
|
@@ -38,6 +72,10 @@ module Bp3
|
|
|
38
72
|
# to test Sqnr
|
|
39
73
|
include Sqnr
|
|
40
74
|
|
|
75
|
+
# to test SystemLogs
|
|
76
|
+
include SystemLogs # to use log methods on an instance
|
|
77
|
+
extend SystemLogs # to use log methods on the class
|
|
78
|
+
|
|
41
79
|
# to test Tenantable
|
|
42
80
|
# first define this:
|
|
43
81
|
def self.connection; end
|
data/lib/bp3/core/version.rb
CHANGED
data/lib/bp3/core.rb
CHANGED
|
@@ -9,6 +9,7 @@ require_relative 'core/displayable'
|
|
|
9
9
|
require_relative 'core/feature_flags'
|
|
10
10
|
require_relative 'core/ransackable'
|
|
11
11
|
require_relative 'core/settings'
|
|
12
|
+
require_relative 'core/system_logs'
|
|
12
13
|
require_relative 'core/tenantable'
|
|
13
14
|
require_relative 'core/rqid'
|
|
14
15
|
require_relative 'core/sqnr'
|
metadata
CHANGED
|
@@ -1,43 +1,56 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: bp3-core
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Wim den Braven
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: exe
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: actionview
|
|
15
14
|
requirement: !ruby/object:Gem::Requirement
|
|
16
15
|
requirements:
|
|
17
|
-
- - "
|
|
16
|
+
- - "~>"
|
|
18
17
|
- !ruby/object:Gem::Version
|
|
19
|
-
version:
|
|
18
|
+
version: '8.1'
|
|
20
19
|
type: :runtime
|
|
21
20
|
prerelease: false
|
|
22
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
22
|
requirements:
|
|
24
|
-
- - "
|
|
23
|
+
- - "~>"
|
|
25
24
|
- !ruby/object:Gem::Version
|
|
26
|
-
version:
|
|
25
|
+
version: '8.1'
|
|
27
26
|
- !ruby/object:Gem::Dependency
|
|
28
27
|
name: activesupport
|
|
29
28
|
requirement: !ruby/object:Gem::Requirement
|
|
30
29
|
requirements:
|
|
31
|
-
- - "
|
|
30
|
+
- - "~>"
|
|
32
31
|
- !ruby/object:Gem::Version
|
|
33
|
-
version:
|
|
32
|
+
version: '8.1'
|
|
34
33
|
type: :runtime
|
|
35
34
|
prerelease: false
|
|
36
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
36
|
requirements:
|
|
38
|
-
- - "
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '8.1'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: bp3-request_state
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - "~>"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '0.1'
|
|
47
|
+
type: :runtime
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - "~>"
|
|
39
52
|
- !ruby/object:Gem::Version
|
|
40
|
-
version:
|
|
53
|
+
version: '0.1'
|
|
41
54
|
- !ruby/object:Gem::Dependency
|
|
42
55
|
name: rake
|
|
43
56
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -108,7 +121,6 @@ dependencies:
|
|
|
108
121
|
- - ">="
|
|
109
122
|
- !ruby/object:Gem::Version
|
|
110
123
|
version: '2.25'
|
|
111
|
-
description:
|
|
112
124
|
email:
|
|
113
125
|
- wimdenbraven@persuavis.com
|
|
114
126
|
executables: []
|
|
@@ -120,6 +132,7 @@ files:
|
|
|
120
132
|
- ".ruby-version"
|
|
121
133
|
- ".yardopts"
|
|
122
134
|
- CHANGELOG.md
|
|
135
|
+
- CLAUDE.md
|
|
123
136
|
- Gemfile
|
|
124
137
|
- Gemfile.lock
|
|
125
138
|
- LICENSE.txt
|
|
@@ -136,6 +149,7 @@ files:
|
|
|
136
149
|
- lib/bp3/core/rqid.rb
|
|
137
150
|
- lib/bp3/core/settings.rb
|
|
138
151
|
- lib/bp3/core/sqnr.rb
|
|
152
|
+
- lib/bp3/core/system_logs.rb
|
|
139
153
|
- lib/bp3/core/tenantable.rb
|
|
140
154
|
- lib/bp3/core/test.rb
|
|
141
155
|
- lib/bp3/core/version.rb
|
|
@@ -149,7 +163,6 @@ metadata:
|
|
|
149
163
|
source_code_uri: https://github.com/persuavis/bp3-core
|
|
150
164
|
changelog_uri: https://github.com/persuavis/bp3-core/blob/main/CHANGELOG.md
|
|
151
165
|
rubygems_mfa_required: 'true'
|
|
152
|
-
post_install_message:
|
|
153
166
|
rdoc_options: []
|
|
154
167
|
require_paths:
|
|
155
168
|
- lib
|
|
@@ -164,8 +177,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
164
177
|
- !ruby/object:Gem::Version
|
|
165
178
|
version: '0'
|
|
166
179
|
requirements: []
|
|
167
|
-
rubygems_version:
|
|
168
|
-
signing_key:
|
|
180
|
+
rubygems_version: 4.0.4
|
|
169
181
|
specification_version: 4
|
|
170
182
|
summary: bp3-core provides core concerns for BP3 (persuavis/black_phoebe_3).
|
|
171
183
|
test_files: []
|