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