* feat: Add DiscountCondition entity + Join table per relation (#1146) * feat: Convert DiscountService to TypeScript (#1149) * feat: Add DiscountRepository + bulk insert and remove (#1156) * feat: Add `conditions` to payload in `POST /discounts` and `POST /discounts/:id` (#1170) * feat: Add DiscountRuleCondition entity * fix relation * fix join key * Add discount rule condition repo * add join table per relation * Convert DiscountService to TypeScript * feat: Add DiscountConditionRepository * Add migration + remove use of valid_for * revert changes to files, not done yet * init work on create discount endpoint * Add conditions to create discount endpoint * Add conditions to update discount endpoint * Add unique constraint to discount condition * integration tests passing * fix imports of models * fix tests (excluding totals calculations) * Fix commented code * add unique constraint on discount condition * Add generic way of generating retrieve configs * Requested changes + ExactlyOne validator * Remove isLocal flag from error handler * Use postgres error constant * remove commented code * initial * add migration scripts * make getMigrationsFolder generic * add datamodel migration command * add datamodel run to migraitons cli * remove data migration code from migrations * add inner join * add migration script for discount migration * redo all script changes after adding script file * address pr feedback * cherrypick files from develop * remove unused import * suggestions * Update packages/medusa/src/scripts/discount-rule-migration.ts Co-authored-by: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com> * fix: revert rule id to dr_id Co-authored-by: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com> Co-authored-by: olivermrbl <oliver@mrbltech.com>
Structure
-
Models (
/models) This is where the data layer lives. Define data models here no logic only schema and data access layer. (Default is MongoDB so we have data access layer defined for us already) -
Services (
/services) This is where our business logic lives. Define services that perform calculations, update the data layer, synchronize services, etc. -
Controllers (
/api) This is the interface lives. Define how the user interacts with the service layer. Ensure that the user has permission to do what they intend to, authenticate requests, call service layer. -
Jobs (
/jobs) This is where background and recurring tasks live. Want to send some data somewhere every night, this would be where to do it. Calls service layer methods and should, like controllers, not contain business logic. -
Subscribers (
/subscribers) This is where events live. Want to perform a certain task whenever something else happens, this is where to do it.
Extending the core
The core will look for files in the folders listed above, and inject the custom code.
Checkout flow
To create an order from a cart the customer must have filled in:
- their details (shipping/billing address, email)
- shipping method
- payment method
The steps can be done in any order. The standard path would probably be:
- submit details (PUT /cart/shipping-address, PUT /cart/email)
- select shipping method (PUT /cart/shipping-method)
- enter payment details (PUT /cart/payment-method)
- complete order (POST /order)
Assuming that shipping methods are static within each region we can display all shipping methods at checkout time. If shipping is dynamically calculated the price of the shipping method may change, we will ask the fulfillment provider for new rates.
Payment details can be entered at any point as long as the final amount is known. If the final amount changes after the payment details are entered the payment method may therefore be invalidated.
Within the store UI you could imagine each step being taken care of by a single button click, which calls all endpoints.