Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,17 @@ FROM node:20-alpine
WORKDIR /app

COPY package*.json ./
RUN npm install
RUN npm config set registry https://registry.npmjs.org/ && \
npm ci --prefer-offline || npm install --fetch-retry-mintimeout 20000 \
--fetch-retry-maxtimeout 120000 \
--fetch-retries 5

COPY . .

# Generate Prisma client
RUN npx prisma generate

EXPOSE 3000
EXPOSE 3001

# CMD ["sh", "-c", "npx prisma migrate deploy && npm run start:dev"]
CMD ["npm", "run", "start:dev"]
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ services:
context: .
dockerfile: Dockerfile
ports:
- "3000:3000"
- "3001:3001"
- "5555:5555"
volumes:
- .:/app
Expand Down
15 changes: 15 additions & 0 deletions prisma/migrations/20260226015842_add_app_logs/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
-- CreateEnum
CREATE TYPE "LogLevel" AS ENUM ('INFO', 'WARN', 'ERROR');

-- CreateTable
CREATE TABLE "AppLog" (
"id" TEXT NOT NULL,
"level" "LogLevel" NOT NULL,
"action" TEXT NOT NULL,
"message" TEXT NOT NULL,
"userId" TEXT,
"metadata" JSONB,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,

CONSTRAINT "AppLog_pkey" PRIMARY KEY ("id")
);
26 changes: 26 additions & 0 deletions prisma/migrations/20260226233649_add_custody_status/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
Warnings:

- You are about to drop the column `gender` on the `pets` table. All the data in the column will be lost.
- You are about to drop the column `size` on the `pets` table. All the data in the column will be lost.
- You are about to drop the `documents` table. If the table is not empty, all the data it contains will be lost.

*/
-- DropForeignKey
ALTER TABLE "documents" DROP CONSTRAINT "documents_adoption_id_fkey";

-- DropForeignKey
ALTER TABLE "documents" DROP CONSTRAINT "documents_uploaded_by_id_fkey";

-- AlterTable
ALTER TABLE "pets" DROP COLUMN "gender",
DROP COLUMN "size";

-- DropTable
DROP TABLE "documents";

-- DropEnum
DROP TYPE "PetGender";

-- DropEnum
DROP TYPE "PetSize";
21 changes: 21 additions & 0 deletions prisma/migrations/20260227054055_add_document_model/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
-- CreateTable
CREATE TABLE "Document" (
"id" TEXT NOT NULL,
"fileName" TEXT NOT NULL,
"fileUrl" TEXT NOT NULL,
"publicId" TEXT NOT NULL,
"mimeType" TEXT NOT NULL,
"size" INTEGER NOT NULL,
"uploadedById" TEXT NOT NULL,
"adoptionId" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,

CONSTRAINT "Document_pkey" PRIMARY KEY ("id")
);

-- AddForeignKey
ALTER TABLE "Document" ADD CONSTRAINT "Document_uploadedById_fkey" FOREIGN KEY ("uploadedById") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "Document" ADD CONSTRAINT "Document_adoptionId_fkey" FOREIGN KEY ("adoptionId") REFERENCES "adoptions"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
127 changes: 71 additions & 56 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

generator client {
provider = "prisma-client-js"
}
Expand All @@ -22,6 +23,9 @@ enum PetSpecies {
OTHER
}




enum AdoptionStatus {
REQUESTED
PENDING
Expand All @@ -32,12 +36,13 @@ enum AdoptionStatus {
CANCELLED
}


enum CustodyStatus {
PENDING
ACTIVE
RETURNED
CANCELLED
VIOLATION
PENDING
}

enum CustodyType {
Expand All @@ -46,6 +51,8 @@ enum CustodyType {
SHELTER
}



enum EscrowStatus {
CREATED
FUNDED
Expand All @@ -54,6 +61,7 @@ enum EscrowStatus {
DISPUTED
}


enum EventEntityType {
USER
PET
Expand All @@ -62,6 +70,7 @@ enum EventEntityType {
ESCROW
}


enum EventType {
USER_REGISTERED
PET_REGISTERED
Expand All @@ -76,17 +85,11 @@ enum EventType {
TRUST_SCORE_UPDATED
}

enum PetGender {
MALE
FEMALE
}

enum PetSize {
SMALL
MEDIUM
LARGE
enum LogLevel {
INFO
WARN
ERROR
}

// ─── Models ──────────────────────────────────────────────

model User {
Expand All @@ -97,41 +100,41 @@ model User {
lastName String @map("last_name")
role UserRole @default(USER)

trustScore Float @default(50)
trustScore Float @default(50)

stellarPublicKey String? @unique @map("stellar_public_key")
avatarUrl String? @map("avatar_url")

createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")

petsOwned Pet[] @relation("PetOwner")
petsOwned Pet[] @relation("PetOwner")

adoptionsAsAdopter Adoption[] @relation("Adopter")
adoptionsAsOwner Adoption[] @relation("Owner")

custodiesHeld Custody[] @relation("CustodyHolder")

events EventLog[] @relation("ActorEvents")
events EventLog[] @relation("ActorEvents")

documents Document[]

@@map("users")
}



model Pet {
id String @id @default(uuid())
id String @id @default(uuid())
name String
species PetSpecies
breed String?
age Int?
description String?
imageUrl String? @map("image_url")
imageUrl String? @map("image_url")

gender PetGender? // Optional gender field
size PetSize? // Optional size field

currentOwnerId String? @map("current_owner_id")
currentOwner User? @relation("PetOwner", fields: [currentOwnerId], references: [id])
currentOwnerId String? @map("current_owner_id")
currentOwner User? @relation("PetOwner", fields: [currentOwnerId], references: [id])

createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
Expand All @@ -144,6 +147,7 @@ model Pet {
@@map("pets")
}


model Adoption {
id String @id @default(uuid())
status AdoptionStatus @default(REQUESTED)
Expand All @@ -158,27 +162,29 @@ model Adoption {
ownerId String @map("owner_id")
owner User @relation("Owner", fields: [ownerId], references: [id])

escrowId String? @unique @map("escrow_id")
escrowId String? @unique @map("escrow_id")
escrow Escrow? @relation(fields: [escrowId], references: [id])

createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")

documents Document[]
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")

@@index([status])
@@index([adopterId])
@@index([ownerId])
@@map("adoptions")
}



model Custody {
id String @id @default(uuid())
status CustodyStatus @default(ACTIVE)
type CustodyType
id String @id @default(uuid())
status CustodyStatus @default(ACTIVE)
type CustodyType

depositAmount Decimal? @db.Decimal(12, 2)

startDate DateTime @map("start_date")
startDate DateTime @map("start_date")
endDate DateTime?

petId String @map("pet_id")
Expand All @@ -198,20 +204,21 @@ model Custody {
@@map("custodies")
}


model Escrow {
id String @id @default(uuid())

stellarPublicKey String @unique @map("stellar_public_key")
stellarPublicKey String @unique @map("stellar_public_key")
stellarSecretEncrypted String @map("stellar_secret_encrypted")

assetCode String @default("XLM") @map("asset_code")
assetCode String @default("XLM") @map("asset_code")
assetIssuer String? @map("asset_issuer")

amount Decimal @db.Decimal(12, 2)

fundingTxHash String? @map("funding_tx_hash")
releaseTxHash String? @map("release_tx_hash")
refundTxHash String? @map("refund_tx_hash")
fundingTxHash String? @map("funding_tx_hash")
releaseTxHash String? @map("release_tx_hash")
refundTxHash String? @map("refund_tx_hash")

requiredSignatures Int @default(2)

Expand All @@ -227,11 +234,23 @@ model Escrow {
@@map("escrows")
}


model AppLog {
id String @id @default(uuid())
level LogLevel
action String
message String
userId String?
metadata Json?
createdAt DateTime @default(now())
}


model EventLog {
id String @id @default(uuid())
entityType EventEntityType @map("entity_type")
entityId String @map("entity_id")
eventType EventType @map("event_type")
id String @id @default(uuid())
entityType EventEntityType @map("entity_type")
entityId String @map("entity_id")
eventType EventType @map("event_type")

actorId String? @map("actor_id")
actor User? @relation("ActorEvents", fields: [actorId], references: [id])
Expand All @@ -251,22 +270,18 @@ model EventLog {
}

model Document {
id String @id @default(uuid())
fileName String @map("file_name")
fileUrl String @map("file_url")
publicId String @map("public_id")
mimeType String @map("mime_type")
size Int

uploadedById String @map("uploaded_by_id")
uploadedBy User @relation(fields: [uploadedById], references: [id], onDelete: Cascade)

adoptionId String? @map("adoption_id")
adoption Adoption? @relation(fields: [adoptionId], references: [id], onDelete: Cascade)

createdAt DateTime @default(now()) @map("created_at")

@@index([uploadedById])
@@index([adoptionId])
@@map("documents")
id String @id @default(cuid())
fileName String
fileUrl String
publicId String
mimeType String
size Int
uploadedById String
adoptionId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt

uploadedBy User @relation(fields: [uploadedById], references: [id])
adoption Adoption @relation(fields: [adoptionId], references: [id])
}

24 changes: 16 additions & 8 deletions src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ import { EventsModule } from './events/events.module';
import { StellarModule } from './stellar/stellar.module';
import { AuthModule } from './auth/auth.module';
import { HealthModule } from './health/health.module';
import { CloudinaryModule } from './cloudinary/cloudinary.module';
import { UsersModule } from './users/users.module';
import { EmailModule } from './email/email.module';
import { LoggingModule } from './logging/logging.module';
import { HttpExceptionFilter } from './common/filters/http-exception.filter';
import { APP_INTERCEPTOR } from '@nestjs/core';
import { LoggingInterceptor } from './logging/logging.interceptor';

@Module({
imports: [
Expand All @@ -27,11 +28,18 @@ import { EmailModule } from './email/email.module';
StellarModule,
AuthModule,
HealthModule,
CloudinaryModule,
UsersModule,
EmailModule,
LoggingModule,

],

controllers: [AppController],
providers: [AppService],
providers: [
{
provide: APP_INTERCEPTOR,
useClass: LoggingInterceptor,
},
AppService, HttpExceptionFilter],

})
export class AppModule {}

export class AppModule { }
Loading