Add user management for activation, deactivation, and deletion
Introduce API endpoints and storage methods for setting user passwords, soft deactivation (hiding availability), and hard deletion (removing all associated future data). Replit-Commit-Author: Agent Replit-Commit-Session-Id: 3a22ac80-cd1d-4441-9e36-f24fc2f4c3de Replit-Commit-Checkpoint-Type: intermediate_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/3478f7c3-db8c-4fca-9165-3adbdf1b5829/3a22ac80-cd1d-4441-9e36-f24fc2f4c3de/gBqmpbl
This commit is contained in:
@@ -51,6 +51,11 @@ export interface IStorage {
|
||||
reactivateUser(id: string): Promise<void>;
|
||||
makeAdmin(id: string): Promise<void>;
|
||||
removeAdmin(id: string): Promise<void>;
|
||||
setUserPassword(id: string, password: string, isTemporary?: boolean): Promise<void>;
|
||||
deactivateUserSoft(id: string): Promise<void>;
|
||||
deleteUserHard(id: string): Promise<void>;
|
||||
getUserActiveStatus(id: string): Promise<boolean>;
|
||||
createUserWithPassword(userData: InsertUser & { password: string, isTemporary?: boolean }): Promise<User>;
|
||||
|
||||
// Event operations
|
||||
createEvent(event: InsertEvent): Promise<Event>;
|
||||
@@ -149,6 +154,18 @@ export class DatabaseStorage implements IStorage {
|
||||
return user;
|
||||
}
|
||||
|
||||
async createUserWithPassword(userData: InsertUser & { password: string, isTemporary?: boolean }): Promise<User> {
|
||||
const { password, isTemporary, ...userFields } = userData;
|
||||
const [user] = await db.insert(users).values({
|
||||
...userFields,
|
||||
password,
|
||||
tempPassword: isTemporary ? password : null,
|
||||
needsPasswordChange: isTemporary || false,
|
||||
isActive: true // Activate immediately when password is provided
|
||||
}).returning();
|
||||
return user;
|
||||
}
|
||||
|
||||
async upsertUser(userData: UpsertUser): Promise<User> {
|
||||
const [user] = await db
|
||||
.insert(users)
|
||||
@@ -193,6 +210,55 @@ export class DatabaseStorage implements IStorage {
|
||||
await db.update(users).set({ role: "dj", updatedAt: new Date() }).where(eq(users.id, id));
|
||||
}
|
||||
|
||||
async setUserPassword(id: string, password: string, isTemporary: boolean = false): Promise<void> {
|
||||
await db.update(users).set({
|
||||
password,
|
||||
tempPassword: isTemporary ? password : null,
|
||||
needsPasswordChange: isTemporary,
|
||||
isActive: true, // Activate user when password is set
|
||||
updatedAt: new Date()
|
||||
}).where(eq(users.id, id));
|
||||
}
|
||||
|
||||
async deactivateUserSoft(id: string): Promise<void> {
|
||||
// Soft deactivation - hide from availability/scheduling but keep all data
|
||||
await db.update(users).set({ isActive: false, updatedAt: new Date() }).where(eq(users.id, id));
|
||||
}
|
||||
|
||||
async deleteUserHard(id: string): Promise<void> {
|
||||
// Hard deletion - remove user and all future schedules/availability
|
||||
const currentDate = new Date().toISOString().split('T')[0];
|
||||
|
||||
// Delete future availability
|
||||
await db.delete(availability)
|
||||
.where(and(eq(availability.djId, id), gte(availability.startDate, currentDate)));
|
||||
|
||||
// Delete future events (keep past events for historical purposes)
|
||||
await db.delete(events)
|
||||
.where(and(eq(events.djId, id), gte(events.date, currentDate)));
|
||||
|
||||
// Delete slot eligibility
|
||||
await db.delete(slotEligibility).where(eq(slotEligibility.djId, id));
|
||||
|
||||
// Delete social links
|
||||
await db.delete(socialLinks).where(eq(socialLinks.djId, id));
|
||||
|
||||
// Delete removal requests
|
||||
await db.delete(removalRequests).where(eq(removalRequests.djId, id));
|
||||
|
||||
// Finally delete the user
|
||||
await db.delete(users).where(eq(users.id, id));
|
||||
}
|
||||
|
||||
async getUserActiveStatus(id: string): Promise<boolean> {
|
||||
const [user] = await db.select({ isActive: users.isActive, password: users.password })
|
||||
.from(users)
|
||||
.where(eq(users.id, id));
|
||||
|
||||
// User is considered active if they have isActive=true AND have a password set
|
||||
return user ? user.isActive && !!user.password : false;
|
||||
}
|
||||
|
||||
// Event operations
|
||||
async createEvent(event: InsertEvent): Promise<Event> {
|
||||
const [newEvent] = await db.insert(events).values(event).returning();
|
||||
|
||||
Reference in New Issue
Block a user