// src/server/entities/user-permissions.ts
import { bigint as bigint2, boolean as boolean4, text as text4, timestamp as timestamp2, index as index4, unique } from "drizzle-orm/pg-core";
import { id as id4, timestamps as timestamps4 } from "@spfn/core/db";

// src/server/entities/users.ts
import { text as text2, timestamp, check, boolean as boolean2, bigint, index as index2 } from "drizzle-orm/pg-core";
import { id as id2, timestamps as timestamps2 } from "@spfn/core/db";
import { sql } from "drizzle-orm";

// src/server/entities/roles.ts
import { text, boolean, integer, index } from "drizzle-orm/pg-core";
import { id, timestamps } from "@spfn/core/db";

// src/server/entities/schema.ts
import { createFunctionSchema } from "@spfn/core/db";
var authSchema = createFunctionSchema("@spfn/auth");

// src/server/entities/roles.ts
var roles = authSchema.table(
  "roles",
  {
    // Primary key
    id: id(),
    // Role identifier (used in code, e.g., 'admin', 'editor')
    // Must be unique, lowercase, kebab-case recommended
    name: text("name").notNull().unique(),
    // Display name for UI (e.g., 'Administrator', 'Content Editor')
    displayName: text("display_name").notNull(),
    // Role description
    description: text("description"),
    // Built-in role flag
    // true: Core package roles (user, admin, superadmin) - cannot be deleted
    // false: Custom or preset roles - can be deleted
    isBuiltin: boolean("is_builtin").notNull().default(false),
    // System role flag
    // true: Defined in code (builtin or preset) - deletion restricted
    // false: Runtime created custom role - fully manageable
    isSystem: boolean("is_system").notNull().default(false),
    // Active status
    // false: Deactivated role (users cannot be assigned)
    isActive: boolean("is_active").notNull().default(true),
    // Priority level (higher = more privileged)
    // superadmin: 100, admin: 80, user: 10
    // Used for role hierarchy and conflict resolution
    priority: integer("priority").notNull().default(10),
    ...timestamps()
  },
  (table) => [
    index("roles_name_idx").on(table.name),
    index("roles_is_system_idx").on(table.isSystem),
    index("roles_is_active_idx").on(table.isActive),
    index("roles_is_builtin_idx").on(table.isBuiltin),
    index("roles_priority_idx").on(table.priority)
  ]
);

// src/server/entities/users.ts
var users = authSchema.table(
  "users",
  {
    // Identity
    id: id2(),
    // Email address (unique identifier)
    // Used for: login, password reset, notifications
    email: text2("email").unique(),
    // Phone number in E.164 international format
    // Format: +[country code][number] (e.g., +821012345678)
    // Used for: SMS login, 2FA, notifications
    phone: text2("phone").unique(),
    // Authentication
    // Bcrypt password hash ($2b$10$[salt][hash], 60 chars)
    // Nullable to support OAuth-only accounts
    passwordHash: text2("password_hash"),
    // Force password change on next login
    // Use cases: initial setup, security breach, policy violation
    passwordChangeRequired: boolean2("password_change_required").notNull().default(false),
    // Authorization (Role-Based Access Control)
    // Foreign key to roles table
    // References built-in roles: user (default), admin, superadmin
    // Can also reference custom roles created at runtime
    roleId: bigint("role_id", { mode: "number" }).references(() => roles.id).notNull(),
    // Account status
    // - active: Normal operation (default)
    // - inactive: Deactivated (user request, dormant)
    // - suspended: Locked (security incident, ToS violation)
    status: text2(
      "status",
      {
        enum: ["active", "inactive", "suspended"]
      }
    ).notNull().default("active"),
    // Verification timestamps
    // null = unverified, timestamp = verified at this time
    // Email verification (via verification code or magic link)
    emailVerifiedAt: timestamp("email_verified_at", { withTimezone: true }),
    // Phone verification (via SMS OTP)
    phoneVerifiedAt: timestamp("phone_verified_at", { withTimezone: true }),
    // Metadata
    // Last successful login timestamp
    // Used for: security auditing, dormant account detection
    lastLoginAt: timestamp("last_login_at", { withTimezone: true }),
    ...timestamps2()
  },
  (table) => [
    // Database constraints
    // Ensure at least one identifier exists (email OR phone)
    check(
      "email_or_phone_check",
      sql`${table.email} IS NOT NULL OR ${table.phone} IS NOT NULL`
    ),
    // Indexes for query optimization
    index2("users_email_idx").on(table.email),
    index2("users_phone_idx").on(table.phone),
    index2("users_status_idx").on(table.status),
    index2("users_role_id_idx").on(table.roleId)
  ]
);

// src/server/entities/permissions.ts
import { text as text3, boolean as boolean3, index as index3 } from "drizzle-orm/pg-core";
import { id as id3, timestamps as timestamps3 } from "@spfn/core/db";
var permissions = authSchema.table(
  "permissions",
  {
    // Primary key
    id: id3(),
    // Permission identifier (e.g., 'user:delete', 'post:publish')
    // Format: resource:action or namespace:resource:action
    // Must be unique
    name: text3("name").notNull().unique(),
    // Display name for UI
    displayName: text3("display_name").notNull(),
    // Permission description
    description: text3("description"),
    // Category for grouping (e.g., 'user', 'post', 'admin', 'system')
    category: text3("category"),
    // Built-in permission flag
    // true: Core package permissions - cannot be deleted
    // false: Custom or preset permissions
    isBuiltin: boolean3("is_builtin").notNull().default(false),
    // System permission flag
    // true: Defined in code (builtin or preset)
    // false: Runtime created custom permission
    isSystem: boolean3("is_system").notNull().default(false),
    // Active status
    // false: Deactivated permission (not enforced)
    isActive: boolean3("is_active").notNull().default(true),
    ...timestamps3()
  },
  (table) => [
    index3("permissions_name_idx").on(table.name),
    index3("permissions_category_idx").on(table.category),
    index3("permissions_is_system_idx").on(table.isSystem),
    index3("permissions_is_active_idx").on(table.isActive),
    index3("permissions_is_builtin_idx").on(table.isBuiltin)
  ]
);

// src/server/entities/user-permissions.ts
var userPermissions = authSchema.table(
  "user_permissions",
  {
    // Primary key
    id: id4(),
    // Foreign key to users table
    userId: bigint2("user_id", { mode: "number" }).notNull().references(() => users.id, { onDelete: "cascade" }),
    // Foreign key to permissions table
    permissionId: bigint2("permission_id", { mode: "number" }).notNull().references(() => permissions.id, { onDelete: "cascade" }),
    // Grant or revoke
    // true: Grant this permission (even if role doesn't have it)
    // false: Revoke this permission (even if role has it)
    granted: boolean4("granted").notNull().default(true),
    // Reason for grant/revocation (audit trail)
    reason: text4("reason"),
    // Expiration timestamp (optional)
    // null: Permanent override
    // timestamp: Permission expires at this time
    expiresAt: timestamp2("expires_at", { withTimezone: true }),
    ...timestamps4()
  },
  (table) => [
    // Indexes for query performance
    index4("user_permissions_user_id_idx").on(table.userId),
    index4("user_permissions_permission_id_idx").on(table.permissionId),
    index4("user_permissions_expires_at_idx").on(table.expiresAt),
    // Unique constraint: one user-permission pair only
    unique("user_permissions_unique").on(table.userId, table.permissionId)
  ]
);
export {
  userPermissions
};
//# sourceMappingURL=user-permissions.js.map