From 88f20bbb3b5c15d8c6c99c6c912d3c3c009c23e5 Mon Sep 17 00:00:00 2001 From: dimitar Date: Sat, 5 Apr 2025 01:39:25 +0200 Subject: [PATCH] seting up dev vs prod enviroment --- .cursorrules | 34 ------- .gitignore | 2 +- Dockerfile | 70 +++++++++++++ TODO.md | 13 +++ _.env | 35 ------- _docker-compose.yml | 97 ------------------- backend/.dockerignore | 4 +- backend/Dockerfile.dev | 33 +++++++ backend/__Dockerfile | 76 --------------- backend/docker-compose.dev.yml | 75 ++++++++++++++ backend/env.development | 34 +++++++ backend/package.json | 5 +- .../20250404211916_init/migration.sql | 5 + backend/prisma/migrations/migration_lock.toml | 2 +- backend/scripts/_init-db.sh | 9 ++ backend/scripts/init-db.sh | 29 ++++-- backend/scripts/init-dev.sh | 20 ++++ backend/scripts/start-dev.sh | 30 ++++++ backend/scripts/test-db.sh | 0 backend/scripts/wait-for-db.sh | 0 backend/src/auth/auth.controller.spec.ts | 21 ++-- backend/src/config/cors.config.ts | 6 +- backend/src/dto/create-user.dto.ts | 4 +- backend/src/main.ts | 8 +- backend/start-dev.sh | 11 +++ docker-compose.yaml | 47 +++++++++ docker-reset.md | 17 ++++ .../documentUpload/DocumentUpload.jsx | 2 +- .../documentUpload/{Users.jsx => Users.tsx} | 34 ++++++- frontend/src/services/api.js | 5 +- 30 files changed, 451 insertions(+), 277 deletions(-) delete mode 100644 .cursorrules create mode 100644 Dockerfile create mode 100644 TODO.md delete mode 100644 _.env delete mode 100644 _docker-compose.yml create mode 100644 backend/Dockerfile.dev delete mode 100644 backend/__Dockerfile create mode 100644 backend/docker-compose.dev.yml create mode 100644 backend/env.development create mode 100644 backend/prisma/migrations/20250404211916_init/migration.sql create mode 100755 backend/scripts/_init-db.sh mode change 100644 => 100755 backend/scripts/init-db.sh create mode 100755 backend/scripts/init-dev.sh create mode 100755 backend/scripts/start-dev.sh mode change 100644 => 100755 backend/scripts/test-db.sh mode change 100644 => 100755 backend/scripts/wait-for-db.sh create mode 100755 backend/start-dev.sh create mode 100644 docker-compose.yaml rename frontend/src/components/documentUpload/{Users.jsx => Users.tsx} (87%) diff --git a/.cursorrules b/.cursorrules deleted file mode 100644 index 37c6096..0000000 --- a/.cursorrules +++ /dev/null @@ -1,34 +0,0 @@ -You are a Senior full-stack Developer and an Expert in Nestjs, Prisma,ReactJS, JavaScript, TypeScript, HTML, CSS and modern UI/UX frameworks (e.g., TailwindCSS, Shadcn, Radix). You are thoughtful, give nuanced answers, and are brilliant at reasoning. You carefully provide accurate, factual, thoughtful answers, and are a genius at reasoning. - -- Follow the user’s requirements carefully & to the letter. -- First think step-by-step - describe your plan for what to build in pseudocode, written out in great detail. -- Confirm, then write code! -- Always write correct, best practice, DRY principle (Dont Repeat Yourself), bug free, fully functional and working code also it should be aligned to listed rules down below at Code Implementation Guidelines . -- Focus on easy and readability code, over being performant. -- Fully implement all requested functionality. -- Leave NO todo’s, placeholders or missing pieces. -- Ensure code is complete! Verify thoroughly finalised. -- Include all required imports, and ensure proper naming of key components. -- Be concise Minimize any other prose. -- If you think there might not be a correct answer, you say so. -- If you do not know the answer, say so, instead of guessing. - -### Coding Environment -The user asks questions about the following coding languages: -- ReactJS -- Nestjs -- Prisma -- JavaScript -- TypeScript -- TailwindCSS -- HTML -- CSS - -### Code Implementation Guidelines -Follow these rules when you write code: -- Use early returns whenever possible to make the code more readable. -- Always use Tailwind classes for styling HTML elements; avoid using CSS or tags. -- Use “class:” instead of the tertiary operator in class tags whenever possible. -- Use descriptive variable and function/const names. Also, event functions should be named with a “handle” prefix, like “handleClick” for onClick and “handleKeyDown” for onKeyDown. -- Implement accessibility features on elements. For example, a tag should have a tabindex=“0”, aria-label, on:click, and on:keydown, and similar attributes. -- Use consts instead of functions, for example, “const toggle = () =>”. Also, define a type if possible. \ No newline at end of file diff --git a/.gitignore b/.gitignore index 7c230fd..272b464 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,4 @@ frontend/.vite node_modules pestgres_data/ redis_data/ - +aisugestions.md diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..56b7e24 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,70 @@ + +# backend/Dockerfile +FROM node:18-alpine AS builder + +WORKDIR /app + +# Install necessary tools +RUN apk add --no-cache curl wget postgresql-client + +# Copy package files +COPY package*.json ./ + +# Install dependencies including dev dependencies for building +RUN npm install + +# Install NestJS CLI globally +RUN npm install -g @nestjs/cli + +# Copy prisma files +COPY prisma ./prisma/ + +# Generate Prisma client +RUN npx prisma generate + +# Copy source code +COPY . . + +# Build the application +RUN npm run build + +# Production stage +FROM node:18-alpine + +WORKDIR /app + +# Install necessary tools +RUN apk add --no-cache curl wget postgresql-client + +# Copy package files +COPY package*.json ./ + +# Install production dependencies only +RUN npm install --omit=dev + +# Copy prisma files and generate client +COPY prisma ./prisma/ +RUN npx prisma generate + +# Copy built application from builder stage +COPY --from=builder /app/dist ./dist + +# Create the start script +RUN printf '#!/bin/sh\n\ + until pg_isready -h postgres -p 5432 -U ${POSTGRES_USER} -d ${POSTGRES_DB}; do\n\ + echo "Waiting for postgres..."\n\ + sleep 2\n\ + done\n\ + \n\ + echo "PostgreSQL is ready!"\n\ + \n\ + npx prisma migrate deploy\n\ + node dist/main.js\n' > /app/start.sh + +# Make the script executable +RUN chmod +x /app/start.sh + +EXPOSE 3000 + +# Use shell form to ensure environment variables are expanded +CMD ["/bin/sh", "/app/start.sh"] diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..2bd1045 --- /dev/null +++ b/TODO.md @@ -0,0 +1,13 @@ +# Todo + +- [ ] on password reset page, link in the sent to user email is undefined; +- [ ] translate mail template in backend; +- [x] translate user dashboard; +- [ ] clean console logs; +- [ ] remove TUF logo; +- [ ] arrow down fix; +- [ ] use posthog for monitoring; + - [ ] comprehensive monitoring solution for the backend; + - [ ] add monitoring to the frontend; + - [ ] add monitoring to the database; + - [ ] diff --git a/_.env b/_.env deleted file mode 100644 index 0ffc5a0..0000000 --- a/_.env +++ /dev/null @@ -1,35 +0,0 @@ -# Environment variables declared in this file are automatically made available to Prisma. -# See the documentation for more detail: https://pris.ly/d/prisma-schema#accessing-environment-variables-from-the-schema - -# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB. -# See the documentation for all the connection string options: https://pris.ly/d/connection-strings - -DATABASE_URL="postgresql://root:irina76@localhost:5433/imk2?schema=public" -JWT_SECRET=some-secret -AWS_REGION=EU2 -AWS_ACCESS_KEY_ID=4d2f5655369a02100375e3247d7e1fe6 -AWS_SECRET_ACCESS_KEY=6d4723e14c0d799b89948c24dbe983e4 -AWS_S3_BUCKET_NAME=imk-data -AWS_ENDPOINT_URL=https://eu2.contabostorage.com - -#Email Configuration -# SMTP_HOST=smtp.gmail.com -# SMTP_PORT=587 -# SMTP_USER=taratur@gmail.com -# SMTP_PASS=dziy nccc svgg bovb -# EMAIL_FROM=taratur@gmail.com - -SMTP_HOST=imk.mk -SMTP_PORT=465 -SMTP_USER=mailer@imk.mk -SMTP_PASS=76Avtostoperski76 -SMTP_FROM=mailer@imk.mk -# FRONTEND_URL=https://imk.mk -EMAIL_FROM=mailer@yandex.com - -ADMIN_EMAIL=taratur@gmail.com - -# default app ADMIN -DEFAULT_ADMIN_EMAIL=taratur@gmail.com -DEFAULT_ADMIN_PASSWORD=irina7654321 -DEFAULT_ADMIN_NAME=admin diff --git a/_docker-compose.yml b/_docker-compose.yml deleted file mode 100644 index 0555ce8..0000000 --- a/_docker-compose.yml +++ /dev/null @@ -1,97 +0,0 @@ -version: "3.8" - -services: - backend: - logging: - driver: "json-file" - options: - max-size: "10m" - max-file: "3" - container_name: imk-backend - build: - context: ./backend - dockerfile: Dockerfile - ports: - - "3000:3000" - environment: - - NODE_ENV=production - - PORT=3000 - - DATABASE_URL=postgresql://postgres:postgres@imk-postgres:5432/postgres?schema=public - - FRONTEND_URL=https://www.placebo.mk - env_file: - - .env - deploy: - resources: - limits: - memory: 2G - reservations: - memory: 512M - depends_on: - postgres: - condition: service_healthy - redis: - condition: service_started - networks: - - app_network - healthcheck: - test: - [ - "CMD", - "wget", - "-q", - "--spider", - "http://localhost:3000/health || exit 1", - ] - interval: 30s - timeout: 10s - retries: 3 - start_period: 15s - restart: always - postgres: - container_name: imk-postgres - image: postgres:14-alpine - environment: - POSTGRES_USER: postgres - POSTGRES_PASSWORD: postgres - POSTGRES_DB: postgres - PGDATA: /var/lib/postgresql/data/pgdata - ports: - - "5432:5432" - volumes: - - postgres_data:/var/lib/postgresql/data - healthcheck: - test: ["CMD-SHELL", "pg_isready -U postgres"] - interval: 10s - timeout: 5s - retries: 5 - networks: - - app_network - restart: always - - redis: - container_name: imk-redis - image: redis:alpine - command: redis-server --appendonly yes - ports: - - "6379:6379" - volumes: - - redis_data:/data - networks: - - app_network - healthcheck: - test: ["CMD", "redis-cli", "ping"] - interval: 10s - timeout: 5s - retries: 3 - restart: always - -networks: - app_network: - driver: bridge - name: app_network - -volumes: - postgres_data: - name: imk_postgres_data - redis_data: - name: imk_redis_data diff --git a/backend/.dockerignore b/backend/.dockerignore index b5abc38..df1944d 100644 --- a/backend/.dockerignore +++ b/backend/.dockerignore @@ -1,6 +1,6 @@ # backend/.dockerignore node_modules dist -.env -.env.* +#.env +#.env.* *.log diff --git a/backend/Dockerfile.dev b/backend/Dockerfile.dev new file mode 100644 index 0000000..db2d9d9 --- /dev/null +++ b/backend/Dockerfile.dev @@ -0,0 +1,33 @@ + +FROM node:18-alpine + +WORKDIR /app + +# Install necessary tools +RUN apk add --no-cache \ + curl \ + wget \ + postgresql-client \ + bash + +# Install global packages +RUN npm install -g @nestjs/cli + + +# Copy scripts +COPY scripts/start-dev.sh /app/scripts/ +RUN chmod +x /app/scripts/start-dev.sh + +COPY package.json package-lock.json ./ +RUN npm install + +# Copy prisma files +COPY prisma ./prisma/ + +# Generate Prisma client +RUN npx prisma generate + +EXPOSE 3000 9229 + +# Use the initialization script as the entry point +CMD ["/app/scripts/start-dev.sh"] diff --git a/backend/__Dockerfile b/backend/__Dockerfile deleted file mode 100644 index 5c9fa43..0000000 --- a/backend/__Dockerfile +++ /dev/null @@ -1,76 +0,0 @@ -# backend/Dockerfile -FROM node:18-alpine - -# Add build arguments -ARG NODE_ENV -ARG API_URL -ARG CORS_ORIGIN -ARG DATABASE_URL -ARG POSTGRES_USER -ARG POSTGRES_PASSWORD -ARG POSTGRES_DB -ARG JWT_SECRET -ARG SMTP_HOST -ARG SMTP_PORT -ARG SMTP_USER -ARG SMTP_PASS -ARG EMAIL_FROM -ARG DEFAULT_ADMIN_EMAIL -ARG DEFAULT_ADMIN_PASSWORD -ARG DEFAULT_ADMIN_NAME - -# Set environment variables from build args -ENV NODE_ENV=${NODE_ENV} -ENV API_URL=${API_URL} -ENV CORS_ORIGIN=${CORS_ORIGIN} -ENV DATABASE_URL=${DATABASE_URL} -ENV POSTGRES_USER=${POSTGRES_USER} -ENV POSTGRES_PASSWORD=${POSTGRES_PASSWORD} -ENV POSTGRES_DB=${POSTGRES_DB} -ENV JWT_SECRET=${JWT_SECRET} -ENV SMTP_HOST=${SMTP_HOST} -ENV SMTP_PORT=${SMTP_PORT} -ENV SMTP_USER=${SMTP_USER} -ENV SMTP_PASS=${SMTP_PASS} -ENV EMAIL_FROM=${EMAIL_FROM} -ENV DEFAULT_ADMIN_EMAIL=${DEFAULT_ADMIN_EMAIL} -ENV DEFAULT_ADMIN_PASSWORD=${DEFAULT_ADMIN_PASSWORD} -ENV DEFAULT_ADMIN_NAME=${DEFAULT_ADMIN_NAME} - -WORKDIR /usr/src/app - -# Install necessary tools -RUN apk add --no-cache curl wget postgresql-client - -# Copy package files -COPY package*.json ./ -COPY prisma ./prisma/ -# Install dependencies -RUN npm install --omit-dev - -# Copy prisma schema -# COPY prisma ./prisma/ - -# Generate Prisma client -RUN npx prisma generate -# RUN npx prisma migrate deploy - -# Copy source code -COPY . . - -# Build the application -RUN npm run build - -# Expose port -EXPOSE 3000 - -# ADD https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh /wait-for-it.sh -# RUN chmod +x /wait-for-it.sh -# Add healthcheck -HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ - CMD wget -q --spider http://localhost:3000/health || exit 1 - -# Start the application -# CMD ["npm", "run", "start:prod"] - -CMD ["node", "dist/main.js"] diff --git a/backend/docker-compose.dev.yml b/backend/docker-compose.dev.yml new file mode 100644 index 0000000..a26d267 --- /dev/null +++ b/backend/docker-compose.dev.yml @@ -0,0 +1,75 @@ +version: "3.8" + +services: + postgres: + container_name: imk-postgres-dev + image: postgres:14-alpine + environment: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: imk_db + volumes: + - postgres_data_dev:/var/lib/postgresql/data + ports: + - "5432:5432" + networks: + - imk_network_dev + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"] + interval: 10s + timeout: 5s + retries: 5 + restart: unless-stopped + + backend: + container_name: imk-backend-dev + build: + context: . + dockerfile: Dockerfile.dev + volumes: + - ./src:/app/src:delegated + - ./prisma:/app/prisma:delegated + - ./package.json:/app/package.json:delegated + - ./package-lock.json:/app/package-lock.json:delegated + - ./tsconfig.json:/app/tsconfig.json:delegated + - ./nest-cli.json:/app/nest-cli.json:delegated + - node_modules:/app/node_modules + environment: + - NODE_ENV=production + - DATABASE_URL=postgresql://postgres:postgres@postgres:5432/imk_db?schema=public + - POSTGRES_USER=postgres + - POSTGRES_PASSWORD=postgres + - POSTGRES_DB=imk_db + - JWT_SECRET=${JWT_SECRET} + - AWS_REGION=${AWS_REGION} + - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} + - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} + - AWS_S3_BUCKET_NAME=${AWS_S3_BUCKET_NAME} + - AWS_ENDPOINT_URL=${AWS_ENDPOINT_URL} + - SMTP_HOST=${SMTP_HOST} + - SMTP_PORT=${SMTP_PORT} + - SMTP_USER=${SMTP_USER} + - SMTP_PASS=${SMTP_PASS} + - EMAIL_FROM=${EMAIL_FROM} + - FRONTEND_URL=${FRONTEND_URL} + ports: + - "3000:3000" + - "9229:9229" + depends_on: + postgres: + condition: service_healthy + networks: + - imk_network_dev + restart: unless-stopped + command: ["/app/scripts/start-dev.sh"] + tty: true + stdin_open: true + # command: sh -c "rm -rf /app/dist && npm run start:dev" + +networks: + imk_network_dev: + driver: bridge + +volumes: + postgres_data_dev: + node_modules: diff --git a/backend/env.development b/backend/env.development new file mode 100644 index 0000000..126b689 --- /dev/null +++ b/backend/env.development @@ -0,0 +1,34 @@ +# imk_copy/backend/.env.development +# Database +POSTGRES_USER=postgres +POSTGRES_PASSWORD=postgres +POSTGRES_DB=imk_dev +DATABASE_URL=postgresql://postgres:postgres@postgres:5432/imk_dev?schema=public + +# JWT +JWT_SECRET=your_development_jwt_secret + +# AWS/S3 +AWS_REGION=your-region +AWS_ACCESS_KEY_ID=your-access-key +AWS_SECRET_ACCESS_KEY=your-secret-key +AWS_S3_BUCKET_NAME=your-bucket-name +AWS_ENDPOINT_URL=your-endpoint-url + +# SMTP +SMTP_HOST=smtp.example.com +SMTP_PORT=587 +SMTP_USER=your-smtp-user +SMTP_PASS=your-smtp-password +EMAIL_FROM=noreply@example.com + +# Frontend +FRONTEND_URL=http://localhost:5173 + +# Admin defaults +DEFAULT_ADMIN_EMAIL=admin@example.com +DEFAULT_ADMIN_PASSWORD=admin123 +DEFAULT_ADMIN_NAME=System Admin + +# Node +NODE_ENV=development diff --git a/backend/package.json b/backend/package.json index ea55759..28b4e61 100644 --- a/backend/package.json +++ b/backend/package.json @@ -23,7 +23,10 @@ "test:e2e": "jest --config ./test/jest-e2e.json", "prisma:generate": "prisma generate", "prisma:migrate:dev": "prisma migrate dev", - "prisma:migrate": "prisma migrate deploy" + "prisma:migrate": "prisma migrate deploy", + "docker:dev": "docker-compose -f docker-compose.dev.yml up", + "docker:dev:build": "docker-compose -f docker-compose.dev.yml up --build", + "docker:dev:down": "docker-compose -f docker-compose.dev.yml down -v" }, "dependencies": { "@aws-sdk/client-s3": "^3.679.0", diff --git a/backend/prisma/migrations/20250404211916_init/migration.sql b/backend/prisma/migrations/20250404211916_init/migration.sql new file mode 100644 index 0000000..19f2cb1 --- /dev/null +++ b/backend/prisma/migrations/20250404211916_init/migration.sql @@ -0,0 +1,5 @@ +-- AlterTable +ALTER TABLE "_SharedDocuments" ADD CONSTRAINT "_SharedDocuments_AB_pkey" PRIMARY KEY ("A", "B"); + +-- DropIndex +DROP INDEX "_SharedDocuments_AB_unique"; diff --git a/backend/prisma/migrations/migration_lock.toml b/backend/prisma/migrations/migration_lock.toml index fbffa92..648c57f 100644 --- a/backend/prisma/migrations/migration_lock.toml +++ b/backend/prisma/migrations/migration_lock.toml @@ -1,3 +1,3 @@ # Please do not edit this file manually -# It should be added in your version-control system (i.e. Git) +# It should be added in your version-control system (e.g., Git) provider = "postgresql" \ No newline at end of file diff --git a/backend/scripts/_init-db.sh b/backend/scripts/_init-db.sh new file mode 100755 index 0000000..7e0b8a7 --- /dev/null +++ b/backend/scripts/_init-db.sh @@ -0,0 +1,9 @@ +#!/bin/bash +# backend/scripts/init-db.sh + +set -e + +psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL + CREATE DATABASE $POSTGRES_DB; + GRANT ALL PRIVILEGES ON DATABASE $POSTGRES_DB TO $POSTGRES_USER; +EOSQL diff --git a/backend/scripts/init-db.sh b/backend/scripts/init-db.sh old mode 100644 new mode 100755 index 7e0b8a7..a13de12 --- a/backend/scripts/init-db.sh +++ b/backend/scripts/init-db.sh @@ -1,9 +1,24 @@ -#!/bin/bash -# backend/scripts/init-db.sh +#!/bin/sh -set -e +echo "Starting development initialization..." -psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL - CREATE DATABASE $POSTGRES_DB; - GRANT ALL PRIVILEGES ON DATABASE $POSTGRES_DB TO $POSTGRES_USER; -EOSQL +# Wait for database to be ready +echo "Waiting for database to be ready..." +until PGPASSWORD=$POSTGRES_PASSWORD psql -h postgres -U $POSTGRES_USER -d postgres -c '\q'; do + echo "Postgres is unavailable - sleeping" + sleep 1 +done + +echo "Database is ready!" + +# Run Prisma migrations +echo "Running Prisma migrations..." +npx prisma migrate dev + +# Generate Prisma Client (just in case) +echo "Generating Prisma Client..." +npx prisma generate + +# Start the application +echo "Starting application in development mode..." +npm run start:dev diff --git a/backend/scripts/init-dev.sh b/backend/scripts/init-dev.sh new file mode 100755 index 0000000..4f41e06 --- /dev/null +++ b/backend/scripts/init-dev.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +echo "Starting development server..." + +# Wait for database to be ready +echo "Waiting for database to be ready..." +until PGPASSWORD=$POSTGRES_PASSWORD psql -h postgres -U $POSTGRES_USER -d postgres -c '\q'; do + echo "Postgres is unavailable - sleeping" + sleep 1 +done + +echo "Database is ready!" + +# Run Prisma migrations +echo "Running Prisma migrations..." +npx prisma migrate dev --name init + +# Start the application +echo "Starting application..." +npm run start:dev diff --git a/backend/scripts/start-dev.sh b/backend/scripts/start-dev.sh new file mode 100755 index 0000000..15d851f --- /dev/null +++ b/backend/scripts/start-dev.sh @@ -0,0 +1,30 @@ +#!/bin/sh + +echo "Starting development initialization..." + +# Wait for database to be ready +echo "Waiting for database to be ready..." +until PGPASSWORD=$POSTGRES_PASSWORD psql -h postgres -U $POSTGRES_USER -d postgres -c '\q'; do + echo "Postgres is unavailable - sleeping" + sleep 1 +done + +echo "Database is ready!" + +# Run Prisma migrations +echo "Running Prisma migrations..." +npx prisma migrate dev --name init + +# Generate Prisma Client (just in case) +echo "Generating Prisma Client..." +npx prisma generate + +# Clean dist directory if it exists +if [ -d "dist" ]; then + echo "Cleaning dist directory..." + rm -rf dist +fi + +# Start the application in development mode +echo "Starting application in development mode..." +exec npm run start:dev diff --git a/backend/scripts/test-db.sh b/backend/scripts/test-db.sh old mode 100644 new mode 100755 diff --git a/backend/scripts/wait-for-db.sh b/backend/scripts/wait-for-db.sh old mode 100644 new mode 100755 diff --git a/backend/src/auth/auth.controller.spec.ts b/backend/src/auth/auth.controller.spec.ts index 71e2e1e..d34dac3 100644 --- a/backend/src/auth/auth.controller.spec.ts +++ b/backend/src/auth/auth.controller.spec.ts @@ -1,9 +1,9 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { AuthController } from './auth.controller'; -import { AuthService } from './auth.service'; -import { CreateUserDto } from '../dto/create-user.dto'; +import { Test, TestingModule } from "@nestjs/testing"; +import { AuthController } from "./auth.controller"; +import { AuthService } from "./auth.service"; +import { CreateUserDto } from "../dto/create-user.dto"; -describe('AuthController', () => { +describe("AuthController", () => { let controller: AuthController; let authService: AuthService; @@ -24,12 +24,13 @@ describe('AuthController', () => { authService = module.get(AuthService); }); - describe('register', () => { - it('should call authService.createUser with CreateUserDto', async () => { + describe("register", () => { + it("should call authService.createUser with CreateUserDto", async () => { const createUserDto: CreateUserDto = { - name: 'testuser', - password: 'password123', - email: 'test@example.com', + name: "testuser", + password: "password123", + email: "test@example.com", + isAdmin: false, }; await controller.register(createUserDto); diff --git a/backend/src/config/cors.config.ts b/backend/src/config/cors.config.ts index f25c638..3778439 100644 --- a/backend/src/config/cors.config.ts +++ b/backend/src/config/cors.config.ts @@ -4,9 +4,9 @@ export const corsConfig = { "https://www.placebo.mk", "https://placebo.mk", "https://imkapi.oblak.solutions", - "https://eu-assets.i.posthog.com", - "https://app.posthog.com", - "https://eu.posthog.com", + // "https://eu-assets.i.posthog.com", + // "https://app.posthog.com", + // "https://eu.posthog.com", ], methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"], credentials: true, diff --git a/backend/src/dto/create-user.dto.ts b/backend/src/dto/create-user.dto.ts index 7edbf87..90467b9 100644 --- a/backend/src/dto/create-user.dto.ts +++ b/backend/src/dto/create-user.dto.ts @@ -1,5 +1,5 @@ -import { IsString, IsEmail, MinLength, IsBoolean } from 'class-validator'; -import { Transform } from 'class-transformer'; +import { IsString, IsEmail, MinLength, IsBoolean } from "class-validator"; +import { Transform } from "class-transformer"; export class CreateUserDto { @IsString() diff --git a/backend/src/main.ts b/backend/src/main.ts index 042d3a8..da87609 100644 --- a/backend/src/main.ts +++ b/backend/src/main.ts @@ -25,6 +25,12 @@ async function bootstrap() { whitelist: true, }), ); + app.useGlobalPipes( + new ValidationPipe({ + transform: true, + whitelist: true, + }), + ); app.use( helmet({ @@ -69,7 +75,7 @@ async function bootstrap() { logger.log(`Attempting to start server on port ${port}...`); await app.listen(port, "0.0.0.0"); - logger.log(`Application is running on: ${await app.getUrl()}`); + logger.log(`Application is Running on: ${await app.getUrl()}`); } catch (error) { logger.error("Failed to start application:", error); process.exit(1); diff --git a/backend/start-dev.sh b/backend/start-dev.sh new file mode 100755 index 0000000..c95bf60 --- /dev/null +++ b/backend/start-dev.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +until pg_isready -h postgres -p 5432 -U ${POSTGRES_USER} -d ${POSTGRES_DB}; do + echo "Waiting for postgres..." + sleep 2 +done + +echo "PostgreSQL is ready!" + +npx prisma migrate dev --name init +npm run start:dev diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..f2bb70e --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,47 @@ +version: "3.8" + +services: + backend: + container_name: imk-backend + build: + context: . + dockerfile: Dockerfile + environment: + - NODE_ENV=production + - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}?schema=public + - POSTGRES_USER=postgres + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + - POSTGRES_DB=${POSTGRES_DB} + ports: + - "3000:3000" + depends_on: + postgres: + condition: service_healthy + networks: + - imk_network + + postgres: + container_name: imk-postgres + image: postgres:14-alpine + environment: + - POSTGRES_USER=postgres + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + - POSTGRES_DB=${POSTGRES_DB} + volumes: + - postgres_data:/var/lib/postgresql/data + ports: + - "5433:5432" + networks: + - imk_network + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres -d ${POSTGRES_DB}"] + interval: 10s + timeout: 5s + retries: 5 + +networks: + imk_network: + driver: bridge + +volumes: + postgres_data: diff --git a/docker-reset.md b/docker-reset.md index 2dd15b5..7e42cd6 100644 --- a/docker-reset.md +++ b/docker-reset.md @@ -12,3 +12,20 @@ docker rmi -f $(docker images -q) # Start fresh docker-compose up --build + + + +# reset development +# Stop containers and remove volumes +docker-compose -f docker-compose.dev.yml down -v + +# Remove existing images +docker rmi $(docker images -q backend_backend) + +# Rebuild and start +docker-compose -f docker-compose.dev.yml up --build + + + + +docker-compose -f docker-compose.dev.yml up --build --force-recreate diff --git a/frontend/src/components/documentUpload/DocumentUpload.jsx b/frontend/src/components/documentUpload/DocumentUpload.jsx index d89b7b9..70da531 100644 --- a/frontend/src/components/documentUpload/DocumentUpload.jsx +++ b/frontend/src/components/documentUpload/DocumentUpload.jsx @@ -7,7 +7,7 @@ import { Card } from "../UI/Card"; function DocumentUpload() { const [file, setFile] = useState(null); const [title, setTitle] = useState(""); - const [selectedUserId, setSelectedUserId] = useState(""); // Changed from array to single value + const [selectedUserId, setSelectedUserId] = useState(""); const [availableUsers, setAvailableUsers] = useState([]); const [status, setStatus] = useState("idle"); const [errorMessage, setErrorMessage] = useState(""); diff --git a/frontend/src/components/documentUpload/Users.jsx b/frontend/src/components/documentUpload/Users.tsx similarity index 87% rename from frontend/src/components/documentUpload/Users.jsx rename to frontend/src/components/documentUpload/Users.tsx index f52a52e..74fea76 100644 --- a/frontend/src/components/documentUpload/Users.jsx +++ b/frontend/src/components/documentUpload/Users.tsx @@ -1,13 +1,38 @@ +import react from "react"; import { useState } from "react"; +import { + getAllUsers, + getUserInfo, + createUser, + resetUserPassword, +} from "../../services/api"; +import { useNavigate } from "react-router-dom"; + +import { FiKey, FiUserPlus } from "react-icons/fi"; function Users() { - const [newUser, setNewUser] = useState({}); + const navigate = useNavigate(); + const [users, setUsers] = useState([]); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(""); + const [isAdmin, setIsAdmin] = useState(false); + const [resetPasswordModal, setResetPasswordModal] = useState({ + isOpen: false, + userId: null, + userName: "", + newPassword: "", + }); + const [newUser, setNewUser] = useState({ + name: "", + email: "", + password: "", + isAdmin: false, + }); return ( - <> +

Креирај корисник

@@ -131,6 +156,7 @@ function Users() {
- +
); } +export default Users; diff --git a/frontend/src/services/api.js b/frontend/src/services/api.js index 9d26dc3..68a704d 100644 --- a/frontend/src/services/api.js +++ b/frontend/src/services/api.js @@ -1,8 +1,9 @@ import axios from "axios"; -const API_URL = "https://imkapi.oblak.solutions:3000"; +// const API_URL = "https://imkapi.oblak.solutions:3000"; +const API_URL = "https://localhost:3000"; const api = axios.create({ - baseURL: "https://imkapi.oblak.solutions", + baseURL: API_URL, withCredentials: true, headers: { Accept: "application/json, text/plain, */*",