feat: add complex user invitation and management features

- Implemented complex member and invitation schemas using Zod for validation.
- Created new API endpoints for inviting, accepting, revoking, and canceling complex user invitations.
- Developed handlers for managing complex users, including listing, inviting, revoking, and canceling invitations.
- Added frontend components for displaying and managing complex users and invitations.
- Introduced session storage management for pending invitations.
- Integrated Gravatar for user avatars based on email.
- Created database migration for complex invitations table.
This commit is contained in:
Jose Selesan
2026-04-22 15:30:04 -03:00
parent 5f2a7fd494
commit 6ad4fc9ee9
37 changed files with 1935 additions and 78 deletions

View File

@@ -12,6 +12,7 @@ model Complex {
updatedAt DateTime @updatedAt @map("updated_at")
plan Plan? @relation(fields: [planCode], references: [code])
users ComplexUser[]
invitations ComplexInvitation[]
courts Court[]
@@index([planCode])
@@ -36,3 +37,20 @@ model ComplexUser {
@@index([userId])
@@map("complex_users")
}
model ComplexInvitation {
id String @id @db.Uuid
complexId String @map("complex_id") @db.Uuid
email String @db.VarChar(255)
tokenHash String @unique @map("token_hash")
expiresAt DateTime @map("expires_at")
acceptedAt DateTime? @map("accepted_at")
revokedAt DateTime? @map("revoked_at")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
complex Complex @relation(fields: [complexId], references: [id], onDelete: Cascade)
@@index([complexId, email])
@@index([email])
@@map("complex_invitations")
}

View File

@@ -0,0 +1,26 @@
-- CreateTable
CREATE TABLE "complex_invitations" (
"id" UUID NOT NULL,
"complex_id" UUID NOT NULL,
"email" VARCHAR(255) NOT NULL,
"token_hash" TEXT NOT NULL,
"expires_at" TIMESTAMP(3) NOT NULL,
"accepted_at" TIMESTAMP(3),
"revoked_at" TIMESTAMP(3),
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
CONSTRAINT "complex_invitations_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "complex_invitations_token_hash_key" ON "complex_invitations"("token_hash");
-- CreateIndex
CREATE INDEX "complex_invitations_complex_id_email_idx" ON "complex_invitations"("complex_id", "email");
-- CreateIndex
CREATE INDEX "complex_invitations_email_idx" ON "complex_invitations"("email");
-- AddForeignKey
ALTER TABLE "complex_invitations" ADD CONSTRAINT "complex_invitations_complex_id_fkey" FOREIGN KEY ("complex_id") REFERENCES "complexes"("id") ON DELETE CASCADE ON UPDATE CASCADE;