schema.sql 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. -- PostgreSQL schema for schedule-management-system (RBAC + core domain)
  2. -- Requires: CREATE EXTENSION IF NOT EXISTS "pgcrypto";
  3. CREATE EXTENSION IF NOT EXISTS "pgcrypto";
  4. CREATE TABLE roles (
  5. id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  6. name TEXT NOT NULL UNIQUE,
  7. external_role_id TEXT UNIQUE,
  8. description TEXT,
  9. is_system BOOLEAN NOT NULL DEFAULT TRUE,
  10. created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  11. updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
  12. );
  13. CREATE TABLE permissions (
  14. code TEXT PRIMARY KEY,
  15. name TEXT NOT NULL,
  16. module TEXT NOT NULL,
  17. created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
  18. );
  19. CREATE TABLE role_permissions (
  20. role_id UUID NOT NULL REFERENCES roles(id) ON DELETE CASCADE,
  21. permission_code TEXT NOT NULL REFERENCES permissions(code) ON DELETE CASCADE,
  22. PRIMARY KEY (role_id, permission_code)
  23. );
  24. CREATE TABLE campuses (
  25. id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  26. name TEXT NOT NULL UNIQUE,
  27. external_hosp_id TEXT UNIQUE,
  28. created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  29. updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
  30. );
  31. CREATE TABLE departments (
  32. id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  33. campus_id UUID NOT NULL REFERENCES campuses(id) ON DELETE RESTRICT,
  34. name TEXT NOT NULL,
  35. external_dept_id TEXT UNIQUE,
  36. created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  37. updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
  38. );
  39. CREATE TABLE sync_states (
  40. key TEXT PRIMARY KEY,
  41. token TEXT NOT NULL,
  42. last_sync_at TIMESTAMPTZ,
  43. created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  44. updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
  45. );
  46. CREATE TABLE users (
  47. id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  48. name TEXT NOT NULL,
  49. account TEXT NOT NULL UNIQUE,
  50. phone TEXT,
  51. title TEXT,
  52. avatar TEXT,
  53. external_user_id TEXT,
  54. tenant_id TEXT,
  55. tenant_name TEXT,
  56. hosp_id TEXT,
  57. hosp_name TEXT,
  58. role_id UUID NOT NULL REFERENCES roles(id) ON DELETE RESTRICT,
  59. campus_id UUID REFERENCES campuses(id) ON DELETE SET NULL,
  60. dept_id UUID REFERENCES departments(id) ON DELETE SET NULL,
  61. status TEXT NOT NULL DEFAULT 'active' CHECK (status IN ('active', 'inactive')),
  62. password_hash TEXT NOT NULL,
  63. token_version INTEGER NOT NULL DEFAULT 1,
  64. created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  65. updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
  66. );
  67. CREATE TABLE shifts (
  68. id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  69. name TEXT NOT NULL,
  70. start_time TIME NOT NULL,
  71. end_time TIME NOT NULL,
  72. enabled BOOLEAN NOT NULL DEFAULT TRUE,
  73. remark TEXT,
  74. created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  75. updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
  76. );
  77. CREATE TABLE schedule_items (
  78. id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  79. dept_id UUID NOT NULL REFERENCES departments(id) ON DELETE RESTRICT,
  80. date DATE NOT NULL,
  81. shift_id UUID REFERENCES shifts(id) ON DELETE RESTRICT,
  82. staff_id UUID NOT NULL REFERENCES users(id) ON DELETE RESTRICT,
  83. tag TEXT NOT NULL DEFAULT 'normal' CHECK (tag IN ('normal', 'substitute', 'substituted', 'stopClinic')),
  84. note TEXT,
  85. original_staff_id UUID REFERENCES users(id) ON DELETE SET NULL,
  86. substitute_for_id UUID REFERENCES schedule_items(id) ON DELETE SET NULL,
  87. reason TEXT,
  88. created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  89. updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  90. UNIQUE (dept_id, date, shift_id, staff_id)
  91. );
  92. CREATE INDEX schedule_items_dept_date_idx ON schedule_items (dept_id, date);
  93. CREATE INDEX schedule_items_staff_date_idx ON schedule_items (staff_id, date);
  94. CREATE TABLE duty_items (
  95. id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  96. date DATE NOT NULL,
  97. staff_id UUID NOT NULL REFERENCES users(id) ON DELETE RESTRICT,
  98. duty_type TEXT NOT NULL CHECK (duty_type IN ('day', 'night', '24h')),
  99. contact TEXT,
  100. note TEXT,
  101. created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  102. updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
  103. );
  104. CREATE INDEX duty_items_date_idx ON duty_items (date);
  105. CREATE TABLE adjust_logs (
  106. id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  107. dept_id UUID NOT NULL REFERENCES departments(id) ON DELETE RESTRICT,
  108. date DATE NOT NULL,
  109. type TEXT NOT NULL CHECK (type IN ('swap', 'stopClinic', 'substitute')),
  110. operator TEXT NOT NULL,
  111. created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  112. note TEXT
  113. );
  114. CREATE TABLE audit_logs (
  115. id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  116. actor_id UUID REFERENCES users(id) ON DELETE SET NULL,
  117. action TEXT NOT NULL,
  118. target_type TEXT NOT NULL,
  119. target_id UUID,
  120. detail JSONB,
  121. ip TEXT,
  122. created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
  123. );