# Role Registry — Single Source of Truth
#
# Canonical role definitions for the application. Every layer that refers
# to roles MUST derive from this file:
#
#   rbac.ncl          — group names validated against this list at eval time
#   DB migrations     — user_roles table seeded from entries where db_seed = true
#   Rust Role enum    — rustelo_core_lib::auth::Role variants mapped via rust_variant
#
# DB migration note:
#   Migration 3 seeds only "admin" and "user".
#   Roles added here with db_seed = true that are absent from the DB require
#   a new migration:
#     INSERT INTO user_roles (name, description) VALUES
#       ('supervisor', '...'), ('moderator', '...'), ('guest', '...')
#     ON CONFLICT (name) DO NOTHING;
#
# Rust enum note:
#   rustelo_core_lib::auth::Role = Admin | Moderator | User | Guest | Custom(String)
#   Roles without a dedicated variant use rust_variant = "Custom" — the name
#   string becomes the Custom payload when parsing from JWT claims.
#
# Validate: nickel export site/config/roles.ncl

let C = import "rbac/roles_contracts.ncl" in

{
  roles = [
    {
      name         = "admin",
      description  = "Full system access — unrestricted access to all resources and admin functions",
      db_seed      = true,
      is_system    = true,
      parent_roles = [],
      rust_variant = "Admin",
      db_level     = 100,
    },
    {
      name         = "supervisor",
      description  = "Elevated user with notification broadcast rights; inherits user permissions",
      db_seed      = true,
      is_system    = false,
      parent_roles = ["user"],
      rust_variant = "Custom",
      db_level     = 40,
    },
    {
      name         = "moderator",
      description  = "Content moderator — read/write/delete content and access admin content pages",
      db_seed      = true,
      is_system    = false,
      parent_roles = ["user"],
      rust_variant = "Moderator",
      db_level     = 30,
    },
    {
      name         = "user",
      description  = "Regular authenticated user with access to their own data and public content",
      db_seed      = true,
      is_system    = true,
      is_default   = true,
      parent_roles = [],
      rust_variant = "User",
      db_level     = 10,
    },
    {
      name         = "guest",
      description  = "Virtual role for unauthenticated visitors — no DB row, used only in policy logic",
      db_seed      = false,
      is_system    = true,
      parent_roles = [],
      rust_variant = "Guest",
      db_level     = 0,
    },
  ],
} | C.RolesConfig | C.ExactlyOneDefaultRole
