ProjectForge — краткое описание проекта

📚 Полный список документации · Сравнение с конкурентами

Что это

ProjectForge — корпоративный веб-портал для управления проектами, задачами, календарями, сотрудниками, отпусками, книгами и другими бизнес-сущностями. Проектно-ориентированная система для средних компаний с сильным акцентом на управление проектами и учёт рабочего времени.

Разрабатывается Micromata GmbH (Германия) с 2001 года. Открытый исходный код, двойная лицензия (GPLv3 / коммерческая).

Тип программы

Монолитное веб-приложение. Один JAR-файл, внутри которого:

ФронтендURLТехнологияСостояние
Wicket/Java Wicket (серверный рендеринг)Основной, legacy
React/react/**React + Redux + Vite (клиентский рендеринг)Активно развивается, мигрирует с CRA на Vite

Оба фронтенда живут в одном JAR и работают одновременно — пользователь переключается между ними незаметно.

Что нужно знать чтобы разбираться в кодовой базе

1. Как запустить

./gradlew bootRun

Открыть http://localhost:8080 (Wicket) или http://localhost:8080/react/ (React).

Для фронтенд-разработки (React, hot reload):

cd projectforge-webapp && npm install && npm run dev

Vite-сервер на http://localhost:5173, проксирует API-запросы на localhost:8080.

2. Структура директорий (что где лежит)

projectforge/
├── projectforge-business/      ← бизнес-логика (Kotlin/Java), сервисы, работа с БД
│   └── src/main/
│       ├── kotlin/org/projectforge/
│       │   ├── login/          ← аутентификация (LoginService, LoginHandler)
│       │   └── business/user/  ← пользователи, группы, куки (CookieService)
│       └── resources/
│           ├── application.properties   ← конфигурация
│           └── flyway/         ← миграции БД
├── projectforge-rest/         ← REST API (Kotlin/Java, Spring MVC)
│   └── src/main/kotlin/org/projectforge/rest/
│       ├── pub/               ← публичные эндпоинты (логин, статус)
│       ├── UserStatusRest.kt  ← GET /rs/userStatus — «кто я?»
│       └── config/Rest.java   ← URL-префиксы (/rs, /rsPublic)
├── projectforge-webapp/       ← React-фронтенд (JavaScript, Vite)
│   ├── src/
│   │   ├── actions/           Redux thunk'и (логин, проверка сессии)
│   │   ├── reducers/          Redux редьюсеры (состояние аутентификации)
│   │   ├── utilities/rest.js  ← fetch-обёртка (baseURL, handleHTTPErrors)
│   │   ├── components/        ← UI-компоненты
│   │   └── containers/        ← страницы (ProjectForge.jsx — точка входа)
│   ├── vite.config.ts         ← конфигурация Vite
│   └── package.json           ← зависимости (React, Redux, Vitest, …)
├── projectforge-idp/          ← интеграция с IdP (Keycloak / Authentik)
├── projectforge-model/        ← общие Java-модели
│   └── rest/RestPaths.java    ← константы: REST = "rs", REST_PUBLIC = "rsPublic"
└── buildSrc/                  Gradle-конвенции

3. Как фронтенд общается с бэкендом

React делает fetch() на REST API:

React (браузер)                Java (Spring Boot)
─────────────────              ────────────────────
login(username, password)  →   POST /rsPublic/login  →  LoginPageRest.kt
loadUserStatus()           →   GET  /rs/userStatus    →  UserStatusRest.kt

Все запросы идут с credentials: 'include' — браузер отправляет сессионную куку JSESSIONID. Сервер проверяет её и возвращает либо данные пользователя (200), либо 401 (не залогинен).

Ключевые файлы для понимания этого моста:

ФронтендБэкендЧто делает
actions/authentication.jsrest/pub/LoginPageRest.ktЛогин
actions/authentication.jsrest/UserStatusRest.ktПроверка сессии
utilities/rest.jsmodel/rest/RestPaths.javaURL-префиксы
utilities/rest.jsbusiness/…/CookieService.ktКуки
reducers/authentication.jsСостояние на фронтенде

4. Что нужно знать про аутентификацию

В проекте два типа «входа»:

Сессия (JSESSIONID) — стандартная Java-сессия. Ставится сервером после логина. Живёт пока браузер открыт.

Постоянный вход (stayLoggedIn) — отдельная кука на 30 дней. Если сессия истекла но кука жива — сервер автоматически пересоздаёт сессию без пароля.

Фронтенд при старте делает loadUserStatus() — спрашивает сервер «кто я?». Если сессия жива — получает данные пользователя. Если нет — редирект на страницу логина.

5. Ключевые технологии

СлойТехнология
БэкендKotlin, Java 17, Spring Boot, Hibernate/JPA, Flyway
База данныхHSQLDB (dev), PostgreSQL (prod)
ФронтендReact 18, Redux, Vite 6, react-big-calendar, reactstrap
Тесты (фронтенд)Vitest, redux-mock-store
СборкаGradle (Kotlin DSL), npm
Старый фронтендApache Wicket (Java-фреймворк, серверный рендеринг)

6. Поток данных при логине (упрощённо)

1. Пользователь вводит логин/пароль в React-форме
2. React:  login(username, password, keepSignedIn)
3. fetch:  POST /rsPublic/login  { username, password, stayLoggedIn }
4. Java:   LoginPageRest → LoginService.authenticate()
5. Java:   LoginHandler.checkLogin() → проверка пароля в БД
6. Java:   если keepSignedIn — ставит куку stayLoggedIn на 30 дней
7. Java:   создаёт сессию (JSESSIONID)
8. React:  .then(() => loadUserStatus()(dispatch))
9. fetch:  GET /rs/userStatus
10. Java:  UserStatusRest → проверяет сессию → возвращает userData
11. React: dispatch(USER_LOGIN_SUCCESS) → Redux знает кто залогинен

7. Что ещё полезно знать

  • /rs — префикс REST API, определён в RestPaths.java:31 как public static final String REST = "rs". Весь REST API живёт под /rs/*.
  • /rsPublic — публичные эндпоинты (логин, восстановление пароля) — не требуют аутентификации.
  • Кука JSESSIONID — создаётся не кодом ProjectForge, а сервлет-контейнером (Tomcat). ProjectForge только управляет её жизненным циклом (инвалидация после логина для защиты от session fixation).
  • Два фронтенда в одном JARWicket (/) и React (/react/**). Wicket использует index.html, React использует react-app.html (переименовывается при сборке Gradle'ом).
  • Миграции БДFlyway. SQL-скрипты в projectforge-business/src/main/resources/flyway/migrate/.

Конкуренты

Подробное сравнение с 7 конкурентами →

Кратко: OpenProject — самый прямой конкурент (GPLv3, немецкий, PM-фокус, но без финансов/HR). ERPNext/Odoo — шире по ERP, сложнее в деплое. Jira — уходит с self-hosted рынка к 2029. Personio — только HR (SaaS). Monday.com — красивый SaaS без self-hosted. Уникальность ProjectForge — единственный кто даёт PM + финансы + HR + календарь в одном JAR со встроенной БД.