/** * Every permission id (`rid`) the admin panel actually enforces. * * Regenerated mechanically from legacy (see scratchpad/convert_tree.js) as the * union of two enforcement points: * - 58 gated by a route's `meta.role` (router/admin.js, router/branch.js) * - 100 gated inside views via `$hasPermission('...')` * = 144 distinct rids (the two sets overlap) * * An earlier revision of this file listed only the 58 route-gated ones, which * left the seeded super-admin unable to use the in-view actions. Corrected. * * These are LEAVES as written. Ancestors ("order" from "order.list", "persons" * from "persons.list.client.omde", ...) are NOT stored — they are derived at * runtime by expandWithParents(), exactly as legacy's checkParent() did. */ export const ALL_RIDS = [ 'branch.create', 'branch.list', 'buy.order.list', 'cities.create', 'cities.list', 'cities.list.remove', 'cities.list.view', 'cities.list.view.edit', 'collection.create', 'collection.list', 'collection.list.edit', 'collection.list.remove', 'comment', 'comment.remove', 'comment.state', 'comment.view', 'comment.view.edit', 'config.report', 'config.statics', 'config.statics.brand', 'config.statics.brand.create', 'config.statics.brand.edit', 'config.statics.brand.remove', 'config.statics.tags', 'config.statics.tags.create', 'config.statics.tags.edit', 'config.statics.tags.remove', 'config.wallet', 'custom.config.statics.slider', 'custom.config.statics.tags.banner.ids', 'dashboard.omde', 'dashboard.tak', 'document.create', 'document.list', 'document.list.confirm', 'document.list.deny', 'document.list.edit', 'document.list.get', 'document.list.remove', 'invoice.create', 'invoice.list', 'newsletters', 'notify.create', 'notify.me', 'offers.autopromotion', 'offers.create', 'offers.create.tak', 'offers.list', 'offers.list.edit', 'offers.list.remove', 'offers.list.tak.edit', 'offers.list.tak.remove', 'offersIgnore', 'order.create', 'order.list', 'order.list.pdf', 'order.list.sts', 'order.list.sts.remove', 'order.list.sts.submit', 'order.list.view', 'order.list.view.edit', 'order.makeOrder', 'order.makeOrder.get', 'order.makeOrder.remove', 'order.makeOrder.state', 'order.makeOrder.state.remove', 'order.makeOrder.state.submit', 'order.makeOrder.view', 'order.makeOrder.view.edit', 'order.omde', 'order.omde.get', 'order.omde.remove', 'order.omde.state', 'order.omde.state.remove', 'order.omde.state.submit', 'order.omde.view', 'order.omde.view.edit', 'order.omde.view.remove', 'order.tamin', 'order.tamin.state', 'order.tamin.state.remove', 'order.tamin.state.submit', 'order.tamin.view', 'order.tamin.view.edit', 'persons.create', 'persons.create.client', 'persons.create.customer.tak', 'persons.create.seller', 'persons.list.client.omde', 'persons.list.client.omde.able', 'persons.list.client.omde.able.order', 'persons.list.client.omde.edit', 'persons.list.client.omde.unable', 'persons.list.client.omde.unable.order', 'persons.list.client.omde.view', 'persons.list.client.omde.view.documents', 'persons.list.client.omde.view.orders', 'persons.list.client.single', 'persons.list.client.single.edit', 'persons.list.client.single.view', 'persons.list.sellers', 'persons.list.sellers.able', 'persons.list.sellers.able.order', 'persons.list.sellers.edit', 'persons.list.sellers.unable', 'persons.list.sellers.unable.order', 'persons.list.sellers.view', 'persons.list.sellers.view.documents', 'persons.list.sellers.view.orders', 'product.create', 'product.list', 'product.list.edit', 'product.list.group.edit', 'product.list.remove', 'product.list.variants', 'product.list.variants.add', 'product.list.variants.edit', 'product.list.variants.remove', 'product.list.view', 'product.percent', 'report.order.item', 'report.product', 'sms.create', 'sms.create.all', 'sms.create.multiple', 'sms.create.omde', 'sms.create.reagent', 'sms.create.single', 'sms.list', 'statics', 'user.create', 'user.list', 'user.list.create', 'user.list.edit', 'user.list.remove', 'user.permission', 'user.permission.create', 'user.permission.edit', 'wallet', 'wallet.charge', 'wallet.list', 'wallet.percent', 'workshop.create', 'workshop.list', ] as const; export type Rid = (typeof ALL_RIDS)[number]; /** * Port of henza_admin/src/store/users/index.js getParents() — returns every * ancestor of a dotted rid, longest first. * * getParents(['a','b','c']) -> ['a.b', 'a'] */ function getParents(keys: string[]): string[] { const work = [...keys]; const parents: string[] = []; while (work.length > 1) { work.pop(); parents.push(work.join('.')); } return parents; } /** * Port of henza_admin/src/store/users/index.js checkParent(). * * Granting "persons.list.client.omde" implicitly grants "persons.list.client", * "persons.list" and "persons", so parent menu nodes stay visible. The legacy * version mutated a module-scoped `rid` variable; this one is pure, which changes * nothing observable but makes it safe to call concurrently on the server. * * Note this only walks UP. A rid never implies its children — which is why the * legacy nav item guarded by "wallet.list" stays hidden for a user granted only * "wallet". That mismatch is a legacy bug, recorded in docs/ADMIN-PORT-PLAN.md, * and is preserved here rather than silently repaired. */ export function expandWithParents(values: string[]): string[] { let rid: string[] = [...values]; for (const x of values) { const keys = x.split('.'); if (keys.length > 1) { rid = [...new Set([...rid, ...getParents(keys)])]; } } return rid; }