Improved README.md with restructured sections, better formatting, and added examples for local development, testing, and architecture overview.

This commit is contained in:
oskar 2026-01-12 22:50:15 +01:00
parent 8cfb81c99d
commit d8f91f42e5

View file

@ -2,65 +2,65 @@
Production-ready Kotlin/Spring Boot 3 modular monolith skeleton for patient-caregiver-doctor coordination. Production-ready Kotlin/Spring Boot 3 modular monolith skeleton for patient-caregiver-doctor coordination.
## Requirements ## 🏛 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
- Java 21 - Java 21
- Docker + Docker Compose - Docker + Docker Compose
## Local run ## 🚀 Local Run
1) Start dependencies:
### 1. Start Dependencies
```bash ```bash
docker compose up -d docker compose up -d
``` ```
2) Run the API (local profile, local auth enabled): ### 2. Run the API
Choose a profile:
**Local Development (with mock auth):**
```bash ```bash
SPRING_PROFILES_ACTIVE=local \ SPRING_PROFILES_ACTIVE=local ALLOW_LOCAL_AUTH=true ./gradlew :app:bootRun
ALLOW_LOCAL_AUTH=true \ ```
./gradlew :app:bootRun *Allows bypassing Keycloak using `X-Local-*` headers.*
**Dev Mode (with Keycloak):**
```bash
SPRING_PROFILES_ACTIVE=dev ./gradlew :app:bootRun
``` ```
```bash ### 3. Run the Worker (Optional)
SPRING_PROFILES_ACTIVE=dev \
ALLOW_LOCAL_AUTH=false \
./gradlew :app:bootRun
```
3) (Optional) Run the worker:
```bash ```bash
./gradlew :workers:notification-worker:bootRun ./gradlew :workers:notification-worker:bootRun
``` ```
Required env flags (local/dev): ## 🧪 Testing
- `SPRING_PROFILES_ACTIVE=local` Run all tests:
- `ALLOW_LOCAL_AUTH=true` (enables local auth headers) ```bash
- `KEYCLOAK_ISSUER_URI=http://localhost:8081/realms/mosenioring` (if using Keycloak) ./gradlew test
- Frontend should set `USE_LOCAL_AUTH=true` when using local auth headers. ```
## Auth ## 🔐 Auth & Multi-tenancy
- The backend is a JWT resource server and does not handle user passwords. - **JWT Resource Server**: Uses Keycloak by default.
- Local auth shortcut is available only when `SPRING_PROFILES_ACTIVE=local` - **Multi-tenancy**: Enforced via `X-Tenant-Id` header (local) or `tenant_id` JWT claim.
and `ALLOW_LOCAL_AUTH=true`. - **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.
Local headers (dev only): ## 🔗 Key Services & Links
- `X-Local-Email`: user id/email - **OpenAPI**: [http://localhost:8080/swagger-ui/index.html](http://localhost:8080/swagger-ui/index.html)
- `X-Local-Roles`: comma-separated roles (ADMIN, DOCTOR, CAREGIVER) - **Health**: [http://localhost:8080/health](http://localhost:8080/health)
- `X-Tenant-Id`: tenant id - **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)
## OpenAPI ## 📝 Notes
- http://localhost:8080/swagger-ui/index.html - **Outbox Pattern**: Medication plans publish events to an outbox table for reliable messaging.
## Health - **Idempotency**: Workers use Redis to ensure events are processed only once.
- http://localhost:8080/health
## Key services
- Postgres: localhost:5432 (mosenioring/mosenioring)
- Keycloak: http://localhost:8081 (admin/admin)
- RabbitMQ: http://localhost:15672 (guest/guest)
- MinIO: http://localhost:9001 (minio/minio123)
## Notes
- Tenant ID is enforced via `TenantFilter` using JWT claim `tenant_id`, or `X-Tenant-Id` header (local).
- Medication plan creation publishes a `MedicationPlanCreated` outbox event.
- Worker consumes and emits `NotificationRequested` events with idempotency via Redis.