v1.0
This commit is contained in:
+138
@@ -0,0 +1,138 @@
|
||||
import {
|
||||
mysqlTable,
|
||||
mysqlEnum,
|
||||
serial,
|
||||
varchar,
|
||||
text,
|
||||
timestamp,
|
||||
bigint,
|
||||
int,
|
||||
decimal,
|
||||
index,
|
||||
} from "drizzle-orm/mysql-core";
|
||||
|
||||
// ── Users (base auth table) ──────────────────────────────────
|
||||
export const users = mysqlTable("users", {
|
||||
id: serial("id").primaryKey(),
|
||||
unionId: varchar("unionId", { length: 255 }).notNull().unique(),
|
||||
name: varchar("name", { length: 255 }),
|
||||
email: varchar("email", { length: 320 }),
|
||||
passwordHash: text("password_hash"),
|
||||
avatar: text("avatar"),
|
||||
role: mysqlEnum("role", ["admin", "officer", "manager"]).default("manager").notNull(),
|
||||
createdAt: timestamp("createdAt").defaultNow().notNull(),
|
||||
updatedAt: timestamp("updatedAt").defaultNow().notNull().$onUpdate(() => new Date()),
|
||||
lastSignInAt: timestamp("lastSignInAt").defaultNow().notNull(),
|
||||
});
|
||||
|
||||
export type User = typeof users.$inferSelect;
|
||||
export type InsertUser = typeof users.$inferInsert;
|
||||
|
||||
// ── Places of Worship ─────────────────────────────────────────
|
||||
export const placesOfWorship = mysqlTable(
|
||||
"places_of_worship",
|
||||
{
|
||||
id: serial("id").primaryKey(),
|
||||
name: varchar("name", { length: 255 }).notNull(),
|
||||
type: mysqlEnum("type", ["mosque", "church", "temple", "vihara", "other"]).notNull(),
|
||||
address: text("address"),
|
||||
latitude: decimal("latitude", { precision: 10, scale: 8 }).notNull(),
|
||||
longitude: decimal("longitude", { precision: 11, scale: 8 }).notNull(),
|
||||
radius: int("radius").default(1000).notNull(), // radius in meters
|
||||
capacity: int("capacity").default(100).notNull(), // max beneficiaries
|
||||
contactName: varchar("contact_name", { length: 255 }),
|
||||
contactPhone: varchar("contact_phone", { length: 20 }),
|
||||
managerId: bigint("manager_id", { mode: "number", unsigned: true }),
|
||||
isActive: mysqlEnum("is_active", ["yes", "no"]).default("yes").notNull(),
|
||||
createdAt: timestamp("created_at").defaultNow().notNull(),
|
||||
updatedAt: timestamp("updated_at").defaultNow().notNull().$onUpdate(() => new Date()),
|
||||
},
|
||||
(table) => ({
|
||||
typeIdx: index("pow_type_idx").on(table.type),
|
||||
managerIdx: index("pow_manager_idx").on(table.managerId),
|
||||
})
|
||||
);
|
||||
|
||||
export type PlaceOfWorship = typeof placesOfWorship.$inferSelect;
|
||||
export type InsertPlaceOfWorship = typeof placesOfWorship.$inferInsert;
|
||||
|
||||
// ── Recipients (beneficiaries) ─────────────────────────────────
|
||||
export const recipients = mysqlTable(
|
||||
"recipients",
|
||||
{
|
||||
id: serial("id").primaryKey(),
|
||||
nik: varchar("nik", { length: 16 }).notNull().unique(),
|
||||
name: varchar("name", { length: 255 }).notNull(),
|
||||
birthDate: varchar("birth_date", { length: 10 }),
|
||||
gender: mysqlEnum("gender", ["male", "female"]),
|
||||
address: text("address"),
|
||||
phone: varchar("phone", { length: 15 }),
|
||||
latitude: decimal("latitude", { precision: 10, scale: 8 }),
|
||||
longitude: decimal("longitude", { precision: 11, scale: 8 }),
|
||||
familyMembers: int("family_members").default(1),
|
||||
incomePerMonth: int("income_per_month").default(0),
|
||||
status: mysqlEnum("status", ["pending", "active", "rejected", "suspended"]).default("pending").notNull(),
|
||||
rejectionReason: text("rejection_reason"),
|
||||
placeOfWorshipId: bigint("place_of_worship_id", { mode: "number", unsigned: true }).notNull(),
|
||||
registeredBy: bigint("registered_by", { mode: "number", unsigned: true }),
|
||||
verifiedBy: bigint("verified_by", { mode: "number", unsigned: true }),
|
||||
verifiedAt: timestamp("verified_at"),
|
||||
notes: text("notes"),
|
||||
createdAt: timestamp("created_at").defaultNow().notNull(),
|
||||
updatedAt: timestamp("updated_at").defaultNow().notNull().$onUpdate(() => new Date()),
|
||||
},
|
||||
(table) => ({
|
||||
nikIdx: index("rec_nik_idx").on(table.nik),
|
||||
statusIdx: index("rec_status_idx").on(table.status),
|
||||
powIdx: index("rec_pow_idx").on(table.placeOfWorshipId),
|
||||
})
|
||||
);
|
||||
|
||||
export type Recipient = typeof recipients.$inferSelect;
|
||||
export type InsertRecipient = typeof recipients.$inferInsert;
|
||||
|
||||
// ── Distributions ──────────────────────────────────────────────
|
||||
export const distributions = mysqlTable(
|
||||
"distributions",
|
||||
{
|
||||
id: serial("id").primaryKey(),
|
||||
placeOfWorshipId: bigint("place_of_worship_id", { mode: "number", unsigned: true }).notNull(),
|
||||
recipientId: bigint("recipient_id", { mode: "number", unsigned: true }).notNull(),
|
||||
distributedBy: bigint("distributed_by", { mode: "number", unsigned: true }),
|
||||
aidType: varchar("aid_type", { length: 100 }).notNull(),
|
||||
amount: decimal("amount", { precision: 12, scale: 2 }).default("0.00"),
|
||||
quantity: int("quantity").default(1),
|
||||
unit: varchar("unit", { length: 50 }).default("package"),
|
||||
distributionDate: timestamp("distribution_date").defaultNow().notNull(),
|
||||
notes: text("notes"),
|
||||
createdAt: timestamp("created_at").defaultNow().notNull(),
|
||||
},
|
||||
(table) => ({
|
||||
powIdx: index("dist_pow_idx").on(table.placeOfWorshipId),
|
||||
recIdx: index("dist_rec_idx").on(table.recipientId),
|
||||
})
|
||||
);
|
||||
|
||||
export type Distribution = typeof distributions.$inferSelect;
|
||||
export type InsertDistribution = typeof distributions.$inferInsert;
|
||||
|
||||
// ── Activity Logs ──────────────────────────────────────────────
|
||||
export const activityLogs = mysqlTable(
|
||||
"activity_logs",
|
||||
{
|
||||
id: serial("id").primaryKey(),
|
||||
userId: bigint("user_id", { mode: "number", unsigned: true }),
|
||||
action: varchar("action", { length: 50 }).notNull(), // e.g. "CREATE", "UPDATE", "DELETE", "VERIFY"
|
||||
entityType: varchar("entity_type", { length: 50 }).notNull(), // "recipient", "place_of_worship", "distribution"
|
||||
entityId: bigint("entity_id", { mode: "number", unsigned: true }),
|
||||
details: text("details"),
|
||||
createdAt: timestamp("created_at").defaultNow().notNull(),
|
||||
},
|
||||
(table) => ({
|
||||
userIdx: index("act_user_idx").on(table.userId),
|
||||
entityIdx: index("act_entity_idx").on(table.entityType, table.entityId),
|
||||
})
|
||||
);
|
||||
|
||||
export type ActivityLog = typeof activityLogs.$inferSelect;
|
||||
export type InsertActivityLog = typeof activityLogs.$inferInsert;
|
||||
Reference in New Issue
Block a user