Hollar Solidus Web Application and API
10K+
Running MySQL and Elasticsearch locally can be done easily with Docker, however due to known performance issues with shared volumes, it is best to run ruby/rails locally outside of Docker.
# Requirements (one-time commands):
brew install mysql imagemagick wget
docker network create hollar
docker run -d --name elasticsearch-hollar \
--network hollar \
-p 9200:9200 -p 9300:9300 \
elasticsearch:2-alpine
docker run -d --name mysql-hollar \
--network hollar \
-e MYSQL_ALLOW_EMPTY_PASSWORD=yes -e MYSQL_ROOT_PASSWORD="" \
-p 3306:3306 \
mysql
# Bootstrap a clean environment
# Running this will wipe your existing environment
./bin/bootstrap
# Start the application
./bin/start
# Site is now accessible via http://localhost:3000
Please note: After a reboot, you will need to start your MySQL and Elasticsearch services via:
docker start elasticsearch-hollar
docker start mysql-hollar
Running in 100% Docker is the easiest way to get up and running and is great for testing. However, due to known performance issues with Docker shared volumes and Docker for Mac/Win, it is the least performant option and certain requests will take 2x-5x longer than those in Option 1.
docker network create hollar
docker-compose run --rm web ./bin/bootstrap
docker-compose up -d
# Site is now accessible via http://localhost:33000
This is an object-oriented codebase, built on top of a typical Rails application (Solidus) which provides the vast majority of domain logic in the application. That is an introduction to this, our one architectural rule:
Now, let me explain. I like the idea of a service-oriented architecture, and appreciate that it provides many benefits, such as refactoring, decoupling, testing, small source files and so on. However, the basic fact is that while a service-oriented architecture has many practical benefits, this application is in fact not service-oriented. It is fundamentally, overwhelmingly, object-oriented.
Attempting to cross the streams of these two design philosophies by creating "service object" classes by extracting methods into classes (the "Command" pattern) is an extremely popular technique that, undermines existing object-oriented design. Domain services in Domain-Driven Design are supposed to be stateless standalone interfaces, so the correct implementation choice in Ruby for that interface is a module, not a class. Therefore we should be writing domain modules, not domain objects.
And Rails, in fact, has a solution for how to create and integrate such modules and address the same problems of code organization, which is ActiveSupport concerns. ActiveRecord is inherently a system for combining data persistence and domain logic in a single class, which is to say it is fundamental to the classic design of Rails applications. Concerns maintain that design while providing the architectural benefits of domain services.
On the other hand, using objects for domain services introduces service-orientation into the object-oriented paradigm of a language which never meant to support liberating methods from their natural context. It explodes the number of concepts and classes by removing every complex method from an object. It removes logic from objects with the goal of making them dumb data structures, which, again, is antithetical to the concept of ActiveRecord. And most problematic of all, it moves us towards a design goal we can never actually reach, because we are building on top of Solidus, which is not built with that design, which is on top of Rails, which makes it difficult to support that design. I can see where this design structure is useful, but this is not the case for this application.
The following thoughts are warning signs that you are about to create a service object that doesn't belong in this app:
call, even though this class isn't Rack middleware.Now for the good news. We have a great place to create a service-oriented architecture, which is our Elixir repo. Elixir, being unburdened with the object-oriented paradigm at the language level, is actually a fantastic environment for service-oriented architecture, CQRS, plugs and adapters -- really, all the best ideas of application design from the last fifteen years. Because they really are useful and practical, but are difficult to combine with object-oriented design, and after experiencing writing them in Elixir, that will be more apparent.
So to sum up:
Finally, yes, there is some code in this repo which predates and violates this rule. That's why this note was added.
Social login stuff really depends on the port that your localhost is running on.
It would be amazing if this was set to 2388.
List of credit cards to use Sandbox control panel
On your local development server, in Spree admin, you need to add a Payment Method in Configuration and provide this information:
Provider : Spree::Gateway::BraintreeGateway
Name : (Choose a descriptive name, like "Braintree Development")
Environment : sandbox
Display : Both
Active : Yes
Merchant ID : Check the .env File
Public Key : Check the .env File
Private Key : Check the .env File
Client SEK : Check the .env File
The merchant ID goes under the "Merchant" field in Solidus. The differance between a Merchant ID and Merchant Account ID can be found in the following Braintree docs
To run the background workers against Amazon SQS:
bundle exec shoryuken -R -C config/shoryuken.yml
There are 4 configured queues for each environment (low, medium, high and urgent), e.g:
The local queues are therefore shared across all developers and job processing may crisscross if multiple developers are running the workers concurrently. Local separation of queues might be possible in the near future.
The config/database.yml was removed from github. In order to have a proper database
file, we can copy the config/database.yml.example file to the config/database.yml file.
We can import the data from Filemaker into our own database in 2 different way.
Both of those import way are achieve via rake tasks.
To import the data directly from Filemaker without any filter whatsoever. The following command can be run
`rake 'filemaker:importer:all_products'`
This will import all the products from Filemaker. Please be aware that this can take a long time since there are over 10 000 products right now into Filemaker.
If you wish to import only a partial amount for testing locally you can add an optional argument to the task
`rake 'filemaker:importer:all_products[10]'`
This would import the first 10 products it finds.
If you wish to simply import specific SKUs of Filemaker, you can create a
{whatever_name}.csv file in the following directory tmp/import/csv/. Within
that file, you must specify one SKU per line. Once that done run the
following command
`rake 'filemaker:importer:all_products_from_csv'`
It will check for every line and do a single query to Filemaker that will
retrieve all the searched products. By default, once it's done it will archive
the file that you have just imported to the tmp/import/csv/archive folder.
That way you know when the file has been parsed correctly and makes it that you
can't run the same file multiple time on a production server.
If you do not wish to archive the file you can run the previous command with an additional parameter.
`rake 'filemaker:importer:all_products_from_csv[false]'`
This will not put the file in the archive folder. This is useful when developing a feature and you have to constantly wipe your database.
Please Note: You can create as many .csv file in that directory and run
the command and it will import every SKU from every file in one time.
Since we do not know how Filemaker processes the images yet. There is a rake task that let's you import image manually.
`rake 'filemaker:importer:import_images'`
It will look at the SKU of the image picture that resides in tmp/import/images
and set the product image accordingly. This process may take a long time since
it upload the image in multiple format to S3.
By default it archives. If you do not which to archive processed images, please set the flag to false
`rake 'filemaker:importer:import_images[false]'`
In order to easily reproduce API calls made from the apps. (Android / IOS) we have setup Postman to easily make to queries.
There are two ways to get Postman here: https://www.getpostman.com/
Backup.postman_dump.json file from the api_queries folder of the projectSome of us also uses PAW. In order to import postman data in PAW, please follow the following URL: https://luckymarmot.com/paw/doc/migrate/postman
General Notes:
Gift Card.gift-card' character are mandatory in order for the command to
run. There are some shells that doesn't not correctly supports argument within a
rake task and having the single quote makes it parse correctly.process_image(base_product, product) from
build_product and build_variant of
/app/domain/importer/product/product_factory.rb.lib/tasks/importer.rake rake task file.Content type
Image
Digest
Size
429.6 MB
Last updated
about 9 years ago
docker pull hollar/hollar-solidus