2026-01-09 18:35:06 +01:00
|
|
|
# Mosenioring Backend
|
|
|
|
|
|
|
|
|
|
Production-ready Kotlin/Spring Boot 3 modular monolith skeleton for patient-caregiver-doctor coordination.
|
|
|
|
|
|
2026-01-12 22:50:15 +01:00
|
|
|
## 🏛 Architecture
|
|
|
|
|
This project follows a **Modular Monolith** architecture:
|
|
|
|
|
- `app`: Main entry point, configuration, and shared controllers.
|
|
|
|
|
- `common`: Cross-cutting concerns (security, tenant handling, outbox pattern).
|
|
|
|
|
- `modules/*`: Independent business modules (Clinical, Identity, Messaging, etc.).
|
|
|
|
|
- `workers/*`: Background event consumers/processors.
|
|
|
|
|
|
|
|
|
|
## 🛠 Requirements
|
2026-01-16 14:56:22 +01:00
|
|
|
- Java 17
|
2026-01-09 18:35:06 +01:00
|
|
|
- Docker + Docker Compose
|
2026-01-16 14:56:22 +01:00
|
|
|
- CI uses a custom `gradle:8.12-jdk17`-based image (see `ci/images/gradle-node/Dockerfile`); match that locally to avoid toolchain download delays.
|
2026-01-09 18:35:06 +01:00
|
|
|
|
2026-01-12 22:50:15 +01:00
|
|
|
## 🚀 Local Run
|
2026-01-09 18:35:06 +01:00
|
|
|
|
2026-01-12 22:50:15 +01:00
|
|
|
### 1. Start Dependencies
|
2026-01-09 18:35:06 +01:00
|
|
|
```bash
|
|
|
|
|
docker compose up -d
|
|
|
|
|
```
|
|
|
|
|
|
2026-01-12 22:50:15 +01:00
|
|
|
### 2. Run the API
|
|
|
|
|
Choose a profile:
|
2026-01-09 18:35:06 +01:00
|
|
|
|
2026-01-12 22:50:15 +01:00
|
|
|
**Local Development (with mock auth):**
|
2026-01-09 18:35:06 +01:00
|
|
|
```bash
|
2026-01-12 22:50:15 +01:00
|
|
|
SPRING_PROFILES_ACTIVE=local ALLOW_LOCAL_AUTH=true ./gradlew :app:bootRun
|
2026-01-09 18:35:06 +01:00
|
|
|
```
|
2026-01-12 22:50:15 +01:00
|
|
|
*Allows bypassing Keycloak using `X-Local-*` headers.*
|
2026-01-09 18:35:06 +01:00
|
|
|
|
2026-01-12 22:50:15 +01:00
|
|
|
**Dev Mode (with Keycloak):**
|
2026-01-12 18:38:15 +01:00
|
|
|
```bash
|
2026-01-12 22:50:15 +01:00
|
|
|
SPRING_PROFILES_ACTIVE=dev ./gradlew :app:bootRun
|
2026-01-12 18:38:15 +01:00
|
|
|
```
|
|
|
|
|
|
2026-01-12 22:50:15 +01:00
|
|
|
### 3. Run the Worker (Optional)
|
2026-01-09 18:35:06 +01:00
|
|
|
```bash
|
|
|
|
|
./gradlew :workers:notification-worker:bootRun
|
|
|
|
|
```
|
|
|
|
|
|
2026-01-12 22:50:15 +01:00
|
|
|
## 🧪 Testing
|
|
|
|
|
Run all tests:
|
|
|
|
|
```bash
|
|
|
|
|
./gradlew test
|
|
|
|
|
```
|
2026-01-09 18:35:06 +01:00
|
|
|
|
2026-01-12 22:50:15 +01:00
|
|
|
## 🔐 Auth & Multi-tenancy
|
|
|
|
|
- **JWT Resource Server**: Uses Keycloak by default.
|
|
|
|
|
- **Multi-tenancy**: Enforced via `X-Tenant-Id` header (local) or `tenant_id` JWT claim.
|
|
|
|
|
- **Local Auth Headers** (only when `ALLOW_LOCAL_AUTH=true`):
|
|
|
|
|
- `X-Local-Email`: User identity.
|
|
|
|
|
- `X-Local-Roles`: e.g., `ADMIN, DOCTOR, CAREGIVER`.
|
|
|
|
|
- `X-Tenant-Id`: Target tenant.
|
2026-01-09 18:35:06 +01:00
|
|
|
|
2026-01-14 15:12:10 +01:00
|
|
|
## 📨 Invitation Onboarding
|
|
|
|
|
- **Invite-only registration**: Admins create invites; users accept with a token.
|
|
|
|
|
- **Resolve endpoint**: `POST /api/v1/invites/resolve` returns only masked email + expiry.
|
|
|
|
|
- **Accept endpoint**: `POST /api/v1/invites/accept` links the authenticated user to a patient.
|
|
|
|
|
- **Token hashing**: Invitation tokens are stored as HMAC-SHA256 with a server-side pepper.
|
|
|
|
|
- **Config**: Set `app.invites.token-pepper` in `back001/app/src/main/resources/application.yml` for non-dev environments.
|
|
|
|
|
|
2026-01-12 22:50:15 +01:00
|
|
|
## 🔗 Key Services & Links
|
|
|
|
|
- **OpenAPI**: [http://localhost:8080/swagger-ui/index.html](http://localhost:8080/swagger-ui/index.html)
|
|
|
|
|
- **Health**: [http://localhost:8080/health](http://localhost:8080/health)
|
|
|
|
|
- **Postgres**: `localhost:5432` (mosenioring/mosenioring)
|
|
|
|
|
- **Keycloak**: [http://localhost:8081](http://localhost:8081) (admin/admin)
|
|
|
|
|
- **RabbitMQ**: [http://localhost:15672](http://localhost:15672) (guest/guest)
|
|
|
|
|
- **MinIO**: [http://localhost:9001](http://localhost:9001) (minio/minio123)
|
2026-01-09 18:35:06 +01:00
|
|
|
|
2026-01-12 22:50:15 +01:00
|
|
|
## 📝 Notes
|
|
|
|
|
- **Outbox Pattern**: Medication plans publish events to an outbox table for reliable messaging.
|
|
|
|
|
- **Idempotency**: Workers use Redis to ensure events are processed only once.
|