@ozdao/martyrs 0.2.518 → 0.2.520
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_virtual/index.cjs +4 -4
- package/dist/_virtual/index.js +4 -4
- package/dist/_virtual/index2.cjs +4 -4
- package/dist/_virtual/index2.js +4 -4
- package/dist/{abac-Cf_9lCSh.js → abac-CnJsrv8S.js} +3 -3
- package/dist/{abac-6LjoG9u-.cjs → abac-DOyUjhee.cjs} +3 -3
- package/dist/builder.cjs +27 -25
- package/dist/builder.js +27 -25
- package/dist/chats.server.cjs +198 -1
- package/dist/chats.server.js +198 -1
- package/dist/{crud-sE7GLPbj.js → crud-BIFl1W1i.js} +6 -6
- package/dist/{crud-JN_LFj01.cjs → crud-CC6k6yY5.cjs} +6 -6
- package/dist/{globals.logger-CZMgIMlM.cjs → globals.logger-BuW7JHMY.cjs} +63 -53
- package/dist/{globals.logger-Bf6rRU7j.js → globals.logger-VRHh-WUW.js} +63 -53
- package/dist/{globals.observer-CV2wCzzh.cjs → globals.observer-C_FYclgV.cjs} +36 -1
- package/dist/{globals.observer-CDqUjVU5.js → globals.observer-MZsqaE6F.js} +36 -1
- package/dist/globals.server.cjs +1 -1
- package/dist/globals.server.js +1 -1
- package/dist/inventory.server.cjs +276 -376
- package/dist/inventory.server.js +276 -376
- package/dist/main-BM3GslOO.cjs +11 -0
- package/dist/{main-wmEhGVvD.js → main-Qcn7YlTx.js} +1834 -1830
- package/dist/martyrs/src/components/Address/{Address.vue2.cjs → Address.vue.cjs} +2 -2
- package/dist/martyrs/src/components/Address/{Address.vue2.js.map → Address.vue.cjs.map} +1 -1
- package/dist/martyrs/src/components/Address/{Address.vue2.js → Address.vue.js} +2 -2
- package/dist/martyrs/src/components/Address/Address.vue.js.map +1 -0
- package/dist/martyrs/src/components/Button/Button.vue.cjs +1 -1
- package/dist/martyrs/src/components/Button/Button.vue.cjs.map +1 -1
- package/dist/martyrs/src/components/Button/Button.vue.js +1 -1
- package/dist/martyrs/src/components/Button/Button.vue.js.map +1 -1
- package/dist/martyrs/src/components/Chips/{Chips.vue.cjs → Chips.vue2.cjs} +2 -2
- package/dist/martyrs/src/components/Chips/Chips.vue2.cjs.map +1 -0
- package/dist/martyrs/src/components/Chips/{Chips.vue.js → Chips.vue2.js} +2 -2
- package/dist/martyrs/src/components/Chips/Chips.vue2.js.map +1 -0
- package/dist/martyrs/src/components/Dropdown/{Dropdown.vue.cjs → Dropdown.vue2.cjs} +2 -2
- package/dist/martyrs/src/components/Dropdown/Dropdown.vue2.cjs.map +1 -0
- package/dist/martyrs/src/components/Dropdown/{Dropdown.vue.js → Dropdown.vue2.js} +2 -2
- package/dist/martyrs/src/components/Dropdown/{Dropdown.vue.cjs.map → Dropdown.vue2.js.map} +1 -1
- package/dist/martyrs/src/components/EditImages/EditImages.vue.cjs +0 -93
- package/dist/martyrs/src/components/EditImages/EditImages.vue.cjs.map +1 -1
- package/dist/martyrs/src/components/EditImages/EditImages.vue.js +1 -94
- package/dist/martyrs/src/components/EditImages/EditImages.vue.js.map +1 -1
- package/dist/martyrs/src/components/EditImages/EditImages.vue2.cjs +93 -0
- package/dist/martyrs/src/components/EditImages/EditImages.vue2.cjs.map +1 -1
- package/dist/martyrs/src/components/EditImages/EditImages.vue2.js +94 -1
- package/dist/martyrs/src/components/EditImages/EditImages.vue2.js.map +1 -1
- package/dist/martyrs/src/components/Feed/Feed.vue.cjs +2 -3
- package/dist/martyrs/src/components/Feed/Feed.vue.cjs.map +1 -1
- package/dist/martyrs/src/components/Feed/Feed.vue.js +2 -3
- package/dist/martyrs/src/components/Feed/Feed.vue.js.map +1 -1
- package/dist/martyrs/src/components/FieldTags/FieldTags.vue.cjs +1 -1
- package/dist/martyrs/src/components/FieldTags/FieldTags.vue.js +1 -1
- package/dist/martyrs/src/components/Loader/Loader.vue2.cjs +1 -1
- package/dist/martyrs/src/components/Loader/Loader.vue2.cjs.map +1 -1
- package/dist/martyrs/src/components/Loader/Loader.vue2.js +1 -1
- package/dist/martyrs/src/components/Loader/Loader.vue2.js.map +1 -1
- package/dist/martyrs/src/components/LocationMarker/{LocationMarker.vue2.cjs → LocationMarker.vue.cjs} +2 -2
- package/dist/martyrs/src/components/LocationMarker/{LocationMarker.vue2.js.map → LocationMarker.vue.cjs.map} +1 -1
- package/dist/martyrs/src/components/LocationMarker/{LocationMarker.vue2.js → LocationMarker.vue.js} +2 -2
- package/dist/martyrs/src/components/LocationMarker/LocationMarker.vue.js.map +1 -0
- package/dist/martyrs/src/components/Select/{Select.vue2.cjs → Select.vue.cjs} +2 -2
- package/dist/martyrs/src/components/Select/{Select.vue2.js.map → Select.vue.cjs.map} +1 -1
- package/dist/martyrs/src/components/Select/{Select.vue2.js → Select.vue.js} +2 -2
- package/dist/martyrs/src/components/Select/Select.vue.js.map +1 -0
- package/dist/martyrs/src/modules/auth/views/components/blocks/CardUser.vue.cjs +2 -2
- package/dist/martyrs/src/modules/auth/views/components/blocks/CardUser.vue.js +2 -2
- package/dist/martyrs/src/modules/auth/views/components/layouts/Auth.vue.cjs +1 -1
- package/dist/martyrs/src/modules/auth/views/components/layouts/Auth.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/auth/views/components/layouts/Auth.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/layouts/Auth.vue.js.map +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/Invite.vue.cjs +2 -2
- package/dist/martyrs/src/modules/auth/views/components/pages/Invite.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/Invite.vue.js +4 -4
- package/dist/martyrs/src/modules/auth/views/components/pages/Invite.vue.js.map +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/Profile.vue.cjs +41 -51
- package/dist/martyrs/src/modules/auth/views/components/pages/Profile.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/Profile.vue.js +59 -69
- package/dist/martyrs/src/modules/auth/views/components/pages/Profile.vue.js.map +1 -1
- package/dist/martyrs/src/modules/auth/views/components/sections/SliderFeatures.vue.cjs +11 -13
- package/dist/martyrs/src/modules/auth/views/components/sections/SliderFeatures.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/auth/views/components/sections/SliderFeatures.vue.js +11 -13
- package/dist/martyrs/src/modules/auth/views/components/sections/SliderFeatures.vue.js.map +1 -1
- package/dist/martyrs/src/modules/auth/views/store/auth.cjs +10 -1
- package/dist/martyrs/src/modules/auth/views/store/auth.cjs.map +1 -1
- package/dist/martyrs/src/modules/auth/views/store/auth.js +10 -1
- package/dist/martyrs/src/modules/auth/views/store/auth.js.map +1 -1
- package/dist/martyrs/src/modules/backoffice/components/partials/Sidebar.vue.cjs +6 -0
- package/dist/martyrs/src/modules/backoffice/components/partials/Sidebar.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/backoffice/components/partials/Sidebar.vue.js +6 -0
- package/dist/martyrs/src/modules/backoffice/components/partials/Sidebar.vue.js.map +1 -1
- package/dist/martyrs/src/modules/chats/components/blocks/ChatMessage.vue.cjs +27 -11
- package/dist/martyrs/src/modules/chats/components/blocks/ChatMessage.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/chats/components/blocks/ChatMessage.vue.js +28 -12
- package/dist/martyrs/src/modules/chats/components/blocks/ChatMessage.vue.js.map +1 -1
- package/dist/martyrs/src/modules/chats/components/sections/ChatWindow.vue.cjs +62 -0
- package/dist/martyrs/src/modules/chats/components/sections/ChatWindow.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/chats/components/sections/ChatWindow.vue.js +63 -1
- package/dist/martyrs/src/modules/chats/components/sections/ChatWindow.vue.js.map +1 -1
- package/dist/martyrs/src/modules/chats/store/chat.store.cjs +60 -1
- package/dist/martyrs/src/modules/chats/store/chat.store.cjs.map +1 -1
- package/dist/martyrs/src/modules/chats/store/chat.store.js +60 -1
- package/dist/martyrs/src/modules/chats/store/chat.store.js.map +1 -1
- package/dist/martyrs/src/modules/community/components/blocks/CardBlogpost.vue.cjs +1 -1
- package/dist/martyrs/src/modules/community/components/blocks/CardBlogpost.vue.js +1 -1
- package/dist/martyrs/src/modules/community/components/layouts/Community.vue.cjs +3 -3
- package/dist/martyrs/src/modules/community/components/layouts/Community.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/community/components/layouts/Community.vue.js +3 -3
- package/dist/martyrs/src/modules/community/components/layouts/Community.vue.js.map +1 -1
- package/dist/martyrs/src/modules/community/components/pages/BlogPost.vue.cjs +2 -2
- package/dist/martyrs/src/modules/community/components/pages/BlogPost.vue.js +2 -2
- package/dist/martyrs/src/modules/community/components/pages/CreateBlogPost.vue.cjs +1 -1
- package/dist/martyrs/src/modules/community/components/pages/CreateBlogPost.vue.js +1 -1
- package/dist/martyrs/src/modules/community/components/pages/Posts.vue.cjs +50 -368
- package/dist/martyrs/src/modules/community/components/pages/Posts.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/community/components/pages/Posts.vue.js +53 -371
- package/dist/martyrs/src/modules/community/components/pages/Posts.vue.js.map +1 -1
- package/dist/martyrs/src/modules/events/components/blocks/CardEvent.vue.cjs +1 -1
- package/dist/martyrs/src/modules/events/components/blocks/CardEvent.vue.js +1 -1
- package/dist/martyrs/src/modules/events/components/pages/EditEvent.vue.cjs +1 -1
- package/dist/martyrs/src/modules/events/components/pages/EditEvent.vue.js +1 -1
- package/dist/martyrs/src/modules/events/components/pages/EditEventTickets.vue.cjs +1 -1
- package/dist/martyrs/src/modules/events/components/pages/EditEventTickets.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/events/components/pages/EditEventTickets.vue.js +1 -1
- package/dist/martyrs/src/modules/events/components/pages/EditEventTickets.vue.js.map +1 -1
- package/dist/martyrs/src/modules/events/components/pages/Event.vue.cjs +2 -3
- package/dist/martyrs/src/modules/events/components/pages/Event.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/events/components/pages/Event.vue.js +2 -3
- package/dist/martyrs/src/modules/events/components/pages/Event.vue.js.map +1 -1
- package/dist/martyrs/src/modules/events/components/pages/Events.vue.cjs +2 -2
- package/dist/martyrs/src/modules/events/components/pages/Events.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/events/components/pages/Events.vue.js +2 -2
- package/dist/martyrs/src/modules/events/components/pages/Events.vue.js.map +1 -1
- package/dist/martyrs/src/modules/gallery/components/sections/BackofficeGallery.vue.cjs +3 -3
- package/dist/martyrs/src/modules/gallery/components/sections/BackofficeGallery.vue.js +3 -3
- package/dist/martyrs/src/modules/globals/views/classes/globals.i18n.cjs +1 -1
- package/dist/martyrs/src/modules/globals/views/classes/globals.i18n.js +1 -1
- package/dist/martyrs/src/modules/globals/views/components/blocks/CardHeader.vue.cjs +2 -2
- package/dist/martyrs/src/modules/globals/views/components/blocks/CardHeader.vue.js +2 -2
- package/dist/martyrs/src/modules/globals/views/components/partials/Header.vue.cjs +2 -2
- package/dist/martyrs/src/modules/globals/views/components/partials/Header.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/globals/views/components/partials/Header.vue.js +2 -2
- package/dist/martyrs/src/modules/globals/views/components/partials/Header.vue.js.map +1 -1
- package/dist/martyrs/src/modules/globals/views/components/partials/LocationSelection.vue.cjs +2 -2
- package/dist/martyrs/src/modules/globals/views/components/partials/LocationSelection.vue.js +2 -2
- package/dist/martyrs/src/modules/globals/views/components/partials/Navigation.vue.cjs +1 -1
- package/dist/martyrs/src/modules/globals/views/components/partials/Navigation.vue.js +1 -1
- package/dist/martyrs/src/modules/globals/views/components/partials/Sidebar.vue.cjs +16 -3
- package/dist/martyrs/src/modules/globals/views/components/partials/Sidebar.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/globals/views/components/partials/Sidebar.vue.js +17 -4
- package/dist/martyrs/src/modules/globals/views/components/partials/Sidebar.vue.js.map +1 -1
- package/dist/martyrs/src/modules/globals/views/components/sections/Walkthrough.vue.cjs +1 -1
- package/dist/martyrs/src/modules/globals/views/mixins/mixins.cjs +7 -0
- package/dist/martyrs/src/modules/globals/views/mixins/mixins.cjs.map +1 -1
- package/dist/martyrs/src/modules/globals/views/mixins/mixins.js +7 -0
- package/dist/martyrs/src/modules/globals/views/mixins/mixins.js.map +1 -1
- package/dist/martyrs/src/modules/icons/pages/IconsPage.vue.cjs +1 -1
- package/dist/martyrs/src/modules/inventory/components/forms/AdjustmentForm.vue.cjs +67 -43
- package/dist/martyrs/src/modules/inventory/components/forms/AdjustmentForm.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/inventory/components/forms/AdjustmentForm.vue.js +68 -44
- package/dist/martyrs/src/modules/inventory/components/forms/AdjustmentForm.vue.js.map +1 -1
- package/dist/martyrs/src/modules/inventory/components/forms/ColumnSettingsMenu.vue.cjs +22 -7
- package/dist/martyrs/src/modules/inventory/components/forms/ColumnSettingsMenu.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/inventory/components/forms/ColumnSettingsMenu.vue.js +23 -8
- package/dist/martyrs/src/modules/inventory/components/forms/ColumnSettingsMenu.vue.js.map +1 -1
- package/dist/martyrs/src/modules/inventory/components/forms/HistoryView.vue.cjs +47 -32
- package/dist/martyrs/src/modules/inventory/components/forms/HistoryView.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/inventory/components/forms/HistoryView.vue.js +48 -33
- package/dist/martyrs/src/modules/inventory/components/forms/HistoryView.vue.js.map +1 -1
- package/dist/martyrs/src/modules/inventory/components/forms/StockAlertsForm.vue.cjs +47 -26
- package/dist/martyrs/src/modules/inventory/components/forms/StockAlertsForm.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/inventory/components/forms/StockAlertsForm.vue.js +48 -27
- package/dist/martyrs/src/modules/inventory/components/forms/StockAlertsForm.vue.js.map +1 -1
- package/dist/martyrs/src/modules/inventory/components/pages/Inventory.vue.cjs +42 -52
- package/dist/martyrs/src/modules/inventory/components/pages/Inventory.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/inventory/components/pages/Inventory.vue.js +43 -53
- package/dist/martyrs/src/modules/inventory/components/pages/Inventory.vue.js.map +1 -1
- package/dist/martyrs/src/modules/inventory/components/pages/InventoryEdit.vue.cjs +18 -18
- package/dist/martyrs/src/modules/inventory/components/pages/InventoryEdit.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/inventory/components/pages/InventoryEdit.vue.js +3 -3
- package/dist/martyrs/src/modules/inventory/components/pages/InventoryEdit.vue.js.map +1 -1
- package/dist/martyrs/src/modules/inventory/store/{ inventory.store.cjs → inventory.store.cjs} +46 -2
- package/dist/martyrs/src/modules/inventory/store/inventory.store.cjs.map +1 -0
- package/dist/martyrs/src/modules/inventory/store/{ inventory.store.js → inventory.store.js} +46 -2
- package/dist/martyrs/src/modules/inventory/store/inventory.store.js.map +1 -0
- package/dist/martyrs/src/modules/marketplace/views/components/layouts/Marketplace.vue.cjs +180 -19
- package/dist/martyrs/src/modules/marketplace/views/components/layouts/Marketplace.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/marketplace/views/components/layouts/Marketplace.vue.js +181 -20
- package/dist/martyrs/src/modules/marketplace/views/components/layouts/Marketplace.vue.js.map +1 -1
- package/dist/martyrs/src/modules/music/components/forms/AlbumForm.vue.cjs +1 -1
- package/dist/martyrs/src/modules/music/components/forms/AlbumForm.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/forms/ArtistForm.vue.cjs +1 -1
- package/dist/martyrs/src/modules/music/components/forms/ArtistForm.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/forms/TrackForm.vue.cjs +1 -1
- package/dist/martyrs/src/modules/music/components/forms/TrackForm.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/pages/Album.vue.cjs +1 -1
- package/dist/martyrs/src/modules/music/components/pages/Album.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/pages/Playlist.vue.cjs +1 -1
- package/dist/martyrs/src/modules/music/components/pages/Playlist.vue.js +1 -1
- package/dist/martyrs/src/modules/music/components/pages/Track.vue.cjs +1 -1
- package/dist/martyrs/src/modules/music/components/pages/Track.vue.js +1 -1
- package/dist/martyrs/src/modules/music/router/music.cjs +1 -2
- package/dist/martyrs/src/modules/music/router/music.cjs.map +1 -1
- package/dist/martyrs/src/modules/music/router/music.js +1 -2
- package/dist/martyrs/src/modules/music/router/music.js.map +1 -1
- package/dist/martyrs/src/modules/orders/components/blocks/CardOrderBackoffice.vue.cjs +2 -2
- package/dist/martyrs/src/modules/orders/components/blocks/CardOrderBackoffice.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/orders/components/blocks/CardOrderBackoffice.vue.js +2 -2
- package/dist/martyrs/src/modules/orders/components/blocks/CardOrderBackoffice.vue.js.map +1 -1
- package/dist/martyrs/src/modules/orders/components/forms/FormApplicationDetails.vue.cjs +1 -1
- package/dist/martyrs/src/modules/orders/components/forms/FormApplicationDetails.vue.js +1 -1
- package/dist/martyrs/src/modules/orders/components/forms/FormCustomerDetails.vue.cjs +1 -1
- package/dist/martyrs/src/modules/orders/components/forms/FormCustomerDetails.vue.js +1 -1
- package/dist/martyrs/src/modules/orders/components/pages/OrderBackoffice.vue.cjs +1 -1
- package/dist/martyrs/src/modules/orders/components/pages/OrderBackoffice.vue.js +1 -1
- package/dist/martyrs/src/modules/orders/components/sections/FormDelivery.vue.cjs +3 -4
- package/dist/martyrs/src/modules/orders/components/sections/FormDelivery.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/orders/components/sections/FormDelivery.vue.js +3 -4
- package/dist/martyrs/src/modules/orders/components/sections/FormDelivery.vue.js.map +1 -1
- package/dist/martyrs/src/modules/orders/components/sections/FormPayment.vue.cjs +1 -1
- package/dist/martyrs/src/modules/orders/components/sections/FormPayment.vue.js +1 -1
- package/dist/martyrs/src/modules/orders/orders.client.cjs +2 -2
- package/dist/martyrs/src/modules/orders/orders.client.cjs.map +1 -1
- package/dist/martyrs/src/modules/orders/orders.client.js +2 -2
- package/dist/martyrs/src/modules/orders/orders.client.js.map +1 -1
- package/dist/martyrs/src/modules/orders/router/customers.router.cjs +1 -1
- package/dist/martyrs/src/modules/orders/router/customers.router.cjs.map +1 -1
- package/dist/martyrs/src/modules/orders/router/customers.router.js +1 -1
- package/dist/martyrs/src/modules/orders/router/customers.router.js.map +1 -1
- package/dist/martyrs/src/modules/organizations/components/blocks/CardDepartment.vue.cjs +2 -24
- package/dist/martyrs/src/modules/organizations/components/blocks/CardDepartment.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/organizations/components/blocks/CardDepartment.vue.js +5 -27
- package/dist/martyrs/src/modules/organizations/components/blocks/CardDepartment.vue.js.map +1 -1
- package/dist/martyrs/src/modules/organizations/components/blocks/CardOrganization.vue.cjs +1 -1
- package/dist/martyrs/src/modules/organizations/components/blocks/CardOrganization.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/blocks/Socials.vue.cjs +4 -1
- package/dist/martyrs/src/modules/organizations/components/blocks/Socials.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/organizations/components/blocks/Socials.vue.js +4 -1
- package/dist/martyrs/src/modules/organizations/components/blocks/Socials.vue.js.map +1 -1
- package/dist/martyrs/src/modules/organizations/components/elements/ButtonToggleMembership.vue.cjs +3 -3
- package/dist/martyrs/src/modules/organizations/components/elements/ButtonToggleMembership.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/organizations/components/elements/ButtonToggleMembership.vue.js +3 -3
- package/dist/martyrs/src/modules/organizations/components/elements/ButtonToggleMembership.vue.js.map +1 -1
- package/dist/martyrs/src/modules/organizations/components/forms/AddExistingMembersForm.vue.cjs +195 -0
- package/dist/martyrs/src/modules/organizations/components/forms/AddExistingMembersForm.vue.cjs.map +1 -0
- package/dist/martyrs/src/modules/organizations/components/forms/AddExistingMembersForm.vue.js +195 -0
- package/dist/martyrs/src/modules/organizations/components/forms/AddExistingMembersForm.vue.js.map +1 -0
- package/dist/martyrs/src/modules/organizations/components/forms/DepartmentForm.vue.cjs +402 -0
- package/dist/martyrs/src/modules/organizations/components/forms/DepartmentForm.vue.cjs.map +1 -0
- package/dist/martyrs/src/modules/organizations/components/forms/DepartmentForm.vue.js +402 -0
- package/dist/martyrs/src/modules/organizations/components/forms/DepartmentForm.vue.js.map +1 -0
- package/dist/martyrs/src/modules/organizations/components/forms/InviteForm.vue.cjs +86 -0
- package/dist/martyrs/src/modules/organizations/components/forms/InviteForm.vue.cjs.map +1 -0
- package/dist/martyrs/src/modules/organizations/components/forms/InviteForm.vue.js +86 -0
- package/dist/martyrs/src/modules/organizations/components/forms/InviteForm.vue.js.map +1 -0
- package/dist/martyrs/src/modules/organizations/components/pages/Department.vue.cjs +10 -10
- package/dist/martyrs/src/modules/organizations/components/pages/Department.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/Department.vue.js +11 -11
- package/dist/martyrs/src/modules/organizations/components/pages/Department.vue.js.map +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/Members.vue.cjs +279 -191
- package/dist/martyrs/src/modules/organizations/components/pages/Members.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/Members.vue.js +285 -197
- package/dist/martyrs/src/modules/organizations/components/pages/Members.vue.js.map +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/Organization.vue.cjs +7 -7
- package/dist/martyrs/src/modules/organizations/components/pages/Organization.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/Organization.vue.js +7 -7
- package/dist/martyrs/src/modules/organizations/components/pages/Organization.vue.js.map +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/OrganizationEdit.vue.cjs +2 -2
- package/dist/martyrs/src/modules/organizations/components/pages/OrganizationEdit.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/OrganizationEdit.vue.js +2 -2
- package/dist/martyrs/src/modules/organizations/components/pages/OrganizationEdit.vue.js.map +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/Organizations.vue.cjs +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/Organizations.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/Organizations.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/Organizations.vue.js.map +1 -1
- package/dist/martyrs/src/modules/organizations/components/sections/MembersAdd.vue.cjs +1 -1
- package/dist/martyrs/src/modules/organizations/components/sections/MembersAdd.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/sections/Organizations.vue.cjs +3 -3
- package/dist/martyrs/src/modules/organizations/components/sections/Organizations.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/organizations/components/sections/Organizations.vue.js +3 -3
- package/dist/martyrs/src/modules/organizations/components/sections/Organizations.vue.js.map +1 -1
- package/dist/martyrs/src/modules/organizations/components/sections/Publics.vue.cjs +4 -4
- package/dist/martyrs/src/modules/organizations/components/sections/Publics.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/organizations/components/sections/Publics.vue.js +4 -4
- package/dist/martyrs/src/modules/organizations/components/sections/Publics.vue.js.map +1 -1
- package/dist/martyrs/src/modules/organizations/configs/navigation.organization.config.cjs +42 -41
- package/dist/martyrs/src/modules/organizations/configs/navigation.organization.config.cjs.map +1 -1
- package/dist/martyrs/src/modules/organizations/configs/navigation.organization.config.js +53 -52
- package/dist/martyrs/src/modules/organizations/configs/navigation.organization.config.js.map +1 -1
- package/dist/martyrs/src/modules/organizations/organizations.client.cjs +23 -16
- package/dist/martyrs/src/modules/organizations/organizations.client.cjs.map +1 -1
- package/dist/martyrs/src/modules/organizations/organizations.client.js +35 -28
- package/dist/martyrs/src/modules/organizations/organizations.client.js.map +1 -1
- package/dist/martyrs/src/modules/organizations/router/departments.router.cjs +0 -18
- package/dist/martyrs/src/modules/organizations/router/departments.router.cjs.map +1 -1
- package/dist/martyrs/src/modules/organizations/router/departments.router.js +0 -18
- package/dist/martyrs/src/modules/organizations/router/departments.router.js.map +1 -1
- package/dist/martyrs/src/modules/organizations/store/departments.store.cjs +6 -0
- package/dist/martyrs/src/modules/organizations/store/departments.store.cjs.map +1 -0
- package/dist/martyrs/src/modules/organizations/store/departments.store.js +6 -0
- package/dist/martyrs/src/modules/organizations/store/departments.store.js.map +1 -0
- package/dist/martyrs/src/modules/organizations/store/invites.store.cjs +6 -0
- package/dist/martyrs/src/modules/organizations/store/invites.store.cjs.map +1 -0
- package/dist/martyrs/src/modules/organizations/store/invites.store.js +6 -0
- package/dist/martyrs/src/modules/organizations/store/invites.store.js.map +1 -0
- package/dist/martyrs/src/modules/organizations/store/memberships.store.cjs +20 -0
- package/dist/martyrs/src/modules/organizations/store/memberships.store.cjs.map +1 -0
- package/dist/martyrs/src/modules/organizations/store/memberships.store.js +20 -0
- package/dist/martyrs/src/modules/organizations/store/memberships.store.js.map +1 -0
- package/dist/martyrs/src/modules/products/components/blocks/ProductDiscounts.vue.cjs +1 -1
- package/dist/martyrs/src/modules/products/components/blocks/ProductDiscounts.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/pages/CategoryEdit.vue.cjs +3 -4
- package/dist/martyrs/src/modules/products/components/pages/CategoryEdit.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/products/components/pages/CategoryEdit.vue.js +3 -4
- package/dist/martyrs/src/modules/products/components/pages/CategoryEdit.vue.js.map +1 -1
- package/dist/martyrs/src/modules/products/components/pages/ProductEdit.vue.cjs +2 -2
- package/dist/martyrs/src/modules/products/components/pages/ProductEdit.vue.js +2 -2
- package/dist/martyrs/src/modules/products/components/pages/Products.vue.cjs +1 -1
- package/dist/martyrs/src/modules/products/components/pages/Products.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/products/components/pages/Products.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/pages/Products.vue.js.map +1 -1
- package/dist/martyrs/src/modules/products/components/sections/EditDiscounts.vue.cjs +1 -1
- package/dist/martyrs/src/modules/products/components/sections/EditDiscounts.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/sections/EditVariants.vue.cjs +2 -2
- package/dist/martyrs/src/modules/products/components/sections/EditVariants.vue.js +2 -2
- package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttToolbar.vue.cjs +1 -1
- package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttToolbar.vue.js +1 -1
- package/dist/martyrs/src/modules/reports/components/sections/FormReport.vue.cjs +1 -1
- package/dist/martyrs/src/modules/reports/components/sections/FormReport.vue.js +1 -1
- package/dist/martyrs/src/modules/spots/components/blocks/CardSpot.vue.cjs +3 -3
- package/dist/martyrs/src/modules/spots/components/blocks/CardSpot.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/spots/components/blocks/CardSpot.vue.js +3 -3
- package/dist/martyrs/src/modules/spots/components/blocks/CardSpot.vue.js.map +1 -1
- package/dist/martyrs/src/modules/spots/components/blocks/SpotMemberModify.vue.cjs +1 -1
- package/dist/martyrs/src/modules/spots/components/blocks/SpotMemberModify.vue.js +1 -1
- package/dist/martyrs/src/modules/spots/components/layouts/Spots.vue.cjs +1 -1
- package/dist/martyrs/src/modules/spots/components/layouts/Spots.vue.js +1 -1
- package/dist/martyrs/src/modules/spots/components/pages/SpotEdit.vue.cjs +3 -3
- package/dist/martyrs/src/modules/spots/components/pages/SpotEdit.vue.js +3 -3
- package/dist/martyrs/src/modules/spots/components/pages/Spots.vue.cjs +60 -272
- package/dist/martyrs/src/modules/spots/components/pages/Spots.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/spots/components/pages/Spots.vue.js +62 -274
- package/dist/martyrs/src/modules/spots/components/pages/Spots.vue.js.map +1 -1
- package/dist/martyrs/src/modules/spots/components/sections/WorktimeEdit.vue.cjs +1 -1
- package/dist/martyrs/src/modules/spots/components/sections/WorktimeEdit.vue.js +1 -1
- package/dist/martyrs/src/modules/wallet/views/components/blocks/CryptoDeposit.vue.cjs +1 -1
- package/dist/martyrs/src/modules/wallet/views/components/blocks/CryptoDeposit.vue.js +1 -1
- package/dist/martyrs/src/modules/wallet/views/components/pages/Wallet.vue.cjs +4 -4
- package/dist/martyrs/src/modules/wallet/views/components/pages/Wallet.vue.js +4 -4
- package/dist/martyrs.cjs.js +1 -1
- package/dist/martyrs.css +1 -1
- package/dist/martyrs.es.js +1 -1
- package/dist/music.server.cjs +9 -9
- package/dist/music.server.js +9 -9
- package/dist/notifications.server.cjs +0 -24
- package/dist/notifications.server.js +0 -24
- package/dist/orders.server.cjs +3 -6
- package/dist/orders.server.js +3 -6
- package/dist/organizations.server.cjs +119 -43
- package/dist/organizations.server.js +119 -43
- package/dist/products.server.cjs +5 -5
- package/dist/products.server.js +5 -5
- package/dist/rents.server.cjs +3 -3
- package/dist/rents.server.js +3 -3
- package/dist/style.css +16 -17
- package/dist/wallet.server.cjs +2 -2
- package/dist/wallet.server.js +2 -2
- package/dist/{web-B5wZTKbK.cjs → web-B0cfxzgu.cjs} +1 -1
- package/dist/{web-520xCgXy.js → web-DVR8m2fm.js} +1 -1
- package/package.json +1 -1
- package/src/builder/modes/ssr.rspack.dev.js +20 -12
- package/src/builder/rspack/rspack.config.base.js +16 -15
- package/src/components/Button/Button.vue +1 -1
- package/src/components/Feed/Feed.old.vue +0 -1
- package/src/components/Feed/Feed.vue +1 -31
- package/src/components/Loader/Loader.vue +1 -1
- package/src/modules/auth/FIXES.md +61 -0
- package/src/modules/auth/PROMT.md +33 -0
- package/src/modules/auth/auth.server.js +1 -0
- package/src/modules/auth/views/components/blocks/CardUser.vue +2 -2
- package/src/modules/auth/views/components/layouts/Auth.vue +1 -1
- package/src/modules/auth/views/components/pages/Invite.vue +2 -2
- package/src/modules/auth/views/components/pages/Profile.vue +33 -48
- package/src/modules/auth/views/components/sections/SliderFeatures.vue +5 -7
- package/src/modules/auth/views/store/auth.js +16 -1
- package/src/modules/auth//320/220/320/240/320/245/320/230/320/242/320/225/320/232/320/242/320/243/320/240/320/220.md +445 -0
- package/src/modules/backoffice/components/partials/Sidebar.vue +6 -0
- package/src/modules/chats/CLAUDE.md +137 -0
- package/src/modules/chats/components/blocks/ChatMessage.vue +12 -0
- package/src/modules/chats/components/sections/ChatWindow.vue +84 -2
- package/src/modules/chats/controllers/chats.controller.js +187 -0
- package/src/modules/chats/models/chat.model.js +21 -0
- package/src/modules/chats/routes/chats.routes.js +46 -0
- package/src/modules/chats/store/chat.store.js +67 -0
- package/src/modules/community/components/layouts/Community.vue +2 -2
- package/src/modules/community/components/pages/Posts.vue +3 -328
- package/src/modules/events/components/pages/EditEventTickets.vue +1 -1
- package/src/modules/events/components/pages/Events.vue +2 -2
- package/src/modules/globals/controllers/classes/globals.cache.js +64 -55
- package/src/modules/globals/controllers/classes/globals.logger.js +40 -4
- package/src/modules/globals/controllers/classes/globals.observer.js +54 -4
- package/src/modules/globals/views/components/partials/Header.vue +1 -1
- package/src/modules/globals/views/components/partials/Sidebar.vue +17 -13
- package/src/modules/globals/views/mixins/mixins.js +7 -0
- package/src/modules/inventory/CLAUDE.md +330 -0
- package/src/modules/inventory/PROMT.md +25 -0
- package/src/modules/inventory/components/forms/AdjustmentForm.vue +53 -36
- package/src/modules/inventory/components/forms/ColumnSettingsMenu.vue +11 -6
- package/src/modules/inventory/components/forms/HistoryView.vue +21 -9
- package/src/modules/inventory/components/forms/StockAlertsForm.vue +33 -22
- package/src/modules/inventory/components/pages/Inventory.vue +40 -40
- package/src/modules/inventory/components/pages/InventoryEdit.vue +1 -1
- package/src/modules/inventory/docs/01-intro.md +126 -0
- package/src/modules/inventory/docs/02-architecture.md +266 -0
- package/src/modules/inventory/docs/03-components-and-relationships.md +338 -0
- package/src/modules/inventory/docs/04-business-logic-and-algorithms.md +376 -0
- package/src/modules/inventory/docs/05-api-specification.md +356 -0
- package/src/modules/inventory/docs/06-access-control.md +320 -0
- package/src/modules/inventory/inventory.server.js +6 -2
- package/src/modules/inventory/{services → middlewares}/inventory.verifier.js +5 -16
- package/src/modules/inventory/models/stock.availability.model.js +20 -7
- package/src/modules/inventory/routes/inventory.routes.js +14 -17
- package/src/modules/inventory/services/adjustment.service.js +137 -0
- package/src/modules/inventory/services/audit.service.js +160 -0
- package/src/modules/inventory/services/availability.service.js +323 -0
- package/src/modules/inventory/services/inventory.helpers.old.js +217 -0
- package/src/modules/inventory/store/{ inventory.store.js → inventory.store.js} +0 -14
- package/src/modules/inventory/workers/inventory.availability.worker.js +29 -30
- package/src/modules/marketplace/views/components/layouts/Marketplace.vue +160 -8
- package/src/modules/notifications/controllers/notifications.controller.js +0 -6
- package/src/modules/notifications/services/notification.service.js +1 -17
- package/src/modules/notifications/services/web-push.service.js +0 -2
- package/src/modules/orders/components/blocks/CardOrderBackoffice.vue +2 -2
- package/src/modules/orders/components/blocks/CardOrderVar1.vue +1 -1
- package/src/modules/orders/controllers/orders.controller.js +2 -4
- package/src/modules/orders/orders.client.js +2 -2
- package/src/modules/orders/router/customers.router.js +1 -1
- package/src/modules/organizations/CLAUDE.md +259 -0
- package/src/modules/organizations/components/blocks/CardDepartment.vue +1 -22
- package/src/modules/organizations/components/blocks/Socials.vue +1 -1
- package/src/modules/organizations/components/elements/ButtonToggleMembership.vue +3 -3
- package/src/modules/organizations/components/forms/AddExistingMembersForm.vue +191 -0
- package/src/modules/organizations/components/forms/DepartmentForm.vue +390 -0
- package/src/modules/organizations/components/forms/InviteForm.vue +81 -0
- package/src/modules/organizations/components/pages/Department.vue +10 -10
- package/src/modules/organizations/components/pages/DepartmentEdit.vue +8 -8
- package/src/modules/organizations/components/pages/Members.vue +265 -171
- package/src/modules/organizations/components/pages/Organization.new.vue +172 -183
- package/src/modules/organizations/components/pages/Organization.vue +6 -6
- package/src/modules/organizations/components/pages/OrganizationEdit.vue +1 -1
- package/src/modules/organizations/components/pages/Organizations.vue +1 -1
- package/src/modules/organizations/components/sections/Organizations.vue +2 -2
- package/src/modules/organizations/components/sections/Publics.vue +4 -4
- package/src/modules/organizations/configs/navigation.organization.config.js +40 -39
- package/src/modules/organizations/controllers/departments.controller.js +53 -34
- package/src/modules/organizations/controllers/invites.controller.js +44 -5
- package/src/modules/organizations/controllers/memberships.controller.js +43 -4
- package/src/modules/organizations/organizations.client.js +24 -15
- package/src/modules/organizations/router/departments.router.js +0 -18
- package/src/modules/organizations/routes/departments.routes.js +6 -8
- package/src/modules/organizations/routes/invites.routes.js +6 -4
- package/src/modules/organizations/routes/memberships.routes.js +6 -5
- package/src/modules/organizations/routes/organizations.routes.js +1 -1
- package/src/modules/organizations/store/departments.store.js +5 -0
- package/src/modules/organizations/store/invites.store.js +5 -0
- package/src/modules/organizations/store/memberships.store.js +23 -0
- package/src/modules/products/components/pages/Products.vue +0 -1
- package/src/modules/spots/components/blocks/CardSpot.vue +1 -1
- package/src/modules/spots/components/pages/Spots.vue +3 -203
- package/src/styles/base/all.scss +0 -15
- package/src/styles/responsive.scss +1 -31
- package/src/styles/typography.scss +20 -5
- package/dist/main-CSzPfQYR.cjs +0 -11
- package/dist/martyrs/src/components/Address/Address.vue2.cjs.map +0 -1
- package/dist/martyrs/src/components/Chips/Chips.vue.cjs.map +0 -1
- package/dist/martyrs/src/components/Chips/Chips.vue.js.map +0 -1
- package/dist/martyrs/src/components/Dropdown/Dropdown.vue.js.map +0 -1
- package/dist/martyrs/src/components/LocationMarker/LocationMarker.vue2.cjs.map +0 -1
- package/dist/martyrs/src/components/Select/Select.vue2.cjs.map +0 -1
- package/dist/martyrs/src/modules/globals/views/components/blocks/BlockFilter.vue.cjs +0 -76
- package/dist/martyrs/src/modules/globals/views/components/blocks/BlockFilter.vue.cjs.map +0 -1
- package/dist/martyrs/src/modules/globals/views/components/blocks/BlockFilter.vue.js +0 -76
- package/dist/martyrs/src/modules/globals/views/components/blocks/BlockFilter.vue.js.map +0 -1
- package/dist/martyrs/src/modules/inventory/store/ inventory.store.cjs.map +0 -1
- package/dist/martyrs/src/modules/inventory/store/ inventory.store.js.map +0 -1
- package/dist/martyrs/src/modules/organizations/components/pages/DepartmentEdit.vue.cjs +0 -280
- package/dist/martyrs/src/modules/organizations/components/pages/DepartmentEdit.vue.cjs.map +0 -1
- package/dist/martyrs/src/modules/organizations/components/pages/DepartmentEdit.vue.js +0 -280
- package/dist/martyrs/src/modules/organizations/components/pages/DepartmentEdit.vue.js.map +0 -1
- package/dist/martyrs/src/modules/organizations/store/departments.cjs +0 -121
- package/dist/martyrs/src/modules/organizations/store/departments.cjs.map +0 -1
- package/dist/martyrs/src/modules/organizations/store/departments.js +0 -121
- package/dist/martyrs/src/modules/organizations/store/departments.js.map +0 -1
- package/dist/martyrs/src/modules/organizations/store/invites.cjs +0 -64
- package/dist/martyrs/src/modules/organizations/store/invites.cjs.map +0 -1
- package/dist/martyrs/src/modules/organizations/store/invites.js +0 -64
- package/dist/martyrs/src/modules/organizations/store/invites.js.map +0 -1
- package/dist/martyrs/src/modules/organizations/store/memberships.cjs +0 -87
- package/dist/martyrs/src/modules/organizations/store/memberships.cjs.map +0 -1
- package/dist/martyrs/src/modules/organizations/store/memberships.js +0 -87
- package/dist/martyrs/src/modules/organizations/store/memberships.js.map +0 -1
- package/src/modules/globals/controllers/classes/globals.websocket.ws.js +0 -102
- package/src/modules/globals/views/components/blocks/BlockFilter.vue +0 -60
- package/src/modules/inventory/docs/README.md +0 -291
- package/src/modules/inventory/models/stock.balance.model.js +0 -43
- package/src/modules/inventory/services/inventory.crud.js +0 -710
- package/src/modules/inventory/tests/inventory.test.js +0 -281
- package/src/modules/organizations/store/departments.js +0 -137
- package/src/modules/organizations/store/invites.js +0 -76
- package/src/modules/organizations/store/memberships.js +0 -110
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
# 5. API спецификация
|
|
2
|
+
|
|
3
|
+
## Обзор API endpoints
|
|
4
|
+
|
|
5
|
+
Модуль Inventory предоставляет RESTful API для управления складскими запасами. Все endpoints требуют аутентификации через JWT токен и поддерживают ABAC авторизацию.
|
|
6
|
+
|
|
7
|
+
**Base URL**: `/api/inventory`
|
|
8
|
+
|
|
9
|
+
## Stock Adjustments API
|
|
10
|
+
|
|
11
|
+
### GET /api/inventory/adjustments
|
|
12
|
+
Получение списка движений товаров с фильтрацией и пагинацией.
|
|
13
|
+
|
|
14
|
+
**Аутентификация**: Требуется JWT (`jwt.verifyToken(true)`)
|
|
15
|
+
**Авторизация**: Не требуется (только фильтрация по owner)
|
|
16
|
+
|
|
17
|
+
**Query параметры**:
|
|
18
|
+
```javascript
|
|
19
|
+
{
|
|
20
|
+
product?: string, // ObjectId товара
|
|
21
|
+
variant?: string, // ObjectId варианта
|
|
22
|
+
storage?: string, // ObjectId склада
|
|
23
|
+
reason?: string, // Причина движения
|
|
24
|
+
dateStart?: date, // Начало периода
|
|
25
|
+
dateEnd?: date, // Конец периода
|
|
26
|
+
skip?: integer, // Offset для пагинации (default: 0)
|
|
27
|
+
limit?: integer // Лимит записей (default: 20, max: 100)
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**Пример запроса**:
|
|
32
|
+
```bash
|
|
33
|
+
GET /api/inventory/adjustments?storage=507f1f77bcf86cd799439011&reason=restock&limit=10
|
|
34
|
+
Authorization: Bearer <jwt_token>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**Пример ответа**:
|
|
38
|
+
```json
|
|
39
|
+
[
|
|
40
|
+
{
|
|
41
|
+
"_id": "507f1f77bcf86cd799439012",
|
|
42
|
+
"product": "507f1f77bcf86cd799439013",
|
|
43
|
+
"variant": "507f1f77bcf86cd799439014",
|
|
44
|
+
"storage": "507f1f77bcf86cd799439011",
|
|
45
|
+
"source": {
|
|
46
|
+
"type": "User",
|
|
47
|
+
"target": "507f1f77bcf86cd799439015"
|
|
48
|
+
},
|
|
49
|
+
"reason": "restock",
|
|
50
|
+
"quantity": 50,
|
|
51
|
+
"cost": 1000,
|
|
52
|
+
"comment": "Поступление от поставщика",
|
|
53
|
+
"productData": {
|
|
54
|
+
"name": "Пицца Маргарита",
|
|
55
|
+
"sku": "PIZZA-001"
|
|
56
|
+
},
|
|
57
|
+
"createdAt": "2023-12-01T10:30:00Z",
|
|
58
|
+
"owner": { "type": "organization", "target": "..." },
|
|
59
|
+
"creator": { "type": "user", "target": "..." }
|
|
60
|
+
}
|
|
61
|
+
]
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### POST /api/inventory/adjustments/create
|
|
65
|
+
Создание движения товара (поступление/расход).
|
|
66
|
+
|
|
67
|
+
**Аутентификация**: Требуется JWT (`jwt.verifyToken()`)
|
|
68
|
+
**Авторизация**: ABAC `stockAdjustment:create`
|
|
69
|
+
|
|
70
|
+
**Request Body**:
|
|
71
|
+
```javascript
|
|
72
|
+
{
|
|
73
|
+
product: string, // ObjectId товара (required)
|
|
74
|
+
variant?: string, // ObjectId варианта
|
|
75
|
+
storage: string, // ObjectId склада (required)
|
|
76
|
+
source: { // Источник движения (required)
|
|
77
|
+
type: 'User' | 'Order' | 'Inventory',
|
|
78
|
+
target: string // ObjectId источника
|
|
79
|
+
},
|
|
80
|
+
reason: 'restock' | 'sale' | 'return' | 'damage' | 'transfer' | 'custom',
|
|
81
|
+
quantity: integer, // Изменение количества (+/-) (required)
|
|
82
|
+
cost?: number, // Стоимость (>=0)
|
|
83
|
+
comment?: string // Комментарий
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**Пример запроса**:
|
|
88
|
+
```bash
|
|
89
|
+
POST /api/inventory/adjustments/create
|
|
90
|
+
Authorization: Bearer <jwt_token>
|
|
91
|
+
Content-Type: application/json
|
|
92
|
+
|
|
93
|
+
{
|
|
94
|
+
"product": "507f1f77bcf86cd799439013",
|
|
95
|
+
"variant": "507f1f77bcf86cd799439014",
|
|
96
|
+
"storage": "507f1f77bcf86cd799439011",
|
|
97
|
+
"source": {
|
|
98
|
+
"type": "User",
|
|
99
|
+
"target": "507f1f77bcf86cd799439015"
|
|
100
|
+
},
|
|
101
|
+
"reason": "restock",
|
|
102
|
+
"quantity": 100,
|
|
103
|
+
"cost": 2500,
|
|
104
|
+
"comment": "Поступление товара на склад"
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
**Пример ответа**:
|
|
109
|
+
```json
|
|
110
|
+
{
|
|
111
|
+
"_id": "507f1f77bcf86cd799439016",
|
|
112
|
+
"product": "507f1f77bcf86cd799439013",
|
|
113
|
+
"variant": "507f1f77bcf86cd799439014",
|
|
114
|
+
"storage": "507f1f77bcf86cd799439011",
|
|
115
|
+
"source": {
|
|
116
|
+
"type": "User",
|
|
117
|
+
"target": "507f1f77bcf86cd799439015"
|
|
118
|
+
},
|
|
119
|
+
"reason": "restock",
|
|
120
|
+
"quantity": 100,
|
|
121
|
+
"cost": 2500,
|
|
122
|
+
"comment": "Поступление товара на склад",
|
|
123
|
+
"createdAt": "2023-12-01T10:30:00Z",
|
|
124
|
+
"owner": { "type": "organization", "target": "..." },
|
|
125
|
+
"creator": { "type": "user", "target": "..." }
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
**Побочные эффекты**:
|
|
130
|
+
- Обновляется количество в `StockAvailability` для товара
|
|
131
|
+
- Пересчитывается доступность в `StockAvailability` для всех зависимых вариантов
|
|
132
|
+
- Проверяются и отправляются `StockAlert` уведомления
|
|
133
|
+
- Генерируется событие `stock.adjusted`
|
|
134
|
+
- Инвалидируется кеш с тегами `['adjustments', 'availability']`
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
## Stock Availability API
|
|
138
|
+
|
|
139
|
+
### GET /api/inventory/availability
|
|
140
|
+
Получение текущих остатков и доступности товаров для продажи с учетом ингредиентов.
|
|
141
|
+
|
|
142
|
+
**Аутентификация**: Не требуется (публичный endpoint)
|
|
143
|
+
**Авторизация**: Не требуется
|
|
144
|
+
|
|
145
|
+
**Query параметры**:
|
|
146
|
+
```javascript
|
|
147
|
+
{
|
|
148
|
+
product?: string, // Фильтр по товару
|
|
149
|
+
storage?: string, // Фильтр по складу
|
|
150
|
+
skip?: integer, // Offset (default: 0)
|
|
151
|
+
limit?: integer, // Лимит (default: 50, max: 100)
|
|
152
|
+
details?: string, // Дополнительная детализация
|
|
153
|
+
search?: string, // Поиск по названию
|
|
154
|
+
sortParam?: string, // Поле сортировки
|
|
155
|
+
sortOrder?: 'asc' | 'desc' // Направление сортировки
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
**Особенности ответа**:
|
|
160
|
+
- Включает поле `quantity` (физический остаток)
|
|
161
|
+
- Включает расчетные поля `available` и `constraints`
|
|
162
|
+
- Показывает ограничения по ингредиентам
|
|
163
|
+
- Оптимизирован для e-commerce интеграции
|
|
164
|
+
|
|
165
|
+
**Пример ответа**:
|
|
166
|
+
```json
|
|
167
|
+
[
|
|
168
|
+
{
|
|
169
|
+
"_id": "507f1f77bcf86cd799439018",
|
|
170
|
+
"product": "507f1f77bcf86cd799439013",
|
|
171
|
+
"variant": "507f1f77bcf86cd799439014",
|
|
172
|
+
"storage": "507f1f77bcf86cd799439011",
|
|
173
|
+
"quantity": 10, // Физический остаток
|
|
174
|
+
"available": 8, // Доступно для продажи
|
|
175
|
+
"reservations": 2, // Зарезервировано
|
|
176
|
+
"constraints": [ // Ограничения по ингредиентам
|
|
177
|
+
{
|
|
178
|
+
"ingredient": "507f1f77bcf86cd799439019",
|
|
179
|
+
"stock": 50, // Остаток ингредиента
|
|
180
|
+
"required": 2, // Требуется на единицу
|
|
181
|
+
"available": 25 // Можно произвести единиц
|
|
182
|
+
}
|
|
183
|
+
],
|
|
184
|
+
"calculatedAt": "2023-12-01T10:35:00Z"
|
|
185
|
+
}
|
|
186
|
+
]
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Stock Audit API
|
|
190
|
+
|
|
191
|
+
### GET /api/inventory/audits
|
|
192
|
+
Получение списка инвентаризаций.
|
|
193
|
+
|
|
194
|
+
**Аутентификация**: Требуется JWT
|
|
195
|
+
**Авторизация**: Не требуется (фильтрация по owner)
|
|
196
|
+
|
|
197
|
+
**Query параметры**: Стандартные для листинга
|
|
198
|
+
|
|
199
|
+
**Пример ответа**:
|
|
200
|
+
```json
|
|
201
|
+
[
|
|
202
|
+
{
|
|
203
|
+
"_id": "507f1f77bcf86cd79943901A",
|
|
204
|
+
"storage": "507f1f77bcf86cd799439011",
|
|
205
|
+
"status": "published",
|
|
206
|
+
"positions": [
|
|
207
|
+
{
|
|
208
|
+
"product": "507f1f77bcf86cd799439013",
|
|
209
|
+
"variant": "507f1f77bcf86cd799439014",
|
|
210
|
+
"quantity": 5,
|
|
211
|
+
"reason": "custom",
|
|
212
|
+
"comment": "Недостача при инвентаризации"
|
|
213
|
+
}
|
|
214
|
+
],
|
|
215
|
+
"comment": "Плановая инвентаризация декабрь 2023",
|
|
216
|
+
"createdAt": "2023-12-01T09:00:00Z",
|
|
217
|
+
"owner": { "type": "organization", "target": "..." },
|
|
218
|
+
"creator": { "type": "user", "target": "..." }
|
|
219
|
+
}
|
|
220
|
+
]
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### POST /api/inventory/audits/create
|
|
224
|
+
Создание новой инвентаризации.
|
|
225
|
+
|
|
226
|
+
**Аутентификация**: Требуется JWT
|
|
227
|
+
**Авторизация**: ABAC `stockAudit:create`
|
|
228
|
+
|
|
229
|
+
**Request Body**:
|
|
230
|
+
```javascript
|
|
231
|
+
{
|
|
232
|
+
storage: string, // ObjectId склада (required)
|
|
233
|
+
comment?: string, // Комментарий к инвентаризации
|
|
234
|
+
status?: 'draft' | 'published', // Статус (default: 'draft')
|
|
235
|
+
positions: [ // Массив позиций (required)
|
|
236
|
+
{
|
|
237
|
+
product: string, // ObjectId товара (required)
|
|
238
|
+
variant?: string, // ObjectId варианта
|
|
239
|
+
quantity: integer // Количество для корректировки (required)
|
|
240
|
+
}
|
|
241
|
+
]
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
**Поведение в зависимости от статуса**:
|
|
246
|
+
- **draft**: Сохраняет данные без влияния на остатки
|
|
247
|
+
- **published**: Сразу создает adjustments и обновляет балансы
|
|
248
|
+
|
|
249
|
+
### POST /api/inventory/audits/complete
|
|
250
|
+
Публикация (завершение) инвентаризации.
|
|
251
|
+
|
|
252
|
+
**Аутентификация**: Требуется JWT
|
|
253
|
+
**Авторизация**: ABAC `stockAudit:edit`
|
|
254
|
+
|
|
255
|
+
**Request Body**:
|
|
256
|
+
```javascript
|
|
257
|
+
{
|
|
258
|
+
_id: string // ObjectId инвентаризации
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
**Выполняемые операции**:
|
|
263
|
+
1. Создание `StockAdjustment` для каждой позиции
|
|
264
|
+
2. Batch обновление количества в `StockAvailability`
|
|
265
|
+
3. Пересчет доступности в `StockAvailability` для затронутых товаров
|
|
266
|
+
4. Изменение статуса audit на `published`
|
|
267
|
+
5. Генерация события `inventory.completed`
|
|
268
|
+
|
|
269
|
+
## Stock Alerts API
|
|
270
|
+
|
|
271
|
+
### Полный CRUD через универсальный контроллер
|
|
272
|
+
**Base Path**: `/api/inventory/alerts`
|
|
273
|
+
|
|
274
|
+
**Доступные endpoints**:
|
|
275
|
+
- `GET /api/inventory/alerts` - Список алертов
|
|
276
|
+
- `POST /api/inventory/alerts` - Создание алерта
|
|
277
|
+
- `GET /api/inventory/alerts/:id` - Получение алерта
|
|
278
|
+
- `PUT /api/inventory/alerts/:id` - Обновление алерта
|
|
279
|
+
- `DELETE /api/inventory/alerts/:id` - Удаление алерта
|
|
280
|
+
|
|
281
|
+
**Схема алерта**:
|
|
282
|
+
```javascript
|
|
283
|
+
{
|
|
284
|
+
product: string, // ObjectId товара (required)
|
|
285
|
+
variant?: string, // ObjectId варианта (null = все варианты)
|
|
286
|
+
storage?: string, // ObjectId склада (null = все склады)
|
|
287
|
+
threshold: number, // Пороговое значение (required, >=0)
|
|
288
|
+
enabled: boolean // Активность алерта (default: true)
|
|
289
|
+
}
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
**Пример создания алерта**:
|
|
293
|
+
```bash
|
|
294
|
+
POST /api/inventory/alerts
|
|
295
|
+
Authorization: Bearer <jwt_token>
|
|
296
|
+
Content-Type: application/json
|
|
297
|
+
|
|
298
|
+
{
|
|
299
|
+
"product": "507f1f77bcf86cd799439013",
|
|
300
|
+
"variant": null,
|
|
301
|
+
"storage": "507f1f77bcf86cd799439011",
|
|
302
|
+
"threshold": 10,
|
|
303
|
+
"enabled": true
|
|
304
|
+
}
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
## Коды ошибок и обработка
|
|
308
|
+
|
|
309
|
+
### Стандартные HTTP коды
|
|
310
|
+
- `200` - Успешная операция
|
|
311
|
+
- `201` - Создание ресурса
|
|
312
|
+
- `400` - Ошибка валидации
|
|
313
|
+
- `401` - Не авторизован
|
|
314
|
+
- `403` - Доступ запрещен
|
|
315
|
+
- `404` - Ресурс не найден
|
|
316
|
+
- `500` - Внутренняя ошибка сервера
|
|
317
|
+
|
|
318
|
+
### Формат ошибок валидации
|
|
319
|
+
```json
|
|
320
|
+
{
|
|
321
|
+
"errors": [
|
|
322
|
+
{
|
|
323
|
+
"field": "quantity",
|
|
324
|
+
"message": "Quantity must be an integer",
|
|
325
|
+
"value": "invalid_value"
|
|
326
|
+
}
|
|
327
|
+
]
|
|
328
|
+
}
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
### Формат серверных ошибок
|
|
332
|
+
```json
|
|
333
|
+
{
|
|
334
|
+
"message": "Internal server error occurred",
|
|
335
|
+
"code": "INVENTORY_ERROR",
|
|
336
|
+
"details": "Additional error context"
|
|
337
|
+
}
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
## Производительность и кеширование
|
|
341
|
+
|
|
342
|
+
### Кешируемые endpoints
|
|
343
|
+
- `GET /api/inventory/adjustments` - TTL 300 секунд, теги `['adjustments']`
|
|
344
|
+
- `GET /api/inventory/availability` - TTL 300 секунд, теги `['availability']`
|
|
345
|
+
- `GET /api/inventory/alerts` - TTL 300 секунд, теги `['stockAlerts', 'inventory']`
|
|
346
|
+
|
|
347
|
+
### Инвалидация кеша
|
|
348
|
+
- **Stock Adjustment операции** → инвалидация `['adjustments', 'availability']`
|
|
349
|
+
- **Inventory Audit операции** → инвалидация `['inventories', 'availability']`
|
|
350
|
+
- **Alert операции** → инвалидация `['stockAlerts', 'inventory']`
|
|
351
|
+
|
|
352
|
+
### Рекомендации по использованию
|
|
353
|
+
- Используйте пагинацию для больших наборов данных
|
|
354
|
+
- Применяйте фильтры для снижения объема трафика
|
|
355
|
+
- Кешируйте результаты на клиенте с учетом TTL
|
|
356
|
+
- Подписывайтесь на события через WebSocket для real-time обновлений
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
# 6. Права доступа
|
|
2
|
+
|
|
3
|
+
## Архитектура системы авторизации
|
|
4
|
+
|
|
5
|
+
Модуль Inventory использует многоуровневую систему контроля доступа, основанную на трех основных принципах:
|
|
6
|
+
|
|
7
|
+
1. **JWT Authentication** - Базовая аутентификация пользователей
|
|
8
|
+
2. **ABAC Authorization** - Attribute-Based Access Control для fine-grained permissions
|
|
9
|
+
3. **Owner-based filtering** - Мультитенантная изоляция данных
|
|
10
|
+
|
|
11
|
+
## JWT Authentication Layer
|
|
12
|
+
|
|
13
|
+
### Типы аутентификации по endpoints
|
|
14
|
+
|
|
15
|
+
```javascript
|
|
16
|
+
// Строгая аутентификация - только авторизованные пользователи
|
|
17
|
+
app.post('/api/inventory/adjustments/create',
|
|
18
|
+
jwt.verifyToken(), // Требует валидный JWT
|
|
19
|
+
// ... other middleware
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
// Мягкая аутентификация - поддержка анонимных запросов с фильтрацией
|
|
23
|
+
app.get('/api/inventory/adjustments',
|
|
24
|
+
jwt.verifyToken(true), // true = не блокирует анонимов
|
|
25
|
+
// ... other middleware
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
// Публичный доступ - без аутентификации
|
|
29
|
+
app.get('/api/inventory/availability',
|
|
30
|
+
// Нет jwt.verifyToken() - публичный endpoint
|
|
31
|
+
verifier.verifyAvailabilityQuery,
|
|
32
|
+
controller.availability.read
|
|
33
|
+
);
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Извлечение пользователя из JWT
|
|
37
|
+
|
|
38
|
+
После успешной аутентификации JWT middleware устанавливает:
|
|
39
|
+
- `req.userId` - ObjectId текущего пользователя
|
|
40
|
+
- `req.userDoc` - (опционально) полный объект пользователя с ролями
|
|
41
|
+
|
|
42
|
+
## ABAC Authorization System
|
|
43
|
+
|
|
44
|
+
### Текущее состояние политик
|
|
45
|
+
|
|
46
|
+
**Важно**: В текущей версии все ABAC политики в файле `inventory.policies.js` **закомментированы**, что означает **permissive mode** - все операции разрешены после JWT аутентификации.
|
|
47
|
+
|
|
48
|
+
```javascript
|
|
49
|
+
// Эти политики готовы к активации, но сейчас отключены:
|
|
50
|
+
|
|
51
|
+
// abac.registerResourcePolicy('stockAdjustment', async context => {
|
|
52
|
+
// const { user, action, data } = context;
|
|
53
|
+
//
|
|
54
|
+
// if (action === 'create') {
|
|
55
|
+
// const userDoc = context.userDoc || await db.user.findById(user).populate('roles');
|
|
56
|
+
// const hasWarehouseRole = userDoc?.roles?.some(r =>
|
|
57
|
+
// ['warehouse', 'admin', 'moderator'].includes(r.name || r)
|
|
58
|
+
// );
|
|
59
|
+
//
|
|
60
|
+
// if (!hasWarehouseRole) {
|
|
61
|
+
// return { allow: false, reason: 'WAREHOUSE_ROLE_REQUIRED' };
|
|
62
|
+
// }
|
|
63
|
+
// }
|
|
64
|
+
//
|
|
65
|
+
// return { allow: true, force: false };
|
|
66
|
+
// });
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Middleware интеграция ABAC
|
|
70
|
+
|
|
71
|
+
В маршрутах ABAC middleware активно используется:
|
|
72
|
+
|
|
73
|
+
```javascript
|
|
74
|
+
// Stock Adjustment creation
|
|
75
|
+
app.post('/api/inventory/adjustments/create',
|
|
76
|
+
jwt.verifyToken(),
|
|
77
|
+
verifier.verifyAdjustmentBody,
|
|
78
|
+
abac.middleware('stockAdjustment', 'create'), // ABAC проверка
|
|
79
|
+
controller.adjustments.create
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
// Stock Audit completion
|
|
83
|
+
app.post('/api/inventory/audits/complete',
|
|
84
|
+
jwt.verifyToken(),
|
|
85
|
+
verifier.verifyInventoryComplete,
|
|
86
|
+
abac.middleware('stockAudit', 'edit'), // ABAC проверка
|
|
87
|
+
controller.inventory.complete
|
|
88
|
+
);
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Потенциальные политики доступа
|
|
92
|
+
|
|
93
|
+
#### Stock Adjustment Policies
|
|
94
|
+
|
|
95
|
+
**Концепция**: Только складские работники могут изменять остатки товаров.
|
|
96
|
+
|
|
97
|
+
```javascript
|
|
98
|
+
// Готовая к активации политика
|
|
99
|
+
abac.registerResourcePolicy('stockAdjustment', async context => {
|
|
100
|
+
const { user, action, data } = context;
|
|
101
|
+
|
|
102
|
+
if (action === 'create') {
|
|
103
|
+
// Проверка роли пользователя
|
|
104
|
+
const userDoc = context.userDoc || await db.user.findById(user).populate('roles');
|
|
105
|
+
const hasWarehouseRole = userDoc?.roles?.some(r =>
|
|
106
|
+
['warehouse', 'admin', 'moderator'].includes(r.name || r)
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
if (!hasWarehouseRole) {
|
|
110
|
+
return { allow: false, reason: 'WAREHOUSE_ROLE_REQUIRED' };
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return { allow: true, force: false };
|
|
115
|
+
});
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**Применение**:
|
|
119
|
+
- `warehouse` role - основные складские операции
|
|
120
|
+
- `admin` role - полный доступ ко всем операциям
|
|
121
|
+
- `moderator` role - надзорные функции
|
|
122
|
+
|
|
123
|
+
#### Stock Audit Policies
|
|
124
|
+
|
|
125
|
+
**Концепция**: Только создатель инвентаризации или администратор может ее завершить.
|
|
126
|
+
|
|
127
|
+
```javascript
|
|
128
|
+
// Готовая к активации политика
|
|
129
|
+
abac.registerResourcePolicy('stockAudit', async context => {
|
|
130
|
+
const { user, action, currentResource } = context;
|
|
131
|
+
|
|
132
|
+
if (action === 'edit' && currentResource) {
|
|
133
|
+
// Проверка ownership или admin прав
|
|
134
|
+
if (currentResource.creator.target.toString() !== user) {
|
|
135
|
+
const userDoc = context.userDoc || await db.user.findById(user).populate('roles');
|
|
136
|
+
const isAdmin = userDoc?.roles?.some(r => r.name === 'admin' || r === 'admin');
|
|
137
|
+
|
|
138
|
+
if (!isAdmin) {
|
|
139
|
+
return { allow: false, reason: 'NOT_INVENTORY_CREATOR' };
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return { allow: true, force: false };
|
|
145
|
+
});
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**Применение**:
|
|
149
|
+
- Создатель audit может его завершить
|
|
150
|
+
- Admin может завершать любые audit
|
|
151
|
+
- Другие пользователи получают отказ
|
|
152
|
+
|
|
153
|
+
## Owner-based Data Isolation
|
|
154
|
+
|
|
155
|
+
### Мультитенантная архитектура
|
|
156
|
+
|
|
157
|
+
Все основные модели используют `ownership.schema` для изоляции данных:
|
|
158
|
+
|
|
159
|
+
```javascript
|
|
160
|
+
// В каждой модели (кроме StockAvailability)
|
|
161
|
+
applyOwnershipSchema(StockAdjustmentSchema, db);
|
|
162
|
+
|
|
163
|
+
// Структура ownership
|
|
164
|
+
{
|
|
165
|
+
owner: {
|
|
166
|
+
type: 'organization' | 'user',
|
|
167
|
+
target: ObjectId // ID организации или пользователя
|
|
168
|
+
},
|
|
169
|
+
creator: {
|
|
170
|
+
type: 'user',
|
|
171
|
+
target: ObjectId // ID создавшего пользователя
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Автоматическая фильтрация по owner
|
|
177
|
+
|
|
178
|
+
В контроллерах происходит неявная фильтрация данных:
|
|
179
|
+
|
|
180
|
+
```javascript
|
|
181
|
+
// Пример из availability controller
|
|
182
|
+
const matchConditions = {
|
|
183
|
+
...(req.verifiedQuery?.owner && {
|
|
184
|
+
'owner.target': new db.mongoose.Types.ObjectId(req.verifiedQuery.owner)
|
|
185
|
+
})
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
// Пользователи видят только свои данные или данные своей организации
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Наследование ownership
|
|
192
|
+
|
|
193
|
+
При создании ресурсов owner наследуется:
|
|
194
|
+
|
|
195
|
+
```javascript
|
|
196
|
+
// В adjustment creation
|
|
197
|
+
const adjustmentData = {
|
|
198
|
+
...req.verifiedBody,
|
|
199
|
+
creator: { type: 'user', target: req.userId }, // Создатель = текущий пользователь
|
|
200
|
+
owner: req.verifiedBody.owner // Owner передается в запросе
|
|
201
|
+
};
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
## Права доступа по операциям
|
|
205
|
+
|
|
206
|
+
### Матрица доступа
|
|
207
|
+
|
|
208
|
+
| Операция | Аутентификация | ABAC Policy | Owner Filter | Публичный доступ |
|
|
209
|
+
|----------|---------------|-------------|--------------|------------------|
|
|
210
|
+
| **GET /adjustments** | Мягкая ✓ | Нет | ✓ | Частично |
|
|
211
|
+
| **POST /adjustments/create** | Строгая ✓ | stockAdjustment:create | ✓ | Нет |
|
|
212
|
+
| **GET /balance** | Мягкая ✓ | Нет | ✓ | Частично |
|
|
213
|
+
| **GET /availability** | Нет | Нет | Частично | ✓ |
|
|
214
|
+
| **GET /audits** | Строгая ✓ | Нет | ✓ | Нет |
|
|
215
|
+
| **POST /audits/create** | Строгая ✓ | stockAudit:create | ✓ | Нет |
|
|
216
|
+
| **POST /audits/complete** | Строгая ✓ | stockAudit:edit | ✓ | Нет |
|
|
217
|
+
| **CRUD /alerts/** | Строгая ✓ | Настраиваемо | ✓ | Нет |
|
|
218
|
+
|
|
219
|
+
### Особенности доступа
|
|
220
|
+
|
|
221
|
+
#### Публичный endpoint availability
|
|
222
|
+
```javascript
|
|
223
|
+
// Единственный endpoint без аутентификации
|
|
224
|
+
app.get('/api/inventory/availability',
|
|
225
|
+
verifier.verifyAvailabilityQuery, // Только валидация
|
|
226
|
+
controller.availability.read // Без auth/abac middleware
|
|
227
|
+
);
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
**Назначение**: Поддержка e-commerce интеграций, где внешние системы должны проверять доступность товаров без аутентификации.
|
|
231
|
+
|
|
232
|
+
#### Мягкая аутентификация для чтения
|
|
233
|
+
```javascript
|
|
234
|
+
// Поддерживает и авторизованных, и анонимных пользователей
|
|
235
|
+
app.get('/api/inventory/adjustments',
|
|
236
|
+
jwt.verifyToken(true), // true = не блокирует анонимов
|
|
237
|
+
verifier.verifyAdjustmentQuery,
|
|
238
|
+
controller.adjustments.read
|
|
239
|
+
);
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
**Логика**:
|
|
243
|
+
- Авторизованные пользователи видят данные своей организации
|
|
244
|
+
- Анонимные пользователи получают пустые результаты (owner filter блокирует)
|
|
245
|
+
|
|
246
|
+
## Context-aware авторизация
|
|
247
|
+
|
|
248
|
+
### Различия контекстов
|
|
249
|
+
|
|
250
|
+
Клиентская часть поддерживает два контекста с разными правами:
|
|
251
|
+
|
|
252
|
+
```javascript
|
|
253
|
+
// Backoffice context - админская панель
|
|
254
|
+
meta: { context: 'backoffice' }
|
|
255
|
+
// Полный доступ ко всем функциям, cross-organization просмотр
|
|
256
|
+
|
|
257
|
+
// Organization context - клиентский интерфейс
|
|
258
|
+
meta: { context: 'organization' }
|
|
259
|
+
// Ограниченный доступ только к данным своей организации
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### Влияние на UI
|
|
263
|
+
|
|
264
|
+
```vue
|
|
265
|
+
<!-- Условный рендеринг на основе контекста -->
|
|
266
|
+
<button
|
|
267
|
+
v-if="route.meta.context === 'backoffice'"
|
|
268
|
+
@click="router.push({ name: 'BackofficeInventoryAudit' })"
|
|
269
|
+
/>
|
|
270
|
+
|
|
271
|
+
<button
|
|
272
|
+
v-if="route.meta.context === 'organization'"
|
|
273
|
+
@click="router.push({
|
|
274
|
+
name: 'OrganizationInventoryAudit',
|
|
275
|
+
params: { _id: route.params._id }
|
|
276
|
+
})"
|
|
277
|
+
/>
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
## Активация политик безопасности
|
|
281
|
+
|
|
282
|
+
### Пошаговая активация ABAC
|
|
283
|
+
|
|
284
|
+
Для включения строгих политик доступа:
|
|
285
|
+
|
|
286
|
+
1. **Раскомментировать политики** в `inventory.policies.js`
|
|
287
|
+
2. **Настроить роли пользователей** в системе управления ролями
|
|
288
|
+
3. **Протестировать политики** на тестовой среде
|
|
289
|
+
4. **Задокументировать изменения** для команды
|
|
290
|
+
|
|
291
|
+
### Пример активации
|
|
292
|
+
|
|
293
|
+
```javascript
|
|
294
|
+
// 1. Раскомментировать политику
|
|
295
|
+
abac.registerResourcePolicy('stockAdjustment', async context => {
|
|
296
|
+
// ... policy logic
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
// 2. Обновить тесты
|
|
300
|
+
it('should deny access for non-warehouse users', async () => {
|
|
301
|
+
const response = await request(app)
|
|
302
|
+
.post('/api/inventory/adjustments/create')
|
|
303
|
+
.set('Authorization', `Bearer ${regularUserToken}`)
|
|
304
|
+
.send(adjustmentData);
|
|
305
|
+
|
|
306
|
+
expect(response.status).toBe(403);
|
|
307
|
+
expect(response.body.reason).toBe('WAREHOUSE_ROLE_REQUIRED');
|
|
308
|
+
});
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### Мигграционные соображения
|
|
312
|
+
|
|
313
|
+
**Текущее состояние**: Permissive mode позволяет всем аутентифицированным пользователям выполнять любые операции.
|
|
314
|
+
|
|
315
|
+
**После активации**: Потребуется:
|
|
316
|
+
- Назначить роли существующим пользователям
|
|
317
|
+
- Обновить интеграции для обработки 403 ошибок
|
|
318
|
+
- Подготовить документацию по ролям для бизнес-пользователей
|
|
319
|
+
|
|
320
|
+
Эта архитектура обеспечивает гибкость настройки прав доступа от полностью открытой системы до строго регламентированной с детальным контролем на уровне операций и ресурсов.
|