H1Trips PRD - Molino App
version: 2026.04
status: locked
owner: Molino
scope: app/trips
last_updated: 2026-05-06
H2Focus Strip
| Now | Lock | Do Not Break | Next Closure |
|---|---|---|---|
Rebuild /trips landing toward original Al-Andalus cadence | Direct page stack + builder-backed content + public projection | Section keys/content ids, trip-engine pricing, public/draft separation, planner assistant autocomplete | Apply same production criteria to /trips/[tripId] |
H2Session Update - 2026-04-29
Current verified state after the first reference-driven pass:
/tripskeeps the builder-backed section surface and now includes a dedicated direct-booking band inside featured experiences.- FareHarbor booking on
/tripswas verified locally onhttp://localhost:3002/trips; clickingBook Córdoba tourkept the user on Trips and opened the lightframe path instead of redirecting away. /tripsnow exposes a visibleBack To Studiobridge in the final CTA/footer area even when persisted section content omits it./trips/[tripId]no longer fails just because edit bootstrap is unavailable; public trip detail renders again with pricing preview, schedule, join panel, and project-offer bridge routes.
Open product gap from the same check:
- persisted builder content is still overriding several newer registry defaults, so the live public copy and CTA targets are not yet aligned with the full legacy landing cadence.
H2Session Update - 2026-05-06 - Trips Dock Added To Homepage
Current staged code state:
/tripsnow mounts the existing bottom-centeredTripEditDock, matching the hide/reveal tools button pattern already exposed on/experiences.- This reuses the existing Trips dock component rather than creating a second control pattern.
- On the homepage the dock exposes the trip-generation path cleanly, while trip detail/edit routes keep the richer edit/view behavior tied to a concrete
tripId.
H2Session Update - 2026-05-06 - Plans/Experiences Type Mapping Corrected
Current staged code state:
trip_featured_planswas incorrectly mapped toTripFeaturedCitiesContentinsideTripsSectionContentMap.- Corrected that mapping to
TripFeaturedExperiencesContent, which matches current code reality: in the Trips landing, "plans" are using the same entity/id surface as experiences. - This preserves the current semantic overlap in the codebase where plans/city-plans/experiences can share
experienceId-based selection without forcing a broader rename pass yet.
H2Session Update - 2026-05-06 - Travel Symbol Header
Current staged code state:
- Added a very subtle fixed travel header shared by Trips and Experiences.
- The header links
⺢back to/studio,🛬to/trips, and🚩to/experiences. - It is intentionally symbolic and overlay-only so it does not disturb the locked Trips hero or the Experiences twin header.
H2Session Update - 2026-05-06 - Trips Landing Direct Stack
Current staged code state:
/trips/page.tsxno longer renders the public landing through the dynamic registry renderer.TripsLandingSectionscomposes the visible landing sections directly in page order while keeping persisted section ids, local edit state, andupdateTripsLandingSectionContentcommits.TripsSectionRendererand the unused dynamicTripsPageClientwere removed from active app code.- The Trips registry remains available for defaults, seeds, and section tooling, but it is no longer the public page layout engine.
H2Session Update - 2026-04-29 - Trip Detail Access Guard
Current staged code state:
/trips/[tripId]now checks trip visibility on the server before rendering detail data.- A trip is visible when
shareForOthersis true, or when the signed-in user owns the trip project, or when the user is an admin. - The trip edit bootstrap is only loaded for users who can edit the trip; the previous fallback edit bootstrap was removed so private edit state cannot be reconstructed by the public detail route.
- The trip edit dock disables the edit path unless the current detail/edit page has confirmed edit permission.
- The assistant route-awareness context and trip planner context now use stable callbacks/memoized provider values to prevent maximum-update-depth loops during trip editor mount.
Verification:
- Targeted ESLint passed for the touched trip and assistant context files.
- Local HTTP check:
http://localhost:3000/trips/1returned200 OK. - Local headless browser hydration check on
/trips/1completed without maximum-update-depth or page runtime errors. - Local unauthenticated edit check:
http://localhost:3000/trips/1/editreturned404 Not Found. - Full
tsc --noEmitis still blocked by existing milestone/md/experience Prisma type drift outside this Trips pass.
H2Session Update - 2026-04-29 - Trip Editor Persistence Boundary
Current staged code state:
- The trip planner edit surface keeps React state as a draft only.
- Persistence still goes through the server action
updateTripFromPlanner; the client does not write directly to Prisma. - Edit mode now saves on field blur, route/service selection commits, explicit
Save, step tab changes, bottom step navigation, and finalDone. - Successful saves call
router.refresh()so server-rendered trip detail, pricing, schedule, and visibility state can re-project from database truth. - Save failures are now visible in the editor instead of silently disappearing.
Important data-model note:
Tripcurrently persistsname,startDate,numPax,featured,shareForOthers,hotelStandards, andTripCityrows.- Planner fields
hotelMode,numDoubleRooms, andnumSingleRoomsdo not currently exist onTrip; they exist on quote/join flows. Those fields will not be canonical trip persistence until the schema/storage contract is extended or they are moved out of the trip editor.
H2Session Update - 2026-04-29 - Trip Command Surface Implemented
Current staged code state:
/trips/[tripId]now loads under a Suspense-backed server content boundary.- The visible hero H1 becomes the edit surface for the trip title when edit mode and trip write access are active.
- The detail page no longer mounts the large planner form as the primary edit surface; it uses focused command islands for trip settings and per-city edits.
- New server actions persist through the database only:
updateTripBasicsupdateTripCitycreateTripCitydeleteTripCitysyncTripProjection
- Each successful command revalidates trip routes and refreshes the client surface.
- TripCity edits update one relation row at a time instead of replacing every city row.
shareForOthersandfeaturedremain separate meanings: shared/joinable vs Molino-curated.
Schema contract staged:
Trip:targetParticipants,hotelMode,numDoubleRooms,numSingleRooms,mainImage.TripCity:choiceMeals,packageType.- Prisma Client and Zod schemas were regenerated against the staged schema.
Verification:
- Targeted ESLint passed for the touched trip command/page/action files.
- Filtered TypeScript check showed no
app/tripserrors. - Full typecheck is still blocked by unrelated milestone/md/experience drift.
prisma migrate deploywas not applied because the configured database is the remote Prisma Accelerate/Postgres target and escalation was rejected as too risky without explicit DB-deploy approval.
H2Legacy Lane Copy Targets (latest-aelib)
These are the commercial lane/CTA phrases we are treating as explicit targets to reintroduce into /trips (in builder content and/or repo defaults), because they communicate the landing intent cleanly:
Daytime Plans Designed By Locals!Design & Share Your Own Private TripJoin Our Featured Group TripsTravel Professional? Join Our Local Team
Done when:
- these phrases (or extremely close wording) appear as the primary lane titles on
/trips - each lane CTA routes to a real Molino Trips route without leaving the Trips domain (except the explicit Studio/About bridge)
H2Legacy Flow Parity Checklist (Structure First)
Target structure parity with the classic/legacy landing flow:
- Intro/Hero
- Commercial lanes (4)
- Featured trips section
- Banner separator: Featured Cities
- Featured cities list
- Banner separator: Featured City Plans
- Featured plans list
- Banner separator: Articles / Updates
- Updates teaser + continue reading
- Keep-in-touch / pro-local network CTA
- Anchor footer quick-links block
- Final CTA / Studio bridge
Current status in code:
- Registry-backed landing now includes banner separators, plans, updates, keep-in-touch, and anchor footer keys.
- Remaining mismatches to resolve later (after parity):
- Replace placeholder updates content with real content feed (or a curated list) for
/trips/updates. - Replace keep-in-touch CTA
/studio#connectwith a Trips-native contact surface when ready (or embed a controlled form). - Align
/trips/featuredstyling closer to the old travel “calendar + featured trips” vibe after the main landing flow is locked.
- Replace placeholder updates content with real content feed (or a curated list) for
H2Legacy Harvest - 2026-04-29
Reference files reviewed:
legacy-version-reference/components/forms/TripForm.tsxlegacy-version-reference/components/forms/TripEditForm.tsxlegacy-version-reference/components/forms/TripAdminEditForm.tsxlegacy-version-reference/components/forms/PublicTripForm.tsxlegacy-version-reference/components/forms/TripCityQuoteForm.tsxlegacy-version-reference/components/forms/PlanForm.tsxlegacy-version-reference/pages/cities/index.tsxlegacy-version-reference/pages/cities/[name].tsxlegacy-version-reference/pages/featured/index.tsxlegacy-version-reference/pages/featured/[id].tsxlegacy-version-reference/pages/plans/index.tsxlegacy-version-reference/pages/plans/[id].tsxlegacy-version-reference/pages/pro/collaborators.tsxlegacy-version-reference/pages/pro/organisers.tsx
H3Legacy trip form details worth preserving
- Stepper shape existed explicitly:
- register/login
- trip basics
- city selection
- Trip basics included:
- trip name
- start date
- expected participants
- public/open-for-others toggle
- featured toggle
- hotel standard
- double rooms
- single rooms
- main image
- Public/shared trip flow added:
- target participants
- estimated price per participant
- Admin/private edit flows also exposed:
- minimum participants for public trips
- featured/public controls
- main image editing
- City rows carried more execution detail than the current planner surface:
- city name
- nights
- local guide choice
- tours choice
- meals choice
- package type
- intercity transport
- city transport
- attached plan ids
H3Legacy trip-side concerns still not fully implemented in current Molino
- Public/shared trip authoring still needs a clearer current equivalent for:
- target participants
- public joinability thresholds
- explicit per-person estimate preview
- City stop editing still lacks first-class current UI for:
- transport mode selection
- guide/tours/meals toggles
- package type framing
- Provider quote input existed per city through
TripCityQuoteForm:- accommodation
- city transport
- intercity transport
- travel guide This is still relevant to later quote, supplier, or booking-bundle workflows.
H3Legacy cities route behavior
/citieswas simple but useful:- published city listing only
/cities/[name]carried a stronger city-detail pattern than the current Trips city page:- hero/banner image
- longer editorial city narrative
- multi-part description/content blocks
- owner/admin edit path
- embedded list of available local plans
- bottom bridge back into broader city discovery
H3Current-gap note for cities
Current Molino already has:
/trips/cities/trips/cities/[citySlug]
But the current implementation is still lighter than legacy:
- list page is present and clean
- detail page is present but mostly summary + local-plan links
- missing richer city story, image-led detail, and deeper city-to-plans presentation
H32026-05-06 UI polish pass
- Trips landing components were visually tuned toward the locked Spaces/editorial baseline without changing global tokens.
- Image integration was improved across core landing sections with clearer aspect ratios, lighter card surfaces, and less cramped spacing.
- Featured experiences and plans now use a more Pinterest-like masonry rhythm for browsing, while featured trips and cities remain more structured and route-led.
- Weekly sessions and collaboration surfaces were brightened and given more breathing room so the page stays luminous rather than heavy or overly dark.
- The editorial features card row now acts as the first local candidate for a reusable Spaces-guided poster-card standard: contained images, varied aspect ratios, light surfaces, restrained borders/shadows, and a less square browsing rhythm.
H3Legacy featured route behavior
pages/featuredwas effectively a marketing/magazine/landing-page system backed by item-like lander payloads:- hero section
- repeated sections with subtitle/title/description/image/cta/style
- footer CTA
- social links
- This was closer to a curated landing-builder than to canonical trip/product truth.
H3Current interpretation for featured
- Treat legacy
featuredas a reference for:- curated magazine-like campaign pages
- item-driven landing content
- reusable hero/section/footer structures
- Do not treat it as trip execution truth.
- Best current home is alongside:
- Trips builder-backed marketing sections
/mdor editorial surfaces- future curated campaign or feature pages
H3Legacy plans route behavior
/planswas a public list of published local plans plus a feature CTA./plans/[id]combined several important commercial behaviors:- plan hero/detail narrative
- choose date
- set participant count
- calculate per-person and group price view
- standalone booking action
- add to existing trip
- create a new trip from the plan
- city-context bridge
H3Current interpretation for plans
- In Molino, this maps mostly to
Experienceas the supporting inventory/entity. - Keep the conceptual bridge:
- experience/plan as standalone bookable or requestable unit
- experience/plan as ingredient inside a Trip
- FareHarbor item shape should be treated as a projection/integration shape:
- not canonical truth
- but important enough to model explicitly in adapters/types
H3Legacy pro route behavior
pages/pro/collaborators.tsxandpages/pro/organisers.tsxwere long-form partner/network landing pages.- They covered:
- local experts
- organisers
- guides
- workshops
- B2B/private groups
- API/distribution language
- collaboration/network positioning
H3Current interpretation for pro/network
- Best current home is
/trips/network. - Use as reference for the second narrative lane:
- traveller/group organiser
- local expert/provider/travel professional
- Preserve the provider/pro narrative without mixing it into the public trip-planning flow.
H3Recommended closure order from this harvest
- Enrich the current Trips planner/edit surface with the missing legacy stop/service fields, but keep
TripPlannerContextand normalized stops as the authority. - Deepen
/trips/cities/[citySlug]so it reads more like a real city landing with plans, not just a summary card wall. - Deepen
/trips/plans/[planSlug]andExperiencedetail so standalone booking, add-to-trip, and trip-creation bridges are explicit again. - Use legacy
proandfeaturedmostly as narrative/content references for/trips/network, builder sections, and curated campaign/editorial pages rather than as execution models.
| State | Meaning |
|---|---|
| built/locked | /trips/page.tsx, registry rendering, getTripsPublicData() |
| built/partial | planner create/update, TripJoin snapshots, quote output |
| docs-ahead | one canonical quote/join -> LineItem/Offer path |
H10. Implementation Snapshot
H1Corrected Next Slice - Respect Builder + Trips Hub
status: aligned with architecture
scope: /trips hub via Section Builder (NOT hardcoded page)
priority: HIGH
H1Core Correction
You are correct.
Previous direction to avoid:
- hardcoding sections in
/trips/page.tsx - bypassing builder system
Correct direction:
/tripsis a Section Builder surface- sections = editable + deployable content units
- page = renderer only
- components (like yours) = dual-mode (edit/view)
This component proves:
- Builder is already the authority.
- We must compose registry + content, not override it.
H1Already Confirmed
From your component:
- Section Builder integration working.
useSectionContentmerges defaults and persisted content.useSectionContentFieldgives field-level authority.useArrayFieldsupports deterministic list editing.- editMode is respected.
- commit-on-blur pattern is respected.
- no mutation leakage.
H1Next Slice
H2GOAL
Turn /trips into:
Builder-driven commercial hub
NOT:
- static layout
- hardcoded sections
H1G-B1 - /trips Page = Builder Orchestrator
H3file
app/(pages)/trips/page.tsx
import { Suspense } from "react"
import { getPageSections } from "@/app/(home)/builder/actions/getPageSections"
import { renderSection } from "@/app/(home)/builder/lib/renderSection"
export default async function TripsPage() {
const sections = await getPageSections("trips")
return (
<>
{sections.map((section) => (
<Suspense key={section.id}>
{renderSection(section)}
</Suspense>
))}
</>
)
}
H2Current goal
H3Ship the first working booking surface end-to-end in `/studio/travel`
Use one city tour card and one featured trip card with real FareHarbor buttons while keeping /trips as the visible commercial trip hub with four clear lanes.
H3Keep featured experiences as a supporting commercial lane
Do not promote featured experiences into a separate primary business root.
H2Remaining features
H3Render the four lanes near the top with native Molino cards in `/trips`
Keep the commercial lanes visible and easy to scan.
H3Wire FareHarbor buttons through Lightframe modal execution only
Use button-driven modal execution only, with no embedded grids or calendars.
H3Keep the `/studio/travel` cards aligned with the same FareHarbor button behavior
Make the travel bridge behave like the Trips booking surface.
H3Keep planner, join, pricing, and collaboration paths visibly separate
Do not collapse booking, planning, and enquiry into one generic flow.
H3Add the footer bridge back to `/studio`
Keep the reverse handoff visible without weakening Trips.
H3Preserve the experience read model inside Trips while keeping Trip, LineItem, Offer, and Order as the execution chain
Treat experiences as supporting inventory and preserve the trip-to-commerce bridge.
H2Next build steps
H3Inspect `app/trips/components/`, the travel card helpers, and landing actions before changing UI
Check the current route structure before adjusting the booking surface.
H3Confirm `FareHarborBookAction`, `TravelBookingCard`, `FeaturedTripBookingCard`, `FlexibleTripPlannerCard`, and `CollaborationsCard`
Verify the existing lane components still match the intended surface.
H3Verify the `/studio/travel` booking cards use the same real FareHarbor button behavior as `/trips`
Keep the booking behavior consistent across the two entry surfaces.
H3Verify trip pricing still maps through `TripPricing` and downstream `LineItem`
Preserve the commercial bridge before any UI work ships.
H3Run the `/trips` route after changes and check draft/public separation
Confirm the live route still renders and keeps the read layers separate.
H3Keep the featured experiences lane aligned with the reusable experience catalog, not with trip authority
Avoid moving discovery inventory into the core execution root.
H2Prompt starter summary
H3Ship the first working booking surface in `/studio/travel` plus the four-lane commercial trip hub in `/trips`
Use native Molino cards, Lightframe FareHarbor buttons, a read-only page, a preserved footer bridge back to /studio, and a supporting featured-experiences lane.
H2Prompt starter
Implement the next Trips PRD slice. Use _PRD/trips/README.md as source of truth. Keep /trips as the commercial trip hub with four visible lanes: ready-made city tours, featured guided group trip, flexible trip planning, and collaborations. Use native Molino cards. FareHarbor is button/modal execution only through Lightframe; do not embed FareHarbor grids, calendars, or widget React children. Keep mutations in app/trips/actions/, page.tsx read-only, and TripPricing -> LineItem as the economic bridge. Preserve draft/public separation and add or maintain the footer bridge back to /studio.
H2Functional note
H3The lane structure is live, and the active public projection is no longer the old dummy read layer
Treat app/trips/actions/trips.read.actions.ts as an obsolete reference surface unless a route imports it directly. The active /trips public read chain is:
app/trips/page.tsxapp/trips/actions/tripsLanding.actions.tsapp/trips/lib/mapProjectSectionsToTripsSections.tsapp/trips/components/TripsLandingSections.tsxapp/trips/actions/trips.read.actions.tsapp/trips/actions/trips.list.read.actions.ts
H2Public Read Layer - Locked
H3Use a single projection helper for `/trips` landing lanes
/trips/page.tsx supplies featuredTrips, featuredCities, and featuredExperiences to the direct landing stack while section content still comes from the andalusian-trips-lab builder project.
Current implementation note:
featuredTripsandpublicTripscome from PrismaTriprows whereshareForOthersis true andstartDateis not in the past.featuredTripsalso requiresfeaturedtrue.- trip pricing is attached through
tripEngine(mapEntityToTripInput(trip)). featuredExperiencescomes from active PrismaExperiencerows with optionalCityrelation.- FareHarbor execution URLs are derived from
Experience.externalIdwhen present. - the landing project slug is
andalusian-trips-lab.
H2Code Audit - 2026-04-26
H3Built / locked
/trips/page.tsxis a server orchestrator that fetches builder-backed section content and public projection data, then renders the directTripsLandingSectionsstack.getTripsLandingSections()reads the builder project with slugandalusian-trips-laband falls back to registry defaults when needed.mapProjectSectionsToTripsSections()filters invisible or unknown sections and preserves registry authority.getTripsPublicData()is the active lane projection for featured trips, public trips, featured cities, and featured experiences.
H3Built / partial
createTripFromPlanner()creates a privatemy-tripsproject for the user if needed, resolves or creates thetripproduct type, persistsTripandTripCityrecords, and revalidates trip routes.updateTripFromPlanner()checks project owner before replacing TripCity rows and updating trip metadata.createTripJoin()stores a pricing snapshot, total services, total per person, and total group for the join request.recomputeTripJoins()can refresh pricing snapshots for all joins on a trip.quoteTripJoin()returns pricing, mapped line items, totals, and assumptions for enquiry/quote surfaces.
H3Docs-ahead / pending
quoteTripJoin()asks for hotel totals after callingmapTripPricingToLineItems(), but that mapper currently filters hotel rows out. Treat hotel quote totals as pending until the quote mapper preserves or separately handles hotel rows.TripPricingexists in Prisma, but the active public list attaches live computedtripEngineoutput rather than reading persistedTripPricingrows.- The final path from trip quote/join into committed
LineItem -> Offer -> Orderrecords is not fully locked in one canonical action.
H3Critical next step
Lock the trip quote/join to committed LineItem/Offer behavior: decide whether hotels remain excluded from line items or become a separate line-item group, then make the quote totals and offer commit use the same rule.
H3Keep the city-tour lane experience-driven
Derive the city-tour lane from active experiences and their city metadata, not from a separate booking model.
H3Keep the featured-trip lane trip-driven
Use the public trip projection for featured and broader trip cards.
Prompt starter companion:
Audit the Trips route as shipped today. Keep the four commercial lanes and the featured-experiences lane. Preserve Trips as the execution root, keep experiences as supporting inventory, and do not move pricing or booking authority out of Trip -> LineItem -> Offer -> Order. If you update the read layer, preserve the current lane structure and replace the temporary seed data deliberately rather than accidentally.
H2Session Note - 2026-04-28
- pending revision - ✅ completed: aligned the Molino Index section source sheets with the current Trips commercial lanes and synced them back into the local generated data.
- pending revision - ✅ completed: preserved
/tripsas a builder-driven page while improving fallback/default section copy for the four lanes: ready-made city tours, featured guided trips, flexible trip planning, and collaborations/providers. - pending revision - ✅ completed: added visual fallback assets to featured trip, featured city, and featured experience cards so the public Trips surface can read more like a commercial front door even when editable content is sparse.
- pending revision - ✅ completed: verified
200responses for/trips,/trips/featured,/trips/cities,/trips/plans,/trips/network,/trips/planner,/studio/experience,/studio/travel, and/studio/education. - pending revision: human browser review is still needed for final visual polish and real FareHarbor modal-click behavior before main-project integration.
H2Session Note - 2026-04-29
H3Landing Reference Inspection
The older reference at https://latest-aelib.vercel.app/ establishes the target landing cadence:
- compact menu and immediate Al-Andalus brand signal
- stacked primary CTAs for daytime plans, private trip design, featured group trips, professional entry, and local network entry
- welcome section, then Travel / Learn / Experience pillars
- audience sections for travellers, local experts, and trip organisers
- group trip narrative, plan-your-trip section, featured cities, and update/news style content
H3Current Route Inspection
Local /trips already carries the stronger framework base:
- builder-backed section content rendered through the direct
TripsLandingSectionsstack - public trip, featured city, and featured experience projection
- planner route at
/trips/newwith assistant-supported form completion - FareHarbor-style execution links kept separate from trip truth
- detail page and edit page routes at
/trips/[tripId]and/trips/[tripId]/edit
H3Permission Change
Trip edit mode now follows the owner/admin rule:
- owners can edit their own trip records
- admin can edit any trip
- non-owners cannot bootstrap the edit form or persist updates
Admin is currently resolved through ADMIN role or zaruqsummers@gmail.com.
H21. Product Identity
H3Name
Trips
H3One-line Definition
Trips is the canonical commercial planning and public booking surface for Molino trip experiences, including featured experiences as a supporting lane.
H3User-facing Purpose
This feature exists so users can:
- browse trips and featured experiences
- open trip detail and join flows
- start booking or enquiry actions
- understand trip timing, pricing, and availability
H3Internal Platform Purpose
Inside Molino App, this feature exists to:
- preserve trip canonical data
- expose a controlled public route surface
- connect planning, pricing, and booking overlays
- keep LineItems and projection flows stable
- keep experiences visible as reusable ingredients without moving execution authority out of Trips
H22. Route Role
- Trips is the main commercial and operational trip hub.
- Trips is the actual actionable offer surface.
- Trips remains broader than Studio Travel.
- Experiences sit alongside Trips as supporting commercial units, not as the top-level execution root.
H22.1 Experience Positioning
- Trips already renders a featured experiences lane.
- Experiences act as reusable commercial ingredients and discovery surfaces.
- Trip pricing, join flows, and booking authority stay in the Trips execution chain.
H22.2 Naming Alignment
Use one shared concept family across the trip surfaces:
- ready-made city tours
- city highlight tours
- featured experiences
- experience cards
These all refer to the same visible commercial lane: reusable city-linked trip ingredients surfaced inside Trips.
Use one shared planning family for the intake side:
- flexible trip planning
- trip plan
- trip planner
- plans
These all refer to the same planning / intent surface that feeds Trips, not a separate commercial entity.
H22.3 Backend Intent Reference
H3Source meaning
There is an older full backend/API scope for travel operations that should be treated as product-intent reference material, not as a separate deployment target. Its useful scope includes users, cities, trips, trip cities, plans, trip-city-plan joins, items/experiences, participant details, costs, bookings, quotes, payments, hotels, landing pages, and external booking integrations.
Molino should preserve that intent while replacing the split backend shape with the existing Next.js stack. The goal is not to keep a parallel NestJS-style backend or duplicated service layer. The goal is to absorb the useful service boundaries into app/trips, Prisma models, server actions, route handlers where needed, document projection, and the existing Trip -> LineItem -> Offer -> Order commercial chain.
H3Core trip concept
The Trip is the flexible journey record. It may be public, private, cloned, edited, quoted, booked, or projected into documents. A trip can include multiple cities, dates, participants, plans, costs, sessions, hotel options, and external booking references.
Public users should see a clear travel offer. Internal users should manage the canonical operational state.
H3Service-intent map to preserve
- Cities and destinations: spatial anchors such as Cordoba, Granada, Seville, Malaga, Morocco, or future destinations. Cities feed trips, plans, landing pages, public imagery, local notes, and session scheduling.
- Trips: full journey containers that can be created, edited, cloned, listed, previewed, assigned, published, and connected to city plans or schedules.
- Trip cities: ordered route structure inside a trip, including dates, nights, city purpose, and local rhythm.
- Plans: reusable itinerary blocks such as visits, guided walks, workshops, excursions, transfer days, free days, local evenings, and partner-led experiences.
- Trip city plans: the merge layer between a trip, a city, and a plan. This answers which available plans fit a city inside a specific trip.
- Items and experiences: public catalog units such as tours, sessions, workshops, partner services, or standalone bookable products. They may be published independently or surfaced along a route.
- Participant details: traveller names, party size, preferences, rooming notes, requirements, dietary needs, arrival context, and desired support level.
- Costs and estimated pricing: line-level commercial inputs for plans, services, hotels, guides, transport, margins, and optional extras. These should feed the pricing engine and downstream line items instead of being recomputed inside documents.
- Quotes: commercial offer versions generated from a trip plan. A quote can become a document, email draft, payment link, offer, or confirmation path.
- Bookings: accepted traveller intent for a trip, plan, or item. Molino should support both internal booking records and external booking references.
- Payments: gateway execution layer. Trips and quotes create payment intent; Stripe or another provider executes payment; Molino stores the external reference and status.
- Hotels: begin as structured options inside trips, plans, quotes, or line items. API search, geocoding, rate keys, and confirmations are later-stage integrations.
- Landing pages: public conversion surfaces generated from trips, cities, campaigns, featured routes, or partner offers.
- Users and profiles: travellers, admins, collaborators, sponsors, guides, or future subscribers, with ownership and access determining who can create, edit, quote, book, or view private details.
- FareHarbor and external booking: FareHarbor remains the parallel execution surface for core city sessions and standalone bookable experiences. Molino stores public CTA targets, booking modal links, external IDs, and confirmed references.
H3Strategic merge pattern
The important product pattern is the merge between trip bookings and session bookings. A single real dated session, such as a Cordoba walk or Granada visit, can accept standalone FareHarbor bookings while also belonging to a larger private or group trip.
When those streams meet in the same real session, the economics improve: independent travellers, trip participants, and local sessions can share guide time, capacity, and cultural value. This is a central revenue and viability pattern for the trips system.
H3Current scope to keep visible
- public trips page
- trip create/edit/view with persistent records
- page ID routing
- basic city and route structure
- featured trips
- featured cities
- experiences along the route
- manual or semi-structured trip planning CTA
- reusable content from older travel pages
- internal CRUD for trip records
- FareHarbor-compatible public booking links
- documentation and PRD visibility through the markdown renderer
H3Next stage
- trip city ordering and nights
- plan blocks per city
- participant detail forms
- quote draft generation
- estimated pricing and cost line items
- trip schedule view
- trip cloning for reusable routes
- landing pages generated from trip records
- Google Doc trip proposal projection
- Sheet/Docs indexing for content and operations
- sponsor or partner-facing trip summaries
- admin workflow for reviewing and publishing trips
H3Later stage
- Stripe checkout and invoice integration
- booking status workflows
- hotel API/search integration
- user accounts and traveller dashboards
- payment history
- calendar projection
- automated follow-up routines
- multi-party group trip matching
- advanced partner/supplier workflows
- API routes for external integrations
- subscription or sponsor-access layers
H3Replacement rule
Any copied or referenced backend service shape should be translated into Molino's own Next.js architecture before production use. Do not split the codebase or deployment just to preserve the old API shape. Use the old backend as a map of domain intent, then implement the durable parts through local Prisma data, server actions, route handlers, trip engine helpers, document projection, and the commercial Trip -> LineItem -> Offer -> Order path.
H23. Commercial Lanes
H3Lane 1 - Book Ready-Made City Tours
- use app-native cards
- use FareHarbor booking button only
- open booking in Lightframe modal
H3Lane 2 - Join the Featured Guided Group Trip
- use app-native premium featured-trip card
- use FareHarbor booking button only
- open booking in Lightframe modal
H3Lane 3 - Plan a Flexible Trip
- use in-app planner
- use quote or assisted planning
- use Molino trip-building logic
H3Lane 4 - Collaborations
- use dedicated intake flow
- use dedicated application or request path
- do not default to a generic contact form
H24. Section Requirements
- show the four visible commercial lanes above the fold or as close as possible
- present the four visible commercial lanes near the top
- keep planning, calculation, sharing, and promotion paths explicit
- preserve featured trip, custom trip, and collaboration pathways
- avoid raw FareHarbor widgets
- avoid over-editorial Studio language
- avoid one generic form for all intents
H25. Footer Bridge
Add a small closing bridge back upward to Studio:
- Developed by Molino Practice
- link to
/studio - optionally link to Skills, Practice, and Experience
This keeps the reverse transition visible without weakening /trips.
H26. Scope
H3In Scope
- routes:
/trips,/trips/new,/trips/[tripId],/trips/[tripId]/edit,/trips/featured - app folder:
app/trips/ - actions: trip read, planner read/write, join create/recompute, landing read, draft creation
- types:
trip.types.ts,trips.sections.types.ts, planner types - integrations: FareHarbor-facing booking overlays, document/projection handoff, public trip API surfaces
- models:
Trip,TripPricing,TripPost,PublicTrip,TripJoin,LineItem,Offer,Order - related supporting input: featured experiences from the reusable experience catalog
H3Out of Scope
- replacing the trip planner engine with a different product
- turning the public route into a generic CMS
- moving booking authority into client state
H27. Authority Model
page.tsxreads and orchestrates onlyapp/trips/actions/owns mutation logicapp/trips/api/stays for external access onlyTripPricingand downstream line items remain explicit economic layers
H28. Current Implementation Surface
app/trips/actions/trips.read.actions.tsapp/trips/actions/tripsLanding.actions.tsapp/trips/actions/trips.planner.read.actions.tsapp/trips/actions/trips.planner.edit.read.actions.tsapp/trips/actions/trip-join.create.tsapp/trips/actions/trip-join.recompute.tsapp/trips/actions/trip.update.actions.tsapp/trips/actions/createTripDraft.tsapp/trips/components/app/trips/new/app/trips/[tripId]/
H29. FareHarbor Rules
- buttons only
- no calendar embeds
- no item-grid embeds
- no widget rendering as React children
- no production dependence on parsed HTML widget islands except test or reference
- use FH booking URLs or button targets only
H210. Immediate Components
FareHarborBookActionTravelBookingCardFeaturedTripBookingCardFlexibleTripPlannerCardCollaborationsCard
H210.1 Studio Travel Bridge
/studio/travelis the first revenue-capable booking surface.- Use one city tour card and one featured trip card with real FareHarbor buttons there.
- Keep the planner CTA and collaborations CTA as in-app exits, not generic contact fallbacks.
- Treat the Studio surface as the entry bridge into Trips, not as a replacement for the Trips hub.
H211. Acceptance Criteria
- public trip routes render without runtime errors
- draft and public views stay separated
- planner and join flows remain explicit
- trip pricing continues to feed line items through a controlled bridge
- Trips shows the four commercial lanes clearly
- Trips uses native booking cards with FH button execution only
- Trips footer bridges back to Studio
- featured experiences remain visible as support input, not as a second primary hub
- old notes stay in
archive/instead of being deleted
H211.1 Session Notes
H32026-05-06 - Starting points binder added
- Added a small arrival/start-points binder near the top of
/trips, before the broader “Choose how you want to begin” lane section. - This binder now lives inside the Trips section registry/flow rather than outside the page architecture.
- This binder frames practical arrival logic first:
- Madrid arrival and welcome-service connection
- Malaga / Seville gateway connection
- direct Cordoba start
- Purpose: make the trip lane feel more operational and route-aware before the user reaches the wider commercial lane chooser.
- The following lane section was also tightened so it reads less like a duplicate of the arrival binder and more like the actual commercial choice layer: booking a day plan, joining a group trip, planning a private route, or opening a partner path.
H32026-04-28 - Backend intent merged into trip scope
Merged the wider backend/API service scope into the active Trips PRD as a reference, while keeping the implementation rule clear: useful backend services should be translated into Molino's existing Next.js stack, not preserved as a separate NestJS-style backend or deployment. The reference now captures cities, trips, trip cities, plans, participant details, costs, quotes, bookings, payments, hotels, landing pages, users, FareHarbor, and the strategic merge between trip bookings and dated session bookings.
H212. Locked Summary
Trips is the stable Molino module for trip discovery, planning, join flows, and commercial projection. It reads canonical trip data, keeps mutation authority in server actions, preserves the booking and pricing boundary, uses FareHarbor only as a button-driven execution layer, and treats experiences as supporting ingredients rather than the core execution domain.