Operations
This page documents the operational pieces around the backend: caches, jobs, WebSocket broker, image import, and deployment notes.
Runtime Services
The backend expects these services in a full environment:
| Service | Why it is needed |
|---|---|
| PostgreSQL + PostGIS | Primary relational database and branch coordinates. |
| Redis | Caches, branch GEO index, live driver coordinates. |
| RabbitMQ with STOMP | STOMP broker relay for WebSocket topics and user queues. |
| AWS S3 / CloudFront | Image storage and delivery. |
| PokPay API | Payment initiation, payment webhook, refunds. |
| Google Maps or ORS | Route distance and duration calculations. |
PostgreSQL and PostGIS
RestaurantBranch.location uses:
@Column(columnDefinition = "geography(Point,4326)")
private Point location;Use a PostGIS database image locally:
image: postgis/postgis:15-3.4-alpineBefore production, replace spring.jpa.hibernate.ddl-auto=update with migrations such as Flyway or Liquibase. The project already has enough domain rules that schema drift would become painful without migrations.
Redis
Branch GEO Index
Key:
restaurant:locationsValue:
branchId as Redis GEO memberUpdated by:
RestaurantBranchListener
BranchServiceImpl.updateRedisGeoIndexUsed by:
RestaurantServiceImpl.findAvailableRestaurantsCurrent note:
- A commented
rebuildGeoIndexOnStartupexists inBranchServiceImpl. - For production, implement a real startup rebuild job or internal admin job so Redis can be rebuilt after cache loss.
Spring Cache Names
Non-dev profile cache configuration:
| Cache | TTL | Purpose |
|---|---|---|
userProfileCache | 5 seconds | Micro-cache for user profile data. |
dashboardRestaurants | 5 minutes | Restaurant discovery/dashboard pages. |
branchMenus | 2 hours | Full branch menu. |
distanceMatrix | Default config | Distance route results keyed by branch/location/provider. |
Dev profile:
- Only
distanceMatrixuses in-memoryConcurrentMapCache. - Other caches are no-op.
Live Driver Coordinates
Key pattern:
driver_loc:{driverId}TTL:
1 hourExample value:
{
"latitude": 41.3275,
"longitude": 19.8189
}This is a latest-position cache, not a permanent tracking history.
RabbitMQ STOMP Broker
WebSocketConfig uses a broker relay:
config.enableStompBrokerRelay("/topic", "/queue")
.setRelayHost(rabbitmqIp)
.setRelayPort(61613)RabbitMQ must have STOMP enabled. In RabbitMQ this is typically:
rabbitmq-plugins enable rabbitmq_stompIn production, also configure:
- durable broker deployment,
- credentials not shared with app users,
- TLS or private networking,
- monitoring for queue/topic pressure.
WebSocket Client Checklist
Client connects to:
/wsSTOMP connect header:
Authorization: Bearer <jwt>Subscriptions:
/topic/branch.{branchId}.manager
/topic/delivery.global.unassigned
/user/queue/updatesImportant: RabbitMQ topic names in the current code use dots, not slashes.
Internal Jobs
Controller:
InternalJobControllerHeader:
X-Internal-Secret: <app.internal-job-secret>Daily Reset
POST /api/internal/jobs/daily-reset-order-countPurpose:
- Reset branch daily order counts.
- Supports trending logic.
Recommended schedule:
Daily at 00:00 in the business timezonePayment Cleanup
POST /api/internal/jobs/payment-cleanupPurpose:
- Expire stale pending payments.
- Mark abandoned orders.
Recommended schedule:
Every 15-30 minutesImage Upload and Import
Normal Upload
AWSS3Service handles uploading files to S3. TestAWSUpload exposes:
POST /api/uploadThis is useful for testing, but it is public in the current security filter. Protect it or remove it before production.
Bulk File Import
Class:
ImageUploaderProfile:
import_fileBehavior:
- Walks
src/main/resources/json/restaurants/img/. - Splits filenames by the last underscore.
- Uploads original bytes to S3.
- Does not resize in the current implementation path.
Run example:
.\mvnw.cmd spring-boot:run "-Dspring-boot.run.profiles=import_file"Payment Operations
PokPay config keys:
pok.api.baseUrl=
pok.api.keyId=
pok.api.keySecret=
pok.api.merchantId=
pok.redirectUrl=
pok.failRedirectUrl=
pok.webhookUrl=Operational rules:
- Webhook endpoint must be publicly reachable by PokPay.
- Use HTTPS in production.
- Keep webhook idempotency. Current implementation exits early if order payment is already
COMPLETED. - Monitor expired payment cleanup to make sure old pending orders do not pile up.
Logs to Watch
Important log areas:
- Distance matrix failures or fallback
-1. - PokPay login/create/refund failures.
- WebSocket JWT errors.
- Redis connection failures.
- S3 upload failures.
- Payment cleanup counts.
- Delivery coordinate submission logs:
coordinates sent for driverId {id}Deployment Notes
Current Docker Compose
The included compose file is good for local/server experiments:
- Spring Boot backend.
- PostGIS.
- Redis.
- Nginx.
Missing for production:
- RabbitMQ service.
- TLS certificates.
- real secrets management.
- database backups.
- frontend artifact serving.
- persistent Redis/RabbitMQ decisions.
- health checks.
- environment-specific property files.
Recommended Production Shape
For a small real deployment:
- Spring Boot backend container.
- Managed PostgreSQL with PostGIS or self-hosted PostGIS with backups.
- Redis instance for cache/live locations.
- RabbitMQ with STOMP plugin.
- Nginx or cloud load balancer with HTTPS.
- S3 + CloudFront for images.
- External job scheduler for internal jobs.
- Centralized logs.
- Metrics and alerting for payment failures, route API failures, and WebSocket broker health.
Backup and Data Risk
Back up:
- PostgreSQL database.
- S3 bucket objects.
- production application properties/secrets in a secret manager.
Redis is mostly rebuildable, except live driver coordinates, which are intentionally temporary.
Security Checklist
Before serious production:
- Move all secrets out of
.propertiesfiles and into environment variables or a secret manager. - Protect
/api/upload. - Add method-level role annotation to payment branch update endpoint.
- Add method-level role annotation to driver location endpoint.
- Restrict review creation to authenticated customers.
- Add CSRF only if browser cookie auth is introduced. For JWT headers, stateless CSRF disabled is acceptable.
- Configure CORS per environment.
- Add HTTPS everywhere.
- Validate webhook authenticity if PokPay provides signatures or shared secrets.
- Rate limit auth and public discovery endpoints.
- Add database migrations.
- Avoid logging sensitive payment/auth data.