wiki:BuildInstructions

BuildInstructions

Содржина

  1. Опис на развојната околина
    1. Архитектура на проектот
    2. Задолжителен софтвер
    3. Надворешни сервиси и клучеви
  2. Инструкции за градење
    1. Преземање на изворниот код
    2. Подготовка на базата на податоци
    3. Конфигурација на backend
    4. Google Service Account
    5. Google OAuth2 redirect URI
    6. Компајлирање и стартување на backend
    7. Конфигурација и градење на frontend
    8. Цел редослед на пуштање
    9. Продукциско градење и пуштање
    10. Чести проблеми при градење
  3. Инструкции за тестирање
    1. Каде се пушта апликацијата
    2. Кориснички имиња и лозинки
    3. Мини-водич низ главните елементи
    4. Автоматски тестови

Оваа страница ја опишува развојната околина, начинот на градење и начинот на тестирање на проектот Shifter Web App (гранка main).


Опис на развојната околина

Архитектура на проектот

Shifter е веб-апликација составена од два независни дела кои се пуштаат одделно:

Компонента Технологија Директориум Порта (локално)
Backend (REST API) Java 17, Spring Boot 3.5.3, Spring Security (JWT + OAuth2), Spring Data JPA / Hibernate, Maven backend/ 8080
Frontend (SPA) React 19, TypeScript 5.8, Vite 6, Tailwind CSS 4, react-i18next frontend/ 5173
База на податоци PostgreSQL 5432

Задолжителен софтвер

Софтвер Верзија Зошто е потребен Проверка
Git било која Преземање на изворниот код git --version
JDK (Java Development Kit) 17 (Temurin / OpenJDK / Oracle) Компајлирање и извршување на backend-от; pom.xml е фиксиран на java.version=17 java -version
Maven не се инсталира одделно Проектот има Maven Wrapper (mvnw / mvnw.cmd) кој сам ја презема Maven 3.9.9 ./mvnw -v
PostgreSQL 14 или понова (драјвер 42.7.7) База на податоци на апликацијата psql --version
Node.js 20.19+ или 22.12+ (LTS) Градење и пуштање на frontend-от (Vite 6 / React 19) node -v
npm 10 или понова (доаѓа со Node.js) Инсталација на frontend зависности npm -v
Веб-прелистувач Chrome, Firefox, Edge или Safari (актуелна верзија) Тестирање на апликацијата

Надворешни сервиси и клучеви

Backend-от се поврзува на неколку надворешни сервиси. Клучевите се внесуваат преку променливи на околината, види Конфигурација на backend.

Сервис За што служи Потребен за подигање на апликацијата?
PostgreSQL Главна база на податоци Да – без неа апликацијата не се подига
ZeptoMail (Zoho) Емаил за верификација, потврди за состаноци, контакт-форма Да – клучот мора да постои; мора да е и валиден за регистрација преку емаил
Google Cloud – OAuth 2.0 Client ID Најава со Google („Sign in with Google“) Да – вредностите мора да постојат
Google Cloud – Service Account + Calendar ID Читање слободни термини од календарот на експертот Да – види Google Service Account, инаку подигањето паѓа со грешка
Amazon S3 Прикачување и чување фајлови (слики, материјали) Да – вредностите мора да постојат
Zoom (Server-to-Server OAuth App) Автоматско креирање Zoom состанок при закажување консултација Да – вредностите мора да постојат

ВАЖНО: повеќето променливи во application.properties немаат стандардна вредност (пр. ${AWS_S3_REGION}, ${JWT_CONFIG_SECRET}, ${ZOOM_CLIENT_ID}). Ако некоја од нив недостасува, Spring нема да успее да ги создаде бавовите и апликацијата воопшто нема да се стартува. За локален развој е сосема во ред да се стават лажни (dummy) вредности за сервисите што нема да ги тестирате – важно е клучевите да постојат.


Инструкции за градење

Преземање на изворниот код

git clone <URL-на-репозиториумот> Shifter-Web-App
cd Shifter-Web-App
git checkout main

Структура на проектот:

Shifter-Web-App/
├── backend/        # Spring Boot апликација (Maven)
├── frontend/       # React + Vite апликација (npm)
└── modeling/       # модели и дијаграми

Подготовка на базата на податоци

Инсталирајте и стартувајте PostgreSQL, па креирајте корисник и празна база:

CREATE USER shifter WITH PASSWORD 'shifter';
CREATE DATABASE shifter OWNER shifter;
GRANT ALL PRIVILEGES ON DATABASE shifter TO shifter;

Не е потребно рачно да се извршуваат SQL скрипти. На гранката main вредноста е spring.jpa.hibernate.ddl-auto=update, што значи дека Hibernate автоматски ги креира и ажурира сите табели при првото стартување на backend-от. Во продукцискиот профил prod вредноста е validate, т.е. шемата мора веќе да постои.

Конфигурација на backend

Backend-от при стартување чита .env датотека (библиотека dotenv-java). Датотеката не е во Git (наведена е во .gitignore), па мора рачно да се создаде на патека backend/.env:

# ===== Основно =====
SPRING_PROFILES_ACTIVE=default
PORT=8080
BACKEND_URL=http://localhost:8080
FRONTEND_URL=http://localhost:5173
ALLOWED_ORIGINS=http://localhost:5173

# ===== База на податоци =====
SPRING_DATASOURCE_URL=jdbc:postgresql://localhost:5432/shifter
SPRING_DATASOURCE_USERNAME=shifter
SPRING_DATASOURCE_PASSWORD=shifter
DDL_AUTO=update
SHOW_SQL=true

# ===== JWT (мин. 32 знаци, HS256) =====
JWT_CONFIG_SECRET=promeni-go-ovoj-taen-kluc-min-32-znaci!!
JWT_EXPIRATION=86400000
JWT_REFRESH_EXPIRATION=604800000
COOKIE_SECURE=false
COOKIE_SAME_SITE=Lax

# ===== Amazon S3 =====
AWS_S3_REGION=eu-central-1
AWS_S3_BUCKET_NAME=shifter-bucket
AWS_S3_ACCESS_KEY=xxxxxxxxxxxx
AWS_S3_SECRET_KEY=xxxxxxxxxxxx

# ===== Емаил (ZeptoMail) =====
ZEPTOMAIL_API_KEY=xxxxxxxxxxxx

# ===== Google OAuth2 =====
GOOGLE_CLIENT_ID=xxxxxxxxxxxx.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=xxxxxxxxxxxx

# ===== Google Calendar =====
GOOGLE_EXPERT_CALENDAR_ID=expert@shift-er.com
# алтернатива на service-account.json (Base64 од JSON фајлот):
# GOOGLE_CALENDAR_SERVICE_ACCOUNT_JSON_BASE64=xxxxxxxxxxxx

# ===== Zoom (Server-to-Server OAuth) =====
ZOOM_ACCOUNT_ID=xxxxxxxxxxxx
ZOOM_CLIENT_ID=xxxxxxxxxxxx
ZOOM_CLIENT_SECRET=xxxxxxxxxxxx

# ===== Логирање =====
LOG_LEVEL=INFO
APP_LOG_LEVEL=DEBUG

Google Service Account

Класата GoogleCalendarService се иницијализира при подигање на апликацијата. Ако не најде credentials, целата апликација паѓа со GoogleCalendarException: Service account JSON not found in classpath or environment.

Затоа мора да обезбедите еден од следниве два начина:

  • Поставете ја JSON-датотеката на Service Account-от на патека backend/src/main/resources/service-account.json (датотеката е во .gitignore и не се комитира).
  • или поставете ја променливата GOOGLE_CALENDAR_SERVICE_ACCOUNT_JSON_BASE64 со Base64-кодирана содржина на истата датотека:
base64 -i service-account.json | tr -d '\n'

Service Account-от треба да има пристап (Google Calendar API scope https://www.googleapis.com/auth/calendar) до календарот наведен во GOOGLE_EXPERT_CALENDAR_ID.

Google OAuth2 redirect URI

Во Google Cloud Console, во OAuth 2.0 Client ID, додајте го овој Authorized redirect URI:

http://localhost:8080/login/oauth2/code/google

Компајлирање и стартување на backend

Сите команди се извршуваат од директориумот backend/.

cd backend

# Компајлирање и градење (Linux / macOS)
./mvnw clean package -DskipTests

# Компајлирање и градење (Windows)
mvnw.cmd clean package -DskipTests

Резултат: извршна JAR-датотека backend/target/shifter.jar.

# Стартување во развоен режим
./mvnw spring-boot:run

# или стартување на изградената JAR-датотека
java -jar target/shifter.jar

Проверка дека backend-от работи:

curl http://localhost:8080/actuator/health
# очекуван одговор: {"status":"UP"}

Конфигурација и градење на frontend

Сите команди се извршуваат од директориумот frontend/.

Прво креирајте frontend/.env – frontend-от бара една променлива:

VITE_BACKEND_URL=http://localhost:8080

Потоа:

cd frontend
npm install        # инсталација на зависностите
npm run dev        # развоен режим → http://localhost:5173

npm run build      # TypeScript проверка + Vite build → frontend/dist/
npm run preview    # локален преглед на изградената верзија
npm run lint       # ESLint проверка

Содржината од frontend/dist/ се качува на статички хостинг; проектот содржи vercel.json со SPA rewrite правило за Vercel.

Цел редослед на пуштање

# 1. Стартувај PostgreSQL и создај база `shifter`

# 2. Backend
cd backend
# создај .env и service-account.json
./mvnw spring-boot:run
# → http://localhost:8080

# 3. Frontend (во нов терминал)
cd frontend
# создај .env со VITE_BACKEND_URL
npm install
npm run dev
# → http://localhost:5173

Продукциско градење и пуштање

  • Backend: поставете SPRING_PROFILES_ACTIVE=prod. Профилот prod автоматски вклучува spring.jpa.hibernate.ddl-auto=validate (шемата мора да постои однапред), cookie.secure=true и cookie.same-site=Strict (задолжителен HTTPS), намалено логирање и сокриени stack trace-ови.
  • Поставете ги BACKEND_URL, FRONTEND_URL и ALLOWED_ORIGINS на вистинските домени; ALLOWED_ORIGINS прифаќа повеќе вредности одделени со запирка.
  • Додајте го продукцискиот redirect URI во Google Cloud Console: https://<backend-domen>/login/oauth2/code/google.
  • Frontend: npm run build и качете го frontend/dist/; поставете VITE_BACKEND_URL на продукцискиот backend домен.

Чести проблеми при градење

Проблем Причина Решение
Could not resolve placeholder 'AWS_S3_REGION' (или слична променлива) Недостасува променлива во .env Додајте ја во backend/.env; за нетестирани сервиси ставете dummy вредност
GoogleCalendarException: Service account JSON not found Недостасува service-account.json Види Google Service Account
Connection refused кон PostgreSQL Базата не работи или е погрешен URL Проверете дали PostgreSQL е стартуван и дали SPRING_DATASOURCE_URL е точен
CORS грешка во конзолата на прелистувачот ALLOWED_ORIGINS не ја содржи адресата на frontend-от Додајте http://localhost:5173 во ALLOWED_ORIGINS
Мрежни грешки во frontend-от / празни податоци Недостасува frontend/.env Создајте .env со VITE_BACKEND_URL=http://localhost:8080 и рестартирајте npm run dev
WeakKeyException при најава JWT_CONFIG_SECRET е пократок од 32 знаци Поставете подолг таен клуч
Грешки „cannot find symbol“ за getter/setter методи во IDE Исклучено annotation processing (Lombok/MapStruct) Вклучете Enable annotation processing во IDE-то
Vite не се подига Стара верзија на Node.js Инсталирајте Node.js 20.19+ или 22.12+

Инструкции за тестирање

Shifter е веб-апликација, па се тестира преку веб-прелистувач.

Каде се пушта апликацијата

Што Адреса
Frontend (корисничкиот дел) http://localhost:5173
Автоматско пренасочување со јазичен префикс http://localhost:5173/en или http://localhost:5173/mk
Backend REST API http://localhost:8080/api
Health check http://localhost:8080/actuator/health
Најава со Google http://localhost:8080/oauth2/authorization/google

Кориснички имиња и лозинки

Апликацијата нема однапред креирани (seed) корисници. При првото стартување базата е празна и сметката се креира преку формата за регистрација.

Тип на пристап Корисничко име Лозинка
Апликација (регистриран корисник) вашата емаил адреса, пр. test@example.com лозинка што ја бирате при регистрација, пр. Test123!
Апликација (Google најава) вашата Google сметка управувана од Google (нема лозинка во апликацијата)
PostgreSQL база shifter (или postgres) онаа што сте ја поставиле, пр. shifter

Правила за лозинката при регистрација – се проверуваат во формата:

  • најмалку една голема буква (A–Z)
  • најмалку една цифра (0–9)
  • најмалку еден специјален знак (!@#$%^&*(),.?":{}|<>)
  • двете полиња за лозинка мора да се совпаѓаат

Пример за валидна тест-сметка: test@example.com / Test123!

Совет за тестирање без валиден емаил-клуч: регистрацијата преку емаил испраќа порака за верификација преку ZeptoMail и, ако клучот не е валиден, целата регистрација паѓа бидејќи трансакцијата се враќа назад. Ако немате валиден ZEPTOMAIL_API_KEY, тестирајте со Најава преку Google – тој тек не испраќа емаил и корисникот автоматски се означува како верификуван.

Мини-водич низ главните елементи

Долниот водич ги поминува главните екрани по редослед на нормално користење.

Чекор 1: Почетна страница

  • Отворете http://localhost:5173 – автоматски ќе бидете пренасочени на /en (или /mk).
  • Navbar (горе): линкови до Курсеви, Менторство, Консалтинг, Академии, За Нас, Контакт, Бесплатна Сесија и копче Најави се / Регистрирај се.
  • Јазичен прекинувач (долу десно, знаменце): менува меѓу EN и MK; јазикот се одразува во URL-то (/en/.../mk/...).
  • Footer: контакт информации и линкови до социјални мрежи.

Чекор 2: Регистрација

  • Кликнете Најави се / Регистрирај сеРегистрирај се (/en/register).
  • Внесете емаил, лозинка и потврда на лозинката – види Кориснички имиња и лозинки.
  • Алтернативно кликнете „Continue with Google“ за најава преку Google сметка.
  • По успешна регистрација, апликацијата автоматски ве носи на страницата за персонализација (/welcome).

Чекор 3: Верификација и персонализација (/welcome)

  • Страницата го чита token параметарот од URL-то и ја верифицира вашата емаил адреса.
  • Пополнете ги полињата: Целосно име, Работно место и Големина на компанијата (Фриленсер, Микро, Мала, Средна, Среден пазар, Голема компанија, Друго).
  • Кликнете Започни да користиш Shifter. Профилот сега е комплетен и сите заштитени страници стануваат достапни.
  • Ако верификацијата не успее, постои копче Испрати нов емаил за нов линк за верификација.

Чекор 4: Најава (/login)

  • Внесете емаил и лозинка, или користете Continue with Google.
  • По најава access token се чува во меморија, а refresh token во HttpOnly колаче; сесијата се обновува автоматски при истек (401 → /api/auth/refresh).

Чекор 5: Профил (/profile)

  • Мој Профил – измена на име, работна позиција и големина на компанијата; се зачувува со Зачувај Промени.
  • Интереси и Стекнати Вештини – кликнете на секцијата за да отворите модал со теми и изберете барем една.
  • Одјави се – ја затвора сесијата.

Чекор 6: Бесплатна сесија (/free-consultation)

Ова е најкомплексниот тек и ги користи Google Calendar, Zoom и емаил интеграциите:

  • Апликацијата ги повлекува слободните термини на експертот од Google Calendar – работни денови, 08:00–16:30, во вашата временска зона.
  • Изберете датум и час.
  • Пополнете ги полињата: основни информации, за компанијата, предизвици и дополнителни информации.
  • Кликнете на копчето за закажување. Во позадина се креира настан во Google Calendar, се отвора Zoom состанок и се испраќаат емаил потврди до вас и до експертот.
  • Секој корисник има право на една бесплатна консултација – при обид за втора се појавува порака дека веќе е искористена.

Чекор 7: Контакт (/contact)

  • Полињата Име и Е-пошта се автоматски пополнети од вашиот профил.
  • Внесете Причина за контакт и Порака, па кликнете Испрати.
  • Пораката се испраќа до експертот преку ZeptoMail; се појавува потврда на екранот.

Чекор 8: Информативни страници

  • За Нас (/about) – мисија, вредности и претставување на тимот. Јавно достапна.
  • Менторство (/mentoring), Консалтинг (/consulting), Академии (/academies) – опис на услугите. Достапни само за најавени корисници.
  • Курсеви (/courses) – моментално прикажува страница „Дигитални Курсеви – Наскоро“; модулот за курсеви и учење е подготвен во backend-от, но е привремено исклучен во frontend-от.

Автоматски тестови

cd backend
./mvnw test
Last modified 5 days ago Last modified on 08/21/26 08:34:30
Note: See TracWiki for help on using the wiki.