This commit is contained in:
2026-05-31 20:19:44 +12:00
parent 2f2466ecac
commit 84792c0947
59 changed files with 5412 additions and 898 deletions
+27 -2
View File
@@ -3,13 +3,18 @@
Re-running this is safe: it upserts permissions, syncs each role's permission
set to the declared list, and creates or updates the seed users without
duplicating rows. Permission grants are the source of truth — change them
here (or in the DB) rather than in route code.
here (or in the DB) rather than in route code. Existing password hashes are
left intact; only users with no password hash get the current default
``ADMIN_PASSWORD`` hashed into the row.
"""
from __future__ import annotations
from sqlalchemy import select
from sqlalchemy.orm import Session, selectinload
from app.core.config import settings
from app.core.security import hash_password
from app.db.session import SessionLocal
from app.models.access import Permission, Role, User
@@ -24,6 +29,8 @@ PERMISSION_DEFINITIONS: tuple[tuple[str, str], ...] = (
("edit_products", "Create and edit finished products"),
("view_mixes", "View mix master recipes"),
("edit_mixes", "Create and edit mix master recipes"),
("view_throughput", "View operations throughput"),
("edit_throughput", "Create and edit operations throughput entries"),
("view_users", "View internal users and roles"),
("manage_users", "Create, deactivate, and assign user roles"),
("manage_permissions", "Modify roles and role-permission assignments"),
@@ -44,6 +51,8 @@ ROLE_DEFINITIONS: dict[str, dict] = {
"edit_raw_materials",
"view_products",
"view_mixes",
"view_throughput",
"edit_throughput",
"view_users",
"manage_users",
"manage_permissions",
@@ -52,11 +61,13 @@ ROLE_DEFINITIONS: dict[str, dict] = {
],
},
"Operations": {
"description": "Mix calculator only — cannot edit raw materials, products, mixes, users, or settings.",
"description": "Mix calculator and operations throughput — cannot edit raw materials, products, mixes, users, or settings.",
"permissions": [
"view_mix_calculator",
"use_mix_calculator",
"save_mix_calculator_session",
"view_throughput",
"edit_throughput",
],
},
"Full Access": {
@@ -72,6 +83,8 @@ ROLE_DEFINITIONS: dict[str, dict] = {
"edit_products",
"view_mixes",
"edit_mixes",
"view_throughput",
"edit_throughput",
],
},
}
@@ -154,6 +167,8 @@ def _upsert_users(db: Session, roles_by_name: dict[str, Role]) -> None:
user.role_id = role.id
if not user.is_active:
user.is_active = True
if user.password_hash is None:
user.password_hash = hash_password(settings.admin_password)
db.flush()
@@ -162,3 +177,13 @@ def seed_access(db: Session) -> None:
permissions_by_key = _upsert_permissions(db)
roles_by_name = _upsert_roles(db, permissions_by_key)
_upsert_users(db, roles_by_name)
def seed_access_from_session() -> None:
with SessionLocal() as db:
seed_access(db)
db.commit()
if __name__ == "__main__":
seed_access_from_session()