vibes
This commit is contained in:
247
AGENTS.md
Normal file
247
AGENTS.md
Normal file
@@ -0,0 +1,247 @@
|
||||
PROJECT CONTEXT / SYSTEM BRIEF
|
||||
|
||||
This is a hotel-grade Property Management System (PMS) being rebuilt from scratch.
|
||||
This AGENTS file captures both the product rules you gave and my current understanding of
|
||||
the TrisolarisServer codebase as of the last read, so future sessions can resume accurately.
|
||||
|
||||
Tech stack
|
||||
- Spring Boot monolith
|
||||
- Kotlin only
|
||||
- JPA / Hibernate
|
||||
- PostgreSQL
|
||||
- No Flyway for now, schema via JPA during development (Flyway is present in deps but disabled)
|
||||
- Single API domain api.hoteltrisolaris.in
|
||||
- Android app and future website consume the same APIs
|
||||
|
||||
This replaces a very old Firestore-based Android app. Old code exists only to understand behaviour. Do not reuse or mirror 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
|
||||
|
||||
CURRENT DOMAIN MODEL ALREADY CREATED
|
||||
|
||||
Organization
|
||||
Property
|
||||
AppUser
|
||||
PropertyUser with roles
|
||||
RoomType
|
||||
Room
|
||||
Booking
|
||||
Guest
|
||||
RoomStay
|
||||
|
||||
These entities already exist in Kotlin. Do not redesign unless explicitly asked.
|
||||
|
||||
WHAT THE SYSTEM MUST SUPPORT
|
||||
|
||||
Operational behaviour
|
||||
- Staff sees exact room numbers free, occupied, checkout today
|
||||
- Different rates for same room type
|
||||
- Multiple rooms today and fewer tomorrow under the same booking
|
||||
- Room changes without data loss
|
||||
|
||||
Financial behaviour
|
||||
- Advance payments, partial payments, refunds
|
||||
- PayU integration for QR and payment links
|
||||
- Payment status via webhooks
|
||||
- Clear source and destination of money
|
||||
- Staff-wise collection tracking
|
||||
|
||||
Website integration
|
||||
- Website reads live availability from PMS
|
||||
- Website creates booking intents
|
||||
- No inventory sync jobs
|
||||
- Rate plans like DIRECT, WALKIN, OTA are snapshotted at booking time
|
||||
|
||||
Realtime
|
||||
- Firestore-like realtime behaviour
|
||||
- WebSocket or SSE for room board and payment updates
|
||||
- Push notifications later via FCM
|
||||
|
||||
Infrastructure
|
||||
- Nginx reverse proxy
|
||||
- Single domain with multiple paths
|
||||
- Database is never exposed publicly
|
||||
|
||||
IMPORTANT RULES FOR YOU
|
||||
|
||||
- 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.
|
||||
- Propose schema or API changes before coding if unsure
|
||||
- Money logic must be explicit and auditable
|
||||
- Canonical staff roles for now are ADMIN, MANAGER, STAFF, HOUSEKEEPING, FINANCE. Other roles may exist later but must not be depended on unless asked.
|
||||
- Booking is a lifecycle container only. Booking does not own rooms or money. Occupancy is only via RoomStay. Billing is only via Charge and Payment ledgers.
|
||||
- Realtime features must emit derived domain events only. Clients must never subscribe to raw entity state or database changes.
|
||||
|
||||
HOW YOU SHOULD WORK
|
||||
|
||||
- Read the entire repository before making changes
|
||||
- Work file by file
|
||||
- Prefer small focused changes
|
||||
- Ask before touching auth or payment logic
|
||||
- Assume this will run in real production hotels
|
||||
|
||||
FIRST TASK
|
||||
|
||||
Do nothing until asked.
|
||||
Likely upcoming tasks include room board API, charge ledger, payment and PayU webhook flow, booking check-in transaction.
|
||||
|
||||
===============================================================================
|
||||
CURRENT CODEBASE UNDERSTANDING (TrisolarisServer)
|
||||
===============================================================================
|
||||
|
||||
Repository
|
||||
- Root: /home/androidlover5842/IdeaProjects/TrisolarisServer
|
||||
- Language: Kotlin only (Spring Boot 4, JPA)
|
||||
- Entry point: src/main/kotlin/com/android/trisolarisserver/TrisolarisServerApplication.kt
|
||||
- Active controller layer is minimal (Rooms.kt is stubbed/commented)
|
||||
|
||||
Gradle
|
||||
- build.gradle.kts uses:
|
||||
- Spring Boot 4.0.1
|
||||
- Kotlin 2.2.21 (kotlin("jvm"), kotlin("plugin.spring"), kotlin("plugin.jpa"))
|
||||
- Java toolchain 19
|
||||
- JPA, WebMVC, Validation, Security, WebSocket, Flyway (dep), Postgres
|
||||
- Flyway is disabled in application.properties
|
||||
|
||||
Configuration
|
||||
- src/main/resources/application.properties
|
||||
- spring.jpa.hibernate.ddl-auto=update
|
||||
- spring.jpa.open-in-view=false
|
||||
- flyway.enabled=false
|
||||
- application-dev.properties -> jdbc:postgresql://192.168.1.53:5432/trisolaris
|
||||
- application-prod.properties -> jdbc:postgresql://localhost:5432/trisolaris
|
||||
- DB password via env: DB_PASSWORD
|
||||
|
||||
Current packages and code
|
||||
|
||||
com.android.trisolarisserver.component
|
||||
- PropertyAccess
|
||||
- requireMember(propertyId, userId) -> checks PropertyUserRepo
|
||||
- requireAnyRole(propertyId, userId, roles) -> checks roles
|
||||
|
||||
com.android.trisolarisserver.db.repo
|
||||
- PropertyUserRepo
|
||||
- existsByIdPropertyIdAndIdUserId(...)
|
||||
- hasAnyRole(...) via JPQL joining property_user_role
|
||||
- RoomRepo
|
||||
- findFreeRooms(propertyId): active, not maintenance, no open RoomStay
|
||||
- findOccupiedRooms(propertyId): rooms with active RoomStay
|
||||
|
||||
com.android.trisolarisserver.controller
|
||||
- Rooms.kt: placeholder, no active endpoints yet
|
||||
|
||||
Entity model (current Kotlin entities)
|
||||
- Organization
|
||||
- id (uuid), name, createdAt
|
||||
- Property
|
||||
- id (uuid)
|
||||
- org (Organization)
|
||||
- code, name, timezone, currency
|
||||
- active, createdAt
|
||||
- AppUser
|
||||
- id (uuid)
|
||||
- org (Organization)
|
||||
- firebaseUid, phoneE164, name
|
||||
- disabled, createdAt
|
||||
- PropertyUser
|
||||
- composite key PropertyUserId (propertyId, userId)
|
||||
- property (Property), user (AppUser)
|
||||
- roles (ElementCollection of Role)
|
||||
- Role enum
|
||||
- ADMIN, MANAGER, STAFF, HOUSEKEEPING, FINANCE, GUIDE, SUPERVISOR, AGENT
|
||||
- RoomType
|
||||
- id (uuid)
|
||||
- property (Property)
|
||||
- code, name, baseOccupancy, maxOccupancy, createdAt
|
||||
- Room
|
||||
- id (uuid)
|
||||
- property (Property)
|
||||
- roomType (RoomType)
|
||||
- roomNumber, floor
|
||||
- hasNfc, active, maintenance, notes
|
||||
- Booking
|
||||
- id (uuid)
|
||||
- property (Property)
|
||||
- primaryGuest (Guest)
|
||||
- status (BookingStatus)
|
||||
- source, sourceBookingId
|
||||
- checkinAt, checkoutAt
|
||||
- expectedCheckinAt, expectedCheckoutAt
|
||||
- notes
|
||||
- createdBy (AppUser)
|
||||
- createdAt, updatedAt
|
||||
- BookingStatus enum
|
||||
- OPEN, CHECKED_IN, CHECKED_OUT, CANCELLED, NO_SHOW
|
||||
- Guest
|
||||
- id (uuid)
|
||||
- org (Organization)
|
||||
- phoneE164, name, nationality
|
||||
- addressText
|
||||
- createdAt, updatedAt
|
||||
- RoomStay
|
||||
- id (uuid)
|
||||
- property (Property)
|
||||
- booking (Booking)
|
||||
- room (Room)
|
||||
- fromAt, toAt (null = active occupancy)
|
||||
- createdBy (AppUser)
|
||||
- createdAt
|
||||
|
||||
Notes on schema vs migration file
|
||||
- There is a Flyway migration file at src/main/resources/db/migration/V1__core.sql,
|
||||
but Flyway is disabled. The SQL file does NOT match current Kotlin entities in
|
||||
multiple places (columns and tables differ). For now, JPA schema generation is
|
||||
authoritative during development.
|
||||
|
||||
Gaps relative to target design (do not implement unless asked)
|
||||
- No Charge entity yet
|
||||
- No Payment entity yet
|
||||
- No ledger/derived views
|
||||
- No API controllers/services for bookings, rooms, payments
|
||||
- No auth filter or principal model wired (PropertyAccess expects userId)
|
||||
- No WebSocket/SSE endpoints yet
|
||||
|
||||
Behavioral requirements to keep in mind when coding
|
||||
- Every domain object must include property scope
|
||||
- Room availability derived from RoomStay toAt == null
|
||||
- Room changes are new RoomStay + closing old
|
||||
- Charges and payments are append-only (never overwrite totals)
|
||||
- Clients send intent; server derives facts
|
||||
Reference in New Issue
Block a user