Maleku System’s marketplace is the central hub that connects travelers with Costa Rican tourism vendors. Vendors register on the platform, complete a verification process, and then publish listings across five categories — properties/hotels, tours, vehicles, boats, and flights. Every listing is owned by a specific vendor, gated behind role-based access control, and served through a Redis-backed cache layer for high-throughput browsing. The platform takes a 10% commission on each completed transaction, keeping listing creation completely free for vendors.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/IvanchoDev89/maleku-system/llms.txt
Use this file to discover all available pages before exploring further.
Listing Categories
Each category maps to a dedicated FastAPI router and SQLAlchemy model, with its own set of filters, CRUD endpoints, and pricing logic.| Category | Description |
|---|---|
| Properties / Hotels | Accommodation listings (hotels, hostels, eco-lodges, resorts, villas, apartments, cabins, glamping sites, boutique hotels, and aparthotels). Supports room-level pricing, weekend rates, and availability calendars. |
| Tours | Experience listings such as adventure, nature, cultural, water, wellness, gastronomy, beach, and wildlife tours. Priced per person with configurable group sizes and schedule days. |
| Vehicles | Car rental listings filtered by VehicleType (car, suv, van, minibus, motorcycle), seat count, and location. Priced per day with optional weekly and monthly rates. |
| Boats | Nautical equipment rental filtered by BoatType (boat, jet_ski, kayak, paddleboard, equipment), location, and passenger capacity. |
| Flights | Flight listings managed under the same vendor model, allowing operators to list scheduled or charter departures alongside other services. |
Vendor Verification
Before any listing appears publicly in search results or the browsable catalogue, the vendor account must be verified by a platform admin. The verification workflow is:- Vendor Registration — A user registers and creates a vendor profile (
POST /api/v1/vendors/). The profile is assignedVendorStatus.PENDINGandis_verified = False. - Admin Review — A
SUPER_ADMINorADMINcallsPOST /api/v1/vendors/{id}/verify. This flipsis_verifiedtoTrueand transitions the status toVendorStatus.ACTIVE. - Listings Go Live — Only after verification can the vendor’s listings be returned by public endpoints. API queries filter on
is_active = True; inactive or unverified vendor listings are silently excluded. - Suspension — Admins can set a vendor status to
VendorStatus.SUSPENDEDorVendorStatus.REJECTEDat any time, immediately hiding all their listings.
VendorStatus values are pending, active, suspended, and rejected.
Image Management
All listing images are stored and served via Cloudinary CDN. The integration is handled bycloudinary_service.py with the following behaviour:
- Upload endpoint — Images are uploaded via
POST /api/v1/{resource}/{id}/images(e.g.POST /api/v1/properties/{id}/images). The upload handler inupload.pyvalidates file type (jpg, jpeg, png, gif, webp), enforces a maximum file size, and checks the raw bytes before handing off to Cloudinary. - Folder prefix — Every asset is stored under the
CLOUDINARY_FOLDER_PREFIXconfigured in settings, which defaults tocostaricatravel. Sub-folders are appended per resource type (e.g.costaricatravel/properties,costaricatravel/tours). - Automatic optimisation — Cloudinary applies automatic format selection and quality optimisation at delivery time; the backend stores only the
secure_urlreturned by the API. - Fallback — If Cloudinary is not configured or the upload fails, the service falls back to local file storage and logs a warning, so development environments work without credentials.
- Cover image — A separate
PUT /api/v1/properties/{id}/coverendpoint sets thecover_imagefield without re-uploading. Deleting an image viaDELETE /api/v1/properties/{id}/imagesalso clearscover_imageif it matches the removed URL.
Listing Lifecycle
All listing models (Property, Tour, Vehicle, BoatEquipment) follow the same four-stage lifecycle:Create (Vendor)
An authenticated vendor submits a
POST request to the appropriate listing endpoint (e.g. POST /api/v1/properties/). The backend enforces mass-assignment protection via an ALLOWED_FIELDS allowlist, resolves the vendor profile from the JWT identity, auto-generates a URL slug ({name-slug}-{8-char uuid}), and persists the record with is_active = True.Publish / Approve
Properties and tours become publicly visible as soon as
is_active = True and the owning vendor is verified. Admins can additionally toggle is_featured to surface listings in featured carousels (cached at a shorter TTL of 180 s).Update
Vendors update their own listings with
PUT /api/v1/{resource}/{id}. Ownership is verified by matching the JWT vendor profile against the listing’s vendor_id. SUPER_ADMIN can update any listing. On save, the relevant Redis cache keys are invalidated.Soft Delete
DELETE /api/v1/{resource}/{id} does not remove the database row. For properties and tours it sets is_active = False; the deleted_at timestamp column is available on all models for hard-delete scenarios or audit queries. All cache keys for the listing and the global listing list are invalidated on delete.The commission model (10% platform fee) is applied at payment time, not at listing creation. Vendors pay nothing to list; the platform deducts its share only when a booking is paid via Stripe Checkout. The default rate is controlled by
STRIPE_COMMISSION_RATE=0.10 in the backend environment, and can be overridden per vendor via the commission_rate column on the Vendor model.Caching
Maleku System caches listing responses in Redis to minimise database load. Cache keys are tagged so they can be bulk-invalidated when a listing is created, updated, or deleted.| Cache Key Pattern | TTL | Invalidated On |
|---|---|---|
vendors:list:{limit}:{offset} | 300 s | Any vendor create/update/delete |
vendors:detail:{vendor_id} | 600 s | Specific vendor update/delete |
vendors:slug:{slug} | 600 s | Specific vendor update/delete |
properties:list:{filters}:{page} | 300 s | Any property create/update/delete |
properties:detail:{id} | 600 s | Specific property update/delete |
tours:list:{filters}:{page} | 300 s | Any tour create/update/delete |
tours:detail:{id} | 600 s | Specific tour update/delete |
CACHE_TTL_FEATURED) to reflect promotional changes more quickly.