145 lines
5.4 KiB
Markdown
145 lines
5.4 KiB
Markdown
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:
|
|
- dev: https://ai.hoteltrisolaris.in/v1/chat/completions
|
|
- prod: http://localhost:8089/v1/chat/completions
|
|
- 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.
|