Commit inicial - upload de todos os arquivos da pasta

This commit is contained in:
2026-06-13 16:36:29 -03:00
commit 807be1c5ee
275 changed files with 29408 additions and 0 deletions

15
prisma/check-password.ts Normal file
View File

@@ -0,0 +1,15 @@
import { PrismaClient } from '@prisma/client';
import * as bcrypt from 'bcrypt';
const prisma = new PrismaClient();
async function main() {
const user = await prisma.user.findUnique({ where: { email: 'admin@iasis.com.br' } });
if (!user) { console.log('Usuário não encontrado'); return; }
console.log('Hash no banco:', user.password);
const match = await bcrypt.compare('Admin@123456', user.password);
console.log('Senha confere:', match);
}
main().finally(() => prisma.$disconnect());

View File

@@ -0,0 +1,401 @@
-- CreateEnum
CREATE TYPE "Role" AS ENUM ('ADMIN', 'OPERATOR', 'CLIENT');
-- CreateEnum
CREATE TYPE "DeliverableStatus" AS ENUM ('RASCUNHO', 'EMITIDA', 'EM_EXECUCAO', 'AGUARDANDO_VALIDACAO', 'EM_REVISAO', 'APROVADA', 'GLOSADA', 'ENCERRADA', 'CANCELADA', 'AGUARDANDO_PAGAMENTO', 'PAGA');
-- CreateEnum
CREATE TYPE "TimelineEventType" AS ENUM ('CRIACAO', 'EDICAO', 'STATUS_CHANGE', 'ASSIGNMENT', 'BACKLOG', 'ANOTACAO', 'ALOCACAO');
-- CreateEnum
CREATE TYPE "BacklogItemStatus" AS ENUM ('PENDENTE', 'ACEITO', 'REJEITADO');
-- CreateEnum
CREATE TYPE "NoteType" AS ENUM ('OBSERVACAO', 'RISCO', 'IMPEDIMENTO', 'DECISAO');
-- CreateEnum
CREATE TYPE "SprintType" AS ENUM ('DESCOBERTA', 'DESIGN', 'ARQUITETURA', 'CONSTRUCAO');
-- CreateEnum
CREATE TYPE "SprintStatus" AS ENUM ('RASCUNHO', 'EM_EXECUCAO', 'FINALIZADA', 'CANCELADA');
-- CreateEnum
CREATE TYPE "SprintHistoryEventType" AS ENUM ('ENTREGAVEL_ADICIONADO', 'ENTREGAVEL_REMOVIDO', 'STATUS_CHANGE', 'ENTREGAVEL_MOVIDO');
-- CreateTable
CREATE TABLE "users" (
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"email" TEXT NOT NULL,
"password" TEXT NOT NULL,
"role" "Role" NOT NULL DEFAULT 'OPERATOR',
"isActive" BOOLEAN NOT NULL DEFAULT true,
"mustChangePassword" BOOLEAN NOT NULL DEFAULT false,
"client_id" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "users_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "clients" (
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"document" TEXT,
"email" TEXT,
"phone" TEXT,
"contact_name" TEXT,
"description" TEXT,
"is_active" BOOLEAN NOT NULL DEFAULT true,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
CONSTRAINT "clients_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "contract_items" (
"id" TEXT NOT NULL,
"code" TEXT NOT NULL,
"name" TEXT NOT NULL,
"description" TEXT,
"total_ust" DECIMAL(65,30) NOT NULL,
"ust_value" DECIMAL(65,30),
"timebox_descoberta" DECIMAL(65,30),
"timebox_design" DECIMAL(65,30),
"timebox_arquitetura" DECIMAL(65,30),
"timebox_construcao" DECIMAL(65,30),
"is_active" BOOLEAN NOT NULL DEFAULT true,
"client_id" TEXT NOT NULL,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
CONSTRAINT "contract_items_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "professionals" (
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"document" TEXT,
"email" TEXT,
"phone" TEXT,
"role" TEXT,
"is_active" BOOLEAN NOT NULL DEFAULT true,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
CONSTRAINT "professionals_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "contracts" (
"id" TEXT NOT NULL,
"client_id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"code" TEXT,
"description" TEXT,
"start_date" TIMESTAMP(3),
"end_date" TIMESTAMP(3),
"ust_value" DECIMAL(65,30),
"is_active" BOOLEAN NOT NULL DEFAULT true,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
CONSTRAINT "contracts_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "projects" (
"id" TEXT NOT NULL,
"contract_id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"code" TEXT,
"description" TEXT,
"start_date" TIMESTAMP(3),
"end_date" TIMESTAMP(3),
"is_active" BOOLEAN NOT NULL DEFAULT true,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
CONSTRAINT "projects_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "sprints" (
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"code" TEXT,
"type" "SprintType",
"status" "SprintStatus" NOT NULL DEFAULT 'RASCUNHO',
"start_date" TIMESTAMP(3) NOT NULL,
"end_date" TIMESTAMP(3) NOT NULL,
"goal" TEXT,
"is_active" BOOLEAN NOT NULL DEFAULT true,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
CONSTRAINT "sprints_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "deliverables" (
"id" TEXT NOT NULL,
"code" TEXT NOT NULL,
"title" TEXT NOT NULL,
"description" TEXT,
"status" "DeliverableStatus" NOT NULL DEFAULT 'RASCUNHO',
"client_id" TEXT NOT NULL,
"contract_id" TEXT NOT NULL,
"project_id" TEXT NOT NULL,
"contract_item_id" TEXT NOT NULL,
"sprint_id" TEXT NOT NULL,
"start_date" TIMESTAMP(3),
"expected_end_date" TIMESTAMP(3),
"ust_value" DECIMAL(65,30),
"ust_quantity" DECIMAL(65,30),
"total_value" DECIMAL(65,30),
"is_active" BOOLEAN NOT NULL DEFAULT true,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
"created_by" TEXT,
"updated_by" TEXT,
CONSTRAINT "deliverables_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "deliverable_status_history" (
"id" TEXT NOT NULL,
"deliverable_id" TEXT NOT NULL,
"previous_status" "DeliverableStatus",
"new_status" "DeliverableStatus" NOT NULL,
"observation" TEXT,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"created_by" TEXT,
CONSTRAINT "deliverable_status_history_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "deliverable_assignments" (
"id" TEXT NOT NULL,
"deliverable_id" TEXT NOT NULL,
"professional_id" TEXT NOT NULL,
"role" TEXT,
"start_date" TIMESTAMP(3),
"end_date" TIMESTAMP(3),
"observation" TEXT,
"is_active" BOOLEAN NOT NULL DEFAULT true,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
"created_by" TEXT,
CONSTRAINT "deliverable_assignments_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "deliverable_backlog_items" (
"id" TEXT NOT NULL,
"deliverable_id" TEXT NOT NULL,
"title" TEXT NOT NULL,
"description" TEXT,
"acceptance_criteria" TEXT,
"status" "BacklogItemStatus" NOT NULL DEFAULT 'PENDENTE',
"rejection_reason" TEXT,
"sort_order" INTEGER NOT NULL DEFAULT 0,
"is_active" BOOLEAN NOT NULL DEFAULT true,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
"created_by" TEXT,
"updated_by" TEXT,
CONSTRAINT "deliverable_backlog_items_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "timeline_events" (
"id" TEXT NOT NULL,
"deliverable_id" TEXT NOT NULL,
"type" "TimelineEventType" NOT NULL,
"title" TEXT NOT NULL,
"description" TEXT,
"metadata" JSONB,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"created_by" TEXT,
CONSTRAINT "timeline_events_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "notes" (
"id" TEXT NOT NULL,
"deliverable_id" TEXT NOT NULL,
"type" "NoteType" NOT NULL,
"title" TEXT NOT NULL,
"description" TEXT,
"is_relevant" BOOLEAN NOT NULL DEFAULT false,
"is_active" BOOLEAN NOT NULL DEFAULT true,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
"created_by" TEXT,
"updated_by" TEXT,
CONSTRAINT "notes_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "sprint_history" (
"id" TEXT NOT NULL,
"sprint_id" TEXT NOT NULL,
"event_type" "SprintHistoryEventType" NOT NULL,
"description" TEXT NOT NULL,
"deliverable_id" TEXT,
"target_sprint_id" TEXT,
"previous_status" "SprintStatus",
"new_status" "SprintStatus",
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"created_by" TEXT,
CONSTRAINT "sprint_history_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "client_profiles" (
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"is_active" BOOLEAN NOT NULL DEFAULT true,
"client_id" TEXT NOT NULL,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
CONSTRAINT "client_profiles_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "allocation_templates" (
"id" TEXT NOT NULL,
"client_id" TEXT NOT NULL,
"sprint_type" "SprintType" NOT NULL,
"contract_item_id" TEXT NOT NULL,
"is_active" BOOLEAN NOT NULL DEFAULT true,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
CONSTRAINT "allocation_templates_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "allocation_template_items" (
"id" TEXT NOT NULL,
"template_id" TEXT NOT NULL,
"profile_id" TEXT NOT NULL,
"quantity" INTEGER NOT NULL,
"allocation_percentage" DECIMAL(65,30) NOT NULL,
CONSTRAINT "allocation_template_items_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "deliverable_allocations" (
"id" TEXT NOT NULL,
"deliverable_id" TEXT NOT NULL,
"profile_id" TEXT NOT NULL,
"quantity" INTEGER NOT NULL,
"allocation_percentage" DECIMAL(65,30) NOT NULL,
"calculated_value" DECIMAL(65,30),
"is_active" BOOLEAN NOT NULL DEFAULT true,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
"created_by" TEXT,
CONSTRAINT "deliverable_allocations_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "users_email_key" ON "users"("email");
-- CreateIndex
CREATE UNIQUE INDEX "contract_items_code_client_id_key" ON "contract_items"("code", "client_id");
-- CreateIndex
CREATE UNIQUE INDEX "deliverables_code_key" ON "deliverables"("code");
-- CreateIndex
CREATE UNIQUE INDEX "allocation_templates_client_id_sprint_type_contract_item_id_key" ON "allocation_templates"("client_id", "sprint_type", "contract_item_id");
-- AddForeignKey
ALTER TABLE "users" ADD CONSTRAINT "users_client_id_fkey" FOREIGN KEY ("client_id") REFERENCES "clients"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "contract_items" ADD CONSTRAINT "contract_items_client_id_fkey" FOREIGN KEY ("client_id") REFERENCES "clients"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "contracts" ADD CONSTRAINT "contracts_client_id_fkey" FOREIGN KEY ("client_id") REFERENCES "clients"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "projects" ADD CONSTRAINT "projects_contract_id_fkey" FOREIGN KEY ("contract_id") REFERENCES "contracts"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "deliverables" ADD CONSTRAINT "deliverables_client_id_fkey" FOREIGN KEY ("client_id") REFERENCES "clients"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "deliverables" ADD CONSTRAINT "deliverables_contract_id_fkey" FOREIGN KEY ("contract_id") REFERENCES "contracts"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "deliverables" ADD CONSTRAINT "deliverables_project_id_fkey" FOREIGN KEY ("project_id") REFERENCES "projects"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "deliverables" ADD CONSTRAINT "deliverables_contract_item_id_fkey" FOREIGN KEY ("contract_item_id") REFERENCES "contract_items"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "deliverables" ADD CONSTRAINT "deliverables_sprint_id_fkey" FOREIGN KEY ("sprint_id") REFERENCES "sprints"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "deliverable_status_history" ADD CONSTRAINT "deliverable_status_history_deliverable_id_fkey" FOREIGN KEY ("deliverable_id") REFERENCES "deliverables"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "deliverable_assignments" ADD CONSTRAINT "deliverable_assignments_deliverable_id_fkey" FOREIGN KEY ("deliverable_id") REFERENCES "deliverables"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "deliverable_assignments" ADD CONSTRAINT "deliverable_assignments_professional_id_fkey" FOREIGN KEY ("professional_id") REFERENCES "professionals"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "deliverable_backlog_items" ADD CONSTRAINT "deliverable_backlog_items_deliverable_id_fkey" FOREIGN KEY ("deliverable_id") REFERENCES "deliverables"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "timeline_events" ADD CONSTRAINT "timeline_events_deliverable_id_fkey" FOREIGN KEY ("deliverable_id") REFERENCES "deliverables"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "notes" ADD CONSTRAINT "notes_deliverable_id_fkey" FOREIGN KEY ("deliverable_id") REFERENCES "deliverables"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "sprint_history" ADD CONSTRAINT "sprint_history_sprint_id_fkey" FOREIGN KEY ("sprint_id") REFERENCES "sprints"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "sprint_history" ADD CONSTRAINT "sprint_history_target_sprint_id_fkey" FOREIGN KEY ("target_sprint_id") REFERENCES "sprints"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "sprint_history" ADD CONSTRAINT "sprint_history_deliverable_id_fkey" FOREIGN KEY ("deliverable_id") REFERENCES "deliverables"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "client_profiles" ADD CONSTRAINT "client_profiles_client_id_fkey" FOREIGN KEY ("client_id") REFERENCES "clients"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "allocation_templates" ADD CONSTRAINT "allocation_templates_client_id_fkey" FOREIGN KEY ("client_id") REFERENCES "clients"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "allocation_templates" ADD CONSTRAINT "allocation_templates_contract_item_id_fkey" FOREIGN KEY ("contract_item_id") REFERENCES "contract_items"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "allocation_template_items" ADD CONSTRAINT "allocation_template_items_template_id_fkey" FOREIGN KEY ("template_id") REFERENCES "allocation_templates"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "allocation_template_items" ADD CONSTRAINT "allocation_template_items_profile_id_fkey" FOREIGN KEY ("profile_id") REFERENCES "client_profiles"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "deliverable_allocations" ADD CONSTRAINT "deliverable_allocations_deliverable_id_fkey" FOREIGN KEY ("deliverable_id") REFERENCES "deliverables"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "deliverable_allocations" ADD CONSTRAINT "deliverable_allocations_profile_id_fkey" FOREIGN KEY ("profile_id") REFERENCES "client_profiles"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

View File

@@ -0,0 +1,84 @@
/*
Warnings:
- You are about to drop the column `type` on the `sprints` table. All the data in the column will be lost.
- Added the required column `type` to the `deliverables` table without a default value. This is not possible if the table is not empty.
- Added the required column `work_order_id` to the `deliverables` table without a default value. This is not possible if the table is not empty.
*/
-- CreateEnum
CREATE TYPE "WorkOrderStatus" AS ENUM ('RASCUNHO', 'EMITIDA', 'EM_EXECUCAO', 'TOTALMENTE_PAGA', 'CANCELADA');
-- CreateEnum
CREATE TYPE "DeliverableType" AS ENUM ('DESCOBERTA', 'DESIGN', 'ARQUITETURA', 'CONSTRUCAO', 'MANUTENCAO', 'LICENCA');
-- AlterTable
ALTER TABLE "deliverables" ADD COLUMN "type" "DeliverableType" NOT NULL,
ADD COLUMN "work_order_id" TEXT NOT NULL;
-- AlterTable
ALTER TABLE "sprints" DROP COLUMN "type";
-- CreateTable
CREATE TABLE "work_orders" (
"id" TEXT NOT NULL,
"code" TEXT NOT NULL,
"name" TEXT NOT NULL,
"description" TEXT,
"contract_id" TEXT NOT NULL,
"contract_item_id" TEXT NOT NULL,
"reserved_ust" DECIMAL(65,30) NOT NULL,
"status" "WorkOrderStatus" NOT NULL DEFAULT 'RASCUNHO',
"start_date" TIMESTAMP(3) NOT NULL,
"end_date" TIMESTAMP(3),
"is_active" BOOLEAN NOT NULL DEFAULT true,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
"created_by" TEXT,
"updated_by" TEXT,
CONSTRAINT "work_orders_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "work_order_projects" (
"work_order_id" TEXT NOT NULL,
"project_id" TEXT NOT NULL,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "work_order_projects_pkey" PRIMARY KEY ("work_order_id","project_id")
);
-- CreateTable
CREATE TABLE "work_order_status_history" (
"id" TEXT NOT NULL,
"work_order_id" TEXT NOT NULL,
"previous_status" "WorkOrderStatus",
"new_status" "WorkOrderStatus" NOT NULL,
"observation" TEXT,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"created_by" TEXT,
CONSTRAINT "work_order_status_history_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "work_orders_code_contract_id_key" ON "work_orders"("code", "contract_id");
-- AddForeignKey
ALTER TABLE "deliverables" ADD CONSTRAINT "deliverables_work_order_id_fkey" FOREIGN KEY ("work_order_id") REFERENCES "work_orders"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "work_orders" ADD CONSTRAINT "work_orders_contract_id_fkey" FOREIGN KEY ("contract_id") REFERENCES "contracts"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "work_orders" ADD CONSTRAINT "work_orders_contract_item_id_fkey" FOREIGN KEY ("contract_item_id") REFERENCES "contract_items"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "work_order_projects" ADD CONSTRAINT "work_order_projects_work_order_id_fkey" FOREIGN KEY ("work_order_id") REFERENCES "work_orders"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "work_order_projects" ADD CONSTRAINT "work_order_projects_project_id_fkey" FOREIGN KEY ("project_id") REFERENCES "projects"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "work_order_status_history" ADD CONSTRAINT "work_order_status_history_work_order_id_fkey" FOREIGN KEY ("work_order_id") REFERENCES "work_orders"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

View File

@@ -0,0 +1,5 @@
-- CreateEnum
CREATE TYPE "ContractItemType" AS ENUM ('UST', 'SAAS_LICENSE');
-- AlterTable
ALTER TABLE "contract_items" ADD COLUMN "item_type" "ContractItemType" NOT NULL DEFAULT 'UST';

View File

@@ -0,0 +1,3 @@
-- AlterTable
ALTER TABLE "deliverables" ADD COLUMN "num_weeks" INTEGER NOT NULL DEFAULT 1,
ADD COLUMN "timebox_manutencao" DECIMAL(65,30);

View File

@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "deliverables" ALTER COLUMN "num_weeks" DROP DEFAULT;

View File

@@ -0,0 +1,2 @@
-- AlterEnum
ALTER TYPE "TimelineEventType" ADD VALUE 'VALOR_RECALCULADO';

View File

@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "work_orders" ADD COLUMN "total_value" DECIMAL(65,30);

View File

@@ -0,0 +1,9 @@
-- Backfill nullable rows before enforcing NOT NULL.
UPDATE "deliverables" SET "start_date" = "created_at" WHERE "start_date" IS NULL;
UPDATE "deliverables"
SET "expected_end_date" = "start_date" + INTERVAL '7 days'
WHERE "expected_end_date" IS NULL;
-- AlterTable
ALTER TABLE "deliverables" ALTER COLUMN "start_date" SET NOT NULL,
ALTER COLUMN "expected_end_date" SET NOT NULL;

View File

@@ -0,0 +1,44 @@
-- CreateEnum
CREATE TYPE "IntegrationScope" AS ENUM ('DELIVERABLES_READ', 'CLIENTS_READ');
-- CreateTable
CREATE TABLE "integration_api_keys" (
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"hashed_key" TEXT NOT NULL,
"last_four_chars" TEXT NOT NULL,
"scopes" "IntegrationScope"[],
"is_active" BOOLEAN NOT NULL DEFAULT true,
"expires_at" TIMESTAMP(3),
"last_used_at" TIMESTAMP(3),
"rate_limit_per_minute" INTEGER NOT NULL DEFAULT 60,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
"created_by" TEXT,
"updated_by" TEXT,
CONSTRAINT "integration_api_keys_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "integration_api_key_usage" (
"id" TEXT NOT NULL,
"api_key_id" TEXT NOT NULL,
"endpoint" TEXT NOT NULL,
"status_code" INTEGER NOT NULL,
"ip_address" TEXT,
"user_agent" TEXT,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "integration_api_key_usage_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "integration_api_keys_hashed_key_key" ON "integration_api_keys"("hashed_key");
-- CreateIndex
CREATE INDEX "integration_api_key_usage_api_key_id_idx" ON "integration_api_key_usage"("api_key_id");
-- AddForeignKey
ALTER TABLE "integration_api_key_usage" ADD CONSTRAINT "integration_api_key_usage_api_key_id_fkey" FOREIGN KEY ("api_key_id") REFERENCES "integration_api_keys"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

View File

@@ -0,0 +1,20 @@
-- CreateTable
CREATE TABLE "password_reset_tokens" (
"id" TEXT NOT NULL,
"user_id" TEXT NOT NULL,
"token_hash" TEXT NOT NULL,
"expires_at" TIMESTAMP(3) NOT NULL,
"used_at" TIMESTAMP(3),
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "password_reset_tokens_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "password_reset_tokens_token_hash_key" ON "password_reset_tokens"("token_hash");
-- CreateIndex
CREATE INDEX "password_reset_tokens_user_id_idx" ON "password_reset_tokens"("user_id");
-- AddForeignKey
ALTER TABLE "password_reset_tokens" ADD CONSTRAINT "password_reset_tokens_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

View File

@@ -0,0 +1,4 @@
-- AlterTable: change default role from OPERATOR to GESTOR_PROJETOS
-- This must be in a separate migration from the ADD VALUE statements
-- because PostgreSQL requires enum values to be committed before use.
ALTER TABLE "users" ALTER COLUMN "role" SET DEFAULT 'GESTOR_PROJETOS';

View File

@@ -0,0 +1,17 @@
-- AlterEnum
-- This migration adds more than one value to an enum.
-- With PostgreSQL versions 11 and earlier, this is not possible
-- in a single migration. This can be worked around by creating
-- multiple migrations, each migration adding only one value to
-- the enum.
ALTER TYPE "Role" ADD VALUE 'GESTOR_PROJETOS';
ALTER TYPE "Role" ADD VALUE 'PO';
ALTER TYPE "Role" ADD VALUE 'FISCAL_CONTRATO';
ALTER TYPE "Role" ADD VALUE 'GESTOR_CONTRATO';
-- AlterTable: add temporary clientSubRole column only
-- Note: SET DEFAULT 'GESTOR_PROJETOS' must be in a separate migration
-- after the new enum values are committed.
ALTER TABLE "users" ADD COLUMN "client_sub_role" TEXT;

View File

@@ -0,0 +1,3 @@
# Please do not edit this file manually
# It should be added in your version-control system (i.e. Git)
provider = "postgresql"

561
prisma/schema.prisma Normal file
View File

@@ -0,0 +1,561 @@
generator client {
provider = "prisma-client-js"
binaryTargets = ["native", "debian-openssl-3.0.x"]
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
enum Role {
ADMIN
OPERATOR
CLIENT
GESTOR_PROJETOS
PO
FISCAL_CONTRATO
GESTOR_CONTRATO
}
enum DeliverableStatus {
RASCUNHO
EMITIDA
EM_EXECUCAO
AGUARDANDO_VALIDACAO
EM_REVISAO
APROVADA
GLOSADA
ENCERRADA
CANCELADA
AGUARDANDO_PAGAMENTO
PAGA
}
enum TimelineEventType {
CRIACAO
EDICAO
STATUS_CHANGE
ASSIGNMENT
BACKLOG
ANOTACAO
ALOCACAO
VALOR_RECALCULADO
}
enum BacklogItemStatus {
PENDENTE
ACEITO
REJEITADO
}
enum NoteType {
OBSERVACAO
RISCO
IMPEDIMENTO
DECISAO
}
enum SprintType {
DESCOBERTA
DESIGN
ARQUITETURA
CONSTRUCAO
}
enum WorkOrderStatus {
RASCUNHO
EMITIDA
EM_EXECUCAO
TOTALMENTE_PAGA
CANCELADA
}
enum DeliverableType {
DESCOBERTA
DESIGN
ARQUITETURA
CONSTRUCAO
MANUTENCAO
LICENCA
}
enum ContractItemType {
UST
SAAS_LICENSE
}
enum SprintStatus {
RASCUNHO
EM_EXECUCAO
FINALIZADA
CANCELADA
}
enum SprintHistoryEventType {
ENTREGAVEL_ADICIONADO
ENTREGAVEL_REMOVIDO
STATUS_CHANGE
ENTREGAVEL_MOVIDO
}
enum IntegrationScope {
DELIVERABLES_READ
CLIENTS_READ
}
model User {
id String @id @default(uuid())
name String
email String @unique
password String
role Role @default(GESTOR_PROJETOS)
clientSubRole String? @map("client_sub_role")
isActive Boolean @default(true)
mustChangePassword Boolean @default(false)
clientId String? @map("client_id")
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
client Client? @relation(fields: [clientId], references: [id])
passwordResetTokens PasswordResetToken[]
@@map("users")
}
model PasswordResetToken {
id String @id @default(uuid())
userId String @map("user_id")
tokenHash String @unique @map("token_hash")
expiresAt DateTime @map("expires_at")
usedAt DateTime? @map("used_at")
createdAt DateTime @default(now()) @map("created_at")
user User @relation(fields: [userId], references: [id])
@@index([userId])
@@map("password_reset_tokens")
}
model Client {
id String @id @default(uuid())
name String
document String?
email String?
phone String?
contactName String? @map("contact_name")
description String?
isActive Boolean @default(true) @map("is_active")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
contracts Contract[]
contractItems ContractItem[]
deliverables Deliverable[]
users User[]
profiles ClientProfile[]
allocationTemplates AllocationTemplate[]
@@map("clients")
}
model ContractItem {
id String @id @default(uuid())
code String
name String
description String?
totalUst Decimal @map("total_ust")
ustValue Decimal? @map("ust_value")
itemType ContractItemType @default(UST) @map("item_type")
timeboxDescoberta Decimal? @map("timebox_descoberta")
timeboxDesign Decimal? @map("timebox_design")
timeboxArquitetura Decimal? @map("timebox_arquitetura")
timeboxConstrucao Decimal? @map("timebox_construcao")
isActive Boolean @default(true) @map("is_active")
clientId String @map("client_id")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
client Client @relation(fields: [clientId], references: [id])
deliverables Deliverable[]
allocationTemplates AllocationTemplate[]
workOrders WorkOrder[]
@@unique([code, clientId])
@@map("contract_items")
}
model Professional {
id String @id @default(uuid())
name String
document String?
email String?
phone String?
role String?
isActive Boolean @default(true) @map("is_active")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
deliverableAssignments DeliverableAssignment[]
@@map("professionals")
}
model Contract {
id String @id @default(uuid())
clientId String @map("client_id")
name String
code String?
description String?
startDate DateTime? @map("start_date")
endDate DateTime? @map("end_date")
ustValue Decimal? @map("ust_value")
isActive Boolean @default(true) @map("is_active")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
client Client @relation(fields: [clientId], references: [id])
projects Project[]
deliverables Deliverable[]
workOrders WorkOrder[]
@@map("contracts")
}
model Project {
id String @id @default(uuid())
contractId String @map("contract_id")
name String
code String?
description String?
startDate DateTime? @map("start_date")
endDate DateTime? @map("end_date")
isActive Boolean @default(true) @map("is_active")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
contract Contract @relation(fields: [contractId], references: [id])
deliverables Deliverable[]
workOrders WorkOrderProject[]
@@map("projects")
}
model Sprint {
id String @id @default(uuid())
name String
code String?
status SprintStatus @default(RASCUNHO)
startDate DateTime @map("start_date")
endDate DateTime @map("end_date")
goal String?
isActive Boolean @default(true) @map("is_active")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
deliverables Deliverable[]
history SprintHistory[] @relation("SprintHistory")
targetHistory SprintHistory[] @relation("SprintHistoryTarget")
@@map("sprints")
}
model Deliverable {
id String @id @default(uuid())
code String @unique
title String
description String?
status DeliverableStatus @default(RASCUNHO)
type DeliverableType
clientId String @map("client_id")
contractId String @map("contract_id")
projectId String @map("project_id")
contractItemId String @map("contract_item_id")
workOrderId String @map("work_order_id")
sprintId String @map("sprint_id")
startDate DateTime @map("start_date")
expectedEndDate DateTime @map("expected_end_date")
numWeeks Int @map("num_weeks")
timeboxManutencao Decimal? @map("timebox_manutencao")
ustValue Decimal? @map("ust_value")
ustQuantity Decimal? @map("ust_quantity")
totalValue Decimal? @map("total_value")
isActive Boolean @default(true) @map("is_active")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
createdBy String? @map("created_by")
updatedBy String? @map("updated_by")
client Client @relation(fields: [clientId], references: [id])
contract Contract @relation(fields: [contractId], references: [id])
project Project @relation(fields: [projectId], references: [id])
contractItem ContractItem @relation(fields: [contractItemId], references: [id])
workOrder WorkOrder @relation(fields: [workOrderId], references: [id])
sprint Sprint @relation(fields: [sprintId], references: [id])
statusHistory DeliverableStatusHistory[]
assignments DeliverableAssignment[]
backlogItems DeliverableBacklogItem[]
timelineEvents TimelineEvent[]
notes Note[]
sprintHistory SprintHistory[]
allocations DeliverableAllocation[]
@@map("deliverables")
}
model DeliverableStatusHistory {
id String @id @default(uuid())
deliverableId String @map("deliverable_id")
previousStatus DeliverableStatus? @map("previous_status")
newStatus DeliverableStatus @map("new_status")
observation String?
createdAt DateTime @default(now()) @map("created_at")
createdBy String? @map("created_by")
deliverable Deliverable @relation(fields: [deliverableId], references: [id])
@@map("deliverable_status_history")
}
model DeliverableAssignment {
id String @id @default(uuid())
deliverableId String @map("deliverable_id")
professionalId String @map("professional_id")
role String?
startDate DateTime? @map("start_date")
endDate DateTime? @map("end_date")
observation String?
isActive Boolean @default(true) @map("is_active")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
createdBy String? @map("created_by")
deliverable Deliverable @relation(fields: [deliverableId], references: [id])
professional Professional @relation(fields: [professionalId], references: [id])
@@map("deliverable_assignments")
}
model DeliverableBacklogItem {
id String @id @default(uuid())
deliverableId String @map("deliverable_id")
title String
description String?
acceptanceCriteria String? @map("acceptance_criteria")
status BacklogItemStatus @default(PENDENTE)
rejectionReason String? @map("rejection_reason")
sortOrder Int @default(0) @map("sort_order")
isActive Boolean @default(true) @map("is_active")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
createdBy String? @map("created_by")
updatedBy String? @map("updated_by")
deliverable Deliverable @relation(fields: [deliverableId], references: [id])
@@map("deliverable_backlog_items")
}
model TimelineEvent {
id String @id @default(uuid())
deliverableId String @map("deliverable_id")
type TimelineEventType
title String
description String?
metadata Json?
createdAt DateTime @default(now()) @map("created_at")
createdBy String? @map("created_by")
deliverable Deliverable @relation(fields: [deliverableId], references: [id])
@@map("timeline_events")
}
model Note {
id String @id @default(uuid())
deliverableId String @map("deliverable_id")
type NoteType
title String
description String?
isRelevant Boolean @default(false) @map("is_relevant")
isActive Boolean @default(true) @map("is_active")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
createdBy String? @map("created_by")
updatedBy String? @map("updated_by")
deliverable Deliverable @relation(fields: [deliverableId], references: [id])
@@map("notes")
}
model SprintHistory {
id String @id @default(uuid())
sprintId String @map("sprint_id")
eventType SprintHistoryEventType @map("event_type")
description String
deliverableId String? @map("deliverable_id")
targetSprintId String? @map("target_sprint_id")
previousStatus SprintStatus? @map("previous_status")
newStatus SprintStatus? @map("new_status")
createdAt DateTime @default(now()) @map("created_at")
createdBy String? @map("created_by")
sprint Sprint @relation("SprintHistory", fields: [sprintId], references: [id])
targetSprint Sprint? @relation("SprintHistoryTarget", fields: [targetSprintId], references: [id])
deliverable Deliverable? @relation(fields: [deliverableId], references: [id])
@@map("sprint_history")
}
model ClientProfile {
id String @id @default(uuid())
name String
isActive Boolean @default(true) @map("is_active")
clientId String @map("client_id")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
client Client @relation(fields: [clientId], references: [id])
allocationTemplateItems AllocationTemplateItem[]
deliverableAllocations DeliverableAllocation[]
@@map("client_profiles")
}
model AllocationTemplate {
id String @id @default(uuid())
clientId String @map("client_id")
sprintType SprintType @map("sprint_type")
contractItemId String @map("contract_item_id")
isActive Boolean @default(true) @map("is_active")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
client Client @relation(fields: [clientId], references: [id])
contractItem ContractItem @relation(fields: [contractItemId], references: [id])
items AllocationTemplateItem[]
@@unique([clientId, sprintType, contractItemId])
@@map("allocation_templates")
}
model AllocationTemplateItem {
id String @id @default(uuid())
templateId String @map("template_id")
profileId String @map("profile_id")
quantity Int
allocationPercentage Decimal @map("allocation_percentage")
template AllocationTemplate @relation(fields: [templateId], references: [id], onDelete: Cascade)
profile ClientProfile @relation(fields: [profileId], references: [id])
@@map("allocation_template_items")
}
model DeliverableAllocation {
id String @id @default(uuid())
deliverableId String @map("deliverable_id")
profileId String @map("profile_id")
quantity Int
allocationPercentage Decimal @map("allocation_percentage")
calculatedValue Decimal? @map("calculated_value")
isActive Boolean @default(true) @map("is_active")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
createdBy String? @map("created_by")
deliverable Deliverable @relation(fields: [deliverableId], references: [id])
profile ClientProfile @relation(fields: [profileId], references: [id])
@@map("deliverable_allocations")
}
model WorkOrder {
id String @id @default(uuid())
code String
name String
description String?
contractId String @map("contract_id")
contractItemId String @map("contract_item_id")
reservedUst Decimal @map("reserved_ust")
totalValue Decimal? @map("total_value")
status WorkOrderStatus @default(RASCUNHO)
startDate DateTime @map("start_date")
endDate DateTime? @map("end_date")
isActive Boolean @default(true) @map("is_active")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
createdBy String? @map("created_by")
updatedBy String? @map("updated_by")
contract Contract @relation(fields: [contractId], references: [id])
contractItem ContractItem @relation(fields: [contractItemId], references: [id])
projects WorkOrderProject[]
deliverables Deliverable[]
statusHistory WorkOrderStatusHistory[]
@@unique([code, contractId])
@@map("work_orders")
}
model WorkOrderProject {
workOrderId String @map("work_order_id")
projectId String @map("project_id")
createdAt DateTime @default(now()) @map("created_at")
workOrder WorkOrder @relation(fields: [workOrderId], references: [id], onDelete: Cascade)
project Project @relation(fields: [projectId], references: [id])
@@id([workOrderId, projectId])
@@map("work_order_projects")
}
model WorkOrderStatusHistory {
id String @id @default(uuid())
workOrderId String @map("work_order_id")
previousStatus WorkOrderStatus? @map("previous_status")
newStatus WorkOrderStatus @map("new_status")
observation String?
createdAt DateTime @default(now()) @map("created_at")
createdBy String? @map("created_by")
workOrder WorkOrder @relation(fields: [workOrderId], references: [id])
@@map("work_order_status_history")
}
model IntegrationApiKey {
id String @id @default(uuid())
name String
hashedKey String @unique @map("hashed_key")
lastFourChars String @map("last_four_chars")
scopes IntegrationScope[]
isActive Boolean @default(true) @map("is_active")
expiresAt DateTime? @map("expires_at")
lastUsedAt DateTime? @map("last_used_at")
rateLimitPerMinute Int @default(60) @map("rate_limit_per_minute")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
createdBy String? @map("created_by")
updatedBy String? @map("updated_by")
usages IntegrationApiKeyUsage[]
@@map("integration_api_keys")
}
model IntegrationApiKeyUsage {
id String @id @default(uuid())
apiKeyId String @map("api_key_id")
endpoint String
statusCode Int @map("status_code")
ipAddress String? @map("ip_address")
userAgent String? @map("user_agent")
createdAt DateTime @default(now()) @map("created_at")
apiKey IntegrationApiKey @relation(fields: [apiKeyId], references: [id])
@@index([apiKeyId])
@@map("integration_api_key_usage")
}

30
prisma/seed-admin.ts Normal file
View File

@@ -0,0 +1,30 @@
import { PrismaClient } from '@prisma/client';
import * as bcrypt from 'bcrypt';
const prisma = new PrismaClient();
async function main() {
const password = await bcrypt.hash('Admin@123456', 10);
const user = await prisma.user.upsert({
where: { email: 'admin@iasis.com.br' },
update: {},
create: {
name: 'Administrador',
email: 'admin@iasis.com.br',
password,
role: 'ADMIN',
isActive: true,
mustChangePassword: true,
},
});
console.log('Usuário admin criado:', user.email);
}
main()
.catch((e) => {
console.error(e);
process.exit(1);
})
.finally(() => prisma.$disconnect());

186
prisma/seed.ts Normal file
View File

@@ -0,0 +1,186 @@
import { ContractItemType, PrismaClient, Role } from '@prisma/client';
import * as bcrypt from 'bcrypt';
const prisma = new PrismaClient();
async function seedAdmin(): Promise<void> {
const passwordHash = await bcrypt.hash(process.env.PASS_ADMIN_USER || '', 10);
const admin = await prisma.user.upsert({
where: { email: 'admin@iasis.com.br' },
update: {},
create: {
name: 'Admin',
email: 'admin@iasis.com.br',
password: passwordHash,
role: Role.ADMIN,
mustChangePassword: false,
},
});
console.log(`Admin: ${admin.email} (${admin.id})`);
}
async function seedSesMg(): Promise<void> {
const clientData = {
name: 'Secretaria de Estado de Saúde de Minas Gerais (SES-MG)',
document: '18.715.516/0001-88',
email: 'rafael.paiva@saude.mg.gov.br',
phone: '(31) 39152-0221',
contactName: 'Rafael Matos Paiva',
description: 'Cliente SESMG',
};
const existingClient = await prisma.client.findFirst({
where: { document: clientData.document },
});
const client = existingClient
? await prisma.client.update({ where: { id: existingClient.id }, data: clientData })
: await prisma.client.create({ data: clientData });
console.log(`Cliente: ${client.name} (${client.id})`);
const contractData = {
clientId: client.id,
name: 'Contrato SESMG',
code: 'CTSES001',
startDate: new Date('2026-04-01T00:00:00Z'),
};
const existingContract = await prisma.contract.findFirst({
where: { clientId: client.id, code: contractData.code },
});
const contract = existingContract
? await prisma.contract.update({ where: { id: existingContract.id }, data: contractData })
: await prisma.contract.create({ data: contractData });
console.log(`Contrato: ${contract.code} (${contract.id})`);
const items = [
{
code: 'I-01',
name: 'Licença SaaS',
description: 'Licença SaaS',
itemType: ContractItemType.SAAS_LICENSE,
totalUst: 5,
ustValue: 35000000,
timeboxDescoberta: null,
timeboxDesign: null,
timeboxArquitetura: null,
timeboxConstrucao: null,
},
{
code: 'I-02',
name: 'Desenvolvimento e implantação da tecnologia blockchain',
description: 'Desenvolvimento e implantação da tecnologia blockchain',
itemType: ContractItemType.UST,
totalUst: 50400,
ustValue: 533.33,
timeboxDescoberta: 40,
timeboxDesign: 40,
timeboxArquitetura: 40,
timeboxConstrucao: 40,
},
{
code: 'I-03',
name: 'Desenv/Manutenção (treinamento/consultoria pós-implantação)',
description: 'Desenvolvimento e Manutenção (treinamento/consultoria pós-implantação)',
itemType: ContractItemType.UST,
totalUst: 4800,
ustValue: 388.88,
timeboxDescoberta: 40,
timeboxDesign: 40,
timeboxArquitetura: 40,
timeboxConstrucao: 40,
},
{
code: 'I-04',
name: 'Desenvolvimento e Manutenção (manutenção, integrações e automações)',
description: 'Desenvolvimento e Manutenção (manutenção, integrações e automações)',
itemType: ContractItemType.UST,
totalUst: 15120,
ustValue: 533.33,
timeboxDescoberta: 40,
timeboxDesign: 40,
timeboxArquitetura: 40,
timeboxConstrucao: 80,
},
{
code: 'I-05',
name: 'Serviços Técnicos de Inteligência Artificial (IA)',
description: 'Serviços Técnicos de Inteligência Artificial (IA)',
itemType: ContractItemType.UST,
totalUst: 30240,
ustValue: 555.55,
timeboxDescoberta: 40,
timeboxDesign: 40,
timeboxArquitetura: 40,
timeboxConstrucao: 80,
},
];
for (const item of items) {
const saved = await prisma.contractItem.upsert({
where: { code_clientId: { code: item.code, clientId: client.id } },
update: { ...item, clientId: client.id },
create: { ...item, clientId: client.id },
});
console.log(` Item: ${saved.code} - ${saved.name}`);
}
const projectData = {
contractId: contract.id,
name: 'ISIS Platform',
code: 'ISIS-001',
description: 'Plataforma de interoperabilidade ISIS',
};
const existingProject = await prisma.project.findFirst({
where: { contractId: contract.id, code: projectData.code },
});
const project = existingProject
? await prisma.project.update({ where: { id: existingProject.id }, data: projectData })
: await prisma.project.create({ data: projectData });
console.log(`Projeto: ${project.code} (${project.id})`);
const profiles = [
'Especialista de Inteligência (Cientista de Dados)',
'Analista de Negócio/Processo',
'Especialista de Negócio (Saúde)',
'Especialista de Tecnologia / Arquiteto',
'Gerente de Projeto',
'Desenvolvedor / Engenheiro de Dados',
'Especialista de Infraestrutura',
'Scrum Master',
];
for (const name of profiles) {
const existing = await prisma.clientProfile.findFirst({
where: { clientId: client.id, name },
});
const profile = existing
? await prisma.clientProfile.update({ where: { id: existing.id }, data: { name } })
: await prisma.clientProfile.create({ data: { name, clientId: client.id } });
console.log(` Perfil: ${profile.name}`);
}
}
async function main(): Promise<void> {
await seedAdmin();
await seedSesMg();
console.log('Seed concluído.');
}
main()
.catch((e) => {
console.error(e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});