5.4 KiB
PROJECT CONTEXT / SYSTEM BRIEF
This is a hotel-grade Property Management System (PMS) being rebuilt from scratch. This AGENTS file captures the product rules + current codebase state.
Tech stack
- Spring Boot monolith
- Kotlin only
- JPA / Hibernate
- PostgreSQL
- No Flyway for now, schema via JPA during development (Flyway deps present but disabled)
- Single API domain api.hoteltrisolaris.in
- Android app and future website consume the same APIs
Legacy note Old Firestore Android app exists only to understand behavior. Do not reuse old models.
CORE DESIGN PRINCIPLES
Server is the only source of truth Clients never calculate state Clients send intent, server derives facts
Ledger-based design Never store totals Never overwrite money Append rows and derive views
Three independent concerns Occupancy handled by RoomStay Charges handled by Charge Payments handled by Payment Invoices are derived views, not stored state
Room availability is by room number Availability is derived from RoomStay toAt = null means occupied Category counts are only summaries
Room changes must never break billing Changing rooms means closing one RoomStay and opening another Charges are time-bound and linked to booking, optionally to room_stay
Multi-property from day one Every domain object is scoped to property_id Users belong to organization Access is granted per property
Auth and access User exists once as AppUser Property access via PropertyUser Roles are per property Every API call must enforce property membership
IMMUTABLE RULES
- Use Kotlin only
- Follow existing package structure
- No speculative features
- No premature microservices
- Flyway must remain disabled during development. Do not introduce or modify Flyway migrations unless explicitly instructed after schema stabilization.
- Canonical staff roles: ADMIN, MANAGER, STAFF, HOUSEKEEPING, FINANCE (other roles may exist but must not be depended on)
- Booking is a lifecycle container only. Booking does not own rooms or money. Occupancy via RoomStay. Billing via Charge/Payment ledgers.
- Realtime must emit derived events only (no raw entity subscriptions)
- Ask before touching auth or payment logic
=============================================================================== CURRENT CODEBASE UNDERSTANDING (TrisolarisServer)
Repository
- Root: /home/androidlover5842/IdeaProjects/TrisolarisServer
- Entry: src/main/kotlin/com/android/trisolarisserver/TrisolarisServerApplication.kt
- Scheduling enabled (@EnableScheduling)
Security/Auth
- Firebase Admin auth for every request, Firebase UID required.
- Security filter verifies token and maps to MyPrincipal(userId, firebaseUid).
- Endpoints: /auth/verify and /auth/me.
Domain entities
- Organization: id, name, emailAliases
- Property: org, code, name, addressText, timezone, currency, active, emailAddresses, otaAliases
- AppUser: org, firebaseUid, phoneE164, name, disabled
- PropertyUser: roles per property
- Role enum includes ADMIN, MANAGER, STAFF, HOUSEKEEPING, FINANCE, GUIDE, SUPERVISOR, AGENT (but only canonical roles should be used)
- RoomType: code/name/occupancy + otaAliases
- Room: roomNumber, floor, hasNfc, active, maintenance, notes
- Booking: status, source/sourceBookingId, expected check-in/out, emailAuditPdfUrl
- Guest
- RoomStay
- GuestDocument: files for guest/booking with AI-extracted data
- InboundEmail: inbound mail audit (PDF + raw eml), extractedData, status
Repos
- Repos are under com.android.trisolarisserver.repo (note: not db.repo).
- Added repos for Booking, Guest, GuestDocument, InboundEmail.
Key modules
Rooms / inventory
- /properties/{propertyId}/rooms
- /properties/{propertyId}/rooms/board
- /properties/{propertyId}/rooms/availability
- /properties/{propertyId}/rooms/availability-range?from=YYYY-MM-DD&to=YYYY-MM-DD Availability derived from RoomStay. Date range uses overlap [from, to).
Room types
- CRUD with otaAliases in DTOs.
Properties/Orgs
- Property create/update accept addressText, otaAliases, emailAddresses.
- Org create/get returns emailAliases.
Guest documents (files)
- POST /properties/{propertyId}/guests/{guestId}/documents (multipart + bookingId)
- GET list
- GET file (token or auth)
- Files stored under /home/androidlover5842/docs/{propertyId}/{guestId}/{bookingId}/
- AI extraction via llama.cpp with strict system prompt
Inbound email ingestion
- IMAP poller (1 min) with enable flag.
- Saves audit PDF + raw .eml to /home/androidlover5842/docs/emails
- Matches property via To/CC email first, then text aliases (name/code/address/otaAliases)
- AI extracts booking fields and creates/cancels Booking
- Booking gets emailAuditPdfUrl that points to /properties/{propertyId}/inbound-emails/{emailId}/file
AI integration
- Base URL configured per profile:
- LlamaClient uses strict system prompt: only visible text, no guessing.
- Read timeout 5 minutes.
Config
- application.properties: flyway disabled, storage paths, IMAP config, token secrets.
- storage.documents.publicBaseUrl + token secret/ttl.
- storage.emails.publicBaseUrl used for booking audit URL.
- mail.imap.enabled=false by default.
Notes / constraints
- API user creation removed; users are created by app; API only manages roles.
- Admin can assign ADMIN/MANAGER/STAFF/AGENT; Manager can assign STAFF/AGENT.
- Agents can only see free rooms.