dscf-core 0.1.0 → 0.1.2

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.
Files changed (29) hide show
  1. checksums.yaml +4 -4
  2. data/app/models/dscf/core/address.rb +11 -0
  3. data/app/models/dscf/core/business.rb +20 -0
  4. data/app/models/dscf/core/business_type.rb +9 -0
  5. data/app/models/dscf/core/document.rb +19 -0
  6. data/app/models/dscf/core/role.rb +11 -0
  7. data/app/models/dscf/core/user.rb +17 -0
  8. data/app/models/dscf/core/user_profile.rb +12 -0
  9. data/app/models/dscf/core/user_role.rb +10 -0
  10. data/db/migrate/20250821175358_create_dscf_core_users.rb +15 -0
  11. data/db/migrate/20250821185708_create_dscf_core_roles.rb +11 -0
  12. data/db/migrate/20250822054547_create_dscf_core_user_roles.rb +12 -0
  13. data/db/migrate/20250822065156_create_dscf_core_business_types.rb +10 -0
  14. data/db/migrate/20250822072222_create_dscf_core_businesses.rb +15 -0
  15. data/db/migrate/20250822075206_create_dscf_core_addresses.rb +19 -0
  16. data/db/migrate/20250822081522_create_dscf_core_documents.rb +14 -0
  17. data/db/migrate/20250822083000_change_document_type_in_dscf_core_documents.rb +11 -0
  18. data/db/migrate/20250822092031_create_dscf_core_user_profiles.rb +26 -0
  19. data/lib/dscf/core/engine.rb +1 -4
  20. data/lib/dscf/core/version.rb +1 -1
  21. data/spec/factories/dscf/core/addresses.rb +15 -0
  22. data/spec/factories/dscf/core/business_types.rb +5 -0
  23. data/spec/factories/dscf/core/businesses.rb +11 -0
  24. data/spec/factories/dscf/core/documents.rb +25 -0
  25. data/spec/factories/dscf/core/roles.rb +6 -0
  26. data/spec/factories/dscf/core/user_profiles.rb +22 -0
  27. data/spec/factories/dscf/core/user_roles.rb +6 -0
  28. data/spec/factories/dscf/core/users.rb +10 -0
  29. metadata +43 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d30c3cdb9c82b916f92f417b0ac10747e2d1c4f6280e7bb7def4d10f8d5e0b42
4
- data.tar.gz: 128110c87e6cca2b109ad54745a6d42ba8ac225c68569cf50666e640eedd4a0b
3
+ metadata.gz: 113ae71c73f1677c95192abafbe070227cb8938204430fc320e0ee7667546f74
4
+ data.tar.gz: d688f387984a84dc6e2078cacf65cb74560ad568073d4965b6943a5a0997ac9b
5
5
  SHA512:
6
- metadata.gz: 0777070fce9ba3745269227f1d2a12b71220e25f476a4b339c4e499151bb486b7a70c8f769080e9420d26490dafe2ad4e45038867a5def1f174171bdec72c0d0
7
- data.tar.gz: 88715578dcafe4f2fc90b2bc830681470ea09535ccbd84d9997045cc1833b105afc5ce44edb4a96ee5ceefde919644167b41ba2ec0e53ee6caad4feb2155330f
6
+ metadata.gz: e5f9c9c60bcec896a04c131a93b574f7f8dda64a15793816d3f9422cbeaed04788b6200015c8a0b3ea17302b43ac6592c3acce724bbbb016468da8ffa7e23749
7
+ data.tar.gz: 6d0ad2580955a6c87d33d4b7b6131ea9a65944c79f032568dd361c9d301bd3ce77eaada16ddf1b5e87c932e5e6d630151e6ebd97daf8d7712af212d20cfbc05a
@@ -0,0 +1,11 @@
1
+ module Dscf
2
+ module Core
3
+ class Address < ApplicationRecord
4
+ belongs_to :user, class_name: "Dscf::Core::User"
5
+
6
+ enum :address_type, {shipping: 0, residence: 1, current: 2, branch: 3}
7
+
8
+ validates :country, presence: true
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,20 @@
1
+ module Dscf
2
+ module Core
3
+ class Business < ApplicationRecord
4
+ belongs_to :user, class_name: "Dscf::Core::User"
5
+ belongs_to :business_type, class_name: "Dscf::Core::BusinessType"
6
+
7
+ has_one_attached :logo
8
+
9
+ has_many :documents, as: :documentable, dependent: :destroy, class_name: "Dscf::Core::Document"
10
+
11
+ validates :name, presence: true
12
+
13
+ def logo_url
14
+ return nil unless logo.attached?
15
+
16
+ Rails.application.routes.url_helpers.rails_blob_url(logo, only_path: true)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,9 @@
1
+ module Dscf
2
+ module Core
3
+ class BusinessType < ApplicationRecord
4
+ has_many :businesses, dependent: :destroy, class_name: "Dscf::Core::Business"
5
+
6
+ validates :name, presence: true, uniqueness: true
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,19 @@
1
+ module Dscf
2
+ module Core
3
+ class Document < ApplicationRecord
4
+ belongs_to :documentable, polymorphic: true
5
+ belongs_to :verified_by, polymorphic: true, optional: true
6
+ validates :document_type, presence: true
7
+
8
+ has_one_attached :file
9
+
10
+ enum :document_type, {business_license: 0, drivers_license: 1, claim: 2}
11
+
12
+ def file_url
13
+ return nil unless file.attached?
14
+
15
+ Rails.application.routes.url_helpers.rails_blob_url(file, only_path: true)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,11 @@
1
+ module Dscf
2
+ module Core
3
+ class Role < ApplicationRecord
4
+ validates :code, presence: true, uniqueness: true
5
+ validates :name, presence: true
6
+
7
+ has_many :user_roles, class_name: "Dscf::Core::UserRole"
8
+ has_many :users, through: :user_roles, class_name: "Dscf::Core::User"
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,17 @@
1
+ module Dscf
2
+ module Core
3
+ class User < ApplicationRecord
4
+ has_secure_password
5
+
6
+ validates :email, presence: true, uniqueness: true
7
+ validates :phone, presence: true, uniqueness: true
8
+
9
+ has_many :user_roles, class_name: "Dscf::Core::UserRole"
10
+ has_many :roles, through: :user_roles, class_name: "Dscf::Core::Role"
11
+ has_many :businesses, dependent: :destroy, class_name: "Dscf::Core::Business"
12
+ has_many :addresses, dependent: :destroy, class_name: "Dscf::Core::Address"
13
+ has_many :documents, as: :documentable, dependent: :destroy, class_name: "Dscf::Core::Document"
14
+ has_one :user_profile, dependent: :destroy, class_name: "Dscf::Core::UserProfile"
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,12 @@
1
+ module Dscf
2
+ module Core
3
+ class UserProfile < ApplicationRecord
4
+ belongs_to :user, class_name: "Dscf::Core::User"
5
+
6
+ validates :first_name, presence: true
7
+ validates :last_name, presence: true
8
+ validates :watchlist_hit, inclusion: {in: [true, false]}
9
+ validates :verification_status, presence: true
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,10 @@
1
+ module Dscf
2
+ module Core
3
+ class UserRole < ApplicationRecord
4
+ belongs_to :user
5
+ belongs_to :role
6
+
7
+ validates_uniqueness_of :user_id, scope: :role_id
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,15 @@
1
+ class CreateDscfCoreUsers < ActiveRecord::Migration[8.0]
2
+ def change
3
+ create_table :dscf_core_users do |t|
4
+ t.string :email, null: false, limit: 150
5
+ t.string :phone, null: false, limit: 30
6
+ t.datetime :verified_at
7
+ t.boolean :temp_password, null: false
8
+ t.string :password_digest
9
+
10
+ t.timestamps
11
+ end
12
+ add_index :dscf_core_users, :email, unique: true
13
+ add_index :dscf_core_users, :phone, unique: true
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ class CreateDscfCoreRoles < ActiveRecord::Migration[8.0]
2
+ def change
3
+ create_table :dscf_core_roles do |t|
4
+ t.string :code, null: false, limit: 50
5
+ t.string :name, null: false, limit: 100
6
+
7
+ t.timestamps
8
+ end
9
+ add_index :dscf_core_roles, :code, unique: true
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ class CreateDscfCoreUserRoles < ActiveRecord::Migration[8.0]
2
+ def change
3
+ create_table :dscf_core_user_roles do |t|
4
+ t.references :user, null: false, index: {name: "user_on_dc_ur_indx"}, foreign_key: {to_table: :dscf_core_users}
5
+ t.references :role, null: false, index: {name: "role_on_dc_ur_indx"}, foreign_key: {to_table: :dscf_core_roles}
6
+
7
+ t.timestamps
8
+ end
9
+
10
+ add_index :dscf_core_user_roles, %i[user_id role_id], unique: true, name: "user_role_unique_indx"
11
+ end
12
+ end
@@ -0,0 +1,10 @@
1
+ class CreateDscfCoreBusinessTypes < ActiveRecord::Migration[8.0]
2
+ def change
3
+ create_table :dscf_core_business_types do |t|
4
+ t.string :name, null: false
5
+
6
+ t.timestamps
7
+ end
8
+ add_index :dscf_core_business_types, :name, unique: true
9
+ end
10
+ end
@@ -0,0 +1,15 @@
1
+ class CreateDscfCoreBusinesses < ActiveRecord::Migration[8.0]
2
+ def change
3
+ create_table :dscf_core_businesses do |t|
4
+ t.string :name, null: false
5
+ t.string :description
6
+ t.string :contact_email
7
+ t.string :contact_phone
8
+ t.string :tin_number
9
+ t.references :business_type, null: false, foreign_key: {to_table: :dscf_core_business_types}
10
+ t.references :user, null: false, foreign_key: {to_table: :dscf_core_users}
11
+
12
+ t.timestamps
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,19 @@
1
+ class CreateDscfCoreAddresses < ActiveRecord::Migration[8.0]
2
+ def change
3
+ create_table :dscf_core_addresses do |t|
4
+ t.references :user, null: false, index: {name: "user_on_dc_add_indx"}, foreign_key: {to_table: :dscf_core_users}
5
+ t.integer :address_type
6
+ t.string :country, null: false, default: "Ethiopia"
7
+ t.string :city
8
+ t.string :sub_city
9
+ t.string :woreda
10
+ t.string :kebele
11
+ t.string :house_numbers
12
+ t.string :po_box
13
+ t.decimal :latitude, precision: 10, scale: 6
14
+ t.decimal :longitude, precision: 10, scale: 6
15
+
16
+ t.timestamps
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,14 @@
1
+ class CreateDscfCoreDocuments < ActiveRecord::Migration[8.0]
2
+ def change
3
+ create_table :dscf_core_documents do |t|
4
+ t.references :documentable, polymorphic: true, null: false
5
+ t.string :document_type, null: false
6
+ t.boolean :is_verified, default: false
7
+ t.references :verified_by, polymorphic: true, null: true
8
+ t.datetime :verified_at
9
+ t.jsonb :metadata, default: {}
10
+
11
+ t.timestamps
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,11 @@
1
+ class ChangeDocumentTypeInDscfCoreDocuments < ActiveRecord::Migration[8.0]
2
+ def up
3
+ remove_column :dscf_core_documents, :document_type
4
+ add_column :dscf_core_documents, :document_type, :integer, null: false
5
+ end
6
+
7
+ def down
8
+ remove_column :dscf_core_documents, :document_type
9
+ add_column :dscf_core_documents, :document_type, :string, null: false
10
+ end
11
+ end
@@ -0,0 +1,26 @@
1
+ class CreateDscfCoreUserProfiles < ActiveRecord::Migration[8.0]
2
+ def change
3
+ create_table :dscf_core_user_profiles do |t|
4
+ t.references :user, null: false, index: {name: "user_on_dc_up_indx"}, foreign_key: {to_table: :dscf_core_users}
5
+ t.string :first_name, null: false
6
+ t.string :middle_name
7
+ t.string :last_name, null: false
8
+ t.string :gender
9
+ t.string :nationality
10
+ t.date :date_of_birth
11
+ t.string :place_of_birth
12
+ t.string :fayda_number
13
+ t.string :occupation
14
+ t.string :position_title
15
+ t.string :employer_name
16
+ t.decimal :avg_monthly_income, precision: 18, scale: 2
17
+ t.decimal :avg_annual_income, precision: 18, scale: 2
18
+ t.string :pep_status
19
+ t.decimal :risk_score, precision: 5, scale: 2
20
+ t.boolean :watchlist_hit, null: false
21
+ t.string :verification_status, null: false
22
+
23
+ t.timestamps
24
+ end
25
+ end
26
+ end
@@ -15,13 +15,10 @@ module Dscf
15
15
  end
16
16
 
17
17
  initializer :append_migrations do |app|
18
- unless app.root.to_s.match(root.to_s + File::SEPARATOR)
19
- app.config.paths["db/migrate"].concat(config.paths["db/migrate"].expanded)
20
- end
18
+ app.config.paths["db/migrate"].concat(config.paths["db/migrate"].expanded) unless app.root.to_s.match(root.to_s + File::SEPARATOR)
21
19
  end
22
20
 
23
21
  require "active_storage/engine"
24
-
25
22
  end
26
23
  end
27
24
  end
@@ -1,5 +1,5 @@
1
1
  module Dscf
2
2
  module Core
3
- VERSION = "0.1.0"
3
+ VERSION = "0.1.2".freeze
4
4
  end
5
5
  end
@@ -0,0 +1,15 @@
1
+ FactoryBot.define do
2
+ factory :address, class: "Dscf::Core::Address" do
3
+ user
4
+ address_type { Dscf::Core::Address.address_types.keys.sample }
5
+ country { Faker::Address.country }
6
+ city { Faker::Address.city }
7
+ sub_city { Faker::Address.community }
8
+ woreda { Faker::Address.community }
9
+ kebele { Faker::Address.community }
10
+ house_numbers { Faker::Address.building_number }
11
+ po_box { Faker::Address.postcode }
12
+ latitude { Faker::Address.latitude }
13
+ longitude { Faker::Address.longitude }
14
+ end
15
+ end
@@ -0,0 +1,5 @@
1
+ FactoryBot.define do
2
+ factory :business_type, class: "Dscf::Core::BusinessType" do
3
+ name { Faker::Company.unique.industry }
4
+ end
5
+ end
@@ -0,0 +1,11 @@
1
+ FactoryBot.define do
2
+ factory :business, class: "Dscf::Core::Business" do
3
+ name { Faker::Company.name }
4
+ description { Faker::Company.catch_phrase }
5
+ contact_email { Faker::Internet.email }
6
+ contact_phone { Faker::PhoneNumber.phone_number }
7
+ tin_number { Faker::Number.number(digits: 10).to_s }
8
+ user
9
+ business_type
10
+ end
11
+ end
@@ -0,0 +1,25 @@
1
+ FactoryBot.define do
2
+ factory :document, class: "Dscf::Core::Document" do
3
+ association :documentable, factory: :user # Default documentable
4
+ document_type { Dscf::Core::Document.document_types.keys.sample }
5
+ is_verified { false }
6
+ verified_at { nil }
7
+ metadata { {"source" => "test"} }
8
+
9
+ trait :for_user do
10
+ association :documentable, factory: :user
11
+ end
12
+
13
+ trait :for_business do
14
+ association :documentable, factory: :business
15
+ end
16
+
17
+ after(:build) do |document|
18
+ document.file.attach(
19
+ io: File.open(Rails.root.join("app", "fixtures", "images", "logo.jpg")),
20
+ filename: "logo.jpg",
21
+ content_type: "image/jpeg"
22
+ )
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,6 @@
1
+ FactoryBot.define do
2
+ factory :role, class: "Dscf::Core::Role" do
3
+ code { Faker::Lorem.characters(number: 5) }
4
+ name { Faker::Lorem.characters(number: 10) }
5
+ end
6
+ end
@@ -0,0 +1,22 @@
1
+ FactoryBot.define do
2
+ factory :user_profile, class: "Dscf::Core::UserProfile" do
3
+ user
4
+ first_name { Faker::Name.first_name }
5
+ middle_name { Faker::Name.middle_name }
6
+ last_name { Faker::Name.last_name }
7
+ gender { %w[Male Female Other].sample }
8
+ nationality { Faker::Address.country }
9
+ date_of_birth { Faker::Date.birthday(min_age: 18, max_age: 65) }
10
+ place_of_birth { Faker::Address.city }
11
+ fayda_number { Faker::Alphanumeric.alpha(number: 10) }
12
+ occupation { Faker::Job.title }
13
+ position_title { Faker::Job.position }
14
+ employer_name { Faker::Company.name }
15
+ avg_monthly_income { Faker::Number.decimal(l_digits: 5, r_digits: 2) }
16
+ avg_annual_income { Faker::Number.decimal(l_digits: 6, r_digits: 2) }
17
+ pep_status { %w[None Low Medium High].sample }
18
+ risk_score { Faker::Number.decimal(l_digits: 1, r_digits: 2) }
19
+ watchlist_hit { Faker::Boolean.boolean }
20
+ verification_status { %w[Pending Verified Rejected].sample }
21
+ end
22
+ end
@@ -0,0 +1,6 @@
1
+ FactoryBot.define do
2
+ factory :user_role, class: "Dscf::Core::UserRole" do
3
+ user
4
+ role
5
+ end
6
+ end
@@ -0,0 +1,10 @@
1
+ FactoryBot.define do
2
+ factory :user, class: "Dscf::Core::User" do
3
+ email { Faker::Internet.unique.email }
4
+ phone { Faker::Lorem.characters(number: 10) }
5
+
6
+ verified_at { Time.now }
7
+ temp_password { false }
8
+ password { "password" }
9
+ end
10
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dscf-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Asrat
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-08-19 00:00:00.000000000 Z
10
+ date: 2025-08-22 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: active_model_serializers
@@ -107,6 +107,20 @@ dependencies:
107
107
  - - ">="
108
108
  - !ruby/object:Gem::Version
109
109
  version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: pundit
112
+ requirement: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ type: :runtime
118
+ prerelease: false
119
+ version_requirements: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
110
124
  - !ruby/object:Gem::Dependency
111
125
  name: rails
112
126
  requirement: !ruby/object:Gem::Requirement
@@ -136,13 +150,13 @@ dependencies:
136
150
  - !ruby/object:Gem::Version
137
151
  version: '0'
138
152
  - !ruby/object:Gem::Dependency
139
- name: pundit
153
+ name: active_storage_validations
140
154
  requirement: !ruby/object:Gem::Requirement
141
155
  requirements:
142
156
  - - ">="
143
157
  - !ruby/object:Gem::Version
144
158
  version: '0'
145
- type: :runtime
159
+ type: :development
146
160
  prerelease: false
147
161
  version_requirements: !ruby/object:Gem::Requirement
148
162
  requirements:
@@ -288,12 +302,37 @@ files:
288
302
  - app/controllers/dscf/core/application_controller.rb
289
303
  - app/jobs/dscf/core/application_job.rb
290
304
  - app/mailers/dscf/core/application_mailer.rb
305
+ - app/models/dscf/core/address.rb
291
306
  - app/models/dscf/core/application_record.rb
307
+ - app/models/dscf/core/business.rb
308
+ - app/models/dscf/core/business_type.rb
309
+ - app/models/dscf/core/document.rb
310
+ - app/models/dscf/core/role.rb
311
+ - app/models/dscf/core/user.rb
312
+ - app/models/dscf/core/user_profile.rb
313
+ - app/models/dscf/core/user_role.rb
292
314
  - config/routes.rb
315
+ - db/migrate/20250821175358_create_dscf_core_users.rb
316
+ - db/migrate/20250821185708_create_dscf_core_roles.rb
317
+ - db/migrate/20250822054547_create_dscf_core_user_roles.rb
318
+ - db/migrate/20250822065156_create_dscf_core_business_types.rb
319
+ - db/migrate/20250822072222_create_dscf_core_businesses.rb
320
+ - db/migrate/20250822075206_create_dscf_core_addresses.rb
321
+ - db/migrate/20250822081522_create_dscf_core_documents.rb
322
+ - db/migrate/20250822083000_change_document_type_in_dscf_core_documents.rb
323
+ - db/migrate/20250822092031_create_dscf_core_user_profiles.rb
293
324
  - lib/dscf/core.rb
294
325
  - lib/dscf/core/engine.rb
295
326
  - lib/dscf/core/version.rb
296
327
  - lib/tasks/dscf/core_tasks.rake
328
+ - spec/factories/dscf/core/addresses.rb
329
+ - spec/factories/dscf/core/business_types.rb
330
+ - spec/factories/dscf/core/businesses.rb
331
+ - spec/factories/dscf/core/documents.rb
332
+ - spec/factories/dscf/core/roles.rb
333
+ - spec/factories/dscf/core/user_profiles.rb
334
+ - spec/factories/dscf/core/user_roles.rb
335
+ - spec/factories/dscf/core/users.rb
297
336
  homepage: https://mksaddis.com/
298
337
  licenses:
299
338
  - MIT