feat(permissions): granular module permissions + workshop permissions matrix
This commit is contained in:
81
scripts/migrate_workshop_permissions.py
Normal file
81
scripts/migrate_workshop_permissions.py
Normal file
@@ -0,0 +1,81 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Initialize workshop_permissions tenant_config for all existing tenants.
|
||||
|
||||
Uses the same defaults defined in pos/blueprints/config_bp.py. Safe to run
|
||||
multiple times (it overwrites with defaults).
|
||||
|
||||
Example:
|
||||
sudo -u postgres python3 scripts/migrate_workshop_permissions.py
|
||||
"""
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
|
||||
import psycopg2
|
||||
|
||||
# Mirror of pos/blueprints/config_bp.py defaults
|
||||
_WORKSHOP_STATUSES = [
|
||||
'por_revisar', 'en_revision', 'revisada', 'cotizada', 'por_autorizar',
|
||||
'autorizada', 'autorizacion_parcial', 'en_reparacion', 'reparada',
|
||||
'por_entregar', 'entregado', 'por_enviar', 'enviado',
|
||||
'por_facturar', 'facturada', 'por_recolectar', 'cancelada'
|
||||
]
|
||||
|
||||
_ALL_ACTIONS = [
|
||||
'create_order', 'edit_order', 'delete_order', 'assign_mechanic',
|
||||
'add_items', 'add_labor', 'change_status', 'convert_to_sale',
|
||||
'convert_to_remission', 'view_customer_data', 'view_prices', 'view_notes',
|
||||
]
|
||||
|
||||
_DEFAULT_WORKSHOP_PERMISSIONS = {
|
||||
'owner': {'statuses': _WORKSHOP_STATUSES, 'actions': _ALL_ACTIONS},
|
||||
'admin': {'statuses': _WORKSHOP_STATUSES, 'actions': _ALL_ACTIONS},
|
||||
'manager': {'statuses': _WORKSHOP_STATUSES, 'actions': [a for a in _ALL_ACTIONS if a != 'delete_order']},
|
||||
'counter': {'statuses': _WORKSHOP_STATUSES, 'actions': [a for a in _ALL_ACTIONS if a != 'delete_order']},
|
||||
'cashier': {'statuses': _WORKSHOP_STATUSES, 'actions': [a for a in _ALL_ACTIONS if a not in ('delete_order', 'convert_to_sale')]},
|
||||
'workshop': {
|
||||
'statuses': [s for s in _WORKSHOP_STATUSES if s not in ('por_entregar', 'entregado', 'por_enviar', 'enviado', 'por_recolectar')],
|
||||
'actions': ['change_status', 'add_labor', 'view_notes']
|
||||
},
|
||||
'mechanic': {
|
||||
'statuses': ['por_revisar', 'en_revision', 'revisada', 'en_reparacion', 'reparada', 'autorizada', 'cancelada'],
|
||||
'actions': ['change_status', 'add_labor', 'view_notes']
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def get_tenant_dbs(master_db='nexus_autoparts'):
|
||||
conn = psycopg2.connect(f"postgresql://postgres@/{master_db}")
|
||||
cur = conn.cursor()
|
||||
cur.execute("SELECT db_name FROM tenants WHERE is_active = true")
|
||||
dbs = [r[0] for r in cur.fetchall() if r[0]]
|
||||
cur.close(); conn.close()
|
||||
return dbs
|
||||
|
||||
|
||||
def migrate(db_name):
|
||||
conn = psycopg2.connect(f"postgresql://postgres@/{db_name}")
|
||||
cur = conn.cursor()
|
||||
cur.execute("""
|
||||
INSERT INTO tenant_config (key, value) VALUES ('workshop_permissions', %s)
|
||||
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value
|
||||
""", (json.dumps(_DEFAULT_WORKSHOP_PERMISSIONS),))
|
||||
conn.commit()
|
||||
cur.close(); conn.close()
|
||||
return True
|
||||
|
||||
|
||||
def main():
|
||||
dbs = get_tenant_dbs()
|
||||
print(f"Migrating {len(dbs)} tenant(s)...")
|
||||
for db in dbs:
|
||||
try:
|
||||
migrate(db)
|
||||
print(f" OK {db}")
|
||||
except Exception as e:
|
||||
print(f" ERR {db}: {e}")
|
||||
print("Done.")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user