├── .dockerignore
├── .env.template
├── .github
├── CODEOWNERS
├── PULL_REQUEST_TEMPLATE.md
└── workflows
│ ├── ads-java.yml
│ ├── ads.yml
│ ├── backend.yml
│ ├── dbm.yml
│ ├── discounts.yml
│ ├── frontend.yml
│ ├── nginx.yml
│ ├── postgres.yml
│ └── release.yml
├── .gitignore
├── LICENSE.md
├── README.md
├── docker-compose.yml
├── ecs
├── README.md
├── ecs-cluster.json
├── ecs-infrastructure.json
└── tasks
│ └── storedog-task-definition.json
├── scripts
├── backup-db.sh
└── prepend_db_statements.sql
└── services
├── ads
├── README.md
├── java
│ ├── Dockerfile
│ ├── build.gradle
│ ├── gradle
│ │ └── wrapper
│ │ │ ├── gradle-wrapper.jar
│ │ │ └── gradle-wrapper.properties
│ ├── settings.gradle
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── adsjava
│ │ │ │ └── AdsJavaApplication.java
│ │ └── resources
│ │ │ ├── application.yml
│ │ │ ├── logback-spring.xml
│ │ │ └── static
│ │ │ ├── ads
│ │ │ ├── ad1.jpg
│ │ │ ├── ad2.jpg
│ │ │ └── ad3.jpg
│ │ │ └── banner-list.json
│ │ └── test
│ │ └── java
│ │ └── adsjava
│ │ └── AdsJavaApplicationTests.java
└── python
│ ├── .dockerignore
│ ├── Dockerfile
│ ├── ads.py
│ ├── ads
│ ├── 1.jpg
│ ├── 2.jpg
│ └── 3.jpg
│ ├── bootstrap.py
│ ├── models.py
│ └── requirements.txt
├── backend
├── .nvmrc
├── .rspec
├── .rubocop.yml
├── Dockerfile
├── Gemfile
├── Gemfile.lock
├── README.md
├── Rakefile
├── app.json
├── app
│ ├── assets
│ │ ├── builds
│ │ │ ├── .keep
│ │ │ ├── application.js
│ │ │ ├── application.js.map
│ │ │ ├── spree-dashboard.js
│ │ │ └── spree-dashboard.js.map
│ │ ├── config
│ │ │ └── manifest.js
│ │ ├── images
│ │ │ ├── .keep
│ │ │ └── tshirt1.webp
│ │ └── stylesheets
│ │ │ └── spree
│ │ │ └── frontend
│ │ │ └── variables
│ │ │ └── variables.scss
│ ├── controllers
│ │ ├── application_controller.rb
│ │ └── concerns
│ │ │ └── .keep
│ ├── helpers
│ │ └── application_helper.rb
│ ├── javascript
│ │ ├── application.js
│ │ └── spree-dashboard.js
│ ├── jobs
│ │ ├── application_job.rb
│ │ └── sentry_job.rb
│ ├── mailers
│ │ └── .keep
│ ├── models
│ │ ├── .keep
│ │ ├── application_record.rb
│ │ └── concerns
│ │ │ └── .keep
│ ├── services
│ │ └── .keep
│ └── views
│ │ └── .keep
├── bin
│ ├── bundle
│ ├── dev
│ ├── rails
│ ├── rake
│ ├── render-build.sh
│ ├── setup
│ ├── setup-no-docker
│ ├── spring
│ ├── start
│ ├── update
│ └── wait-for-services
├── config.ru
├── config
│ ├── application.rb
│ ├── aws.rb
│ ├── boot.rb
│ ├── cable.yml
│ ├── database.yml
│ ├── environment.rb
│ ├── environments
│ │ ├── development.rb
│ │ ├── production.rb
│ │ └── test.rb
│ ├── initializers
│ │ ├── active_storage.rb
│ │ ├── application_controller_renderer.rb
│ │ ├── assets.rb
│ │ ├── backtrace_silencers.rb
│ │ ├── content_security_policy.rb
│ │ ├── cookies_serializer.rb
│ │ ├── cors.rb
│ │ ├── datadog-tracer.rb
│ │ ├── devise.rb
│ │ ├── filter_parameter_logging.rb
│ │ ├── inflections.rb
│ │ ├── mime_types.rb
│ │ ├── oj.rb
│ │ ├── raven.rb
│ │ ├── redis.rb
│ │ ├── session_store.rb
│ │ ├── spree.rb
│ │ └── wrap_parameters.rb
│ ├── locales
│ │ └── en.yml
│ ├── puma.rb
│ ├── routes.rb
│ ├── secrets.yml
│ ├── sidekiq.yml
│ ├── spring.rb
│ └── storage.yml
├── db
│ ├── migrate
│ │ ├── 20211203185331_create_active_storage_tables.active_storage.rb
│ │ ├── 20211203185340_create_action_mailbox_tables.action_mailbox.rb
│ │ ├── 20211203185341_create_action_text_tables.action_text.rb
│ │ ├── 20211203185342_spree_four_three.spree.rb
│ │ ├── 20211203185343_add_metadata_to_spree_orders.spree.rb
│ │ ├── 20211203185344_add_metadata_to_spree_products.spree.rb
│ │ ├── 20211203185345_add_metadata_to_spree_variants.spree.rb
│ │ ├── 20211203185346_add_metadata_to_spree_line_items.spree.rb
│ │ ├── 20211203185347_add_metadata_to_spree_shipments.spree.rb
│ │ ├── 20211203185348_add_metadata_to_spree_payments.spree.rb
│ │ ├── 20211203185349_add_metadata_to_spree_taxons_and_taxonomies.spree.rb
│ │ ├── 20211203185350_add_metadata_to_spree_stock_transfers.spree.rb
│ │ ├── 20211203185351_add_metadata_to_spree_multiple_tables.spree.rb
│ │ ├── 20211203185352_add_deleted_at_to_spree_stores.spree.rb
│ │ ├── 20211203185353_rename_column_access_hash_to_token.spree.rb
│ │ ├── 20211203185354_create_spree_wishlists.spree.rb
│ │ ├── 20211203185355_create_spree_wished_products.spree.rb
│ │ ├── 20211203185356_rename_spree_wished_products_to_spree_wished_items.spree.rb
│ │ ├── 20211203185357_add_unique_stock_item_stock_location_variant_deleted_at_index.spree.rb
│ │ ├── 20211203185358_create_stock_item_stock_location_id_variant_id_coalesce_deleted_at_unique_index.spree.rb
│ │ ├── 20211203185359_create_spree_digital_links.spree.rb
│ │ ├── 20211203185360_create_spree_digitals.spree.rb
│ │ ├── 20211203185361_rename_secret_to_token_on_spree_digital_links.spree.rb
│ │ ├── 20211203185362_add_settings_to_spree_stores.spree.rb
│ │ ├── 20211203185363_add_api_key_to_spree_users.spree_api.rb
│ │ ├── 20211203185364_resize_api_key_field.spree_api.rb
│ │ ├── 20211203185365_rename_api_key_to_spree_api_key.spree_api.rb
│ │ ├── 20211203185366_add_index_to_user_spree_api_key.spree_api.rb
│ │ ├── 20211203185367_create_doorkeeper_tables.spree_api.rb
│ │ ├── 20211203185368_change_integer_id_columns_type.spree_api.rb
│ │ ├── 20211203185369_create_spree_webhooks_tables.spree_api.rb
│ │ ├── 20211203185370_enable_polymorphic_resource_owner.spree_api.rb
│ │ ├── 20211203185371_create_spree_webhooks_events.spree_api.rb
│ │ ├── 20211203185372_update_braintree_payment_method_type.spree_gateway.rb
│ │ ├── 20211203185373_update_stripe_payment_method_type.spree_gateway.rb
│ │ ├── 20211203185374_update_balanced_payment_method_type.spree_gateway.rb
│ │ ├── 20211203185375_update_paypal_payment_method_type.spree_gateway.rb
│ │ ├── 20211203185376_migrate_stripe_preferences.spree_gateway.rb
│ │ ├── 20211203185377_add_spree_check_payment_source.spree_gateway.rb
│ │ ├── 20211203185378_add_intent_key_to_payment.spree_gateway.rb
│ │ ├── 20211203185379_create_users.spree_auth.rb
│ │ ├── 20211203185380_rename_columns_for_devise.spree_auth.rb
│ │ ├── 20211203185381_convert_user_remember_field.spree_auth.rb
│ │ ├── 20211203185382_add_reset_password_sent_at_to_spree_users.spree_auth.rb
│ │ ├── 20211203185383_make_users_email_index_unique.spree_auth.rb
│ │ ├── 20211203185384_add_deleted_at_to_users.spree_auth.rb
│ │ ├── 20211203185385_add_confirmable_to_users.spree_auth.rb
│ │ ├── 20211203185386_add_missing_indices_on_user.spree_auth.rb
│ │ └── 20211203185387_change_type_of_ship_address_id_and_bill_address_id_for_spree_users.spree_auth.rb
│ ├── schema.rb
│ ├── seeds.rb
│ └── seeds
│ │ └── 001_spree.rb
├── entrypoint.sh
├── lib
│ ├── assets
│ │ └── .keep
│ ├── cloud_flare_middleware.rb
│ └── tasks
│ │ ├── .keep
│ │ ├── clear_cache.rake
│ │ └── custom_seed.rake
├── package-lock.json
├── package.json
├── public
│ ├── 404.html
│ ├── 422.html
│ ├── 500.html
│ ├── favicon.ico
│ └── robots.txt
├── render.yaml
├── spec
│ ├── rails_helper.rb
│ ├── spec_helper.rb
│ └── support
│ │ └── vcr.rb
├── storage
│ ├── 14
│ │ └── zj
│ │ │ └── 14zj5sb9no7mevm8vtzjcym71vy1
│ ├── 16
│ │ └── 9t
│ │ │ └── 169tp3memt7id57sh22o8ejtcblg
│ ├── 41
│ │ └── wp
│ │ │ └── 41wprtxdhsy40nh2h3igvhpdh982
│ ├── 62
│ │ └── xk
│ │ │ └── 62xky8otdpnd1lm3zr07z7udt2bx
│ ├── 75
│ │ └── n1
│ │ │ └── 75n1re2ozjbz45a88irjss1pu9e6
│ ├── 77
│ │ └── of
│ │ │ └── 77of4hptz6t0rf0gn04v0kqjt4dm
│ ├── 86
│ │ └── fg
│ │ │ └── 86fgtuga925kaa17km9eamshazgr
│ ├── 88
│ │ ├── 44
│ │ │ └── 8844gxgfc9ul1djle5kf8sqmgiyc
│ │ └── he
│ │ │ └── 88hekent0qoefm8b69builrth0xv
│ ├── 89
│ │ └── to
│ │ │ └── 89to0ymiqabe72nctvgrgqzyrk0o
│ ├── 97
│ │ └── xe
│ │ │ └── 97xen0j7t6ketkwt4l8vobq14qq9
│ ├── 00
│ │ └── 6g
│ │ │ └── 006gnisak94ytqimt378gbad2hf9
│ ├── 0i
│ │ └── zg
│ │ │ └── 0izgp4zdrg4bxwvji5e0598oa8mp
│ ├── 0k
│ │ └── 8u
│ │ │ └── 0k8uufd4279o44gzgz5efagsqteu
│ ├── 0r
│ │ ├── 42
│ │ │ └── 0r42dufnbi6rctn4vap71d1urqk9
│ │ └── r1
│ │ │ └── 0rr1qtiq705h498m2e65y04aa1fb
│ ├── 1c
│ │ └── n3
│ │ │ └── 1cn3v98qnmqwts7m6l5xkbhzvffn
│ ├── 1j
│ │ └── z1
│ │ │ └── 1jz13ploviow14epdbc68db9fslw
│ ├── 1k
│ │ └── s2
│ │ │ └── 1ks2veug3cveel5c0eeyaq0m647s
│ ├── 2f
│ │ └── y5
│ │ │ └── 2fy5a3t0idckqt117wqp88l1haj8
│ ├── 2o
│ │ └── or
│ │ │ └── 2ooru1xgcss6d2qeg4iwmjjgz2c9
│ ├── 2q
│ │ └── zh
│ │ │ └── 2qzh6w5ugc805s50nivs2k1xxfvi
│ ├── 3l
│ │ └── sq
│ │ │ └── 3lsqhzqyca5o90l7ek5lcic5ge8z
│ ├── 3o
│ │ └── i8
│ │ │ └── 3oi8wwgyay2a5vsted2felpry3yw
│ ├── 3p
│ │ └── nu
│ │ │ └── 3pnujzkcnksw26a0cu1vtyp1uviz
│ ├── 5b
│ │ └── ea
│ │ │ └── 5beayoc679qsbk1udyydvujp3tuv
│ ├── 6f
│ │ └── 85
│ │ │ └── 6f852pkntrw16c0w9wzpdx2rnmud
│ ├── 6m
│ │ └── b7
│ │ │ └── 6mb7uh60to9dg7fvpjljjmqdnyfw
│ ├── 7u
│ │ └── pj
│ │ │ └── 7upjjhp3sbp38un5ii23l5bm1tf8
│ ├── 7v
│ │ └── xz
│ │ │ └── 7vxzmrg3zgfub67kf82hb5vifqzu
│ ├── 8c
│ │ └── kn
│ │ │ └── 8cknyjfznqw5id8jzny40hewyyrm
│ ├── 8d
│ │ └── rw
│ │ │ └── 8drwmhakoag0ra8a1myjdr80mt57
│ ├── 8i
│ │ └── vj
│ │ │ └── 8ivjybuoo1jtnknvptho0ia2ysvl
│ ├── 9l
│ │ ├── c4
│ │ │ └── 9lc4lfmxvou7mvwqsl8g2fm27wfm
│ │ └── ev
│ │ │ └── 9levi783acolroehz6wn0cm0mzwa
│ ├── az
│ │ └── ws
│ │ │ └── azwswza6kecyh2bmfnlpr7besvvb
│ ├── b0
│ │ ├── 72
│ │ │ └── b0726xe61gdgxgmjki58njnwsivr
│ │ └── 95
│ │ │ └── b095fsshrfwmoexn8czq2m3aiqbe
│ ├── b5
│ │ └── 31
│ │ │ └── b531yunrur87esye2s4cwavym6te
│ ├── bb
│ │ ├── 45
│ │ │ └── bb45cs77n8gzn4ps91exl1cxuyft
│ │ └── xn
│ │ │ └── bbxn5vhfqpqdykae8z2cdf5x3dgs
│ ├── bf
│ │ └── kg
│ │ │ └── bfkgrq99dea00vq7i74ludx4q31l
│ ├── bl
│ │ └── xp
│ │ │ └── blxpqifldxzmb0nby4czkfn4u9q6
│ ├── bp
│ │ └── 08
│ │ │ └── bp08j2pskt6xgz9ah0714mqdjwz7
│ ├── bz
│ │ └── 2a
│ │ │ └── bz2awto4gfx6t6udd7k5gjvke8i7
│ ├── c9
│ │ └── cj
│ │ │ └── c9cjtgt3p7hdujcaxt41t08u1kux
│ ├── cb
│ │ └── kx
│ │ │ └── cbkxlh6px78ymmakilgwygcm0qn5
│ ├── cj
│ │ └── 1d
│ │ │ └── cj1dxfmw44hktr8lhbwzpw7aoxz5
│ ├── d7
│ │ └── k8
│ │ │ └── d7k8l52o2ji9tkor07sqd25wpxdk
│ ├── db
│ │ └── ag
│ │ │ └── dbagqumqgq1z6319o338j7bmt5pq
│ ├── dq
│ │ └── c7
│ │ │ └── dqc7t23uxsm5axhesoap039wqjeb
│ ├── e3
│ │ └── lt
│ │ │ └── e3ltmq2g8mfvj4wifyzt7uj3w5ns
│ ├── eb
│ │ └── 2a
│ │ │ └── eb2a2zd73ok9x0rlw0o164mduamd
│ ├── f1
│ │ ├── 6r
│ │ │ └── f16rwfhvanpxrwgn2ct48cgfp326
│ │ └── f6
│ │ │ └── f1f6rz6nuf57ryix259yxq7j3tje
│ ├── f3
│ │ └── dt
│ │ │ └── f3dtrvou5azxky00y68u7qbjgaqn
│ ├── f5
│ │ └── xr
│ │ │ └── f5xr4qy5dtulhpe8kgazjo2x7ubz
│ ├── f7
│ │ └── tg
│ │ │ └── f7tg9iqtd0i6tqxzkf15010kl9xq
│ ├── fj
│ │ └── gx
│ │ │ └── fjgxeszqvcbrc0v0u2n7i70yd956
│ ├── fk
│ │ └── 0o
│ │ │ └── fk0o9nsutjpswot205kna7pdoj02
│ ├── fs
│ │ └── ip
│ │ │ └── fsipi7gdrjs2mxhgop0etbuwsfu2
│ ├── fy
│ │ └── au
│ │ │ └── fyau0gplpld5a6c12gvncp18ravq
│ ├── gq
│ │ └── x4
│ │ │ └── gqx496zj9ao0ce2y69s8ebcdt76c
│ ├── gs
│ │ └── 1o
│ │ │ └── gs1oqg4v74c76h2f8zsqj0p91yjc
│ ├── h3
│ │ └── um
│ │ │ └── h3ump7vjqudll390ky1rdss0xdb4
│ ├── h8
│ │ └── 3c
│ │ │ └── h83cdk6x8kd1amwvte8aavqnxii3
│ ├── hm
│ │ └── nd
│ │ │ └── hmndfefa02esgzpaqksemkf51q88
│ ├── hp
│ │ └── sk
│ │ │ └── hpskdx8sfybt0o39s4e2veuqv6nd
│ ├── hv
│ │ └── lm
│ │ │ └── hvlm8gb3nktx69eteqqt7atj9qrs
│ ├── ir
│ │ └── 5t
│ │ │ └── ir5thn1x7rn9legliqvjh23qg1bl
│ ├── j4
│ │ └── j2
│ │ │ └── j4j2wb67ekv1hle6t5z2aq19gstf
│ ├── jl
│ │ └── mg
│ │ │ └── jlmgno906bkhwsytjqiyns2hqut8
│ ├── jo
│ │ └── ru
│ │ │ └── joru4prw3skdtc8i4ia5dwq5874k
│ ├── jr
│ │ └── qt
│ │ │ └── jrqti00rfi88kdgvjnw4s0tdv7xc
│ ├── k7
│ │ └── hr
│ │ │ └── k7hrw0msrvsspxi698amx5kmh2wg
│ ├── kr
│ │ └── u2
│ │ │ └── kru2kfqkml3mwkuhmc2w0uvtp4x1
│ ├── kw
│ │ └── ch
│ │ │ └── kwchc38i5j2uqyrfui13h914doju
│ ├── l0
│ │ └── id
│ │ │ └── l0idqd59oxu5iz00z9m3iep48pjm
│ ├── l8
│ │ └── 1g
│ │ │ └── l81gft3rnuphlp36xw4q33p4r1cs
│ ├── lp
│ │ └── lr
│ │ │ └── lplrh3v056du1izagk5o76sfu98p
│ ├── lt
│ │ └── mc
│ │ │ └── ltmc7z2yt5ozwpuqmoz2uw98xylf
│ ├── m6
│ │ └── sb
│ │ │ └── m6sbj199y5b8id0eg6dvktm1nbyu
│ ├── ms
│ │ └── m8
│ │ │ └── msm81dgmxk4ggqiud2bv4j9waoie
│ ├── n1
│ │ └── m4
│ │ │ └── n1m4ol3mo2fbg77imv5qn156swi4
│ ├── n8
│ │ └── aa
│ │ │ └── n8aao8d8v8ene7vn4d14zdqxntna
│ ├── nd
│ │ └── mb
│ │ │ └── ndmbmj2or9w5lgnwmyyexp34n509
│ ├── ni
│ │ └── yw
│ │ │ └── niywd6phcjdfuxw97lxi1y8t1sya
│ ├── nx
│ │ └── 9d
│ │ │ └── nx9dapm2zhd2kh991ompea29775m
│ ├── o5
│ │ └── d9
│ │ │ └── o5d9h8s1hih1gihezeeu73fgwa88
│ ├── o7
│ │ └── 2a
│ │ │ └── o72a5s5ye01ie6mtx8h7olnldvko
│ ├── oi
│ │ └── fp
│ │ │ └── oifpdmfenjck5p39s91m8ij5ya5a
│ ├── op
│ │ └── a2
│ │ │ └── opa2g8bl3tpm0ecip3f4yun9hcd8
│ ├── os
│ │ └── vh
│ │ │ └── osvherjecbdx3ezy3jvar6vvfwrk
│ ├── ox
│ │ └── 4i
│ │ │ └── ox4iruasiwuftdu71u98l5t4rpgm
│ ├── p7
│ │ └── d5
│ │ │ └── p7d5guboq24b265ytl0u5w20hzjl
│ ├── p8
│ │ └── 0j
│ │ │ └── p80jyh6ws8gqmfrp8kcjcgctdieh
│ ├── pi
│ │ └── co
│ │ │ └── picolufbbcsybadgh89nutlhun53
│ ├── pk
│ │ └── 18
│ │ │ └── pk18k7l7xvz7fcz9ecz20m01mbg1
│ ├── q5
│ │ └── 90
│ │ │ └── q590wag6b1vszjszc3mfd23192sj
│ ├── q8
│ │ └── 69
│ │ │ └── q869nghoropy7vm31r30cgs85x0d
│ ├── r0
│ │ └── l3
│ │ │ └── r0l3vmf800tdhnaha8ipdutspb1e
│ ├── rc
│ │ └── p1
│ │ │ └── rcp1c0ffcrahrxl6ddwdj502lrzh
│ ├── rp
│ │ └── 62
│ │ │ └── rp62efuo0c81qrdzczbw9vbu1eih
│ ├── rw
│ │ └── st
│ │ │ └── rwst4dkl9wdsmq13w2fwj04ha284
│ ├── rx
│ │ └── 4i
│ │ │ └── rx4ig9xw7h5y1y2sqqmawsq1x17p
│ ├── ss
│ │ └── kb
│ │ │ └── sskbwu2e4lqf6vdd9po2ozhnfm6d
│ ├── t2
│ │ └── gb
│ │ │ └── t2gbiuwefu2cu69nx6ef7mxvlkyf
│ ├── t8
│ │ └── sf
│ │ │ └── t8sfq5w9vte2byg1ql3vrf6erjz6
│ ├── ta
│ │ └── su
│ │ │ └── tasu842mlz829y8ps7va67ttq7my
│ ├── tc
│ │ └── uy
│ │ │ └── tcuywtfa5bo7iswkbmocinkv4obn
│ ├── tq
│ │ └── 3q
│ │ │ └── tq3q5lsbdzh1hfwfto2ub0dwuuul
│ ├── u5
│ │ └── m8
│ │ │ └── u5m8nx87ih2y01eoc5y0og5exoga
│ ├── un
│ │ └── 6x
│ │ │ └── un6xvbm6l3ecxwxwuxffc6b6pksy
│ ├── v2
│ │ └── d6
│ │ │ └── v2d6kiibpmi2n5wei0zvfmgcrcp6
│ ├── vd
│ │ └── hf
│ │ │ └── vdhfjqfz88rsidepmoygmvmzuory
│ ├── vk
│ │ ├── 66
│ │ │ └── vk66376ys3oh94khxr2gyaqe718p
│ │ └── qt
│ │ │ └── vkqtro308bcx9nauolzjgfsdjiaj
│ ├── vn
│ │ └── 91
│ │ │ └── vn912gigj022zdj21b018id2vb0h
│ ├── w7
│ │ └── h1
│ │ │ └── w7h15x1uh9994su68lm16er6p8fj
│ ├── wp
│ │ └── ik
│ │ │ └── wpik6q4kgdlnd8zy9vxfayze9bxl
│ ├── wt
│ │ └── zf
│ │ │ └── wtzfa794b5vpax1qrbegb7xnioi2
│ ├── x0
│ │ └── j5
│ │ │ └── x0j50n6qwk4g0p72hy9h9gmz9l41
│ ├── xp
│ │ └── 7a
│ │ │ └── xp7a6l2hhtrp4ow3oo2e8ozqzuz1
│ ├── yu
│ │ └── 65
│ │ │ └── yu65ul5ekff3gdub9ot599wbqq5t
│ ├── z8
│ │ └── lp
│ │ │ └── z8lp9oe5quoqzkewjtvj14rubeg0
│ └── zi
│ │ └── ae
│ │ └── ziae3tzvaen6pm7pdzsya7rv46l3
└── vendor
│ └── assets
│ ├── javascripts
│ ├── .keep
│ └── spree
│ │ ├── backend
│ │ └── all.js
│ │ └── frontend
│ │ └── all.js
│ └── stylesheets
│ ├── .keep
│ └── spree
│ ├── backend
│ └── all.css
│ └── frontend
│ └── all.css
├── datadog-agent
└── postgres
│ └── dd-agent-conf.yaml
├── dbm
├── .dockerignore
├── Dockerfile
├── README.md
├── bootstrap.py
├── dbm.py
├── dbm_exec.sh
├── dbm_setup.sql
├── models.py
└── requirements.txt
├── discounts
├── .dockerignore
├── Dockerfile
├── README.md
├── bootstrap.py
├── discounts.py
├── models.py
├── requirements.txt
├── test.py
├── words.json
└── words.py
├── frontend
├── .eslintrc
├── .gitignore
├── .prettierignore
├── .prettierrc
├── Dockerfile
├── README.md
├── assets
│ ├── base.css
│ ├── chrome-bug.css
│ ├── components.css
│ └── main.css
├── components
│ ├── ErrorBoundary.tsx
│ ├── cart
│ │ ├── CartItem
│ │ │ ├── CartItem.module.css
│ │ │ ├── CartItem.tsx
│ │ │ └── index.ts
│ │ ├── CartSidebarView
│ │ │ ├── CartSidebarView.module.css
│ │ │ ├── CartSidebarView.tsx
│ │ │ └── index.ts
│ │ └── index.ts
│ ├── checkout
│ │ ├── CheckoutSidebarView
│ │ │ ├── CheckoutSidebarView.module.css
│ │ │ ├── CheckoutSidebarView.tsx
│ │ │ └── index.ts
│ │ ├── OrderConfirmView
│ │ │ ├── OrderConfirmView.module.css
│ │ │ ├── OrderConfirmView.tsx
│ │ │ └── index.ts
│ │ ├── PaymentMethodView
│ │ │ ├── PaymentMethodView.module.css
│ │ │ ├── PaymentMethodView.tsx
│ │ │ └── index.ts
│ │ ├── PaymentWidget
│ │ │ ├── PaymentWidget.module.css
│ │ │ ├── PaymentWidget.tsx
│ │ │ └── index.ts
│ │ ├── ShippingView
│ │ │ ├── ShippingView.module.css
│ │ │ ├── ShippingView.tsx
│ │ │ └── index.ts
│ │ ├── ShippingWidget
│ │ │ ├── ShippingWidget.module.css
│ │ │ ├── ShippingWidget.tsx
│ │ │ └── index.ts
│ │ └── context.tsx
│ ├── common
│ │ ├── Ad
│ │ │ ├── Ad.tsx
│ │ │ └── index.ts
│ │ ├── Avatar
│ │ │ ├── Avatar.tsx
│ │ │ └── index.ts
│ │ ├── Discount
│ │ │ ├── Discount.tsx
│ │ │ └── index.ts
│ │ ├── FeatureBar
│ │ │ ├── FeatureBar.module.css
│ │ │ ├── FeatureBar.tsx
│ │ │ └── index.ts
│ │ ├── Footer
│ │ │ ├── Footer.module.css
│ │ │ ├── Footer.tsx
│ │ │ └── index.ts
│ │ ├── Head
│ │ │ ├── Head.tsx
│ │ │ └── index.ts
│ │ ├── HomeAllProductsGrid
│ │ │ ├── HomeAllProductsGrid.module.css
│ │ │ ├── HomeAllProductsGrid.tsx
│ │ │ └── index.ts
│ │ ├── Layout
│ │ │ ├── Layout.module.css
│ │ │ ├── Layout.tsx
│ │ │ └── index.ts
│ │ ├── Navbar
│ │ │ ├── Navbar.module.css
│ │ │ ├── Navbar.tsx
│ │ │ ├── NavbarRoot.tsx
│ │ │ └── index.ts
│ │ ├── SEO
│ │ │ ├── SEO.tsx
│ │ │ └── index.ts
│ │ ├── Searchbar
│ │ │ ├── Searchbar.module.css
│ │ │ ├── Searchbar.tsx
│ │ │ └── index.ts
│ │ ├── SidebarLayout
│ │ │ ├── SidebarLayout.module.css
│ │ │ ├── SidebarLayout.tsx
│ │ │ └── index.ts
│ │ ├── UserNav
│ │ │ ├── MenuSidebarView
│ │ │ │ ├── MenuSidebarView.module.css
│ │ │ │ ├── MenuSidebarView.tsx
│ │ │ │ └── index.ts
│ │ │ ├── UserNav.module.css
│ │ │ ├── UserNav.tsx
│ │ │ └── index.ts
│ │ └── index.ts
│ ├── icons
│ │ ├── ArrowLeft.tsx
│ │ ├── ArrowRight.tsx
│ │ ├── Bag.tsx
│ │ ├── Check.tsx
│ │ ├── ChevronDown.tsx
│ │ ├── ChevronLeft.tsx
│ │ ├── ChevronRight.tsx
│ │ ├── ChevronUp.tsx
│ │ ├── CreditCard.tsx
│ │ ├── Cross.tsx
│ │ ├── DoubleChevron.tsx
│ │ ├── Github.tsx
│ │ ├── Heart.tsx
│ │ ├── Info.tsx
│ │ ├── MapPin.tsx
│ │ ├── Menu.tsx
│ │ ├── Minus.tsx
│ │ ├── Moon.tsx
│ │ ├── Plus.tsx
│ │ ├── Star.tsx
│ │ ├── Sun.tsx
│ │ ├── Trash.tsx
│ │ ├── Vercel.tsx
│ │ └── index.ts
│ ├── product
│ │ ├── ProductCard
│ │ │ ├── ProductCard-v2.tsx
│ │ │ ├── ProductCard.module.css
│ │ │ ├── ProductCard.tsx
│ │ │ └── index.ts
│ │ ├── ProductList.tsx
│ │ ├── ProductOptions
│ │ │ ├── ProductOptions.tsx
│ │ │ └── index.ts
│ │ ├── ProductSidebar
│ │ │ ├── ProductSidebar.module.css
│ │ │ ├── ProductSidebar.tsx
│ │ │ └── index.ts
│ │ ├── ProductSlider
│ │ │ ├── ProductSlider.module.css
│ │ │ ├── ProductSlider.tsx
│ │ │ └── index.ts
│ │ ├── ProductSliderControl
│ │ │ ├── ProductSliderControl.module.css
│ │ │ ├── ProductSliderControl.tsx
│ │ │ └── index.ts
│ │ ├── ProductTag
│ │ │ ├── ProductTag.module.css
│ │ │ ├── ProductTag.tsx
│ │ │ └── index.ts
│ │ ├── ProductView
│ │ │ ├── ProductView.module.css
│ │ │ ├── ProductView.tsx
│ │ │ └── index.ts
│ │ ├── Swatch
│ │ │ ├── Swatch.module.css
│ │ │ ├── Swatch.tsx
│ │ │ └── index.ts
│ │ ├── helpers.ts
│ │ └── index.ts
│ └── ui
│ │ ├── Button
│ │ ├── Button.module.css
│ │ ├── Button.tsx
│ │ └── index.ts
│ │ ├── Collapse
│ │ ├── Collapse.module.css
│ │ ├── Collapse.tsx
│ │ └── index.ts
│ │ ├── Container
│ │ ├── Container.tsx
│ │ └── index.ts
│ │ ├── Dropdown
│ │ ├── Dropdown.module.css
│ │ └── Dropdown.tsx
│ │ ├── Grid
│ │ ├── Grid.module.css
│ │ ├── Grid.tsx
│ │ └── index.ts
│ │ ├── Hero
│ │ ├── Hero.module.css
│ │ ├── Hero.tsx
│ │ └── index.ts
│ │ ├── Input
│ │ ├── Input.module.css
│ │ ├── Input.tsx
│ │ └── index.ts
│ │ ├── Link
│ │ ├── Link.tsx
│ │ └── index.ts
│ │ ├── LoadingDots
│ │ ├── LoadingDots.module.css
│ │ ├── LoadingDots.tsx
│ │ └── index.ts
│ │ ├── Logo
│ │ ├── Logo.tsx
│ │ └── index.ts
│ │ ├── Marquee
│ │ ├── Marquee.module.css
│ │ ├── Marquee.tsx
│ │ └── index.ts
│ │ ├── Modal
│ │ ├── Modal.module.css
│ │ ├── Modal.tsx
│ │ └── index.ts
│ │ ├── Quantity
│ │ ├── Quantity.module.css
│ │ ├── Quantity.tsx
│ │ └── index.ts
│ │ ├── README.md
│ │ ├── Rating
│ │ ├── Rating.module.css
│ │ ├── Rating.tsx
│ │ └── index.ts
│ │ ├── Sidebar
│ │ ├── Sidebar.module.css
│ │ ├── Sidebar.tsx
│ │ └── index.ts
│ │ ├── Skeleton
│ │ ├── Skeleton.module.css
│ │ ├── Skeleton.tsx
│ │ └── index.ts
│ │ ├── Text
│ │ ├── Text.module.css
│ │ ├── Text.tsx
│ │ └── index.ts
│ │ ├── context.tsx
│ │ └── index.ts
├── config
│ ├── country_iso_codes.json
│ ├── seo_meta.json
│ └── user_data.json
├── featureFlags.config.json
├── global.d.ts
├── lib
│ ├── CartContext.tsx
│ ├── api
│ │ ├── cart.ts
│ │ ├── checkout.ts
│ │ ├── pages.ts
│ │ ├── products.ts
│ │ └── taxons.ts
│ ├── colors.ts
│ ├── focus-trap.tsx
│ ├── hooks
│ │ ├── usePrice.tsx
│ │ └── useUserAvatar.ts
│ ├── range-map.ts
│ └── to-pixels.ts
├── next-env.d.ts
├── next-logger.config.js
├── next.config.js
├── package-lock.json
├── package.json
├── pages
│ ├── 404.tsx
│ ├── [...pages].tsx
│ ├── _app.tsx
│ ├── _document.tsx
│ ├── api
│ │ ├── pages
│ │ │ ├── [slug].ts
│ │ │ └── index.ts
│ │ ├── products
│ │ │ ├── [slug].ts
│ │ │ └── index.ts
│ │ └── taxonomies
│ │ │ ├── [taxonomy]
│ │ │ ├── [slug].ts
│ │ │ └── index.ts
│ │ │ └── index.ts
│ ├── index.tsx
│ ├── products
│ │ ├── [slug].tsx
│ │ └── index.tsx
│ └── taxonomies
│ │ └── [taxonomy]
│ │ ├── [...slug].tsx
│ │ └── index.tsx
├── postcss.config.js
├── public
│ ├── assets
│ │ ├── drop-shirt-0.png
│ │ ├── drop-shirt-1.png
│ │ ├── drop-shirt-2.png
│ │ ├── drop-shirt.png
│ │ ├── lightweight-jacket-0.png
│ │ ├── lightweight-jacket-1.png
│ │ ├── lightweight-jacket-2.png
│ │ ├── t-shirt-0.png
│ │ ├── t-shirt-1.png
│ │ ├── t-shirt-2.png
│ │ ├── t-shirt-3.png
│ │ └── t-shirt-4.png
│ ├── bg-products.svg
│ ├── card.png
│ ├── cursor-left.png
│ ├── cursor-right.png
│ ├── favicon-32x32.png
│ ├── favicon.ico
│ ├── flag-en-us.svg
│ ├── flag-es-ar.svg
│ ├── flag-es-co.svg
│ ├── flag-es.svg
│ ├── icon-144x144.png
│ ├── icon-192x192.png
│ ├── icon-512x512.png
│ ├── icon.png
│ ├── product-img-placeholder.svg
│ ├── site.webmanifest
│ ├── slider-arrows.png
│ └── vercel.svg
├── tailwind.config.js
├── tsconfig.json
└── types
│ ├── cart.ts
│ ├── checkout.ts
│ ├── page.ts
│ ├── product.ts
│ └── taxons.ts
├── nginx
├── Dockerfile
├── default.conf
├── nginx.conf
└── status.conf
├── postgres
├── Dockerfile
├── db
│ └── restore.sql
├── postgresql.conf
└── scripts
│ ├── cleanup-cron
│ └── start-services.sh
├── puppeteer
├── Dockerfile
└── scripts
│ ├── puppeteer.js
│ └── puppeteer.sh
└── worker
└── config
└── initializers
└── datadog-tracer.rb
/.dockerignore:
--------------------------------------------------------------------------------
1 | tmp/*
2 | log/*
3 | .git
4 | node_modules
5 | coverage
6 |
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # These owners will be the default owners for everything in
2 | # the repo. Any future lines will overwrite this default. The last pattern
3 | # that matches, will be the final pattern.
4 | # See https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners
5 |
6 | * @DataDog/training @DataDog/corpweb
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ## Description
2 |
3 |
4 | ## How to test
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.github/workflows/ads-java.yml:
--------------------------------------------------------------------------------
1 | name: Ads - Java
2 |
3 | permissions: {}
4 |
5 | on:
6 | push:
7 | branches: [ main ]
8 | paths:
9 | - services/ads/java/**
10 | workflow_dispatch:
11 |
12 | defaults:
13 | run:
14 | working-directory: ads
15 |
16 | jobs:
17 |
18 | build:
19 |
20 | runs-on: ubuntu-latest
21 | permissions:
22 | packages: write
23 | contents: read
24 |
25 | steps:
26 | - name: Checkout
27 | uses: actions/checkout@v4
28 |
29 | - name: Set up Docker Buildx
30 | uses: docker/setup-buildx-action@v3
31 |
32 | - name: Login to GHCR
33 | id: login-ghcr
34 | uses: docker/login-action@v3
35 | with:
36 | registry: ghcr.io
37 | username: ${{ github.actor }}
38 | password: ${{ secrets.GITHUB_TOKEN }}
39 |
40 | - name: Build and push
41 | uses: docker/build-push-action@v5
42 | with:
43 | context: ./services/ads/java
44 | platforms: linux/amd64,linux/arm64
45 | push: true
46 | tags: ghcr.io/datadog/storedog/ads-java:latest
47 |
48 |
--------------------------------------------------------------------------------
/.github/workflows/ads.yml:
--------------------------------------------------------------------------------
1 | name: Ads - Python
2 |
3 | permissions: {}
4 |
5 | on:
6 | push:
7 | branches: [ main ]
8 | paths:
9 | - services/ads/python/**
10 | workflow_dispatch:
11 |
12 | defaults:
13 | run:
14 | working-directory: ads
15 |
16 | jobs:
17 |
18 | build:
19 |
20 | runs-on: ubuntu-latest
21 | permissions:
22 | packages: write
23 | contents: read
24 |
25 | steps:
26 | - name: Checkout
27 | uses: actions/checkout@v4
28 |
29 | - name: Set up Docker Buildx
30 | uses: docker/setup-buildx-action@v3
31 |
32 | - name: Login to GHCR
33 | id: login-ghcr
34 | uses: docker/login-action@v3
35 | with:
36 | registry: ghcr.io
37 | username: ${{ github.actor }}
38 | password: ${{ secrets.GITHUB_TOKEN }}
39 |
40 | - name: Build and push
41 | uses: docker/build-push-action@v5
42 | with:
43 | context: ./services/ads/python
44 | platforms: linux/amd64,linux/arm64
45 | push: true
46 | tags: ghcr.io/datadog/storedog/ads:latest
47 |
48 |
--------------------------------------------------------------------------------
/.github/workflows/backend.yml:
--------------------------------------------------------------------------------
1 | name: Backend
2 |
3 | permissions: {}
4 |
5 | on:
6 | push:
7 | branches: [ main ]
8 | paths:
9 | - services/backend/**
10 | workflow_dispatch:
11 |
12 | defaults:
13 | run:
14 | working-directory: backend
15 |
16 | jobs:
17 |
18 | build:
19 |
20 | runs-on: ubuntu-latest
21 | permissions:
22 | packages: write
23 | contents: read
24 |
25 | steps:
26 | - name: Checkout
27 | uses: actions/checkout@v4
28 |
29 | - name: Set up Docker Buildx
30 | uses: docker/setup-buildx-action@v3
31 |
32 | - name: Login to GHCR
33 | id: login-ghcr
34 | uses: docker/login-action@v3
35 | with:
36 | registry: ghcr.io
37 | username: ${{ github.actor }}
38 | password: ${{ secrets.GITHUB_TOKEN }}
39 |
40 | - name: Build and push
41 | uses: docker/build-push-action@v5
42 | with:
43 | context: ./services/backend
44 | platforms: linux/amd64,linux/arm64
45 | push: true
46 | tags: ghcr.io/datadog/storedog/backend:latest
47 |
48 |
--------------------------------------------------------------------------------
/.github/workflows/dbm.yml:
--------------------------------------------------------------------------------
1 | name: DBM
2 |
3 | permissions: {}
4 |
5 | on:
6 | push:
7 | branches: [ main ]
8 | paths:
9 | - services/dbm/**
10 | workflow_dispatch:
11 |
12 | defaults:
13 | run:
14 | working-directory: dbm
15 |
16 |
17 | jobs:
18 |
19 | build:
20 |
21 | runs-on: ubuntu-latest
22 | permissions:
23 | packages: write
24 | contents: read
25 |
26 | steps:
27 | - name: Checkout
28 | uses: actions/checkout@v4
29 |
30 | - name: Set up Docker Buildx
31 | uses: docker/setup-buildx-action@v3
32 |
33 | - name: Login to GHCR
34 | id: login-ghcr
35 | uses: docker/login-action@v3
36 | with:
37 | registry: ghcr.io
38 | username: ${{ github.actor }}
39 | password: ${{ secrets.GITHUB_TOKEN }}
40 |
41 | - name: Build and push
42 | uses: docker/build-push-action@v5
43 | with:
44 | context: ./services/dbm
45 | platforms: linux/amd64,linux/arm64
46 | push: true
47 | tags: ghcr.io/datadog/storedog/dbm:latest
48 |
49 |
--------------------------------------------------------------------------------
/.github/workflows/discounts.yml:
--------------------------------------------------------------------------------
1 | name: Discounts
2 |
3 | permissions: {}
4 |
5 | on:
6 | push:
7 | branches: [ main ]
8 | paths:
9 | - services/discounts/**
10 | workflow_dispatch:
11 |
12 | defaults:
13 | run:
14 | working-directory: discounts
15 |
16 | jobs:
17 |
18 | build:
19 |
20 | runs-on: ubuntu-latest
21 | permissions:
22 | packages: write
23 | contents: read
24 |
25 | steps:
26 | - name: Checkout
27 | uses: actions/checkout@v4
28 |
29 | - name: Set up Docker Buildx
30 | uses: docker/setup-buildx-action@v3
31 |
32 | - name: Login to GHCR
33 | id: login-ghcr
34 | uses: docker/login-action@v3
35 | with:
36 | registry: ghcr.io
37 | username: ${{ github.actor }}
38 | password: ${{ secrets.GITHUB_TOKEN }}
39 |
40 | - name: Build and push
41 | uses: docker/build-push-action@v5
42 | with:
43 | context: ./services/discounts
44 | platforms: linux/amd64,linux/arm64
45 | push: true
46 | tags: ghcr.io/datadog/storedog/discounts:latest
47 |
--------------------------------------------------------------------------------
/.github/workflows/frontend.yml:
--------------------------------------------------------------------------------
1 | name: Frontend
2 |
3 | permissions: {}
4 |
5 | on:
6 | push:
7 | branches: [ main ]
8 | paths:
9 | - services/frontend/**
10 | workflow_dispatch:
11 |
12 | defaults:
13 | run:
14 | working-directory: frontend
15 |
16 | jobs:
17 |
18 | build:
19 |
20 | runs-on: ubuntu-latest
21 | permissions:
22 | packages: write
23 | contents: read
24 |
25 | steps:
26 | - name: Checkout
27 | uses: actions/checkout@v3
28 |
29 | - name: Set up Docker Buildx
30 | uses: docker/setup-buildx-action@v3
31 |
32 | - name: Login to GHCR
33 | id: login-ghcr
34 | uses: docker/login-action@v3
35 | with:
36 | registry: ghcr.io
37 | username: ${{ github.actor }}
38 | password: ${{ secrets.GITHUB_TOKEN }}
39 |
40 | - name: Build and push
41 | uses: docker/build-push-action@v5
42 | with:
43 | context: ./services/frontend
44 | platforms: linux/arm64, linux/amd64
45 | push: true
46 | tags: ghcr.io/datadog/storedog/frontend:latest
47 |
48 |
--------------------------------------------------------------------------------
/ecs/README.md:
--------------------------------------------------------------------------------
1 | ## Description
2 |
3 | > [!NOTE] This is a work in progress. The contents of this directory need to be updated to reflect the latest changes in the Storedog app.
4 |
5 | This directory holds the infrastrucutre templates to run Storedog on AWS ECS via EC2. EC2 is the preferred hosting engine due to the `bridge` network mode, which is not available in Fargate. This allows our containers to inter-communicate.
6 |
7 | The memory and CPU settings defined in the `storedog-task-definition.json` assume you are running at least one `m3.xlarge` instance. Note that these settings have not yet been optimized so there is an opportunity to downsize.
--------------------------------------------------------------------------------
/scripts/backup-db.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | # exec dump on postgres container
4 |
5 | # get root of repository
6 | root=$(git rev-parse --show-toplevel)
7 | prependstatements=$root/scripts/prepend_db_statements.sql
8 | destination=$root/services/postgres/db/restore.sql
9 |
10 | # remove old backups in the restore folder
11 | rm -f $root/services/postgres/db/*.sql
12 |
13 | # exec dump
14 | docker compose exec postgres pg_dump -U postgres storedog_db > $destination
15 |
16 | echo "Backup created at $destination"
17 |
18 | # prepend statements to the dump
19 | cat $prependstatements $destination > $destination.tmp
20 | mv $destination.tmp $destination
21 |
--------------------------------------------------------------------------------
/services/ads/java/Dockerfile:
--------------------------------------------------------------------------------
1 | # compile via gradle
2 | FROM gradle:jdk11 AS TEMP_BUILD_IMAGE
3 | ENV APP_HOME=/usr/app/
4 | WORKDIR $APP_HOME
5 | COPY build.gradle settings.gradle $APP_HOME
6 |
7 | COPY gradle $APP_HOME/gradle
8 | COPY --chown=gradle:gradle . /home/gradle/src
9 | USER root
10 | RUN chown -R gradle /home/gradle/src
11 |
12 | COPY . .
13 | RUN gradle clean build
14 |
15 | # app container
16 | FROM alpine:latest
17 | RUN apk --update add openjdk11-jre
18 | ENV ARTIFACT_NAME=ads-java-0.0.1-SNAPSHOT.jar
19 | ENV APP_HOME=/usr/app/
20 | ENV ADS_SERVER_PORT=3030
21 |
22 | WORKDIR $APP_HOME
23 | COPY --from=TEMP_BUILD_IMAGE $APP_HOME/build/libs/$ARTIFACT_NAME .
24 |
25 | RUN wget -O dd-java-agent.jar 'https://dtdg.co/latest-java-tracer'
26 |
27 | ENTRYPOINT exec java -javaagent:/usr/app/dd-java-agent.jar -jar ${ARTIFACT_NAME}
--------------------------------------------------------------------------------
/services/ads/java/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'org.springframework.boot' version '2.7.5'
3 | id 'io.spring.dependency-management' version '1.0.15.RELEASE'
4 | id 'java'
5 | }
6 |
7 | group = 'com.example'
8 | version = '0.0.1-SNAPSHOT'
9 | sourceCompatibility = '11'
10 |
11 | repositories {
12 | mavenCentral()
13 | }
14 |
15 | dependencies {
16 | implementation (
17 | 'commons-io:commons-io:2.4',
18 | 'org.springframework.boot:spring-boot-starter-web'
19 | )
20 | implementation 'com.fasterxml.jackson.core:jackson-databind:2.15.2'
21 | implementation 'net.logstash.logback:logstash-logback-encoder:7.0'
22 | testImplementation 'org.springframework.boot:spring-boot-starter-test'
23 | }
24 |
25 | tasks.named('test') {
26 | useJUnitPlatform()
27 | }
28 |
--------------------------------------------------------------------------------
/services/ads/java/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/ads/java/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/services/ads/java/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/services/ads/java/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'ads-java'
2 |
--------------------------------------------------------------------------------
/services/ads/java/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | server:
2 | port: ${ADS_SERVER_PORT:3030}
3 |
--------------------------------------------------------------------------------
/services/ads/java/src/main/resources/logback-spring.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/services/ads/java/src/main/resources/static/ads/ad1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/ads/java/src/main/resources/static/ads/ad1.jpg
--------------------------------------------------------------------------------
/services/ads/java/src/main/resources/static/ads/ad2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/ads/java/src/main/resources/static/ads/ad2.jpg
--------------------------------------------------------------------------------
/services/ads/java/src/main/resources/static/ads/ad3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/ads/java/src/main/resources/static/ads/ad3.jpg
--------------------------------------------------------------------------------
/services/ads/java/src/main/resources/static/banner-list.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": 1,
4 | "name": "Discount Clothing",
5 | "path": "ad1.jpg",
6 | "url": "/t/clothing",
7 | "weight": 15.1
8 | },
9 | {
10 | "id": 2,
11 | "name": "Cool Hats",
12 | "path": "ad2.jpg",
13 | "url": "/products/datadog-ringer-t-shirt",
14 | "weight": 300.1
15 | },
16 | {
17 | "id": 3,
18 | "name": "Nice Bags",
19 | "path": "ad3.jpg",
20 | "url": "/t/bags",
21 | "weight": 5242.1
22 | }
23 | ]
24 |
--------------------------------------------------------------------------------
/services/ads/java/src/test/java/adsjava/AdsJavaApplicationTests.java:
--------------------------------------------------------------------------------
1 | package adsjava;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import org.springframework.boot.test.context.SpringBootTest;
5 |
6 | @SpringBootTest
7 | class AdsJavaApplicationTests {
8 |
9 | @Test
10 | void contextLoads() {
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/services/ads/python/.dockerignore:
--------------------------------------------------------------------------------
1 | # Version control
2 | .git
3 |
4 | # Compiled Python bytecode
5 | **/__pycache__
6 | **/*.pyc
7 | **/*.pyo
8 |
9 | # Compiled extensions
10 | **/*.pyd
11 | **/*.so
12 |
13 | # coverage.py
14 | .coverage
15 | .coverage.*
16 | htmlcov
17 |
18 | # Cached files
19 | .cache
20 | .mypy_cache
21 | .hypothesis
22 | .pytest_cache
23 |
24 | # Virtualenvs and builds
25 | build/
26 | dist/
27 | .env
28 | .venv
29 | env/
30 | venv/
31 | ENV/
32 | env.bak/
33 | venv.bak/
34 |
35 | # Docker
36 | Dockerfile*
37 | .dockerignore
38 |
--------------------------------------------------------------------------------
/services/ads/python/Dockerfile:
--------------------------------------------------------------------------------
1 | # syntax = docker/dockerfile:1.2
2 | # ^ This enables the new BuildKit stable syntax which can be
3 | # run with the DOCKER_BUILDKIT=1 environment variable in your
4 | # docker build command (see build.sh)
5 | FROM python:3.9.6-slim-buster
6 | # Update, upgrade, and cleanup debian packages
7 | RUN export DEBIAN_FRONTEND=noninteractive && \
8 | apt-get update && \
9 | apt-get upgrade --yes && \
10 | apt-get install --yes build-essential libpq-dev wait-for-it && \
11 | apt-get clean && \
12 | rm -rf /var/lib/apt/lists/*
13 |
14 | # Copy over app
15 | WORKDIR /app
16 | COPY . .
17 |
18 | # Install dependencies via pip and avoid caching build artifacts
19 | RUN pip install --no-cache-dir -r requirements.txt
20 |
21 | # Set default Flask app and development environment
22 | ENV FLASK_APP=ads.py
23 |
24 | # Start the app using ddtrace so we have profiling and tracing
25 | ENTRYPOINT ["ddtrace-run"]
26 | CMD flask run --port=3030 --host=0.0.0.0
27 |
--------------------------------------------------------------------------------
/services/ads/python/ads/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/ads/python/ads/1.jpg
--------------------------------------------------------------------------------
/services/ads/python/ads/2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/ads/python/ads/2.jpg
--------------------------------------------------------------------------------
/services/ads/python/ads/3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/ads/python/ads/3.jpg
--------------------------------------------------------------------------------
/services/ads/python/models.py:
--------------------------------------------------------------------------------
1 | from flask_sqlalchemy import SQLAlchemy
2 | import datetime
3 |
4 | db = SQLAlchemy()
5 |
6 | class Advertisement(db.Model):
7 | id = db.Column(db.Integer, primary_key=True)
8 | name = db.Column(db.String(128))
9 | url = db.Column(db.String(64))
10 | weight = db.Column(db.Float())
11 | path = db.Column(db.String(128))
12 |
13 | def __init__(self, name, url, weight, path):
14 | self.name = name
15 | self.url = url
16 | self.weight = weight
17 | self.path = path
18 |
19 | def serialize(self):
20 | return {
21 | 'id': self.id,
22 | 'name': self.name,
23 | 'url': self.url,
24 | 'weight': self.weight,
25 | 'path': self.path
26 | }
27 |
28 |
29 |
--------------------------------------------------------------------------------
/services/ads/python/requirements.txt:
--------------------------------------------------------------------------------
1 | certifi==2020.11.8
2 | chardet==3.0.4
3 | click==7.1.2
4 | ddtrace==2.16.0
5 | Flask==1.1.2
6 | Flask-Cors==3.0.10
7 | Flask-SQLAlchemy==2.4.4
8 | idna==2.10
9 | intervaltree==3.1.0
10 | itsdangerous==1.1.0
11 | Jinja2==2.11.3
12 | MarkupSafe==1.1.1
13 | nose==1.3.7
14 | protobuf==3.14.0
15 | psycopg2==2.8.6
16 | requests==2.25.1
17 | six==1.15.0
18 | sortedcontainers==2.3.0
19 | SQLAlchemy==1.3.23
20 | tenacity==6.2.0
21 | urllib3==1.26.5
22 | Werkzeug==1.0.1
23 | JSON-log-formatter==0.5.2
--------------------------------------------------------------------------------
/services/backend/.nvmrc:
--------------------------------------------------------------------------------
1 | v16
2 |
--------------------------------------------------------------------------------
/services/backend/.rspec:
--------------------------------------------------------------------------------
1 | --require spec_helper -f documentation
2 |
--------------------------------------------------------------------------------
/services/backend/README.md:
--------------------------------------------------------------------------------
1 | # Backend service (product management)
2 |
3 | ## Overview
4 |
5 | This service manages the products in the store. It is a Ruby on Rails application built using the Spree framework. The service is packaged as a Docker image and typically used in a Docker Compose file (see the root of this repo).
6 |
7 |
--------------------------------------------------------------------------------
/services/backend/Rakefile:
--------------------------------------------------------------------------------
1 | # Add your own tasks in files placed in lib/tasks ending in .rake,
2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3 |
4 | require File.expand_path('../config/application', __FILE__)
5 |
6 | Rails.application.load_tasks
7 |
--------------------------------------------------------------------------------
/services/backend/app/assets/builds/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/app/assets/builds/.keep
--------------------------------------------------------------------------------
/services/backend/app/assets/builds/application.js:
--------------------------------------------------------------------------------
1 | (() => {
2 | })();
3 | //# sourceMappingURL=application.js.map
4 |
--------------------------------------------------------------------------------
/services/backend/app/assets/builds/application.js.map:
--------------------------------------------------------------------------------
1 | {
2 | "version": 3,
3 | "sources": [],
4 | "sourcesContent": [],
5 | "mappings": "",
6 | "names": []
7 | }
8 |
--------------------------------------------------------------------------------
/services/backend/app/assets/config/manifest.js:
--------------------------------------------------------------------------------
1 | //= link_tree ../images
2 | //= link_directory ../stylesheets .css
3 | //= link_tree ../builds
4 |
--------------------------------------------------------------------------------
/services/backend/app/assets/images/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/app/assets/images/.keep
--------------------------------------------------------------------------------
/services/backend/app/assets/images/tshirt1.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/app/assets/images/tshirt1.webp
--------------------------------------------------------------------------------
/services/backend/app/controllers/application_controller.rb:
--------------------------------------------------------------------------------
1 | class ApplicationController < ActionController::Base
2 | # Prevent CSRF attacks by raising an exception.
3 | # For APIs, you may want to use :null_session instead.
4 | protect_from_forgery with: :exception
5 | end
6 |
--------------------------------------------------------------------------------
/services/backend/app/controllers/concerns/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/app/controllers/concerns/.keep
--------------------------------------------------------------------------------
/services/backend/app/helpers/application_helper.rb:
--------------------------------------------------------------------------------
1 | module ApplicationHelper; end
2 |
--------------------------------------------------------------------------------
/services/backend/app/javascript/application.js:
--------------------------------------------------------------------------------
1 | // Entry point for the build script in your package.json
2 |
--------------------------------------------------------------------------------
/services/backend/app/javascript/spree-dashboard.js:
--------------------------------------------------------------------------------
1 | // Entry point for the build script in your package.json
2 |
3 | import "@spree/dashboard"
4 |
5 | new SpreeDashboard.Dashboard()
6 |
7 | // window.Turbo = SpreeDashboard.Turbo
8 |
--------------------------------------------------------------------------------
/services/backend/app/jobs/application_job.rb:
--------------------------------------------------------------------------------
1 | class ApplicationJob < ActiveJob::Base
2 | end
3 |
--------------------------------------------------------------------------------
/services/backend/app/jobs/sentry_job.rb:
--------------------------------------------------------------------------------
1 | class SentryJob < ApplicationJob
2 | queue_as :sentry
3 |
4 | def perform(event)
5 | Raven.send_event(event)
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/services/backend/app/mailers/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/app/mailers/.keep
--------------------------------------------------------------------------------
/services/backend/app/models/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/app/models/.keep
--------------------------------------------------------------------------------
/services/backend/app/models/application_record.rb:
--------------------------------------------------------------------------------
1 | class ApplicationRecord < ActiveRecord::Base
2 | self.abstract_class = true
3 | end
4 |
--------------------------------------------------------------------------------
/services/backend/app/models/concerns/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/app/models/concerns/.keep
--------------------------------------------------------------------------------
/services/backend/app/services/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/app/services/.keep
--------------------------------------------------------------------------------
/services/backend/app/views/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/app/views/.keep
--------------------------------------------------------------------------------
/services/backend/bin/bundle:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
3 | load Gem.bin_path('bundler', 'bundle')
4 |
--------------------------------------------------------------------------------
/services/backend/bin/dev:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | if ! command -v foreman &> /dev/null
4 | then
5 | echo "Installing foreman..."
6 | gem install foreman
7 | fi
8 |
9 | foreman start -f Procfile.dev
10 |
--------------------------------------------------------------------------------
/services/backend/bin/rails:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | APP_PATH = File.expand_path('../config/application', __dir__)
3 | require_relative '../config/boot'
4 | require 'rails/commands'
5 |
--------------------------------------------------------------------------------
/services/backend/bin/rake:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require_relative '../config/boot'
3 | require 'rake'
4 | Rake.application.run
5 |
--------------------------------------------------------------------------------
/services/backend/bin/render-build.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # exit on error
3 | set -o errexit
4 |
5 | bundle install
6 | bundle exec rails assets:precompile
7 | bundle exec rails assets:clean
8 | bundle exec rails db:migrate
9 | bundle exec rails db:seed
10 | bundle exec rake spree_sample:load
11 |
--------------------------------------------------------------------------------
/services/backend/bin/setup:
--------------------------------------------------------------------------------
1 |
2 | rm -rf .env && cp -f .env.sample .env &&
3 | docker-compose build backend &&
4 | docker-compose run --rm backend bash -c '
5 | bin/wait-for-services &&
6 | (bundle check || bundle install) &&
7 | bundle exec rails db:drop &&
8 | bundle exec rails db:create &&
9 | bundle exec rails db:migrate &&
10 | bundle exec rails db:seed &&
11 | rm -rf tmp/latest.dump
12 | ' &&
13 | docker-compose up
14 |
--------------------------------------------------------------------------------
/services/backend/bin/spring:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 |
3 | # This file loads spring without using Bundler, in order to be fast.
4 | # It gets overwritten when you run the `spring binstub` command.
5 |
6 | unless defined?(Spring)
7 | require 'rubygems'
8 | require 'bundler'
9 |
10 | if (match = Bundler.default_lockfile.read.match(/^GEM$.*?^ (?: )*spring \((.*?)\)$.*?^$/m))
11 | Gem.paths = { 'GEM_PATH' => [Bundler.bundle_path.to_s, *Gem.path].uniq }
12 | gem 'spring', match[1]
13 | require 'spring/binstub'
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/services/backend/bin/start:
--------------------------------------------------------------------------------
1 | docker compose up
2 |
--------------------------------------------------------------------------------
/services/backend/bin/update:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require 'fileutils'
3 | include FileUtils
4 |
5 | # path to your application root.
6 | APP_ROOT = File.expand_path('..', __dir__)
7 |
8 | def system!(*args)
9 | system(*args) || abort("\n== Command #{args} failed ==")
10 | end
11 |
12 | chdir APP_ROOT do
13 | # This script is a way to update your development environment automatically.
14 | # Add necessary update steps to this file.
15 |
16 | puts '== Installing dependencies =='
17 | system! 'gem install bundler --conservative'
18 | system('bundle check') || system!('bundle install')
19 |
20 | # Install JavaScript dependencies if using Yarn
21 | # system('bin/yarn')
22 |
23 | puts "\n== Updating database =="
24 | system! 'bin/rails db:migrate'
25 |
26 | puts "\n== Removing old logs and tempfiles =="
27 | system! 'bin/rails log:clear tmp:clear'
28 |
29 | puts "\n== Restarting application server =="
30 | system! 'bin/rails restart'
31 | end
32 |
--------------------------------------------------------------------------------
/services/backend/bin/wait-for-services:
--------------------------------------------------------------------------------
1 | until nc -z -v -w30 $DB_HOST $DB_PORT; do
2 | echo 'Waiting for PostgreSQL...'
3 | sleep 1
4 | done
5 | echo "PostgreSQL is up and running!"
6 |
--------------------------------------------------------------------------------
/services/backend/config.ru:
--------------------------------------------------------------------------------
1 | # This file is used by Rack-based servers to start the application.
2 |
3 | require ::File.expand_path('../config/environment', __FILE__)
4 | run Rails.application
5 |
--------------------------------------------------------------------------------
/services/backend/config/aws.rb:
--------------------------------------------------------------------------------
1 | Aws::VERSION = Gem.loaded_specs["aws-sdk"].version
2 |
--------------------------------------------------------------------------------
/services/backend/config/boot.rb:
--------------------------------------------------------------------------------
1 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
2 |
3 | require 'bundler/setup' # Set up gems listed in the Gemfile.
4 | require 'bootsnap/setup' # Speed up boot time by caching expensive operations.
5 |
--------------------------------------------------------------------------------
/services/backend/config/cable.yml:
--------------------------------------------------------------------------------
1 | development:
2 | adapter: async
3 |
4 | test:
5 | adapter: test
6 |
7 | production:
8 | adapter: redis
9 | url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
10 | channel_prefix: spark_starter_kit_production
11 |
--------------------------------------------------------------------------------
/services/backend/config/environment.rb:
--------------------------------------------------------------------------------
1 | # Load the Rails application.
2 | require_relative 'application'
3 |
4 | # Initialize the Rails application.
5 | Rails.application.initialize!
6 |
--------------------------------------------------------------------------------
/services/backend/config/initializers/active_storage.rb:
--------------------------------------------------------------------------------
1 | Rails.application.config.active_storage.resolve_model_to_route = :rails_storage_proxy
2 |
--------------------------------------------------------------------------------
/services/backend/config/initializers/application_controller_renderer.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # ActiveSupport::Reloader.to_prepare do
4 | # ApplicationController.renderer.defaults.merge!(
5 | # http_host: 'example.org',
6 | # https: false
7 | # )
8 | # end
9 |
--------------------------------------------------------------------------------
/services/backend/config/initializers/assets.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Version of your assets, change this if you want to expire all your assets.
4 | Rails.application.config.assets.version = '1.0'
5 |
6 | # Add additional assets to the asset load path.
7 | # Rails.application.config.assets.paths << Emoji.images_path
8 | # Add Yarn node_modules folder to the asset load path.
9 | if defined?(Webpacker)
10 | Rails.application.config.assets.paths << Rails.root.join('node_modules')
11 | end
12 |
13 | # Precompile additional assets.
14 | # application.js, application.css, and all non-JS/CSS in the app/assets
15 | # folder are already added.
16 | # Rails.application.config.assets.precompile += %w( admin.js admin.css )
17 |
--------------------------------------------------------------------------------
/services/backend/config/initializers/backtrace_silencers.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
5 |
6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
7 | # Rails.backtrace_cleaner.remove_silencers!
8 |
--------------------------------------------------------------------------------
/services/backend/config/initializers/cookies_serializer.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Specify a serializer for the signed and encrypted cookie jars.
4 | # Valid options are :json, :marshal, and :hybrid.
5 | Rails.application.config.action_dispatch.cookies_serializer = :json
6 |
--------------------------------------------------------------------------------
/services/backend/config/initializers/cors.rb:
--------------------------------------------------------------------------------
1 | # Avoid CORS issues when API is called from the frontend app.
2 | # Handle Cross-Origin Resource Sharing (CORS) in order to accept cross-origin AJAX requests.
3 |
4 | # Read more: https://github.com/cyu/rack-cors
5 |
6 | Rails.application.config.middleware.insert_before 0, Rack::Cors, debug: ENV.fetch('RACK_CORS_DEBUG', false), logger: (-> { Rails.logger }) do
7 | allow do
8 | origins ENV.fetch('ALLOWED_ORIGIN_HOSTS', '*').split(',')
9 |
10 | resource '*',
11 | headers: :any,
12 | methods: %i[get post delete put patch options head],
13 | max_age: 0
14 | end
15 | end
16 |
17 |
--------------------------------------------------------------------------------
/services/backend/config/initializers/datadog-tracer.rb:
--------------------------------------------------------------------------------
1 | Datadog.configure do |c|
2 | c.service = ENV['DD_SERVICE'] || 'store-backend'
3 | # Activates and configures an integration
4 | c.tracing.instrument :pg, service_name: 'postgres'
5 | c.tracing.instrument :aws, service_name: 'store-backend-aws'
6 | c.tracing.instrument :dalli, service_name: 'store-backend-memcached'
7 | c.tracing.instrument :active_support, cache_service: 'store-backend-cache'
8 | end
--------------------------------------------------------------------------------
/services/backend/config/initializers/devise.rb:
--------------------------------------------------------------------------------
1 | Devise.secret_key = Rails.application.secrets.secret_key_base
2 | if defined?(Spree::Auth)
3 | Spree::Auth::Config.signout_after_password_change = false
4 | end
5 |
--------------------------------------------------------------------------------
/services/backend/config/initializers/filter_parameter_logging.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Configure sensitive parameters which will be filtered from the log file.
4 | Rails.application.config.filter_parameters += [:password]
5 |
--------------------------------------------------------------------------------
/services/backend/config/initializers/inflections.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Add new inflection rules using the following format. Inflections
4 | # are locale specific, and you may define rules for as many different
5 | # locales as you wish. All of these examples are active by default:
6 | # ActiveSupport::Inflector.inflections(:en) do |inflect|
7 | # inflect.plural /^(ox)$/i, '\1en'
8 | # inflect.singular /^(ox)en/i, '\1'
9 | # inflect.irregular 'person', 'people'
10 | # inflect.uncountable %w( fish sheep )
11 | # end
12 |
13 | # These inflection rules are supported but not enabled by default:
14 | # ActiveSupport::Inflector.inflections(:en) do |inflect|
15 | # inflect.acronym 'RESTful'
16 | # end
17 |
--------------------------------------------------------------------------------
/services/backend/config/initializers/mime_types.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Add new mime types for use in respond_to blocks:
4 | # Mime::Type.register "text/richtext", :rtf
5 |
--------------------------------------------------------------------------------
/services/backend/config/initializers/oj.rb:
--------------------------------------------------------------------------------
1 | require 'oj'
2 |
3 | Oj.optimize_rails
4 |
--------------------------------------------------------------------------------
/services/backend/config/initializers/raven.rb:
--------------------------------------------------------------------------------
1 | Raven.configure do |config|
2 | config.async = lambda { |event| SentryJob.perform_later(event) }
3 | config.environments = %w[ production ]
4 | config.excluded_exceptions += ['ActionController::RoutingError', 'ActiveRecord::RecordNotFound',
5 | 'Rack::Timeout::RequestExpiryError', 'Rack::Timeout::RequestTimeoutException']
6 | config.sanitize_fields = Rails.application.config.filter_parameters.map(&:to_s)
7 | end
8 |
--------------------------------------------------------------------------------
/services/backend/config/initializers/redis.rb:
--------------------------------------------------------------------------------
1 | # fix for Redis config on Heroku
2 | if ENV['REDISCLOUD_URL'].present? && ENV['REDIS_URL'].blank?
3 | ENV['REDIS_URL'] = ENV['REDISCLOUD_URL']
4 | end
5 |
--------------------------------------------------------------------------------
/services/backend/config/initializers/session_store.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | cookie_domain = ENV['COOKIE_DOMAIN'] == 'all' ? :all : ENV['COOKIE_DOMAIN']
4 |
5 | Rails.application.config.session_store :cookie_store,
6 | key: '_spree_starter_session',
7 | domain: cookie_domain,
8 | expire_after: 12.hours,
9 | secure: Rails.env.production?,
10 | httponly: true,
11 | same_site: :lax
12 |
--------------------------------------------------------------------------------
/services/backend/config/initializers/spree.rb:
--------------------------------------------------------------------------------
1 | # Configure Spree Preferences
2 | #
3 | # Note: Initializing preferences available within the Admin will overwrite any changes that were made through the user interface when you restart.
4 | # If you would like users to be able to update a setting with the Admin it should NOT be set here.
5 | #
6 | # Note: If a preference is set here it will be stored within the cache & database upon initialization.
7 | # Just removing an entry from this initializer will not make the preference value go away.
8 | # Instead you must either set a new value or remove entry, clear cache, and remove database entry.
9 | #
10 | # In order to initialize a setting do:
11 | # config.setting_name = 'new value'
12 | Spree.config do |config|
13 | # Example:
14 | # Uncomment to stop tracking inventory levels in the application
15 | # config.track_inventory_levels = false
16 | end
17 |
18 | Spree.user_class = 'Spree::User'
19 |
--------------------------------------------------------------------------------
/services/backend/config/initializers/wrap_parameters.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # This file contains settings for ActionController::ParamsWrapper which
4 | # is enabled by default.
5 |
6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
7 | ActiveSupport.on_load(:action_controller) do
8 | wrap_parameters format: [:json]
9 | end
10 |
11 | # To enable root element in JSON for ActiveRecord objects.
12 | # ActiveSupport.on_load(:active_record) do
13 | # self.include_root_in_json = true
14 | # end
15 |
--------------------------------------------------------------------------------
/services/backend/config/locales/en.yml:
--------------------------------------------------------------------------------
1 | # Files in the config/locales directory are used for internationalization
2 | # and are automatically loaded by Rails. If you want to use locales other
3 | # than English, add the necessary files in this directory.
4 | #
5 | # To use the locales, use `I18n.t`:
6 | #
7 | # I18n.t 'hello'
8 | #
9 | # In views, this is aliased to just `t`:
10 | #
11 | # <%= t('hello') %>
12 | #
13 | # To use a different locale, set it with `I18n.locale`:
14 | #
15 | # I18n.locale = :es
16 | #
17 | # This would use the information in config/locales/es.yml.
18 | #
19 | # The following keys must be escaped otherwise they will not be retrieved by
20 | # the default I18n backend:
21 | #
22 | # true, false, on, off, yes, no
23 | #
24 | # Instead, surround them with single quotes.
25 | #
26 | # en:
27 | # 'true': 'foo'
28 | #
29 | # To learn more, please read the Rails Internationalization guide
30 | # available at https://guides.rubyonrails.org/i18n.html.
31 |
32 | en:
33 | hello: "Hello world"
34 |
--------------------------------------------------------------------------------
/services/backend/config/routes.rb:
--------------------------------------------------------------------------------
1 | Rails.application.routes.draw do
2 | # Spree routes
3 | mount Spree::Core::Engine, at: '/'
4 |
5 | # sidekiq web UI
6 | require 'sidekiq/web'
7 | Sidekiq::Web.use Rack::Auth::Basic do |username, password|
8 | username == Rails.application.secrets.sidekiq_username &&
9 | password == Rails.application.secrets.sidekiq_password
10 | end
11 | mount Sidekiq::Web, at: '/sidekiq'
12 | end
13 |
--------------------------------------------------------------------------------
/services/backend/config/sidekiq.yml:
--------------------------------------------------------------------------------
1 | ---
2 | :concurrency: 5
3 | :max_memory: 512 # MB
4 | :gc_interval: 10 # GC every 10 jobs
5 | :queues:
6 | - default
7 | - mailers
8 | - sentry
9 | - active_storage_analysis
10 | - spree_stock_location_stock_items
11 | - spree_webhooks
12 |
--------------------------------------------------------------------------------
/services/backend/config/spring.rb:
--------------------------------------------------------------------------------
1 | %w(
2 | .ruby-version
3 | .rbenv-vars
4 | tmp/restart.txt
5 | tmp/caching-dev.txt
6 | ).each { |path| Spring.watch(path) }
7 |
--------------------------------------------------------------------------------
/services/backend/db/migrate/20211203185340_create_action_mailbox_tables.action_mailbox.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from action_mailbox (originally 20180917164000)
2 | class CreateActionMailboxTables < ActiveRecord::Migration[6.0]
3 | def change
4 | create_table :action_mailbox_inbound_emails do |t|
5 | t.integer :status, default: 0, null: false
6 | t.string :message_id, null: false
7 | t.string :message_checksum, null: false
8 |
9 | t.timestamps
10 |
11 | t.index [ :message_id, :message_checksum ], name: "index_action_mailbox_inbound_emails_uniqueness", unique: true
12 | end
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/services/backend/db/migrate/20211203185341_create_action_text_tables.action_text.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from action_text (originally 20180528164100)
2 | class CreateActionTextTables < ActiveRecord::Migration[6.0]
3 | def change
4 | create_table :action_text_rich_texts do |t|
5 | t.string :name, null: false
6 | t.text :body, size: :long
7 | t.references :record, null: false, polymorphic: true, index: false
8 |
9 | t.timestamps
10 |
11 | t.index [ :record_type, :record_id, :name ], name: "index_action_text_rich_texts_uniqueness", unique: true
12 | end
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/services/backend/db/migrate/20211203185343_add_metadata_to_spree_orders.spree.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from spree (originally 20210915064321)
2 | class AddMetadataToSpreeOrders < ActiveRecord::Migration[5.2]
3 | def change
4 | change_table :spree_orders do |t|
5 | if t.respond_to? :jsonb
6 | add_column :spree_orders, :public_metadata, :jsonb
7 | add_column :spree_orders, :private_metadata, :jsonb
8 | else
9 | add_column :spree_orders, :public_metadata, :json
10 | add_column :spree_orders, :private_metadata, :json
11 | end
12 | end
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/services/backend/db/migrate/20211203185344_add_metadata_to_spree_products.spree.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from spree (originally 20210915064322)
2 | class AddMetadataToSpreeProducts < ActiveRecord::Migration[5.2]
3 | def change
4 | change_table :spree_products do |t|
5 | if t.respond_to? :jsonb
6 | add_column :spree_products, :public_metadata, :jsonb
7 | add_column :spree_products, :private_metadata, :jsonb
8 | else
9 | add_column :spree_products, :public_metadata, :json
10 | add_column :spree_products, :private_metadata, :json
11 | end
12 | end
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/services/backend/db/migrate/20211203185345_add_metadata_to_spree_variants.spree.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from spree (originally 20210915064323)
2 | class AddMetadataToSpreeVariants < ActiveRecord::Migration[5.2]
3 | def change
4 | change_table :spree_variants do |t|
5 | if t.respond_to? :jsonb
6 | add_column :spree_variants, :public_metadata, :jsonb
7 | add_column :spree_variants, :private_metadata, :jsonb
8 | else
9 | add_column :spree_variants, :public_metadata, :json
10 | add_column :spree_variants, :private_metadata, :json
11 | end
12 | end
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/services/backend/db/migrate/20211203185346_add_metadata_to_spree_line_items.spree.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from spree (originally 20210915064324)
2 | class AddMetadataToSpreeLineItems < ActiveRecord::Migration[5.2]
3 | def change
4 | change_table :spree_line_items do |t|
5 | if t.respond_to? :jsonb
6 | add_column :spree_line_items, :public_metadata, :jsonb
7 | add_column :spree_line_items, :private_metadata, :jsonb
8 | else
9 | add_column :spree_line_items, :public_metadata, :json
10 | add_column :spree_line_items, :private_metadata, :json
11 | end
12 | end
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/services/backend/db/migrate/20211203185347_add_metadata_to_spree_shipments.spree.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from spree (originally 20210915064325)
2 | class AddMetadataToSpreeShipments < ActiveRecord::Migration[5.2]
3 | def change
4 | change_table :spree_shipments do |t|
5 | if t.respond_to? :jsonb
6 | add_column :spree_shipments, :public_metadata, :jsonb
7 | add_column :spree_shipments, :private_metadata, :jsonb
8 | else
9 | add_column :spree_shipments, :public_metadata, :json
10 | add_column :spree_shipments, :private_metadata, :json
11 | end
12 | end
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/services/backend/db/migrate/20211203185348_add_metadata_to_spree_payments.spree.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from spree (originally 20210915064326)
2 | class AddMetadataToSpreePayments < ActiveRecord::Migration[5.2]
3 | def change
4 | change_table :spree_payments do |t|
5 | if t.respond_to? :jsonb
6 | add_column :spree_payments, :public_metadata, :jsonb
7 | add_column :spree_payments, :private_metadata, :jsonb
8 | else
9 | add_column :spree_payments, :public_metadata, :json
10 | add_column :spree_payments, :private_metadata, :json
11 | end
12 | end
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/services/backend/db/migrate/20211203185349_add_metadata_to_spree_taxons_and_taxonomies.spree.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from spree (originally 20210915064327)
2 | class AddMetadataToSpreeTaxonsAndTaxonomies < ActiveRecord::Migration[5.2]
3 | def change
4 | %i[
5 | spree_taxons
6 | spree_taxonomies
7 | ].each do |table_name|
8 | change_table table_name do |t|
9 | if t.respond_to? :jsonb
10 | add_column table_name, :public_metadata, :jsonb
11 | add_column table_name, :private_metadata, :jsonb
12 | else
13 | add_column table_name, :public_metadata, :json
14 | add_column table_name, :private_metadata, :json
15 | end
16 | end
17 | end
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/services/backend/db/migrate/20211203185350_add_metadata_to_spree_stock_transfers.spree.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from spree (originally 20210915064328)
2 | class AddMetadataToSpreeStockTransfers < ActiveRecord::Migration[5.2]
3 | def change
4 | change_table :spree_stock_transfers do |t|
5 | if t.respond_to? :jsonb
6 | add_column :spree_stock_transfers, :public_metadata, :jsonb
7 | add_column :spree_stock_transfers, :private_metadata, :jsonb
8 | else
9 | add_column :spree_stock_transfers, :public_metadata, :json
10 | add_column :spree_stock_transfers, :private_metadata, :json
11 | end
12 | end
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/services/backend/db/migrate/20211203185351_add_metadata_to_spree_multiple_tables.spree.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from spree (originally 20210915064329)
2 | class AddMetadataToSpreeMultipleTables < ActiveRecord::Migration[5.2]
3 | def change
4 | %i[
5 | spree_assets
6 | spree_option_types
7 | spree_option_values
8 | spree_properties
9 | spree_promotions
10 | spree_payment_methods
11 | spree_shipping_methods
12 | spree_prototypes
13 | spree_refunds
14 | spree_customer_returns
15 | spree_users
16 | spree_addresses
17 | spree_credit_cards
18 | spree_store_credits
19 | ].each do |table_name|
20 | change_table table_name do |t|
21 | if t.respond_to? :jsonb
22 | add_column table_name, :public_metadata, :jsonb
23 | add_column table_name, :private_metadata, :jsonb
24 | else
25 | add_column table_name, :public_metadata, :json
26 | add_column table_name, :private_metadata, :json
27 | end
28 | end
29 | end
30 | end
31 | end
32 |
--------------------------------------------------------------------------------
/services/backend/db/migrate/20211203185352_add_deleted_at_to_spree_stores.spree.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from spree (originally 20210920090344)
2 | class AddDeletedAtToSpreeStores < ActiveRecord::Migration[5.2]
3 | def change
4 | unless column_exists?(:spree_stores, :deleted_at)
5 | add_column :spree_stores, :deleted_at, :datetime
6 | add_index :spree_stores, :deleted_at
7 | end
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/services/backend/db/migrate/20211203185353_rename_column_access_hash_to_token.spree.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from spree (originally 20210921070812)
2 | class RenameColumnAccessHashToToken < ActiveRecord::Migration[5.2]
3 | def change
4 | if table_exists?(:spree_wishlists)
5 | rename_column(:spree_wishlists, :access_hash, :token) if column_exists?(:spree_wishlists, :access_hash)
6 | add_reference(:spree_wishlists, :store, index: true) unless column_exists?(:spree_wishlists, :store_id)
7 | end
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/services/backend/db/migrate/20211203185354_create_spree_wishlists.spree.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from spree (originally 20210921070813)
2 | class CreateSpreeWishlists < ActiveRecord::Migration[5.2]
3 | def change
4 | create_table :spree_wishlists, if_not_exists: true do |t|
5 | t.belongs_to :user
6 | t.belongs_to :store
7 |
8 | t.column :name, :string
9 | t.column :token, :string, null: false
10 | t.column :is_private, :boolean, default: true, null: false
11 | t.column :is_default, :boolean, default: false, null: false
12 |
13 | t.timestamps
14 | end
15 |
16 | add_index :spree_wishlists, :token, unique: true
17 | add_index :spree_wishlists, [:user_id, :is_default] unless index_exists?(:spree_wishlists, [:user_id, :is_default])
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/services/backend/db/migrate/20211203185355_create_spree_wished_products.spree.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from spree (originally 20210921070814)
2 | class CreateSpreeWishedProducts < ActiveRecord::Migration[5.2]
3 | def change
4 | create_table :spree_wished_products, if_not_exists: true do |t|
5 | t.references :variant
6 | t.belongs_to :wishlist
7 |
8 | t.column :quantity, :integer, default: 1, null: false
9 |
10 | t.timestamps
11 | end
12 |
13 | add_index :spree_wished_products, [:variant_id, :wishlist_id], unique: true unless index_exists?(:spree_wished_products, [:variant_id, :wishlist_id])
14 | add_index :spree_wished_products, :variant_id unless index_exists?(:spree_wished_products, :variant_id)
15 | add_index :spree_wished_products, :wishlist_id unless index_exists?(:spree_wished_products, :wishlist_id)
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/services/backend/db/migrate/20211203185356_rename_spree_wished_products_to_spree_wished_items.spree.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from spree (originally 20210921070815)
2 | class RenameSpreeWishedProductsToSpreeWishedItems < ActiveRecord::Migration[5.2]
3 | def change
4 | rename_table :spree_wished_products, :spree_wished_items
5 | end
6 | end
7 |
--------------------------------------------------------------------------------
/services/backend/db/migrate/20211203185357_add_unique_stock_item_stock_location_variant_deleted_at_index.spree.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from spree (originally 20210921090344)
2 | class AddUniqueStockItemStockLocationVariantDeletedAtIndex < ActiveRecord::Migration[5.2]
3 | def change
4 | add_index :spree_stock_items, [:stock_location_id, :variant_id, :deleted_at], name: 'stock_item_by_loc_var_id_deleted_at', unique: true
5 | end
6 | end
7 |
--------------------------------------------------------------------------------
/services/backend/db/migrate/20211203185359_create_spree_digital_links.spree.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from spree (originally 20210929091444)
2 | class CreateSpreeDigitalLinks < ActiveRecord::Migration[5.2]
3 | def change
4 | create_table :spree_digital_links, if_not_exists: true do |t|
5 | t.belongs_to :digital
6 | t.belongs_to :line_item
7 | t.string :secret
8 | t.integer :access_counter
9 |
10 | t.timestamps
11 | end
12 | add_index :spree_digital_links, :secret, unique: true unless index_exists?(:spree_digital_links, :secret)
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/services/backend/db/migrate/20211203185360_create_spree_digitals.spree.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from spree (originally 20210929093238)
2 | class CreateSpreeDigitals < ActiveRecord::Migration[5.2]
3 | def change
4 | create_table :spree_digitals, if_not_exists: true do |t|
5 | t.belongs_to :variant
6 |
7 | t.timestamps
8 | end
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/services/backend/db/migrate/20211203185361_rename_secret_to_token_on_spree_digital_links.spree.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from spree (originally 20210930143043)
2 | class RenameSecretToTokenOnSpreeDigitalLinks < ActiveRecord::Migration[5.2]
3 | def change
4 | rename_column :spree_digital_links, :secret, :token
5 | end
6 | end
7 |
--------------------------------------------------------------------------------
/services/backend/db/migrate/20211203185362_add_settings_to_spree_stores.spree.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from spree (originally 20210930155649)
2 | class AddSettingsToSpreeStores < ActiveRecord::Migration[5.2]
3 | def change
4 | change_table :spree_stores do |t|
5 | if t.respond_to? :jsonb
6 | add_column :spree_stores, :settings, :jsonb
7 | else
8 | add_column :spree_stores, :settings, :json
9 | end
10 | end
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/services/backend/db/migrate/20211203185363_add_api_key_to_spree_users.spree_api.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from spree_api (originally 20100107141738)
2 | class AddApiKeyToSpreeUsers < ActiveRecord::Migration[4.2]
3 | def change
4 | unless defined?(User)
5 | add_column :spree_users, :api_key, :string, limit: 40
6 | end
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/services/backend/db/migrate/20211203185364_resize_api_key_field.spree_api.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from spree_api (originally 20120411123334)
2 | class ResizeApiKeyField < ActiveRecord::Migration[4.2]
3 | def change
4 | unless defined?(User)
5 | change_column :spree_users, :api_key, :string, limit: 48
6 | end
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/services/backend/db/migrate/20211203185365_rename_api_key_to_spree_api_key.spree_api.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from spree_api (originally 20120530054546)
2 | class RenameApiKeyToSpreeApiKey < ActiveRecord::Migration[4.2]
3 | def change
4 | unless defined?(User)
5 | rename_column :spree_users, :api_key, :spree_api_key
6 | end
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/services/backend/db/migrate/20211203185366_add_index_to_user_spree_api_key.spree_api.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from spree_api (originally 20131017162334)
2 | class AddIndexToUserSpreeApiKey < ActiveRecord::Migration[4.2]
3 | def change
4 | unless defined?(User)
5 | add_index :spree_users, :spree_api_key
6 | end
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/services/backend/db/migrate/20211203185368_change_integer_id_columns_type.spree_api.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from spree_api (originally 20210727102516)
2 | class ChangeIntegerIdColumnsType < ActiveRecord::Migration[5.2]
3 | def change
4 | change_column :spree_oauth_access_grants, :resource_owner_id, :bigint
5 | change_column :spree_oauth_access_grants, :application_id, :bigint
6 |
7 | change_column :spree_oauth_access_tokens, :resource_owner_id, :bigint
8 | change_column :spree_oauth_access_tokens, :application_id, :bigint
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/services/backend/db/migrate/20211203185369_create_spree_webhooks_tables.spree_api.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from spree_api (originally 20210902162826)
2 | class CreateSpreeWebhooksTables < ActiveRecord::Migration[5.2]
3 | def change
4 | create_table :spree_webhooks_subscribers do |t|
5 | t.string :url, null: false
6 | t.boolean :active, default: false, index: true
7 |
8 | if t.respond_to? :jsonb
9 | t.jsonb :subscriptions
10 | else
11 | t.json :subscriptions
12 | end
13 |
14 | t.timestamps
15 | end
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/services/backend/db/migrate/20211203185371_create_spree_webhooks_events.spree_api.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from spree_api (originally 20211025162826)
2 | class CreateSpreeWebhooksEvents < ActiveRecord::Migration[5.2]
3 | def change
4 | create_table :spree_webhooks_events do |t|
5 | t.integer "execution_time"
6 | t.string "name", null: false
7 | t.string "request_errors"
8 | t.string "response_code", index: true
9 | t.belongs_to "subscriber", null: false, index: true
10 | t.boolean "success", index: true
11 | t.string "url", null: false
12 | t.timestamps
13 | end
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/services/backend/db/migrate/20211203185372_update_braintree_payment_method_type.spree_gateway.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from spree_gateway (originally 20121017004102)
2 | class UpdateBraintreePaymentMethodType < SpreeExtension::Migration[4.2]
3 | def up
4 | Spree::PaymentMethod.where(:type => "Spree::Gateway::Braintree").update_all(:type => "Spree::Gateway::BraintreeGateway")
5 | end
6 |
7 | def down
8 | Spree::PaymentMethod.where(:type => "Spree::Gateway::BraintreeGateway").update_all(:type => "Spree::Gateway::Braintree")
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/services/backend/db/migrate/20211203185373_update_stripe_payment_method_type.spree_gateway.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from spree_gateway (originally 20130213222555)
2 | class UpdateStripePaymentMethodType < SpreeExtension::Migration[4.2]
3 | def up
4 | Spree::PaymentMethod.where(:type => "Spree::Gateway::Stripe").update_all(:type => "Spree::Gateway::StripeGateway")
5 | end
6 |
7 | def down
8 | Spree::PaymentMethod.where(:type => "Spree::Gateway::StripeGateway").update_all(:type => "Spree::Gateway::Stripe")
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/services/backend/db/migrate/20211203185374_update_balanced_payment_method_type.spree_gateway.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from spree_gateway (originally 20130415222802)
2 | class UpdateBalancedPaymentMethodType < SpreeExtension::Migration[4.2]
3 | def up
4 | Spree::PaymentMethod.where(:type => "Spree::Gateway::Balanced").update_all(:type => "Spree::Gateway::BalancedGateway")
5 | end
6 |
7 | def down
8 | Spree::PaymentMethod.where(:type => "Spree::Gateway::BalancedGateway").update_all(:type => "Spree::Gateway::Balanced")
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/services/backend/db/migrate/20211203185375_update_paypal_payment_method_type.spree_gateway.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from spree_gateway (originally 20131008221012)
2 | class UpdatePaypalPaymentMethodType < SpreeExtension::Migration[4.2]
3 | def up
4 | Spree::PaymentMethod.where(:type => "Spree::Gateway::PayPal").update_all(:type => "Spree::Gateway::PayPalGateway")
5 | end
6 |
7 | def down
8 | Spree::PaymentMethod.where(:type => "Spree::Gateway::PayPalGateway").update_all(:type => "Spree::Gateway::PayPal")
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/services/backend/db/migrate/20211203185376_migrate_stripe_preferences.spree_gateway.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from spree_gateway (originally 20131112133401)
2 | class MigrateStripePreferences < SpreeExtension::Migration[4.2]
3 | def up
4 | Spree::Preference.where("#{ActiveRecord::Base.connection.quote_column_name("key")} LIKE 'spree/gateway/stripe_gateway/login%'").each do |pref|
5 | pref.key = pref.key.gsub('login', 'secret_key')
6 | pref.save
7 | end
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/services/backend/db/migrate/20211203185377_add_spree_check_payment_source.spree_gateway.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from spree_gateway (originally 20200317135551)
2 | class AddSpreeCheckPaymentSource < ActiveRecord::Migration[5.1]
3 | def change
4 | create_table :spree_checks do |t|
5 | t.references :payment_method
6 | t.references :user
7 | t.string "account_holder_name"
8 | t.string "account_holder_type"
9 | t.string "routing_number"
10 | t.string "account_number"
11 | t.string "account_type", default: 'checking'
12 | t.string "status"
13 | t.string "last_digits"
14 | t.string "gateway_customer_profile_id"
15 | t.string "gateway_payment_profile_id"
16 |
17 | t.datetime "created_at", null: false
18 | t.datetime "updated_at", null: false
19 | t.datetime "deleted_at"
20 | end
21 | add_index :spree_payment_methods, :id
22 | end
23 | end
24 |
--------------------------------------------------------------------------------
/services/backend/db/migrate/20211203185378_add_intent_key_to_payment.spree_gateway.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from spree_gateway (originally 20200422114908)
2 | class AddIntentKeyToPayment < ActiveRecord::Migration[4.2]
3 | def change
4 | add_column :spree_payments, :intent_client_key, :string
5 | end
6 | end
7 |
--------------------------------------------------------------------------------
/services/backend/db/migrate/20211203185381_convert_user_remember_field.spree_auth.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from spree_auth (originally 20101214150824)
2 | class ConvertUserRememberField < SpreeExtension::Migration[4.2]
3 | def up
4 | remove_column :spree_users, :remember_created_at
5 | add_column :spree_users, :remember_created_at, :datetime
6 | end
7 |
8 | def down
9 | remove_column :spree_users, :remember_created_at
10 | add_column :spree_users, :remember_created_at, :string
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/services/backend/db/migrate/20211203185382_add_reset_password_sent_at_to_spree_users.spree_auth.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from spree_auth (originally 20120203010234)
2 | class AddResetPasswordSentAtToSpreeUsers < SpreeExtension::Migration[4.2]
3 | def change
4 | Spree.user_class.reset_column_information
5 | unless Spree.user_class.column_names.include?("reset_password_sent_at")
6 | add_column :spree_users, :reset_password_sent_at, :datetime
7 | end
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/services/backend/db/migrate/20211203185383_make_users_email_index_unique.spree_auth.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from spree_auth (originally 20120605211305)
2 | class MakeUsersEmailIndexUnique < SpreeExtension::Migration[4.2]
3 | def up
4 | add_index "spree_users", ["email"], name: "email_idx_unique", unique: true
5 | end
6 |
7 | def down
8 | remove_index "spree_users", name: "email_idx_unique"
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/services/backend/db/migrate/20211203185384_add_deleted_at_to_users.spree_auth.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from spree_auth (originally 20140904000425)
2 | class AddDeletedAtToUsers < SpreeExtension::Migration[4.2]
3 | def change
4 | add_column :spree_users, :deleted_at, :datetime
5 | add_index :spree_users, :deleted_at
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/services/backend/db/migrate/20211203185385_add_confirmable_to_users.spree_auth.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from spree_auth (originally 20141002154641)
2 | class AddConfirmableToUsers < SpreeExtension::Migration[4.2]
3 | def change
4 | add_column :spree_users, :confirmation_token, :string
5 | add_column :spree_users, :confirmed_at, :datetime
6 | add_column :spree_users, :confirmation_sent_at, :datetime
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/services/backend/db/migrate/20211203185386_add_missing_indices_on_user.spree_auth.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from spree_auth (originally 20150416152553)
2 | class AddMissingIndicesOnUser < SpreeExtension::Migration[4.2]
3 | def change
4 | unless index_exists?(:spree_users, :bill_address_id)
5 | add_index :spree_users, :bill_address_id
6 | end
7 | unless index_exists?(:spree_users, :ship_address_id)
8 | add_index :spree_users, :ship_address_id
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/services/backend/db/migrate/20211203185387_change_type_of_ship_address_id_and_bill_address_id_for_spree_users.spree_auth.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from spree_auth (originally 20210728103922)
2 | class ChangeTypeOfShipAddressIdAndBillAddressIdForSpreeUsers < ActiveRecord::Migration[4.2]
3 | def change
4 | change_table(:spree_users) do |t|
5 | t.change :ship_address_id, :bigint
6 | t.change :bill_address_id, :bigint
7 | end
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/services/backend/db/seeds.rb:
--------------------------------------------------------------------------------
1 | #
2 | # Place all seeds in /seeds/ folder.
3 | #
4 |
5 | Spree::Webhooks.disable_webhooks do
6 | Dir[File.dirname(__FILE__) + '/seeds/*.rb'].sort.each do |file|
7 | puts "Seeds #{file} ..."
8 | require file
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/services/backend/db/seeds/001_spree.rb:
--------------------------------------------------------------------------------
1 | Spree::Core::Engine.load_seed if defined?(Spree::Core)
2 | Spree::Auth::Engine.load_seed if defined?(Spree::Auth)
3 |
--------------------------------------------------------------------------------
/services/backend/entrypoint.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -e
3 | bundle exec rails db:migrate
4 | exec "$@"
5 |
--------------------------------------------------------------------------------
/services/backend/lib/assets/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/lib/assets/.keep
--------------------------------------------------------------------------------
/services/backend/lib/cloud_flare_middleware.rb:
--------------------------------------------------------------------------------
1 | # CloudFlare masks the true IP
2 | # This middleware ensures the Rails stack obtains the correct IP when using request.remote_ip
3 | # See https://support.cloudflare.com/hc/en-us/articles/200170786
4 |
5 | module Rack
6 | class CloudFlareMiddleware
7 | def initialize(app)
8 | @app = app
9 | end
10 |
11 | def call(env)
12 | if env['HTTP_CF_CONNECTING_IP']
13 | env['HTTP_REMOTE_ADDR_BEFORE_CF'] = env['REMOTE_ADDR']
14 | env['HTTP_X_FORWARDED_FOR_BEFORE_CF'] = env['HTTP_X_FORWARDED_FOR']
15 | env['REMOTE_ADDR'] = env['HTTP_CF_CONNECTING_IP']
16 | env['HTTP_X_FORWARDED_FOR'] = env['HTTP_CF_CONNECTING_IP']
17 | end
18 | @app.call(env)
19 | end
20 | end
21 | end
22 |
--------------------------------------------------------------------------------
/services/backend/lib/tasks/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/lib/tasks/.keep
--------------------------------------------------------------------------------
/services/backend/lib/tasks/clear_cache.rake:
--------------------------------------------------------------------------------
1 | namespace :cache do
2 | desc 'Clears Rails cache'
3 | task clear: :environment do
4 | Rails.cache.clear
5 | end
6 | end
7 |
--------------------------------------------------------------------------------
/services/backend/lib/tasks/custom_seed.rake:
--------------------------------------------------------------------------------
1 | namespace :db do
2 | namespace :seed do
3 | Dir[File.join(Rails.root, 'db', 'seeds', '*.rb')].each do |filename|
4 | task_name = File.basename(filename, '.rb').intern
5 | task task_name => :environment do
6 | load(filename) if File.exist?(filename)
7 | end
8 | end
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/services/backend/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {
3 | "@spree/dashboard": "^0.1.0",
4 | "esbuild": "^0.14.1"
5 | },
6 | "scripts": {
7 | "build": "esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/services/backend/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/public/favicon.ico
--------------------------------------------------------------------------------
/services/backend/public/robots.txt:
--------------------------------------------------------------------------------
1 | # See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file
2 | #
3 | # To ban all spiders from the entire site uncomment the next two lines:
4 | # User-agent: *
5 | # Disallow: /
6 | User-agent: *
7 | Disallow: /checkout
8 | Disallow: /cart
9 | Disallow: /orders
10 | Disallow: /user
11 | Disallow: /account
12 | Disallow: /api
13 | Disallow: /password
14 |
--------------------------------------------------------------------------------
/services/backend/render.yaml:
--------------------------------------------------------------------------------
1 | databases:
2 | - name: spree
3 | databaseName: spree
4 | user: spree
5 |
6 | services:
7 | - type: web
8 | name: spree
9 | env: ruby
10 | buildCommand: "./bin/render-build.sh"
11 | startCommand: "bundle exec puma -C config/puma.rb"
12 | envVars:
13 | - key: DATABASE_URL
14 | fromDatabase:
15 | name: spree
16 | property: connectionString
17 | - key: SECRET_KEY_BASE
18 | generateValue: true
19 | - key: ADMIN_EMAIL
20 | value: 'spree@example.com'
21 | - key: ADMIN_PASSWORD
22 | value: 'spree123'
23 |
--------------------------------------------------------------------------------
/services/backend/spec/support/vcr.rb:
--------------------------------------------------------------------------------
1 | require 'vcr'
2 | require 'webmock/rspec'
3 | require 'uri'
4 | require 'webdrivers'
5 |
6 | driver_hosts = Webdrivers::Common.subclasses.map { |driver| URI(driver.base_url).host }
7 | driver_hosts << 'codeclimate.com'
8 | driver_urls = Webdrivers::Common.subclasses.map(&:base_url)
9 |
10 | WebMock.disable_net_connect!(allow_localhost: true, allow: driver_urls)
11 |
12 | VCR.configure do |c|
13 | c.allow_http_connections_when_no_cassette = false
14 | c.cassette_library_dir = Rails.root.join('spec', 'vcr')
15 | c.hook_into :webmock
16 | c.ignore_localhost = true
17 | c.ignore_hosts(*driver_hosts)
18 | c.configure_rspec_metadata!
19 | c.default_cassette_options = { record: :new_episodes }
20 | end
21 |
--------------------------------------------------------------------------------
/services/backend/storage/00/6g/006gnisak94ytqimt378gbad2hf9:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/00/6g/006gnisak94ytqimt378gbad2hf9
--------------------------------------------------------------------------------
/services/backend/storage/0i/zg/0izgp4zdrg4bxwvji5e0598oa8mp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/0i/zg/0izgp4zdrg4bxwvji5e0598oa8mp
--------------------------------------------------------------------------------
/services/backend/storage/0k/8u/0k8uufd4279o44gzgz5efagsqteu:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/0k/8u/0k8uufd4279o44gzgz5efagsqteu
--------------------------------------------------------------------------------
/services/backend/storage/0r/42/0r42dufnbi6rctn4vap71d1urqk9:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/0r/42/0r42dufnbi6rctn4vap71d1urqk9
--------------------------------------------------------------------------------
/services/backend/storage/0r/r1/0rr1qtiq705h498m2e65y04aa1fb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/0r/r1/0rr1qtiq705h498m2e65y04aa1fb
--------------------------------------------------------------------------------
/services/backend/storage/14/zj/14zj5sb9no7mevm8vtzjcym71vy1:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/14/zj/14zj5sb9no7mevm8vtzjcym71vy1
--------------------------------------------------------------------------------
/services/backend/storage/16/9t/169tp3memt7id57sh22o8ejtcblg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/16/9t/169tp3memt7id57sh22o8ejtcblg
--------------------------------------------------------------------------------
/services/backend/storage/1c/n3/1cn3v98qnmqwts7m6l5xkbhzvffn:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/1c/n3/1cn3v98qnmqwts7m6l5xkbhzvffn
--------------------------------------------------------------------------------
/services/backend/storage/1j/z1/1jz13ploviow14epdbc68db9fslw:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/1j/z1/1jz13ploviow14epdbc68db9fslw
--------------------------------------------------------------------------------
/services/backend/storage/1k/s2/1ks2veug3cveel5c0eeyaq0m647s:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/1k/s2/1ks2veug3cveel5c0eeyaq0m647s
--------------------------------------------------------------------------------
/services/backend/storage/2f/y5/2fy5a3t0idckqt117wqp88l1haj8:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/2f/y5/2fy5a3t0idckqt117wqp88l1haj8
--------------------------------------------------------------------------------
/services/backend/storage/2o/or/2ooru1xgcss6d2qeg4iwmjjgz2c9:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/2o/or/2ooru1xgcss6d2qeg4iwmjjgz2c9
--------------------------------------------------------------------------------
/services/backend/storage/2q/zh/2qzh6w5ugc805s50nivs2k1xxfvi:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/2q/zh/2qzh6w5ugc805s50nivs2k1xxfvi
--------------------------------------------------------------------------------
/services/backend/storage/3l/sq/3lsqhzqyca5o90l7ek5lcic5ge8z:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/3l/sq/3lsqhzqyca5o90l7ek5lcic5ge8z
--------------------------------------------------------------------------------
/services/backend/storage/3o/i8/3oi8wwgyay2a5vsted2felpry3yw:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/3o/i8/3oi8wwgyay2a5vsted2felpry3yw
--------------------------------------------------------------------------------
/services/backend/storage/3p/nu/3pnujzkcnksw26a0cu1vtyp1uviz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/3p/nu/3pnujzkcnksw26a0cu1vtyp1uviz
--------------------------------------------------------------------------------
/services/backend/storage/41/wp/41wprtxdhsy40nh2h3igvhpdh982:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/41/wp/41wprtxdhsy40nh2h3igvhpdh982
--------------------------------------------------------------------------------
/services/backend/storage/5b/ea/5beayoc679qsbk1udyydvujp3tuv:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/5b/ea/5beayoc679qsbk1udyydvujp3tuv
--------------------------------------------------------------------------------
/services/backend/storage/62/xk/62xky8otdpnd1lm3zr07z7udt2bx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/62/xk/62xky8otdpnd1lm3zr07z7udt2bx
--------------------------------------------------------------------------------
/services/backend/storage/6f/85/6f852pkntrw16c0w9wzpdx2rnmud:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/6f/85/6f852pkntrw16c0w9wzpdx2rnmud
--------------------------------------------------------------------------------
/services/backend/storage/6m/b7/6mb7uh60to9dg7fvpjljjmqdnyfw:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/6m/b7/6mb7uh60to9dg7fvpjljjmqdnyfw
--------------------------------------------------------------------------------
/services/backend/storage/75/n1/75n1re2ozjbz45a88irjss1pu9e6:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/75/n1/75n1re2ozjbz45a88irjss1pu9e6
--------------------------------------------------------------------------------
/services/backend/storage/77/of/77of4hptz6t0rf0gn04v0kqjt4dm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/77/of/77of4hptz6t0rf0gn04v0kqjt4dm
--------------------------------------------------------------------------------
/services/backend/storage/7u/pj/7upjjhp3sbp38un5ii23l5bm1tf8:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/7u/pj/7upjjhp3sbp38un5ii23l5bm1tf8
--------------------------------------------------------------------------------
/services/backend/storage/7v/xz/7vxzmrg3zgfub67kf82hb5vifqzu:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/7v/xz/7vxzmrg3zgfub67kf82hb5vifqzu
--------------------------------------------------------------------------------
/services/backend/storage/86/fg/86fgtuga925kaa17km9eamshazgr:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/86/fg/86fgtuga925kaa17km9eamshazgr
--------------------------------------------------------------------------------
/services/backend/storage/88/44/8844gxgfc9ul1djle5kf8sqmgiyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/88/44/8844gxgfc9ul1djle5kf8sqmgiyc
--------------------------------------------------------------------------------
/services/backend/storage/88/he/88hekent0qoefm8b69builrth0xv:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/88/he/88hekent0qoefm8b69builrth0xv
--------------------------------------------------------------------------------
/services/backend/storage/89/to/89to0ymiqabe72nctvgrgqzyrk0o:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/89/to/89to0ymiqabe72nctvgrgqzyrk0o
--------------------------------------------------------------------------------
/services/backend/storage/8c/kn/8cknyjfznqw5id8jzny40hewyyrm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/8c/kn/8cknyjfznqw5id8jzny40hewyyrm
--------------------------------------------------------------------------------
/services/backend/storage/8d/rw/8drwmhakoag0ra8a1myjdr80mt57:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/8d/rw/8drwmhakoag0ra8a1myjdr80mt57
--------------------------------------------------------------------------------
/services/backend/storage/8i/vj/8ivjybuoo1jtnknvptho0ia2ysvl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/8i/vj/8ivjybuoo1jtnknvptho0ia2ysvl
--------------------------------------------------------------------------------
/services/backend/storage/97/xe/97xen0j7t6ketkwt4l8vobq14qq9:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/97/xe/97xen0j7t6ketkwt4l8vobq14qq9
--------------------------------------------------------------------------------
/services/backend/storage/9l/c4/9lc4lfmxvou7mvwqsl8g2fm27wfm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/9l/c4/9lc4lfmxvou7mvwqsl8g2fm27wfm
--------------------------------------------------------------------------------
/services/backend/storage/9l/ev/9levi783acolroehz6wn0cm0mzwa:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/9l/ev/9levi783acolroehz6wn0cm0mzwa
--------------------------------------------------------------------------------
/services/backend/storage/az/ws/azwswza6kecyh2bmfnlpr7besvvb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/az/ws/azwswza6kecyh2bmfnlpr7besvvb
--------------------------------------------------------------------------------
/services/backend/storage/b0/72/b0726xe61gdgxgmjki58njnwsivr:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/b0/72/b0726xe61gdgxgmjki58njnwsivr
--------------------------------------------------------------------------------
/services/backend/storage/b0/95/b095fsshrfwmoexn8czq2m3aiqbe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/b0/95/b095fsshrfwmoexn8czq2m3aiqbe
--------------------------------------------------------------------------------
/services/backend/storage/b5/31/b531yunrur87esye2s4cwavym6te:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/b5/31/b531yunrur87esye2s4cwavym6te
--------------------------------------------------------------------------------
/services/backend/storage/bb/45/bb45cs77n8gzn4ps91exl1cxuyft:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/bb/45/bb45cs77n8gzn4ps91exl1cxuyft
--------------------------------------------------------------------------------
/services/backend/storage/bb/xn/bbxn5vhfqpqdykae8z2cdf5x3dgs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/bb/xn/bbxn5vhfqpqdykae8z2cdf5x3dgs
--------------------------------------------------------------------------------
/services/backend/storage/bf/kg/bfkgrq99dea00vq7i74ludx4q31l:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/bf/kg/bfkgrq99dea00vq7i74ludx4q31l
--------------------------------------------------------------------------------
/services/backend/storage/bl/xp/blxpqifldxzmb0nby4czkfn4u9q6:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/bl/xp/blxpqifldxzmb0nby4czkfn4u9q6
--------------------------------------------------------------------------------
/services/backend/storage/bp/08/bp08j2pskt6xgz9ah0714mqdjwz7:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/bp/08/bp08j2pskt6xgz9ah0714mqdjwz7
--------------------------------------------------------------------------------
/services/backend/storage/bz/2a/bz2awto4gfx6t6udd7k5gjvke8i7:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/bz/2a/bz2awto4gfx6t6udd7k5gjvke8i7
--------------------------------------------------------------------------------
/services/backend/storage/c9/cj/c9cjtgt3p7hdujcaxt41t08u1kux:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/c9/cj/c9cjtgt3p7hdujcaxt41t08u1kux
--------------------------------------------------------------------------------
/services/backend/storage/cb/kx/cbkxlh6px78ymmakilgwygcm0qn5:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/cb/kx/cbkxlh6px78ymmakilgwygcm0qn5
--------------------------------------------------------------------------------
/services/backend/storage/cj/1d/cj1dxfmw44hktr8lhbwzpw7aoxz5:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/cj/1d/cj1dxfmw44hktr8lhbwzpw7aoxz5
--------------------------------------------------------------------------------
/services/backend/storage/d7/k8/d7k8l52o2ji9tkor07sqd25wpxdk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/d7/k8/d7k8l52o2ji9tkor07sqd25wpxdk
--------------------------------------------------------------------------------
/services/backend/storage/db/ag/dbagqumqgq1z6319o338j7bmt5pq:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/db/ag/dbagqumqgq1z6319o338j7bmt5pq
--------------------------------------------------------------------------------
/services/backend/storage/dq/c7/dqc7t23uxsm5axhesoap039wqjeb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/dq/c7/dqc7t23uxsm5axhesoap039wqjeb
--------------------------------------------------------------------------------
/services/backend/storage/e3/lt/e3ltmq2g8mfvj4wifyzt7uj3w5ns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/e3/lt/e3ltmq2g8mfvj4wifyzt7uj3w5ns
--------------------------------------------------------------------------------
/services/backend/storage/eb/2a/eb2a2zd73ok9x0rlw0o164mduamd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/eb/2a/eb2a2zd73ok9x0rlw0o164mduamd
--------------------------------------------------------------------------------
/services/backend/storage/f1/6r/f16rwfhvanpxrwgn2ct48cgfp326:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/f1/6r/f16rwfhvanpxrwgn2ct48cgfp326
--------------------------------------------------------------------------------
/services/backend/storage/f1/f6/f1f6rz6nuf57ryix259yxq7j3tje:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/f1/f6/f1f6rz6nuf57ryix259yxq7j3tje
--------------------------------------------------------------------------------
/services/backend/storage/f3/dt/f3dtrvou5azxky00y68u7qbjgaqn:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/f3/dt/f3dtrvou5azxky00y68u7qbjgaqn
--------------------------------------------------------------------------------
/services/backend/storage/f5/xr/f5xr4qy5dtulhpe8kgazjo2x7ubz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/f5/xr/f5xr4qy5dtulhpe8kgazjo2x7ubz
--------------------------------------------------------------------------------
/services/backend/storage/f7/tg/f7tg9iqtd0i6tqxzkf15010kl9xq:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/f7/tg/f7tg9iqtd0i6tqxzkf15010kl9xq
--------------------------------------------------------------------------------
/services/backend/storage/fj/gx/fjgxeszqvcbrc0v0u2n7i70yd956:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/fj/gx/fjgxeszqvcbrc0v0u2n7i70yd956
--------------------------------------------------------------------------------
/services/backend/storage/fk/0o/fk0o9nsutjpswot205kna7pdoj02:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/fk/0o/fk0o9nsutjpswot205kna7pdoj02
--------------------------------------------------------------------------------
/services/backend/storage/fs/ip/fsipi7gdrjs2mxhgop0etbuwsfu2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/fs/ip/fsipi7gdrjs2mxhgop0etbuwsfu2
--------------------------------------------------------------------------------
/services/backend/storage/fy/au/fyau0gplpld5a6c12gvncp18ravq:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/fy/au/fyau0gplpld5a6c12gvncp18ravq
--------------------------------------------------------------------------------
/services/backend/storage/gq/x4/gqx496zj9ao0ce2y69s8ebcdt76c:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/gq/x4/gqx496zj9ao0ce2y69s8ebcdt76c
--------------------------------------------------------------------------------
/services/backend/storage/gs/1o/gs1oqg4v74c76h2f8zsqj0p91yjc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/gs/1o/gs1oqg4v74c76h2f8zsqj0p91yjc
--------------------------------------------------------------------------------
/services/backend/storage/h3/um/h3ump7vjqudll390ky1rdss0xdb4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/h3/um/h3ump7vjqudll390ky1rdss0xdb4
--------------------------------------------------------------------------------
/services/backend/storage/h8/3c/h83cdk6x8kd1amwvte8aavqnxii3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/h8/3c/h83cdk6x8kd1amwvte8aavqnxii3
--------------------------------------------------------------------------------
/services/backend/storage/hm/nd/hmndfefa02esgzpaqksemkf51q88:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/hm/nd/hmndfefa02esgzpaqksemkf51q88
--------------------------------------------------------------------------------
/services/backend/storage/hp/sk/hpskdx8sfybt0o39s4e2veuqv6nd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/hp/sk/hpskdx8sfybt0o39s4e2veuqv6nd
--------------------------------------------------------------------------------
/services/backend/storage/hv/lm/hvlm8gb3nktx69eteqqt7atj9qrs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/hv/lm/hvlm8gb3nktx69eteqqt7atj9qrs
--------------------------------------------------------------------------------
/services/backend/storage/ir/5t/ir5thn1x7rn9legliqvjh23qg1bl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/ir/5t/ir5thn1x7rn9legliqvjh23qg1bl
--------------------------------------------------------------------------------
/services/backend/storage/j4/j2/j4j2wb67ekv1hle6t5z2aq19gstf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/j4/j2/j4j2wb67ekv1hle6t5z2aq19gstf
--------------------------------------------------------------------------------
/services/backend/storage/jl/mg/jlmgno906bkhwsytjqiyns2hqut8:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/jl/mg/jlmgno906bkhwsytjqiyns2hqut8
--------------------------------------------------------------------------------
/services/backend/storage/jo/ru/joru4prw3skdtc8i4ia5dwq5874k:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/jo/ru/joru4prw3skdtc8i4ia5dwq5874k
--------------------------------------------------------------------------------
/services/backend/storage/jr/qt/jrqti00rfi88kdgvjnw4s0tdv7xc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/jr/qt/jrqti00rfi88kdgvjnw4s0tdv7xc
--------------------------------------------------------------------------------
/services/backend/storage/k7/hr/k7hrw0msrvsspxi698amx5kmh2wg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/k7/hr/k7hrw0msrvsspxi698amx5kmh2wg
--------------------------------------------------------------------------------
/services/backend/storage/kr/u2/kru2kfqkml3mwkuhmc2w0uvtp4x1:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/kr/u2/kru2kfqkml3mwkuhmc2w0uvtp4x1
--------------------------------------------------------------------------------
/services/backend/storage/kw/ch/kwchc38i5j2uqyrfui13h914doju:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/kw/ch/kwchc38i5j2uqyrfui13h914doju
--------------------------------------------------------------------------------
/services/backend/storage/l0/id/l0idqd59oxu5iz00z9m3iep48pjm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/l0/id/l0idqd59oxu5iz00z9m3iep48pjm
--------------------------------------------------------------------------------
/services/backend/storage/l8/1g/l81gft3rnuphlp36xw4q33p4r1cs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/l8/1g/l81gft3rnuphlp36xw4q33p4r1cs
--------------------------------------------------------------------------------
/services/backend/storage/lp/lr/lplrh3v056du1izagk5o76sfu98p:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/lp/lr/lplrh3v056du1izagk5o76sfu98p
--------------------------------------------------------------------------------
/services/backend/storage/lt/mc/ltmc7z2yt5ozwpuqmoz2uw98xylf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/lt/mc/ltmc7z2yt5ozwpuqmoz2uw98xylf
--------------------------------------------------------------------------------
/services/backend/storage/m6/sb/m6sbj199y5b8id0eg6dvktm1nbyu:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/m6/sb/m6sbj199y5b8id0eg6dvktm1nbyu
--------------------------------------------------------------------------------
/services/backend/storage/ms/m8/msm81dgmxk4ggqiud2bv4j9waoie:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/ms/m8/msm81dgmxk4ggqiud2bv4j9waoie
--------------------------------------------------------------------------------
/services/backend/storage/n1/m4/n1m4ol3mo2fbg77imv5qn156swi4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/n1/m4/n1m4ol3mo2fbg77imv5qn156swi4
--------------------------------------------------------------------------------
/services/backend/storage/n8/aa/n8aao8d8v8ene7vn4d14zdqxntna:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/n8/aa/n8aao8d8v8ene7vn4d14zdqxntna
--------------------------------------------------------------------------------
/services/backend/storage/nd/mb/ndmbmj2or9w5lgnwmyyexp34n509:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/nd/mb/ndmbmj2or9w5lgnwmyyexp34n509
--------------------------------------------------------------------------------
/services/backend/storage/ni/yw/niywd6phcjdfuxw97lxi1y8t1sya:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/ni/yw/niywd6phcjdfuxw97lxi1y8t1sya
--------------------------------------------------------------------------------
/services/backend/storage/nx/9d/nx9dapm2zhd2kh991ompea29775m:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/nx/9d/nx9dapm2zhd2kh991ompea29775m
--------------------------------------------------------------------------------
/services/backend/storage/o5/d9/o5d9h8s1hih1gihezeeu73fgwa88:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/o5/d9/o5d9h8s1hih1gihezeeu73fgwa88
--------------------------------------------------------------------------------
/services/backend/storage/o7/2a/o72a5s5ye01ie6mtx8h7olnldvko:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/o7/2a/o72a5s5ye01ie6mtx8h7olnldvko
--------------------------------------------------------------------------------
/services/backend/storage/oi/fp/oifpdmfenjck5p39s91m8ij5ya5a:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/oi/fp/oifpdmfenjck5p39s91m8ij5ya5a
--------------------------------------------------------------------------------
/services/backend/storage/op/a2/opa2g8bl3tpm0ecip3f4yun9hcd8:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/op/a2/opa2g8bl3tpm0ecip3f4yun9hcd8
--------------------------------------------------------------------------------
/services/backend/storage/os/vh/osvherjecbdx3ezy3jvar6vvfwrk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/os/vh/osvherjecbdx3ezy3jvar6vvfwrk
--------------------------------------------------------------------------------
/services/backend/storage/ox/4i/ox4iruasiwuftdu71u98l5t4rpgm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/ox/4i/ox4iruasiwuftdu71u98l5t4rpgm
--------------------------------------------------------------------------------
/services/backend/storage/p7/d5/p7d5guboq24b265ytl0u5w20hzjl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/p7/d5/p7d5guboq24b265ytl0u5w20hzjl
--------------------------------------------------------------------------------
/services/backend/storage/p8/0j/p80jyh6ws8gqmfrp8kcjcgctdieh:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/p8/0j/p80jyh6ws8gqmfrp8kcjcgctdieh
--------------------------------------------------------------------------------
/services/backend/storage/pi/co/picolufbbcsybadgh89nutlhun53:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/pi/co/picolufbbcsybadgh89nutlhun53
--------------------------------------------------------------------------------
/services/backend/storage/pk/18/pk18k7l7xvz7fcz9ecz20m01mbg1:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/pk/18/pk18k7l7xvz7fcz9ecz20m01mbg1
--------------------------------------------------------------------------------
/services/backend/storage/q5/90/q590wag6b1vszjszc3mfd23192sj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/q5/90/q590wag6b1vszjszc3mfd23192sj
--------------------------------------------------------------------------------
/services/backend/storage/q8/69/q869nghoropy7vm31r30cgs85x0d:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/q8/69/q869nghoropy7vm31r30cgs85x0d
--------------------------------------------------------------------------------
/services/backend/storage/r0/l3/r0l3vmf800tdhnaha8ipdutspb1e:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/r0/l3/r0l3vmf800tdhnaha8ipdutspb1e
--------------------------------------------------------------------------------
/services/backend/storage/rc/p1/rcp1c0ffcrahrxl6ddwdj502lrzh:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/rc/p1/rcp1c0ffcrahrxl6ddwdj502lrzh
--------------------------------------------------------------------------------
/services/backend/storage/rp/62/rp62efuo0c81qrdzczbw9vbu1eih:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/rp/62/rp62efuo0c81qrdzczbw9vbu1eih
--------------------------------------------------------------------------------
/services/backend/storage/rw/st/rwst4dkl9wdsmq13w2fwj04ha284:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/rw/st/rwst4dkl9wdsmq13w2fwj04ha284
--------------------------------------------------------------------------------
/services/backend/storage/rx/4i/rx4ig9xw7h5y1y2sqqmawsq1x17p:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/rx/4i/rx4ig9xw7h5y1y2sqqmawsq1x17p
--------------------------------------------------------------------------------
/services/backend/storage/ss/kb/sskbwu2e4lqf6vdd9po2ozhnfm6d:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/ss/kb/sskbwu2e4lqf6vdd9po2ozhnfm6d
--------------------------------------------------------------------------------
/services/backend/storage/t2/gb/t2gbiuwefu2cu69nx6ef7mxvlkyf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/t2/gb/t2gbiuwefu2cu69nx6ef7mxvlkyf
--------------------------------------------------------------------------------
/services/backend/storage/t8/sf/t8sfq5w9vte2byg1ql3vrf6erjz6:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/t8/sf/t8sfq5w9vte2byg1ql3vrf6erjz6
--------------------------------------------------------------------------------
/services/backend/storage/ta/su/tasu842mlz829y8ps7va67ttq7my:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/ta/su/tasu842mlz829y8ps7va67ttq7my
--------------------------------------------------------------------------------
/services/backend/storage/tc/uy/tcuywtfa5bo7iswkbmocinkv4obn:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/tc/uy/tcuywtfa5bo7iswkbmocinkv4obn
--------------------------------------------------------------------------------
/services/backend/storage/tq/3q/tq3q5lsbdzh1hfwfto2ub0dwuuul:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/tq/3q/tq3q5lsbdzh1hfwfto2ub0dwuuul
--------------------------------------------------------------------------------
/services/backend/storage/u5/m8/u5m8nx87ih2y01eoc5y0og5exoga:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/u5/m8/u5m8nx87ih2y01eoc5y0og5exoga
--------------------------------------------------------------------------------
/services/backend/storage/un/6x/un6xvbm6l3ecxwxwuxffc6b6pksy:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/un/6x/un6xvbm6l3ecxwxwuxffc6b6pksy
--------------------------------------------------------------------------------
/services/backend/storage/v2/d6/v2d6kiibpmi2n5wei0zvfmgcrcp6:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/v2/d6/v2d6kiibpmi2n5wei0zvfmgcrcp6
--------------------------------------------------------------------------------
/services/backend/storage/vd/hf/vdhfjqfz88rsidepmoygmvmzuory:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/vd/hf/vdhfjqfz88rsidepmoygmvmzuory
--------------------------------------------------------------------------------
/services/backend/storage/vk/66/vk66376ys3oh94khxr2gyaqe718p:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/vk/66/vk66376ys3oh94khxr2gyaqe718p
--------------------------------------------------------------------------------
/services/backend/storage/vk/qt/vkqtro308bcx9nauolzjgfsdjiaj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/vk/qt/vkqtro308bcx9nauolzjgfsdjiaj
--------------------------------------------------------------------------------
/services/backend/storage/vn/91/vn912gigj022zdj21b018id2vb0h:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/vn/91/vn912gigj022zdj21b018id2vb0h
--------------------------------------------------------------------------------
/services/backend/storage/w7/h1/w7h15x1uh9994su68lm16er6p8fj:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/w7/h1/w7h15x1uh9994su68lm16er6p8fj
--------------------------------------------------------------------------------
/services/backend/storage/wp/ik/wpik6q4kgdlnd8zy9vxfayze9bxl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/wp/ik/wpik6q4kgdlnd8zy9vxfayze9bxl
--------------------------------------------------------------------------------
/services/backend/storage/wt/zf/wtzfa794b5vpax1qrbegb7xnioi2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/wt/zf/wtzfa794b5vpax1qrbegb7xnioi2
--------------------------------------------------------------------------------
/services/backend/storage/x0/j5/x0j50n6qwk4g0p72hy9h9gmz9l41:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/x0/j5/x0j50n6qwk4g0p72hy9h9gmz9l41
--------------------------------------------------------------------------------
/services/backend/storage/xp/7a/xp7a6l2hhtrp4ow3oo2e8ozqzuz1:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/xp/7a/xp7a6l2hhtrp4ow3oo2e8ozqzuz1
--------------------------------------------------------------------------------
/services/backend/storage/yu/65/yu65ul5ekff3gdub9ot599wbqq5t:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/yu/65/yu65ul5ekff3gdub9ot599wbqq5t
--------------------------------------------------------------------------------
/services/backend/storage/z8/lp/z8lp9oe5quoqzkewjtvj14rubeg0:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/z8/lp/z8lp9oe5quoqzkewjtvj14rubeg0
--------------------------------------------------------------------------------
/services/backend/storage/zi/ae/ziae3tzvaen6pm7pdzsya7rv46l3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/storage/zi/ae/ziae3tzvaen6pm7pdzsya7rv46l3
--------------------------------------------------------------------------------
/services/backend/vendor/assets/javascripts/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/vendor/assets/javascripts/.keep
--------------------------------------------------------------------------------
/services/backend/vendor/assets/javascripts/spree/backend/all.js:
--------------------------------------------------------------------------------
1 | // This is a manifest file that'll be compiled into including all the files listed below.
2 | // Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
3 | // be included in the compiled file accessible from http://example.com/assets/application.js
4 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
5 | // the compiled file.
6 | //
7 | //= require spree/backend
8 | //= require_tree .
9 |
--------------------------------------------------------------------------------
/services/backend/vendor/assets/javascripts/spree/frontend/all.js:
--------------------------------------------------------------------------------
1 | // This is a manifest file that'll be compiled into including all the files listed below.
2 | // Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
3 | // be included in the compiled file accessible from http://example.com/assets/application.js
4 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
5 | // the compiled file.
6 | //
7 | //= require spree/frontend
8 |
9 | //= require_tree .
10 |
--------------------------------------------------------------------------------
/services/backend/vendor/assets/stylesheets/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/backend/vendor/assets/stylesheets/.keep
--------------------------------------------------------------------------------
/services/backend/vendor/assets/stylesheets/spree/backend/all.css:
--------------------------------------------------------------------------------
1 | /*
2 | * This is a manifest file that'll automatically include all the stylesheets available in this directory
3 | * and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
4 | * the top of the compiled file, but it's generally better to create a new file per style scope.
5 | *
6 | *= require spree/backend
7 | *= require_self
8 | *= require_tree .
9 | */
10 |
--------------------------------------------------------------------------------
/services/backend/vendor/assets/stylesheets/spree/frontend/all.css:
--------------------------------------------------------------------------------
1 | /*
2 | * This is a manifest file that'll automatically include all the stylesheets available in this directory
3 | * and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
4 | * the top of the compiled file, but it's generally better to create a new file per style scope.
5 | *
6 | *= require spree/frontend
7 |
8 | *= require_self
9 | *= require_tree .
10 | */
11 |
--------------------------------------------------------------------------------
/services/dbm/.dockerignore:
--------------------------------------------------------------------------------
1 | # Version control
2 | .git
3 |
4 | # Compiled Python bytecode
5 | **/__pycache__
6 | **/*.pyc
7 | **/*.pyo
8 |
9 | # Compiled extensions
10 | **/*.pyd
11 | **/*.so
12 |
13 | # coverage.py
14 | .coverage
15 | .coverage.*
16 | htmlcov
17 |
18 | # Cached files
19 | .cache
20 | .mypy_cache
21 | .hypothesis
22 | .pytest_cache
23 |
24 | # Virtualenvs and builds
25 | build/
26 | dist/
27 | .env
28 | .venv
29 | env/
30 | venv/
31 | ENV/
32 | env.bak/
33 | venv.bak/
34 |
35 | # Docker
36 | Dockerfile*
37 | .dockerignore
38 |
--------------------------------------------------------------------------------
/services/dbm/Dockerfile:
--------------------------------------------------------------------------------
1 | # syntax = docker/dockerfile:1.2
2 | # ^ This enables the new BuildKit stable syntax which can be
3 | # run with the DOCKER_BUILDKIT=1 environment variable in your
4 | # docker build command (see build.sh)
5 | FROM python:3.9.6-slim-buster
6 |
7 | # Update, upgrade, and cleanup debian packages
8 | RUN export DEBIAN_FRONTEND=noninteractive && \
9 | apt-get update && \
10 | apt-get upgrade --yes && \
11 | apt-get install --yes build-essential libpq-dev && \
12 | apt-get clean && \
13 | rm -rf /var/lib/apt/lists/*
14 |
15 | # Copy over app
16 | WORKDIR /app
17 | COPY . .
18 |
19 | # Install dependencies via pip and avoid caching build artifacts
20 | RUN pip install --no-cache-dir -r requirements.txt
21 |
22 | # Set default Flask app and development environment
23 | ENV FLASK_APP=dbm.py
24 |
25 | # Start the app using ddtrace so we have profiling and tracing
26 | ENTRYPOINT ["ddtrace-run"]
27 | CMD gunicorn --bind 0.0.0.0:7578 dbm:app
28 |
--------------------------------------------------------------------------------
/services/dbm/dbm_exec.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | psql -U postgres -d postgres -a -f /etc/postgresql/13/main/dbm_setup.sql
--------------------------------------------------------------------------------
/services/dbm/dbm_setup.sql:
--------------------------------------------------------------------------------
1 | create user datadog with password 'datadog';
2 | GRANT SELECT ON pg_stat_database TO datadog;
3 | CREATE SCHEMA datadog;
4 | GRANT USAGE ON SCHEMA datadog TO datadog;
5 | GRANT USAGE ON SCHEMA public TO datadog;
6 | GRANT pg_monitor TO datadog;
7 | CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
8 |
9 | CREATE OR REPLACE FUNCTION datadog.explain_statement(
10 | l_query TEXT,
11 | OUT explain JSON
12 | )
13 | RETURNS SETOF JSON AS
14 | $$
15 | DECLARE
16 | curs REFCURSOR;
17 | plan JSON;
18 |
19 | BEGIN
20 | OPEN curs FOR EXECUTE pg_catalog.concat('EXPLAIN (FORMAT JSON) ', l_query);
21 | FETCH curs INTO plan;
22 | CLOSE curs;
23 | RETURN QUERY SELECT plan;
24 | END;
25 | $$
26 | LANGUAGE 'plpgsql'
27 | RETURNS NULL ON NULL INPUT
28 | SECURITY DEFINER;
--------------------------------------------------------------------------------
/services/dbm/requirements.txt:
--------------------------------------------------------------------------------
1 | certifi==2020.11.8
2 | chardet==3.0.4
3 | click==8.0
4 | ddtrace==2.16.0
5 | Flask==2.2.2
6 | Flask-Login==0.6.2
7 | Flask-WTF==1.0.1
8 | Flask-Cors==3.0.10
9 | Flask-SQLAlchemy==3.0.2
10 | idna==2.10
11 | intervaltree==3.1.0
12 | itsdangerous==2.0
13 | Jinja2==3.0
14 | MarkupSafe==2.1.1
15 | nose==1.3.7
16 | protobuf==3.14.0
17 | requests==2.25.1
18 | six==1.15.0
19 | sortedcontainers==2.3.0
20 | SQLAlchemy==1.4.42
21 | psycopg2-binary
22 | tenacity==6.2.0
23 | urllib3==1.26.5
24 | gunicorn==20.1.0
25 | Faker==18.3.2
26 | Werkzeug==2.2.2
27 |
--------------------------------------------------------------------------------
/services/discounts/.dockerignore:
--------------------------------------------------------------------------------
1 | # Version control
2 | .git
3 |
4 | # Compiled Python bytecode
5 | **/__pycache__
6 | **/*.pyc
7 | **/*.pyo
8 |
9 | # Compiled extensions
10 | **/*.pyd
11 | **/*.so
12 |
13 | # coverage.py
14 | .coverage
15 | .coverage.*
16 | htmlcov
17 |
18 | # Cached files
19 | .cache
20 | .mypy_cache
21 | .hypothesis
22 | .pytest_cache
23 |
24 | # Virtualenvs and builds
25 | build/
26 | dist/
27 | .env
28 | .venv
29 | env/
30 | venv/
31 | ENV/
32 | env.bak/
33 | venv.bak/
34 |
35 | # Docker
36 | Dockerfile*
37 | .dockerignore
38 |
--------------------------------------------------------------------------------
/services/discounts/requirements.txt:
--------------------------------------------------------------------------------
1 | certifi==2020.12.5
2 | chardet==4.0.0
3 | click==7.1.2
4 | ddtrace==2.16.0
5 | Flask==1.1.2
6 | Flask-Cors==3.0.10
7 | Flask-SQLAlchemy==2.4.4
8 | idna==2.10
9 | intervaltree==3.1.0
10 | itsdangerous==1.1.0
11 | Jinja2==2.11.3
12 | MarkupSafe==1.1.1
13 | msgpack-python==0.5.6
14 | names==0.3.0
15 | nose==1.3.7
16 | protobuf==3.14.0
17 | psutil==5.8.0
18 | psycopg2==2.8.6
19 | PyDispatcher==2.0.5
20 | PyYAML==5.4.1
21 | requests==2.25.1
22 | six==1.15.0
23 | sortedcontainers==2.3.0
24 | SQLAlchemy==1.3.23
25 | tenacity==6.3.1
26 | urllib3==1.26.5
27 | Werkzeug==1.0.1
28 | wrapt==1.12.1
29 | JSON-log-formatter==0.5.2
--------------------------------------------------------------------------------
/services/frontend/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["next", "prettier"],
3 | "rules": {
4 | "react/no-unescaped-entities": "off"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/services/frontend/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | .next/
13 | out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | *.pem
21 | .idea
22 |
23 | # debug
24 | npm-debug.log*
25 | yarn-debug.log*
26 | yarn-error.log*
27 |
28 | # local env files
29 | .env
30 | .env.development.local
31 | .env.test.local
32 | .env.production.local
33 |
34 | # vercel
35 | .vercel
36 |
--------------------------------------------------------------------------------
/services/frontend/.prettierignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .next
3 | public
--------------------------------------------------------------------------------
/services/frontend/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "semi": false,
3 | "singleQuote": true,
4 | "tabWidth": 2,
5 | "useTabs": false
6 | }
7 |
--------------------------------------------------------------------------------
/services/frontend/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:20 AS builder
2 |
3 | # install wait-for-it
4 | RUN apt-get update && apt-get install -y wait-for-it
5 |
6 | WORKDIR /app
7 | COPY package*.json ./
8 | RUN npm install
9 | COPY . .
10 | EXPOSE 3000
11 |
--------------------------------------------------------------------------------
/services/frontend/README.md:
--------------------------------------------------------------------------------
1 | # Frontend service
2 |
3 | ## Description
4 |
5 | The frontend services is a JavaScript application that uses the Next.js React framework. It includes it's own set of API routes, which are used to fetch data from the backend services.
6 |
7 |
--------------------------------------------------------------------------------
/services/frontend/assets/chrome-bug.css:
--------------------------------------------------------------------------------
1 | /**
2 | * Chrome has a bug with transitions on load since 2012!
3 | *
4 | * To prevent a "pop" of content, you have to disable all transitions until
5 | * the page is done loading.
6 | *
7 | * https://lab.laukstein.com/bug/input
8 | * https://twitter.com/timer150/status/1345217126680899584
9 | */
10 | body.loading * {
11 | transition: none !important;
12 | }
13 |
--------------------------------------------------------------------------------
/services/frontend/assets/components.css:
--------------------------------------------------------------------------------
1 | .fit {
2 | min-height: calc(100vh - 88px);
3 | }
4 |
--------------------------------------------------------------------------------
/services/frontend/assets/main.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @import './base.css';
3 |
4 | @tailwind components;
5 | @import './components.css';
6 |
7 | @tailwind utilities;
8 |
--------------------------------------------------------------------------------
/services/frontend/components/cart/CartItem/CartItem.module.css:
--------------------------------------------------------------------------------
1 | .root {
2 | @apply flex flex-col py-4;
3 | }
4 |
5 | .root:first-child {
6 | padding-top: 0;
7 | }
8 |
9 | .quantity {
10 | appearance: textfield;
11 | @apply w-8 border-accent-2 border mx-3 rounded text-center text-sm text-black;
12 | }
13 |
14 | .quantity::-webkit-outer-spin-button,
15 | .quantity::-webkit-inner-spin-button {
16 | @apply appearance-none m-0;
17 | }
18 |
19 | .productImage {
20 | /* position: absolute;
21 | width: 100%;
22 | height: 100%;
23 | left: 30% !important;
24 | top: 30% !important; */
25 | transform: scale(1.3);
26 | z-index: 1;
27 | }
28 |
29 | .productName {
30 | @apply font-medium cursor-pointer pb-1;
31 | margin-top: -4px;
32 | }
33 |
--------------------------------------------------------------------------------
/services/frontend/components/cart/CartItem/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './CartItem'
2 |
--------------------------------------------------------------------------------
/services/frontend/components/cart/CartSidebarView/CartSidebarView.module.css:
--------------------------------------------------------------------------------
1 | .root {
2 | min-height: 100vh;
3 | }
4 |
5 | .root.empty {
6 | @apply bg-secondary text-secondary;
7 | }
8 |
9 | .lineItemsList {
10 | @apply py-4 space-y-6 sm:py-0 sm:space-y-0 sm:divide-y sm:divide-accent-2 border-accent-2;
11 | }
12 |
--------------------------------------------------------------------------------
/services/frontend/components/cart/CartSidebarView/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './CartSidebarView'
2 |
--------------------------------------------------------------------------------
/services/frontend/components/cart/index.ts:
--------------------------------------------------------------------------------
1 | export { default as CartSidebarView } from './CartSidebarView'
2 | export { default as CartItem } from './CartItem'
3 |
--------------------------------------------------------------------------------
/services/frontend/components/checkout/CheckoutSidebarView/CheckoutSidebarView.module.css:
--------------------------------------------------------------------------------
1 | .root {
2 | min-height: calc(100vh - 322px);
3 | }
4 |
5 | .lineItemsList {
6 | @apply py-4 space-y-6 sm:py-0 sm:space-y-0 sm:divide-y sm:divide-accent-2 border-accent-2;
7 | }
8 |
9 | .fieldset {
10 | @apply flex flex-col my-3;
11 | }
12 |
13 | .fieldset .label {
14 | @apply text-accent-7 uppercase text-xs font-medium mb-2;
15 | }
16 |
17 | .fieldset .input,
18 | .fieldset .select {
19 | @apply p-2 border border-accent-8 w-full text-sm font-normal bg-primary;
20 | }
21 |
22 | .fieldset .input:focus,
23 | .fieldset .select:focus {
24 | @apply outline-none shadow-outline-normal;
25 | }
26 |
27 | .radio {
28 | @apply bg-black;
29 | }
30 |
--------------------------------------------------------------------------------
/services/frontend/components/checkout/CheckoutSidebarView/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './CheckoutSidebarView'
2 |
--------------------------------------------------------------------------------
/services/frontend/components/checkout/OrderConfirmView/OrderConfirmView.module.css:
--------------------------------------------------------------------------------
1 | .root {
2 | @apply border border-accent-2 px-6 py-5 mb-4 text-center
3 | flex items-center cursor-pointer hover:border-accent-4;
4 | }
5 |
--------------------------------------------------------------------------------
/services/frontend/components/checkout/OrderConfirmView/OrderConfirmView.tsx:
--------------------------------------------------------------------------------
1 | import { FC } from 'react';
2 | import { Text } from '@components/ui';
3 | import { useUI } from '@components/ui/context';
4 | import SidebarLayout from '@components/common/SidebarLayout';
5 |
6 | const OrderConfirmView: FC = () => {
7 | const { setSidebarView } = useUI();
8 |
9 | return (
10 |
11 |
setSidebarView('CHECKOUT_VIEW')}>
12 |
13 | Thank you for your purchase!
14 |
15 |
16 |
17 | );
18 | };
19 |
20 | export default OrderConfirmView;
21 |
--------------------------------------------------------------------------------
/services/frontend/components/checkout/OrderConfirmView/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './OrderConfirmView'
--------------------------------------------------------------------------------
/services/frontend/components/checkout/PaymentMethodView/PaymentMethodView.module.css:
--------------------------------------------------------------------------------
1 | .fieldset {
2 | @apply flex flex-col my-3;
3 | }
4 |
5 | .fieldset .label {
6 | @apply text-accent-7 uppercase text-xs font-medium mb-2;
7 | }
8 |
9 | .fieldset .input,
10 | .fieldset .select {
11 | @apply p-2 border border-accent-8 w-full text-sm font-normal bg-primary;
12 | }
13 |
14 | .fieldset .input:focus,
15 | .fieldset .select:focus {
16 | @apply outline-none shadow-outline-normal;
17 | }
18 |
--------------------------------------------------------------------------------
/services/frontend/components/checkout/PaymentMethodView/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './PaymentMethodView'
2 |
--------------------------------------------------------------------------------
/services/frontend/components/checkout/PaymentWidget/PaymentWidget.module.css:
--------------------------------------------------------------------------------
1 | .root {
2 | @apply border border-accent-2 px-6 py-5 mb-4 text-center
3 | flex items-center cursor-pointer hover:border-accent-4;
4 | }
5 |
--------------------------------------------------------------------------------
/services/frontend/components/checkout/PaymentWidget/PaymentWidget.tsx:
--------------------------------------------------------------------------------
1 | import { FC } from 'react'
2 | import s from './PaymentWidget.module.css'
3 | import { ChevronRight, CreditCard, Check } from '@components/icons'
4 |
5 | interface ComponentProps {
6 | onClick?: () => any
7 | isValid?: boolean
8 | }
9 |
10 | const PaymentWidget: FC = ({ onClick, isValid }) => {
11 | return (
12 |
13 |
14 |
15 |
16 | Add Payment Method
17 |
18 | {/* VISA #### #### #### 2345 */}
19 |
20 |
{isValid ? : }
21 | {/*
22 |
23 |
*/}
24 |
25 | )
26 | }
27 |
28 | export default PaymentWidget
29 |
--------------------------------------------------------------------------------
/services/frontend/components/checkout/PaymentWidget/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './PaymentWidget'
2 |
--------------------------------------------------------------------------------
/services/frontend/components/checkout/ShippingView/ShippingView.module.css:
--------------------------------------------------------------------------------
1 | .fieldset {
2 | @apply flex flex-col my-3;
3 | }
4 |
5 | .fieldset .label {
6 | @apply text-accent-7 uppercase text-xs font-medium mb-2;
7 | }
8 |
9 | .fieldset .input,
10 | .fieldset .select {
11 | @apply p-2 border border-accent-8 w-full text-sm font-normal bg-primary;
12 | }
13 |
14 | .fieldset .input:focus,
15 | .fieldset .select:focus {
16 | @apply outline-none shadow-outline-normal;
17 | }
18 |
19 | .radio {
20 | @apply bg-black;
21 | }
22 |
--------------------------------------------------------------------------------
/services/frontend/components/checkout/ShippingView/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './ShippingView'
2 |
--------------------------------------------------------------------------------
/services/frontend/components/checkout/ShippingWidget/ShippingWidget.module.css:
--------------------------------------------------------------------------------
1 | .root {
2 | @apply border border-accent-2 px-6 py-5 mb-4 text-center
3 | flex items-center cursor-pointer hover:border-accent-4;
4 | }
5 |
--------------------------------------------------------------------------------
/services/frontend/components/checkout/ShippingWidget/ShippingWidget.tsx:
--------------------------------------------------------------------------------
1 | import { FC } from 'react'
2 | import s from './ShippingWidget.module.css'
3 | import { ChevronRight, MapPin, Check } from '@components/icons'
4 |
5 | interface ComponentProps {
6 | onClick?: () => any
7 | isValid?: boolean
8 | }
9 |
10 | const ShippingWidget: FC = ({ onClick, isValid }) => {
11 | return (
12 |
13 |
14 |
15 |
16 | Add Shipping Address
17 |
18 |
19 |
{isValid ? : }
20 | {/*
21 |
22 |
*/}
23 |
24 | )
25 | }
26 |
27 | export default ShippingWidget
28 |
--------------------------------------------------------------------------------
/services/frontend/components/checkout/ShippingWidget/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './ShippingWidget'
2 |
--------------------------------------------------------------------------------
/services/frontend/components/common/Ad/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Ad'
2 |
--------------------------------------------------------------------------------
/services/frontend/components/common/Avatar/Avatar.tsx:
--------------------------------------------------------------------------------
1 | import { FC, useRef, useEffect } from 'react'
2 | import { useUserAvatar } from '@lib/hooks/useUserAvatar'
3 |
4 | interface Props {
5 | className?: string
6 | children?: any
7 | }
8 |
9 | const Avatar: FC = ({}) => {
10 | let ref = useRef() as React.MutableRefObject
11 | let { userAvatar } = useUserAvatar()
12 |
13 | return (
14 |
19 | {/* Add an image - We're generating a gradient as placeholder
![]()
*/}
20 |
21 | )
22 | }
23 |
24 | export default Avatar
25 |
--------------------------------------------------------------------------------
/services/frontend/components/common/Avatar/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Avatar'
2 |
--------------------------------------------------------------------------------
/services/frontend/components/common/Discount/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Discount'
2 |
--------------------------------------------------------------------------------
/services/frontend/components/common/FeatureBar/FeatureBar.module.css:
--------------------------------------------------------------------------------
1 | .root {
2 | @apply text-center p-6 bg-primary text-sm flex-row
3 | justify-center items-center font-medium fixed bottom-0
4 | w-full z-30 transition-all duration-300 ease-out
5 | md:flex md:text-left;
6 | }
7 |
--------------------------------------------------------------------------------
/services/frontend/components/common/FeatureBar/FeatureBar.tsx:
--------------------------------------------------------------------------------
1 | import cn from 'clsx'
2 | import s from './FeatureBar.module.css'
3 |
4 | interface FeatureBarProps {
5 | className?: string
6 | title: string
7 | description?: string
8 | hide?: boolean
9 | action?: React.ReactNode
10 | }
11 |
12 | const FeatureBar: React.FC = ({
13 | title,
14 | description,
15 | className,
16 | action,
17 | hide,
18 | }) => {
19 | const rootClassName = cn(
20 | s.root,
21 | {
22 | transform: true,
23 | 'translate-y-0 opacity-100': !hide,
24 | 'translate-y-full opacity-0': hide,
25 | },
26 | className
27 | )
28 | return (
29 |
30 | {title}
31 |
32 | {description}
33 |
34 | {action && action}
35 |
36 | )
37 | }
38 |
39 | export default FeatureBar
40 |
--------------------------------------------------------------------------------
/services/frontend/components/common/FeatureBar/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './FeatureBar'
2 |
--------------------------------------------------------------------------------
/services/frontend/components/common/Footer/Footer.module.css:
--------------------------------------------------------------------------------
1 | .root {
2 | @apply border-t border-accent-2;
3 | }
4 |
5 | .link {
6 | & > svg {
7 | @apply transform duration-75 ease-linear;
8 | }
9 |
10 | &:hover > svg {
11 | @apply scale-110;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/services/frontend/components/common/Footer/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Footer'
2 |
--------------------------------------------------------------------------------
/services/frontend/components/common/Head/Head.tsx:
--------------------------------------------------------------------------------
1 | import type { VFC } from 'react'
2 | import { SEO } from '@components/common'
3 |
4 | const Head: VFC = () => {
5 | return (
6 |
7 |
12 |
13 |
14 | )
15 | }
16 |
17 | export default Head
18 |
--------------------------------------------------------------------------------
/services/frontend/components/common/Head/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Head'
2 |
--------------------------------------------------------------------------------
/services/frontend/components/common/HomeAllProductsGrid/HomeAllProductsGrid.module.css:
--------------------------------------------------------------------------------
1 | .root {
2 | @apply py-12 flex flex-col w-full px-6;
3 |
4 | @screen md {
5 | @apply flex-row;
6 | }
7 |
8 | & .asideWrapper {
9 | @apply pr-3 w-full relative;
10 |
11 | @screen md {
12 | @apply w-48;
13 | }
14 | }
15 |
16 | & .aside {
17 | @apply flex flex-row w-full justify-around mb-12;
18 |
19 | @screen md {
20 | @apply mb-0 block sticky top-32;
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/services/frontend/components/common/HomeAllProductsGrid/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './HomeAllProductsGrid'
2 |
--------------------------------------------------------------------------------
/services/frontend/components/common/Layout/Layout.module.css:
--------------------------------------------------------------------------------
1 | .root {
2 | @apply h-full bg-primary mx-auto transition-colors duration-150;
3 | max-width: 2460px;
4 | }
5 |
--------------------------------------------------------------------------------
/services/frontend/components/common/Layout/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Layout'
2 |
--------------------------------------------------------------------------------
/services/frontend/components/common/Navbar/Navbar.module.css:
--------------------------------------------------------------------------------
1 | .root {
2 | @apply sticky top-0 bg-primary z-40 transition-all duration-150;
3 | min-height: 74px;
4 | }
5 |
6 | .nav {
7 | @apply relative flex flex-row justify-between py-4 md:py-4;
8 | }
9 |
10 | .navMenu {
11 | @apply hidden ml-6 space-x-4 lg:block;
12 | }
13 |
14 | .link {
15 | @apply inline-flex items-center leading-6
16 | transition ease-in-out duration-75 cursor-pointer
17 | text-accent-5 text-lg;
18 | }
19 |
20 | .link:hover {
21 | @apply text-accent-9;
22 | }
23 |
24 | .link:focus {
25 | @apply outline-none text-accent-8;
26 | }
27 |
28 | .logo {
29 | @apply cursor-pointer border transform duration-100 ease-in-out px-3 py-2 bg-primary-2 text-white text-2xl;
30 |
31 | &:hover {
32 | @apply shadow-md;
33 | transform: scale(1.05);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/services/frontend/components/common/Navbar/NavbarRoot.tsx:
--------------------------------------------------------------------------------
1 | import { FC, useState, useEffect } from 'react'
2 | import throttle from 'lodash.throttle'
3 | import cn from 'clsx'
4 | import s from './Navbar.module.css'
5 |
6 | const NavbarRoot: FC = ({ children }) => {
7 | const [hasScrolled, setHasScrolled] = useState(false)
8 |
9 | useEffect(() => {
10 | const handleScroll = throttle(() => {
11 | const offset = 0
12 | const { scrollTop } = document.documentElement
13 | const scrolled = scrollTop > offset
14 |
15 | if (hasScrolled !== scrolled) {
16 | setHasScrolled(scrolled)
17 | }
18 | }, 200)
19 |
20 | document.addEventListener('scroll', handleScroll)
21 | return () => {
22 | document.removeEventListener('scroll', handleScroll)
23 | }
24 | }, [hasScrolled])
25 |
26 | return (
27 |
28 | {children}
29 |
30 | )
31 | }
32 |
33 | export default NavbarRoot
34 |
--------------------------------------------------------------------------------
/services/frontend/components/common/Navbar/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Navbar'
2 |
--------------------------------------------------------------------------------
/services/frontend/components/common/SEO/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './SEO'
2 |
--------------------------------------------------------------------------------
/services/frontend/components/common/Searchbar/Searchbar.module.css:
--------------------------------------------------------------------------------
1 | .root {
2 | @apply relative text-sm bg-accent-0 text-base w-full transition-colors duration-150 border border-accent-2;
3 | }
4 |
5 | .input {
6 | @apply bg-transparent px-3 py-2 appearance-none w-full transition duration-150 ease-in-out pr-10;
7 | }
8 |
9 | .input::placeholder {
10 | @apply text-accent-3;
11 | }
12 |
13 | .input:focus {
14 | @apply outline-none shadow-outline-normal;
15 | }
16 |
17 | .iconContainer {
18 | @apply absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none;
19 | }
20 |
21 | .icon {
22 | @apply h-5 w-5;
23 | }
24 |
25 | @screen sm {
26 | .input {
27 | min-width: 300px;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/services/frontend/components/common/Searchbar/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Searchbar'
2 |
--------------------------------------------------------------------------------
/services/frontend/components/common/SidebarLayout/SidebarLayout.module.css:
--------------------------------------------------------------------------------
1 | .root {
2 | @apply relative h-full flex flex-col;
3 | }
4 |
5 | .header {
6 | @apply sticky top-0 pl-4 py-4 pr-6
7 | flex items-center justify-between
8 | bg-accent-0 box-border w-full z-10;
9 | min-height: 66px;
10 | }
11 |
12 | .container {
13 | @apply flex flex-col flex-1 box-border;
14 | }
15 |
16 | @screen lg {
17 | .header {
18 | min-height: 74px;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/services/frontend/components/common/SidebarLayout/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './SidebarLayout'
2 |
--------------------------------------------------------------------------------
/services/frontend/components/common/UserNav/MenuSidebarView/MenuSidebarView.module.css:
--------------------------------------------------------------------------------
1 | .root {
2 | @apply px-4 sm:px-6 sm:w-full flex-1 z-20;
3 | }
4 |
5 | .item {
6 | @apply text-xl font-bold py-2;
7 | }
8 |
--------------------------------------------------------------------------------
/services/frontend/components/common/UserNav/MenuSidebarView/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './MenuSidebarView'
2 | export interface Link {
3 | href: string
4 | label: string
5 | }
6 |
--------------------------------------------------------------------------------
/services/frontend/components/common/UserNav/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './UserNav'
2 | export { default as MenuSidebarView } from './MenuSidebarView'
3 |
--------------------------------------------------------------------------------
/services/frontend/components/common/index.ts:
--------------------------------------------------------------------------------
1 | export { default as Avatar } from './Avatar'
2 | export { default as FeatureBar } from './FeatureBar'
3 | export { default as Footer } from './Footer'
4 | export { default as Layout } from './Layout'
5 | export { default as Navbar } from './Navbar'
6 | export { default as Searchbar } from './Searchbar'
7 | export { default as UserNav } from './UserNav'
8 | export { default as Head } from './Head'
9 | export { default as SEO } from './SEO'
10 |
--------------------------------------------------------------------------------
/services/frontend/components/icons/ArrowLeft.tsx:
--------------------------------------------------------------------------------
1 | const ArrowLeft = ({ ...props }) => {
2 | return (
3 |
24 | )
25 | }
26 |
27 | export default ArrowLeft
28 |
--------------------------------------------------------------------------------
/services/frontend/components/icons/ArrowRight.tsx:
--------------------------------------------------------------------------------
1 | const ArrowRight = ({ ...props }) => {
2 | return (
3 |
25 | )
26 | }
27 |
28 | export default ArrowRight
29 |
--------------------------------------------------------------------------------
/services/frontend/components/icons/Bag.tsx:
--------------------------------------------------------------------------------
1 | const Bag = ({ ...props }) => {
2 | return (
3 |
30 | )
31 | }
32 |
33 | export default Bag
34 |
--------------------------------------------------------------------------------
/services/frontend/components/icons/Check.tsx:
--------------------------------------------------------------------------------
1 | const Check = ({ ...props }) => {
2 | return (
3 |
18 | )
19 | }
20 |
21 | export default Check
22 |
--------------------------------------------------------------------------------
/services/frontend/components/icons/ChevronDown.tsx:
--------------------------------------------------------------------------------
1 | const ChevronDown = ({ ...props }) => {
2 | return (
3 |
17 | )
18 | }
19 |
20 | export default ChevronDown
21 |
--------------------------------------------------------------------------------
/services/frontend/components/icons/ChevronLeft.tsx:
--------------------------------------------------------------------------------
1 | const ChevronLeft = ({ ...props }) => {
2 | return (
3 |
17 | )
18 | }
19 |
20 | export default ChevronLeft
21 |
--------------------------------------------------------------------------------
/services/frontend/components/icons/ChevronRight.tsx:
--------------------------------------------------------------------------------
1 | const ChevronRight = ({ ...props }) => {
2 | return (
3 |
17 | )
18 | }
19 |
20 | export default ChevronRight
21 |
--------------------------------------------------------------------------------
/services/frontend/components/icons/ChevronUp.tsx:
--------------------------------------------------------------------------------
1 | const ChevronUp = ({ ...props }) => {
2 | return (
3 |
17 | )
18 | }
19 |
20 | export default ChevronUp
21 |
--------------------------------------------------------------------------------
/services/frontend/components/icons/CreditCard.tsx:
--------------------------------------------------------------------------------
1 | const CreditCard = ({ ...props }) => {
2 | return (
3 |
18 | )
19 | }
20 |
21 | export default CreditCard
22 |
--------------------------------------------------------------------------------
/services/frontend/components/icons/Cross.tsx:
--------------------------------------------------------------------------------
1 | const Cross = ({ ...props }) => {
2 | return (
3 |
18 | )
19 | }
20 |
21 | export default Cross
22 |
--------------------------------------------------------------------------------
/services/frontend/components/icons/DoubleChevron.tsx:
--------------------------------------------------------------------------------
1 | const DoubleChevron = ({ ...props }) => {
2 | return (
3 |
19 | )
20 | }
21 |
22 | export default DoubleChevron
23 |
--------------------------------------------------------------------------------
/services/frontend/components/icons/Info.tsx:
--------------------------------------------------------------------------------
1 | const Info = ({ ...props }) => {
2 | return (
3 |
19 | )
20 | }
21 |
22 | export default Info
23 |
--------------------------------------------------------------------------------
/services/frontend/components/icons/MapPin.tsx:
--------------------------------------------------------------------------------
1 | const MapPin = ({ ...props }) => {
2 | return (
3 |
17 | )
18 | }
19 |
20 | export default MapPin
21 |
--------------------------------------------------------------------------------
/services/frontend/components/icons/Menu.tsx:
--------------------------------------------------------------------------------
1 | const Menu = ({ ...props }) => {
2 | return (
3 |
18 | )
19 | }
20 |
21 | export default Menu
22 |
--------------------------------------------------------------------------------
/services/frontend/components/icons/Minus.tsx:
--------------------------------------------------------------------------------
1 | const Minus = ({ ...props }) => {
2 | return (
3 |
12 | )
13 | }
14 |
15 | export default Minus
16 |
--------------------------------------------------------------------------------
/services/frontend/components/icons/Moon.tsx:
--------------------------------------------------------------------------------
1 | const Moon = ({ ...props }) => {
2 | return (
3 |
17 | )
18 | }
19 |
20 | export default Moon
21 |
--------------------------------------------------------------------------------
/services/frontend/components/icons/Plus.tsx:
--------------------------------------------------------------------------------
1 | const Plus = ({ ...props }) => {
2 | return (
3 |
19 | )
20 | }
21 |
22 | export default Plus
23 |
--------------------------------------------------------------------------------
/services/frontend/components/icons/Star.tsx:
--------------------------------------------------------------------------------
1 | const Star = ({ ...props }) => {
2 | return (
3 |
13 | )
14 | }
15 |
16 | export default Star
17 |
--------------------------------------------------------------------------------
/services/frontend/components/icons/Sun.tsx:
--------------------------------------------------------------------------------
1 | const Sun = ({ ...props }) => {
2 | return (
3 |
25 | )
26 | }
27 |
28 | export default Sun
29 |
--------------------------------------------------------------------------------
/services/frontend/components/product/ProductCard/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './ProductCard'
2 |
--------------------------------------------------------------------------------
/services/frontend/components/product/ProductOptions/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './ProductOptions'
2 |
--------------------------------------------------------------------------------
/services/frontend/components/product/ProductSidebar/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './ProductSidebar'
2 |
--------------------------------------------------------------------------------
/services/frontend/components/product/ProductSlider/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './ProductSlider'
2 |
--------------------------------------------------------------------------------
/services/frontend/components/product/ProductSliderControl/ProductSliderControl.module.css:
--------------------------------------------------------------------------------
1 | .control {
2 | @apply bg-violet absolute bottom-10 right-10 flex flex-row
3 | border-accent-0 border text-accent-0 z-30 shadow-xl select-none;
4 | height: 48px;
5 | }
6 |
7 | .leftControl,
8 | .rightControl {
9 | @apply px-9 cursor-pointer;
10 | transition: background-color 0.2s ease;
11 | }
12 |
13 | .leftControl:hover,
14 | .rightControl:hover {
15 | background-color: var(--violet-dark);
16 | }
17 |
18 | .leftControl:focus,
19 | .rightControl:focus {
20 | @apply outline-none;
21 | }
22 |
23 | .rightControl {
24 | @apply border-l border-accent-0;
25 | }
26 |
27 | .leftControl {
28 | margin-right: -1px;
29 | }
30 |
--------------------------------------------------------------------------------
/services/frontend/components/product/ProductSliderControl/ProductSliderControl.tsx:
--------------------------------------------------------------------------------
1 | import { FC, MouseEventHandler, memo } from 'react'
2 | import cn from 'clsx'
3 | import s from './ProductSliderControl.module.css'
4 | import { ArrowLeft, ArrowRight } from '@components/icons'
5 |
6 | interface ProductSliderControl {
7 | onPrev: MouseEventHandler
8 | onNext: MouseEventHandler
9 | }
10 |
11 | const ProductSliderControl: FC = ({ onPrev, onNext }) => (
12 |
13 |
20 |
27 |
28 | )
29 |
30 | export default memo(ProductSliderControl)
31 |
--------------------------------------------------------------------------------
/services/frontend/components/product/ProductSliderControl/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './ProductSliderControl'
2 |
--------------------------------------------------------------------------------
/services/frontend/components/product/ProductTag/ProductTag.module.css:
--------------------------------------------------------------------------------
1 | .root {
2 | @apply transition-colors ease-in-out duration-500
3 | absolute top-0 left-0 z-20 pr-16;
4 | }
5 |
6 | .root .name {
7 | @apply pt-0 w-full max-w-3xl leading-10;
8 | font-size: 1.725rem;
9 | letter-spacing: 0.4px;
10 | }
11 |
12 | .root .name span {
13 | @apply py-1 px-3 bg-primary text-primary font-bold;
14 | line-height: 1.4;
15 | min-height: 70px;
16 | font-size: inherit;
17 | letter-spacing: inherit;
18 | box-decoration-break: clone;
19 | -webkit-box-decoration-break: clone;
20 | }
21 |
22 | .root .name span.fontsizing {
23 | display: flex;
24 | padding-top: 1.5rem;
25 | }
26 |
27 | .root .price {
28 | @apply py-2 px-3 text-sm bg-primary text-accent-9
29 | font-semibold inline-block tracking-wide;
30 | margin-top: -1px;
31 | }
32 |
--------------------------------------------------------------------------------
/services/frontend/components/product/ProductTag/ProductTag.tsx:
--------------------------------------------------------------------------------
1 | import cn from 'clsx'
2 | import s from './ProductTag.module.css'
3 |
4 | interface ProductTagProps {
5 | className?: string
6 | name: string
7 | price: string
8 | fontSize?: number
9 | }
10 |
11 | const ProductTag: React.FC = ({
12 | name,
13 | price,
14 | className = '',
15 | fontSize = 32,
16 | }) => {
17 | return (
18 |
19 |
20 |
27 | {name}
28 |
29 |
30 |
{price}
31 |
32 | )
33 | }
34 |
35 | export default ProductTag
36 |
--------------------------------------------------------------------------------
/services/frontend/components/product/ProductTag/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './ProductTag'
2 |
--------------------------------------------------------------------------------
/services/frontend/components/product/ProductView/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './ProductView'
2 |
--------------------------------------------------------------------------------
/services/frontend/components/product/Swatch/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Swatch'
2 |
--------------------------------------------------------------------------------
/services/frontend/components/product/index.ts:
--------------------------------------------------------------------------------
1 | export { default as Swatch } from './Swatch'
2 | export { default as ProductView } from './ProductView'
3 | export { default as ProductCard } from './ProductCard'
4 | export { default as ProductSlider } from './ProductSlider'
5 | export { default as ProductList } from './ProductList'
6 | export { default as ProductOptions } from './ProductOptions'
7 |
--------------------------------------------------------------------------------
/services/frontend/components/ui/Button/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Button'
2 | export * from './Button'
3 |
--------------------------------------------------------------------------------
/services/frontend/components/ui/Collapse/Collapse.module.css:
--------------------------------------------------------------------------------
1 | .root {
2 | @apply border-b border-accent-2 py-4 flex flex-col outline-none;
3 | }
4 |
5 | .header {
6 | @apply flex flex-row items-center;
7 | }
8 |
9 | .header .label {
10 | @apply text-base font-medium;
11 | }
12 |
13 | .content {
14 | @apply pt-3 overflow-hidden pl-8;
15 | }
16 |
17 | .icon {
18 | @apply mr-3 text-accent-6;
19 | margin-left: -6px;
20 | transition: transform 0.2s ease;
21 | }
22 |
23 | .icon.open {
24 | transform: rotate(90deg);
25 | }
26 |
--------------------------------------------------------------------------------
/services/frontend/components/ui/Collapse/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Collapse'
2 | export * from './Collapse'
3 |
--------------------------------------------------------------------------------
/services/frontend/components/ui/Container/Container.tsx:
--------------------------------------------------------------------------------
1 | import cn from 'clsx'
2 | import React, { FC } from 'react'
3 |
4 | interface ContainerProps {
5 | className?: string
6 | children?: any
7 | el?: HTMLElement
8 | clean?: boolean
9 | }
10 |
11 | const Container: FC = ({
12 | children,
13 | className,
14 | el = 'div',
15 | clean = false, // Full Width Screen
16 | }) => {
17 | const rootClassName = cn(className, {
18 | 'mx-auto max-w-7xl px-6 w-full': !clean,
19 | })
20 |
21 | let Component: React.ComponentType> =
22 | el as any
23 |
24 | return {children}
25 | }
26 |
27 | export default Container
28 |
--------------------------------------------------------------------------------
/services/frontend/components/ui/Container/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Container'
2 |
--------------------------------------------------------------------------------
/services/frontend/components/ui/Dropdown/Dropdown.module.css:
--------------------------------------------------------------------------------
1 | .root {
2 | @apply bg-accent-0;
3 | animation: none;
4 | transition: none;
5 | min-width: 100%;
6 | }
7 |
8 | @media screen(lg) {
9 | .root {
10 | @apply bg-accent-0;
11 | box-shadow: hsl(206 22% 7% / 45%) 0px 10px 38px -10px,
12 | hsl(206 22% 7% / 20%) 0px 10px 20px -15px;
13 | min-width: 14rem;
14 | will-change: transform, opacity;
15 | animation-duration: 600ms;
16 | animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
17 | animation-fill-mode: forwards;
18 | transform-origin: var(--radix-dropdown-menu-content-transform-origin);
19 | animation-name: slideIn;
20 | }
21 | }
22 |
23 | @keyframes slideIn {
24 | 0% {
25 | opacity: 0;
26 | transform: translateY(2px);
27 | }
28 | 100% {
29 | opacity: 1;
30 | transform: translateY(0px);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/services/frontend/components/ui/Dropdown/Dropdown.tsx:
--------------------------------------------------------------------------------
1 | import cn from 'clsx'
2 | import React from 'react'
3 | import s from './Dropdown.module.css'
4 | import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
5 |
6 | export const Dropdown = DropdownMenu.Root
7 | export const DropdownMenuItem = DropdownMenu.Item
8 | export const DropdownTrigger = DropdownMenu.Trigger
9 | export const DropdownMenuLabel = DropdownMenu.Label
10 | export const DropdownMenuGroup = DropdownMenu.Group
11 |
12 | export const DropdownContent = React.forwardRef<
13 | HTMLDivElement,
14 | { children: React.ReactNode } & DropdownMenu.DropdownMenuContentProps &
15 | React.RefAttributes
16 | >(function DropdownContent({ children, className, ...props }, forwardedRef) {
17 | return (
18 |
19 | {children}
20 |
21 | )
22 | })
23 |
--------------------------------------------------------------------------------
/services/frontend/components/ui/Grid/Grid.tsx:
--------------------------------------------------------------------------------
1 | import cn from 'clsx'
2 | import { FC, ReactNode, Component } from 'react'
3 | import s from './Grid.module.css'
4 |
5 | interface GridProps {
6 | className?: string
7 | children?: ReactNode[] | Component[] | any[]
8 | layout?: 'A' | 'B' | 'C' | 'D' | 'normal'
9 | variant?: 'default' | 'filled'
10 | }
11 |
12 | const Grid: FC = ({
13 | className,
14 | layout = 'A',
15 | children,
16 | variant = 'default',
17 | }) => {
18 | const rootClassName = cn(
19 | s.root,
20 | {
21 | [s.layoutA]: layout === 'A',
22 | [s.layoutB]: layout === 'B',
23 | [s.layoutC]: layout === 'C',
24 | [s.layoutD]: layout === 'D',
25 | [s.layoutNormal]: layout === 'normal',
26 | [s.default]: variant === 'default',
27 | [s.filled]: variant === 'filled',
28 | },
29 | className
30 | )
31 | return {children}
32 | }
33 |
34 | export default Grid
35 |
--------------------------------------------------------------------------------
/services/frontend/components/ui/Grid/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Grid'
2 |
--------------------------------------------------------------------------------
/services/frontend/components/ui/Hero/Hero.module.css:
--------------------------------------------------------------------------------
1 | .root {
2 | @apply flex flex-col py-16 mx-auto;
3 | }
4 |
5 | .title {
6 | @apply text-accent-0 font-extrabold text-4xl leading-none tracking-tight;
7 | }
8 |
9 | .description {
10 | @apply mt-4 text-xl leading-8 text-accent-2 mb-1 lg:max-w-4xl;
11 | }
12 |
13 | @screen lg {
14 | .root {
15 | @apply flex-row items-start justify-center py-32;
16 | }
17 | .title {
18 | @apply text-5xl max-w-xl text-right leading-10 -mt-3;
19 | line-height: 3.5rem;
20 | }
21 | .description {
22 | @apply mt-0 ml-6;
23 | }
24 | }
25 |
26 | @screen xl {
27 | .title {
28 | @apply text-6xl;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/services/frontend/components/ui/Hero/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Hero'
2 |
--------------------------------------------------------------------------------
/services/frontend/components/ui/Input/Input.module.css:
--------------------------------------------------------------------------------
1 | .root {
2 | @apply bg-primary py-2 px-6 w-full appearance-none transition duration-150 ease-in-out pr-10 border border-accent-3 text-accent-6;
3 | }
4 |
5 | .root:focus {
6 | @apply outline-none shadow-outline-normal;
7 | }
8 |
--------------------------------------------------------------------------------
/services/frontend/components/ui/Input/Input.tsx:
--------------------------------------------------------------------------------
1 | import cn from 'clsx'
2 | import s from './Input.module.css'
3 | import React, { InputHTMLAttributes } from 'react'
4 |
5 | export interface InputProps extends InputHTMLAttributes {
6 | className?: string
7 | onChange?: (...args: any[]) => any
8 | }
9 |
10 | const Input: React.FC = (props) => {
11 | const { className, children, onChange, ...rest } = props
12 |
13 | const rootClassName = cn(s.root, {}, className)
14 |
15 | const handleOnChange = (e: any) => {
16 | if (onChange) {
17 | onChange(e.target.value)
18 | }
19 | return null
20 | }
21 |
22 | return (
23 |
34 | )
35 | }
36 |
37 | export default Input
38 |
--------------------------------------------------------------------------------
/services/frontend/components/ui/Input/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Input'
2 |
--------------------------------------------------------------------------------
/services/frontend/components/ui/Link/Link.tsx:
--------------------------------------------------------------------------------
1 | import NextLink, { LinkProps as NextLinkProps } from 'next/link'
2 |
3 | const Link: React.FC = ({ href, children, ...props }) => {
4 | return (
5 |
6 | {children}
7 |
8 | )
9 | }
10 |
11 | export default Link
12 |
--------------------------------------------------------------------------------
/services/frontend/components/ui/Link/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Link'
2 |
--------------------------------------------------------------------------------
/services/frontend/components/ui/LoadingDots/LoadingDots.module.css:
--------------------------------------------------------------------------------
1 | .root {
2 | @apply inline-flex text-center items-center leading-7;
3 | }
4 |
5 | .root .dot {
6 | @apply rounded-full h-2 w-2;
7 | background-color: currentColor;
8 | animation-name: blink;
9 | animation-duration: 1.4s;
10 | animation-iteration-count: infinite;
11 | animation-fill-mode: both;
12 | margin: 0 2px;
13 | }
14 |
15 | .root .dot:nth-of-type(2) {
16 | animation-delay: 0.2s;
17 | }
18 |
19 | .root .dot::nth-of-type(3) {
20 | animation-delay: 0.4s;
21 | }
22 |
23 | @keyframes blink {
24 | 0% {
25 | opacity: 0.2;
26 | }
27 | 20% {
28 | opacity: 1;
29 | }
30 | 100% {
31 | opacity: 0.2;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/services/frontend/components/ui/LoadingDots/LoadingDots.tsx:
--------------------------------------------------------------------------------
1 | import s from './LoadingDots.module.css'
2 |
3 | const LoadingDots: React.FC = () => {
4 | return (
5 |
6 |
7 |
8 |
9 |
10 | )
11 | }
12 |
13 | export default LoadingDots
14 |
--------------------------------------------------------------------------------
/services/frontend/components/ui/LoadingDots/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './LoadingDots'
2 |
--------------------------------------------------------------------------------
/services/frontend/components/ui/Logo/Logo.tsx:
--------------------------------------------------------------------------------
1 | import React, { FC } from 'react';
2 |
3 | const Logo: FC = ({ className = '', ...props }) => (
4 |
5 | Storedog
6 |
7 | );
8 |
9 | export default Logo;
10 |
--------------------------------------------------------------------------------
/services/frontend/components/ui/Logo/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Logo'
2 |
--------------------------------------------------------------------------------
/services/frontend/components/ui/Marquee/Marquee.module.css:
--------------------------------------------------------------------------------
1 | .root {
2 | @apply w-full min-w-full relative flex flex-row items-center overflow-hidden py-0;
3 | max-height: 320px;
4 | }
5 |
6 | .root > div {
7 | max-height: 320px;
8 | padding: 0;
9 | margin: 0;
10 | }
11 |
12 | .root > div > * > *:nth-child(2) * {
13 | max-height: 100%;
14 | }
15 |
16 | .primary {
17 | @apply bg-accent-0;
18 | }
19 |
20 | .secondary {
21 | @apply bg-accent-9;
22 | }
23 |
--------------------------------------------------------------------------------
/services/frontend/components/ui/Marquee/Marquee.tsx:
--------------------------------------------------------------------------------
1 | import cn from 'clsx'
2 | import s from './Marquee.module.css'
3 | import { FC, ReactNode, Component, Children } from 'react'
4 | import { default as FastMarquee } from 'react-fast-marquee'
5 |
6 | interface MarqueeProps {
7 | className?: string
8 | children?: ReactNode[] | Component[] | any[]
9 | variant?: 'primary' | 'secondary'
10 | }
11 |
12 | const Marquee: FC = ({
13 | className = '',
14 | children,
15 | variant = 'primary',
16 | }) => {
17 | const rootClassName = cn(
18 | s.root,
19 | {
20 | [s.primary]: variant === 'primary',
21 | [s.secondary]: variant === 'secondary',
22 | },
23 | className
24 | )
25 |
26 | return (
27 |
28 | {Children.map(children, (child) => ({
29 | ...child,
30 | props: {
31 | ...child.props,
32 | className: cn(child.props.className, `${variant}`),
33 | },
34 | }))}
35 |
36 | )
37 | }
38 |
39 | export default Marquee
40 |
--------------------------------------------------------------------------------
/services/frontend/components/ui/Marquee/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Marquee'
2 |
--------------------------------------------------------------------------------
/services/frontend/components/ui/Modal/Modal.module.css:
--------------------------------------------------------------------------------
1 | .root {
2 | @apply fixed bg-black bg-opacity-40 flex items-center inset-0 z-50 justify-center;
3 | backdrop-filter: blur(0.8px);
4 | -webkit-backdrop-filter: blur(0.8px);
5 | }
6 |
7 | .modal {
8 | @apply bg-primary p-12 border border-accent-2 relative;
9 | }
10 |
11 | .modal:focus {
12 | @apply outline-none;
13 | }
14 |
15 | .close {
16 | @apply hover:text-accent-5 transition ease-in-out duration-150 focus:outline-none absolute right-0 top-0 m-6;
17 | }
18 |
--------------------------------------------------------------------------------
/services/frontend/components/ui/Modal/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Modal'
2 |
--------------------------------------------------------------------------------
/services/frontend/components/ui/Quantity/Quantity.module.css:
--------------------------------------------------------------------------------
1 | .actions {
2 | @apply flex p-1 border-accent-2 border items-center justify-center
3 | w-12 text-accent-7;
4 | transition-property: border-color, background, color, transform, box-shadow;
5 |
6 | transition-duration: 0.15s;
7 | transition-timing-function: ease;
8 | user-select: none;
9 | }
10 |
11 | .actions:hover {
12 | @apply border bg-accent-1 border-accent-3 text-accent-9;
13 | transition: border-color;
14 | z-index: 10;
15 | }
16 |
17 | .actions:focus {
18 | @apply outline-none;
19 | }
20 |
21 | .actions:disabled {
22 | @apply cursor-not-allowed;
23 | }
24 |
25 | .input {
26 | @apply bg-transparent px-4 w-full h-full focus:outline-none select-none pointer-events-auto;
27 | }
28 |
--------------------------------------------------------------------------------
/services/frontend/components/ui/Quantity/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Quantity'
2 | export * from './Quantity'
3 |
--------------------------------------------------------------------------------
/services/frontend/components/ui/README.md:
--------------------------------------------------------------------------------
1 | # UI
2 |
3 | Building blocks to build a rich graphical interfaces. Components should be atomic and pure. Serve one purpose.
4 |
--------------------------------------------------------------------------------
/services/frontend/components/ui/Rating/Rating.module.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/frontend/components/ui/Rating/Rating.module.css
--------------------------------------------------------------------------------
/services/frontend/components/ui/Rating/Rating.tsx:
--------------------------------------------------------------------------------
1 | import { FC, memo } from 'react'
2 | import rangeMap from '@lib/range-map'
3 | import { Star } from '@components/icons'
4 | import cn from 'clsx'
5 |
6 | export interface RatingProps {
7 | value: number
8 | }
9 |
10 | const Quantity: FC = ({ value = 5 }) => (
11 |
12 | {rangeMap(5, (i) => (
13 | = Math.floor(value),
17 | })}
18 | >
19 |
20 |
21 | ))}
22 |
23 | )
24 |
25 | export default memo(Quantity)
26 |
--------------------------------------------------------------------------------
/services/frontend/components/ui/Rating/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Rating'
2 | export * from './Rating'
3 |
--------------------------------------------------------------------------------
/services/frontend/components/ui/Sidebar/Sidebar.module.css:
--------------------------------------------------------------------------------
1 | .root {
2 | @apply fixed inset-0 h-full z-50 box-border outline-none;
3 | }
4 |
5 | .sidebar {
6 | @apply h-full flex flex-col text-base bg-accent-0 shadow-xl overflow-y-auto overflow-x-hidden;
7 | -webkit-overflow-scrolling: touch !important;
8 | }
9 |
10 | .backdrop {
11 | @apply absolute inset-0 bg-black bg-opacity-40 duration-100 ease-linear;
12 | backdrop-filter: blur(0.8px);
13 | -webkit-backdrop-filter: blur(0.8px);
14 | }
15 |
--------------------------------------------------------------------------------
/services/frontend/components/ui/Sidebar/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Sidebar'
2 |
--------------------------------------------------------------------------------
/services/frontend/components/ui/Skeleton/Skeleton.module.css:
--------------------------------------------------------------------------------
1 | .skeleton {
2 | @apply block;
3 | background-image: linear-gradient(
4 | 270deg,
5 | var(--accent-0),
6 | var(--accent-2),
7 | var(--accent-0),
8 | var(--accent-1)
9 | );
10 | background-size: 400% 100%;
11 | animation: loading 8s ease-in-out infinite;
12 | }
13 |
14 | .wrapper {
15 | @apply block relative;
16 |
17 | &:not(.show)::before {
18 | content: none;
19 | }
20 |
21 | &::before {
22 | content: '';
23 | position: absolute;
24 | top: 0;
25 | left: 0;
26 | right: 0;
27 | bottom: 0;
28 | z-index: 100;
29 | background-image: linear-gradient(
30 | 270deg,
31 | var(--accent-0),
32 | var(--accent-2),
33 | var(--accent-0),
34 | var(--accent-1)
35 | );
36 | background-size: 400% 100%;
37 | animation: loading 8s ease-in-out infinite;
38 | }
39 | }
40 |
41 | @keyframes loading {
42 | 0% {
43 | background-position: 200% 0;
44 | }
45 | 100% {
46 | background-position: -200% 0;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/services/frontend/components/ui/Skeleton/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Skeleton'
2 |
--------------------------------------------------------------------------------
/services/frontend/components/ui/Text/index.ts:
--------------------------------------------------------------------------------
1 | export { default } from './Text'
2 |
--------------------------------------------------------------------------------
/services/frontend/components/ui/index.ts:
--------------------------------------------------------------------------------
1 | export { default as Hero } from './Hero'
2 | export { default as Logo } from './Logo'
3 | export { default as Grid } from './Grid'
4 | export { default as Button } from './Button'
5 | export { default as Sidebar } from './Sidebar'
6 | export { default as Marquee } from './Marquee'
7 | export { default as Container } from './Container'
8 | export { default as LoadingDots } from './LoadingDots'
9 | export { default as Skeleton } from './Skeleton'
10 | export { default as Modal } from './Modal'
11 | export { default as Text } from './Text'
12 | export { default as Input } from './Input'
13 | export { default as Collapse } from './Collapse'
14 | export { default as Quantity } from './Quantity'
15 | export { default as Rating } from './Rating'
16 | export * from './Dropdown/Dropdown'
17 | export { useUI } from './context'
18 |
--------------------------------------------------------------------------------
/services/frontend/config/seo_meta.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Storedog | Datadog Training",
3 | "titleTemplate": "%s - Storedog",
4 | "description": "Storedog, an ecommerce app used for training at https://learn.datadoghq.com",
5 | "openGraph": {
6 | "title": "Storedog | Datadog Training",
7 | "description": "Storedog, an ecommerce app used for training at https://learn.datadoghq.com",
8 | "type": "website",
9 | "url": "https://learn.datadoghq.com",
10 | "site_name": "Storedog",
11 | "images": [
12 | {
13 | "url": "/card.png",
14 | "width": "800",
15 | "height": "600",
16 | "alt": "Storedog"
17 | }
18 | ]
19 | },
20 | "twitter": {
21 | "handle": "@datadoghq",
22 | "site": "@datadoghq",
23 | "cardType": "summary_large_image"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/services/frontend/featureFlags.config.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "1",
4 | "name": "dbm",
5 | "active": false
6 | },
7 | {
8 | "id": "2",
9 | "name": "error-tracking",
10 | "active": false
11 | },
12 | {
13 | "id": "3",
14 | "name": "api-errors",
15 | "active": false
16 | },
17 | {
18 | "id": "4",
19 | "name": "product-card-frustration",
20 | "active": false
21 | }
22 | ]
23 |
--------------------------------------------------------------------------------
/services/frontend/global.d.ts:
--------------------------------------------------------------------------------
1 | // Declarations for modules without types
2 | declare module 'next-themes'
3 | declare module 'code-stash'
4 |
--------------------------------------------------------------------------------
/services/frontend/lib/hooks/useUserAvatar.ts:
--------------------------------------------------------------------------------
1 | import { useEffect } from 'react'
2 | import { useUI } from '@components/ui/context'
3 | import { getRandomPairOfColors } from '@lib/colors'
4 |
5 | export const useUserAvatar = (name = 'userAvatar') => {
6 | const { userAvatar, setUserAvatar } = useUI()
7 |
8 | useEffect(() => {
9 | if (!userAvatar && localStorage.getItem(name)) {
10 | // Get bg from localStorage and push it to the context.
11 | setUserAvatar(localStorage.getItem(name))
12 | }
13 | if (!localStorage.getItem(name)) {
14 | // bg not set locally, generating one, setting localStorage and context to persist.
15 | const bg = getRandomPairOfColors()
16 | const value = `linear-gradient(140deg, ${bg[0]}, ${bg[1]} 100%)`
17 | localStorage.setItem(name, value)
18 | setUserAvatar(value)
19 | }
20 | }, [])
21 |
22 | return {
23 | userAvatar,
24 | setUserAvatar,
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/services/frontend/lib/range-map.ts:
--------------------------------------------------------------------------------
1 | export default function rangeMap(n: number, fn: (i: number) => any) {
2 | const arr = []
3 | while (n > arr.length) {
4 | arr.push(fn(arr.length))
5 | }
6 | return arr
7 | }
8 |
--------------------------------------------------------------------------------
/services/frontend/lib/to-pixels.ts:
--------------------------------------------------------------------------------
1 | // Convert numbers or strings to pixel value
2 | // Helpful for styled-jsx when using a prop
3 | // height: ${toPixels(height)}; (supports height={20} and height="20px")
4 |
5 | const toPixels = (value: string | number) => {
6 | if (typeof value === 'number') {
7 | return `${value}px`
8 | }
9 |
10 | return value
11 | }
12 |
13 | export default toPixels
14 |
--------------------------------------------------------------------------------
/services/frontend/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
4 | // NOTE: This file should not be edited
5 | // see https://nextjs.org/docs/basic-features/typescript for more information.
6 |
--------------------------------------------------------------------------------
/services/frontend/next-logger.config.js:
--------------------------------------------------------------------------------
1 | const pino = require('pino')
2 |
3 | const logger = (defaultConfig) =>
4 | pino({
5 | ...defaultConfig,
6 | errorKey: 'error',
7 | messageKey: 'message',
8 | })
9 |
10 | module.exports = { logger }
11 |
--------------------------------------------------------------------------------
/services/frontend/pages/404.tsx:
--------------------------------------------------------------------------------
1 | import { Layout } from '@components/common'
2 | import { Text } from '@components/ui'
3 |
4 | export default function NotFound() {
5 | return (
6 |
7 | Not Found
8 |
9 | The requested page doesn't exist or you don't have access to it.
10 |
11 |
12 | )
13 | }
14 |
15 | NotFound.Layout = Layout
16 |
--------------------------------------------------------------------------------
/services/frontend/pages/_document.tsx:
--------------------------------------------------------------------------------
1 | import Document, { Head, Html, Main, NextScript } from 'next/document'
2 |
3 | class MyDocument extends Document {
4 | render() {
5 | return (
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | )
14 | }
15 | }
16 |
17 | export default MyDocument
18 |
--------------------------------------------------------------------------------
/services/frontend/pages/api/pages/index.ts:
--------------------------------------------------------------------------------
1 | import type { NextApiRequest, NextApiResponse } from 'next'
2 | import { getPages } from '@lib/api/pages'
3 | import { codeStash } from 'code-stash'
4 | import config from '../../../featureFlags.config.json'
5 |
6 | export default async function handler(
7 | req: NextApiRequest,
8 | res: NextApiResponse
9 | ) {
10 | if (config && config.length > 0) {
11 | const isError = await codeStash('api-errors', { file: config })
12 |
13 | if (isError) {
14 | const random = Math.random()
15 | if (random < 0.33) {
16 | return res.status(400).json({ message: 'Bad request' })
17 | } else if (random < 0.66) {
18 | return res.status(500).json({ message: 'Internal server error' })
19 | }
20 | }
21 | }
22 |
23 | const pages = await getPages()
24 | res.status(200).json(pages)
25 | }
26 |
--------------------------------------------------------------------------------
/services/frontend/pages/api/products/[slug].ts:
--------------------------------------------------------------------------------
1 | import type { NextApiRequest, NextApiResponse } from 'next'
2 | import { getProduct } from '@lib/api/products'
3 | import { Product } from '@customTypes/product'
4 |
5 | export default async function handler(
6 | req: NextApiRequest,
7 | res: NextApiResponse
8 | ) {
9 | try {
10 | const options = {
11 | id: req.query.slug as string,
12 | include:
13 | req.query.include ||
14 | 'default_variant,variants,option_types,product_properties,taxons,images,primary_variant',
15 | ...req.query,
16 | }
17 |
18 | const product: Product = await getProduct(options)
19 |
20 | if (!product?.id) {
21 | return res.status(404).json({ error: 'Not Found' })
22 | }
23 |
24 | res.status(200).json(product)
25 | } catch (error) {
26 | console.error(error)
27 | res.status(500).json({ error: 'Internal Server Error' })
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/services/frontend/pages/api/products/index.ts:
--------------------------------------------------------------------------------
1 | import type { NextApiRequest, NextApiResponse } from 'next'
2 | import { getProducts } from '@lib/api/products'
3 | import { Product } from '@customTypes/product'
4 |
5 | export default async function handler(
6 | req: NextApiRequest,
7 | res: NextApiResponse
8 | ) {
9 | try {
10 | const options = {
11 | include:
12 | req.query?.includes || 'default_variant,images,primary_variant,taxons',
13 | page: req.query.page || 1,
14 | per_page: req.query.per_page || 25,
15 | ...req.query,
16 | }
17 |
18 | const products: Product[] = await getProducts(options)
19 |
20 | if (products?.length === 0) {
21 | return res.status(404).json({ error: 'No products found' })
22 | }
23 |
24 | res.status(200).json(products)
25 | } catch (error) {
26 | console.error(error)
27 | res.status(500).json({ error: 'Internal Server Error' })
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/services/frontend/pages/api/taxonomies/[taxonomy]/[slug].ts:
--------------------------------------------------------------------------------
1 | import type { NextApiRequest, NextApiResponse } from 'next'
2 | import { getTaxon } from '@lib/api/taxons'
3 |
4 | export default async function handler(
5 | req: NextApiRequest,
6 | res: NextApiResponse
7 | ) {
8 | try {
9 | const options = {
10 | id: `${req.query.taxonomy}/${req.query.slug}`,
11 | include: req.query.include || 'parent,taxonomy,children,image,products',
12 | }
13 |
14 | const taxon = await getTaxon(options)
15 |
16 | if (!taxon?.id) {
17 | return res.status(404).json({ error: 'Not Found' })
18 | }
19 |
20 | res.status(200).json(taxon)
21 | } catch (error) {
22 | console.error(error)
23 | res.status(500).json({ error: 'Internal Server Error' })
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/services/frontend/pages/api/taxonomies/[taxonomy]/index.ts:
--------------------------------------------------------------------------------
1 | import type { NextApiRequest, NextApiResponse } from 'next'
2 | import { getTaxon } from '@lib/api/taxons'
3 |
4 | export default async function handler(
5 | req: NextApiRequest,
6 | res: NextApiResponse
7 | ) {
8 | try {
9 | const options = {
10 | id: req.query.taxonomy as string,
11 | include: req.query.include || 'parent,taxonomy,children,image,products',
12 | }
13 |
14 | const taxon = await getTaxon(options)
15 |
16 | if (!taxon?.id) {
17 | return res.status(404).json({ error: 'Not Found' })
18 | }
19 |
20 | res.status(200).json(taxon)
21 | } catch (error) {
22 | console.error(error)
23 | res.status(500).json({ error: 'Internal Server Error' })
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/services/frontend/pages/api/taxonomies/index.ts:
--------------------------------------------------------------------------------
1 | import type { NextApiRequest, NextApiResponse } from 'next'
2 | import { getTaxons } from '@lib/api/taxons'
3 | import { Taxon } from '@customTypes/taxons'
4 |
5 | export default async function handler(
6 | req: NextApiRequest,
7 | res: NextApiResponse
8 | ) {
9 | try {
10 | const options = {
11 | include: req.query?.includes || 'parent,taxonomy,children,image,products',
12 | page: req.query.page || 1,
13 | per_page: req.query.per_page || 25,
14 | }
15 |
16 | const taxons: Taxon[] = await getTaxons(options)
17 |
18 | if (taxons?.length === 0) {
19 | return res.status(404).json({ error: 'Not Found' })
20 | }
21 |
22 | res.status(200).json(taxons)
23 | } catch (error) {
24 | console.error(error)
25 | res.status(500).json({ error: 'Internal Server Error' })
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/services/frontend/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: [
3 | 'tailwindcss/nesting',
4 | 'tailwindcss',
5 | 'autoprefixer',
6 | 'postcss-flexbugs-fixes',
7 | [
8 | 'postcss-preset-env',
9 | {
10 | autoprefixer: {
11 | flexbox: 'no-2009',
12 | },
13 | stage: 3,
14 | features: {
15 | 'custom-properties': false,
16 | },
17 | },
18 | ],
19 | ],
20 | }
21 |
--------------------------------------------------------------------------------
/services/frontend/public/assets/drop-shirt-0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/frontend/public/assets/drop-shirt-0.png
--------------------------------------------------------------------------------
/services/frontend/public/assets/drop-shirt-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/frontend/public/assets/drop-shirt-1.png
--------------------------------------------------------------------------------
/services/frontend/public/assets/drop-shirt-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/frontend/public/assets/drop-shirt-2.png
--------------------------------------------------------------------------------
/services/frontend/public/assets/drop-shirt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/frontend/public/assets/drop-shirt.png
--------------------------------------------------------------------------------
/services/frontend/public/assets/lightweight-jacket-0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/frontend/public/assets/lightweight-jacket-0.png
--------------------------------------------------------------------------------
/services/frontend/public/assets/lightweight-jacket-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/frontend/public/assets/lightweight-jacket-1.png
--------------------------------------------------------------------------------
/services/frontend/public/assets/lightweight-jacket-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/frontend/public/assets/lightweight-jacket-2.png
--------------------------------------------------------------------------------
/services/frontend/public/assets/t-shirt-0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/frontend/public/assets/t-shirt-0.png
--------------------------------------------------------------------------------
/services/frontend/public/assets/t-shirt-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/frontend/public/assets/t-shirt-1.png
--------------------------------------------------------------------------------
/services/frontend/public/assets/t-shirt-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/frontend/public/assets/t-shirt-2.png
--------------------------------------------------------------------------------
/services/frontend/public/assets/t-shirt-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/frontend/public/assets/t-shirt-3.png
--------------------------------------------------------------------------------
/services/frontend/public/assets/t-shirt-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/frontend/public/assets/t-shirt-4.png
--------------------------------------------------------------------------------
/services/frontend/public/bg-products.svg:
--------------------------------------------------------------------------------
1 |
7 |
8 |
--------------------------------------------------------------------------------
/services/frontend/public/card.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/frontend/public/card.png
--------------------------------------------------------------------------------
/services/frontend/public/cursor-left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/frontend/public/cursor-left.png
--------------------------------------------------------------------------------
/services/frontend/public/cursor-right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/frontend/public/cursor-right.png
--------------------------------------------------------------------------------
/services/frontend/public/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/frontend/public/favicon-32x32.png
--------------------------------------------------------------------------------
/services/frontend/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/frontend/public/favicon.ico
--------------------------------------------------------------------------------
/services/frontend/public/flag-es-co.svg:
--------------------------------------------------------------------------------
1 |
11 |
--------------------------------------------------------------------------------
/services/frontend/public/flag-es.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/services/frontend/public/icon-144x144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/frontend/public/icon-144x144.png
--------------------------------------------------------------------------------
/services/frontend/public/icon-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/frontend/public/icon-192x192.png
--------------------------------------------------------------------------------
/services/frontend/public/icon-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/frontend/public/icon-512x512.png
--------------------------------------------------------------------------------
/services/frontend/public/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/frontend/public/icon.png
--------------------------------------------------------------------------------
/services/frontend/public/site.webmanifest:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Storedog ecommerce",
3 | "short_name": "Storedog",
4 | "description": "Storedog, an ecommerce app used for training at https://learn.datadoghq.com",
5 | "display": "standalone",
6 | "start_url": "/",
7 | "theme_color": "#fff",
8 | "background_color": "#000000",
9 | "orientation": "portrait",
10 | "icons": [
11 | {
12 | "src": "/icon-192x192.png",
13 | "type": "image/png",
14 | "sizes": "192x192"
15 | },
16 | {
17 | "src": "/icon-512x512.png",
18 | "type": "image/png",
19 | "sizes": "512x512"
20 | }
21 | ]
22 | }
23 |
--------------------------------------------------------------------------------
/services/frontend/public/slider-arrows.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DataDog/storedog/b0b3d8a5cc7eae1972e3d9fcc9b36eef472a604f/services/frontend/public/slider-arrows.png
--------------------------------------------------------------------------------
/services/frontend/types/cart.ts:
--------------------------------------------------------------------------------
1 | export type CartLineItem = {
2 | id: string
3 | quantity: number
4 | variantId: string
5 | name: string
6 | path: string
7 | productId: string
8 | discounts: []
9 | variant: {
10 | id: string
11 | sku: string
12 | name: string
13 | price: number
14 | requiresShipping: boolean
15 | availableForSale: boolean
16 | listPrice: number
17 | isInStock: boolean
18 | image: {
19 | url: string
20 | alt: string
21 | }
22 | }
23 | }
24 |
25 | export type Cart = {
26 | createdAt: string
27 | currency: {
28 | code: string
29 | }
30 | customerId: string
31 | discounts: []
32 | email: string | null
33 | id: string
34 | lineItems: CartLineItem[] | []
35 | lineItemsSubtotalPrice: number
36 | shipTotal: number
37 | subtotalPrice: number
38 | taxesIncluded: boolean
39 | totalPrice: number
40 | }
41 |
--------------------------------------------------------------------------------
/services/frontend/types/page.ts:
--------------------------------------------------------------------------------
1 | export interface Page {
2 | id: string
3 | name: string
4 | url: string
5 | content?: string | null
6 | }
7 |
--------------------------------------------------------------------------------
/services/frontend/types/taxons.ts:
--------------------------------------------------------------------------------
1 | export type Taxon = {
2 | id: string
3 | type: string
4 | attributes: {
5 | name: string
6 | pretty_name: string
7 | permalink: string
8 | seo_title?: string
9 | meta_title?: string
10 | meta_description?: string
11 | meta_keywords?: string
12 | }
13 | children?: any[]
14 | parent?: string
15 | products?: any[]
16 | image?: any
17 | }
18 |
--------------------------------------------------------------------------------
/services/nginx/Dockerfile:
--------------------------------------------------------------------------------
1 | ARG NGINX_VERSION=1.26
2 |
3 | FROM nginx:$NGINX_VERSION
4 |
5 | RUN apt-get update \
6 | && apt-get install -y \
7 | build-essential \
8 | libpcre++-dev \
9 | zlib1g-dev \
10 | wget \
11 | git
12 |
13 | FROM nginx:$NGINX_VERSION
14 |
15 | COPY nginx.conf /etc/nginx/nginx.conf
16 | COPY default.conf /etc/nginx/conf.d/default.conf
17 | COPY status.conf /etc/nginx/conf.d/status.conf
18 |
--------------------------------------------------------------------------------
/services/nginx/nginx.conf:
--------------------------------------------------------------------------------
1 |
2 | events {
3 | worker_connections 1024;
4 | # other event-related settings can go here
5 | }
6 |
7 | http {
8 | include /etc/nginx/conf.d/*.conf;
9 |
10 | log_format main '$remote_addr - $remote_user [$time_local] '
11 | '"$request" $status $body_bytes_sent '
12 | '"$http_referer" "$http_user_agent" ';
13 |
14 | access_log /var/log/nginx/access.log main;
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/services/nginx/status.conf:
--------------------------------------------------------------------------------
1 | server {
2 | listen 81;
3 | server_name localhost;
4 |
5 | access_log off;
6 | allow 0.0.0.0/0;
7 | deny all;
8 |
9 | location /nginx_status {
10 | # Choose your status module
11 |
12 | # freely available with open source NGINX
13 | stub_status;
14 |
15 | # for open source NGINX < version 1.7.5
16 | # stub_status on;
17 |
18 | # available only with NGINX Plus
19 | # status;
20 |
21 | # ensures the version information can be retrieved
22 | server_tokens on;
23 | }
24 | }
--------------------------------------------------------------------------------
/services/postgres/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM postgres:15-alpine
2 |
3 | # Install dcron and su-exec for user switching
4 | RUN apk update && apk add --no-cache dcron su-exec
5 |
6 | # Copy SQL dump and PostgreSQL configuration
7 | COPY ./db/restore.sql /docker-entrypoint-initdb.d/
8 | COPY ./postgresql.conf /postgresql.conf
9 |
10 | # Create log directory and set permissions
11 | RUN mkdir -p /var/log/pg_log && \
12 | chown -R postgres:postgres /var/log/pg_log && \
13 | chmod -R 755 /var/log/pg_log
14 |
15 | # Copy the cron job file
16 | COPY ./scripts/cleanup-cron /etc/crontabs/root
17 |
18 | # Copy and set the entrypoint script
19 | COPY ./scripts/start-services.sh /usr/local/bin/start-services.sh
20 | RUN chmod +x /usr/local/bin/start-services.sh
21 |
22 | # Use the custom entrypoint script
23 | ENTRYPOINT ["/usr/local/bin/start-services.sh"]
24 |
25 | # Default command
26 | CMD ["postgres", "-c", "config_file=/postgresql.conf"]
27 |
--------------------------------------------------------------------------------
/services/postgres/scripts/cleanup-cron:
--------------------------------------------------------------------------------
1 | */1 * * * * /usr/bin/find /var/log/pg_log/ -type f -name "*" -mmin +5 -delete >> /var/log/cron.log 2>&1
2 |
--------------------------------------------------------------------------------
/services/postgres/scripts/start-services.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # Start cron as root
4 | crond -f &
5 |
6 | # Ensure data directory has correct permissions
7 | chown -R postgres:postgres /var/lib/postgresql/data
8 | chmod -R 0700 /var/lib/postgresql/data
9 |
10 | # Switch to the postgres user and start PostgreSQL using the original entrypoint
11 | exec su-exec postgres docker-entrypoint.sh "$@"
12 |
--------------------------------------------------------------------------------
/services/puppeteer/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM ghcr.io/puppeteer/puppeteer:20.0.0
2 |
3 | USER pptruser
4 | WORKDIR /home/pptruser
5 |
6 | COPY ./scripts/puppeteer.sh .
7 | COPY ./scripts/puppeteer.js .
8 |
9 | CMD ["bash", "puppeteer.sh"]
--------------------------------------------------------------------------------
/services/puppeteer/scripts/puppeteer.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | checkStoredog() {
4 | wget --quiet -O - $STOREDOG_URL |grep -qi storedog
5 | }
6 |
7 | printf "\nWaiting for Storedog"
8 |
9 | until checkStoredog; do
10 | printf .
11 | sleep 2
12 | done
13 |
14 | printf "\nBrowser replay starting.\n\n"
15 |
16 | while :
17 | do
18 | node puppeteer.js $STOREDOG_URL
19 | done
20 |
--------------------------------------------------------------------------------
/services/worker/config/initializers/datadog-tracer.rb:
--------------------------------------------------------------------------------
1 | Datadog.configure do |c|
2 | c.service = ENV['DD_SERVICE'] || 'store-worker'
3 | # Activates and configures an integration
4 | c.tracing.instrument :sidekiq, tag_args: true
5 | c.tracing.instrument :pg, service_name: 'postgres'
6 | c.tracing.instrument :active_support, cache_service: 'store-worker-cache'
7 | c.tracing.instrument :redis, service_name: 'store-worker-redis'
8 | end
--------------------------------------------------------------------------------