MolinoPro

commercial-pipeline-and-projection-plan

Master Codebase Guidebook
Markdown + HTML Dev-Docs Renderer - Frontend Client Module

Default Index
Open README.md
Root: README.md_PRD
Milestones
H1Commercial Pipeline + Projection Plan

Status: active execution plan
Updated: 2026-05-05
Owner lane: Trips-first commercial flow + Office projection + Spaces seeding


H20) Scope We Are Stapling Down

This plan locks 3 goals:

  1. Trips -> Offer -> Booking (full/partial) -> Stripe -> Order -> Confirmation, with Offer/Order status updates and LineItems as economic truth.
  2. Generic Office adapter/bundler in Molino for Apps Script and future standalone adapter extraction.
  3. Seeding bundles from Molino into Molino Spaces API to generate one landing page per commercial niche, then use Spaces as a landing-page printer.

Operational closure note:

  • Trips landing page V2 plus dual-landing A/B test is now part of Goal 1 closure, because it is the top-of-funnel entry into the commercial flow.
  • Goal 1 also includes full production/marketing readiness for Trips, Experiences, and Products domains before exporting those lanes into Spaces variants.

H21) Current Reality Check (Code + Docs)
H3Already in place
  • Trip, Offer, Order, LineItem, Payment, BookingBundle, TripJoin models exist in Prisma.
  • Offer creation from trip pricing exists: app/trips/actions/trip-offer.actions.ts.
  • Offer to Order conversion exists: app/orders/actions/checkoutOffer.ts, app/orders/actions/orderFromOffer.ts.
  • Stripe payment primitives exist:
    • app/orders/actions/createPaymentIntent.ts
    • app/api/stripe/webhook/route.ts
  • Apps Script office actions already exist in code and docs:
    • docs.create, docs.exportPdf, calendar.create, drive.share, gmail.send
H3Gaps / inconsistencies to resolve
  • checkoutOffer is currently manual-first (creates Order with pending; separate manual confirmOrderPayment), while Stripe flow is separate.
  • Booking flow currently writes directly to Order in app/bookings/actions/booking.actions.ts and is not fully aligned with Offer -> Order pipeline semantics.
  • Partial payment states are not yet fully normalized across Offer/Order/Payment.
  • Canonical idempotency rules are not yet enforced end-to-end for exports/calendar.

H22) Canonical Pipeline Contract (Economic Truth = LineItems)
H3Hard rule

LineItems are the single economic truth surface for:

  • Offer totals
  • Booking totals (full/partial)
  • Order payable amount
  • Payment reconciliation
H3Canonical flow

Trip compute -> Offer instance (+ LineItems) -> Booking intent (full/partial) -> Stripe payment(s) -> Order status reconcile -> Confirmation projection

H3Visibility rule

Offer and Order may be internal-only; they must still be instantiated, linked, and status-synced.


H23) Goal 1 Plan: Trips -> Offer -> Booking -> Stripe -> Order
H2Phase 0 — Surface closure (Trips / Experiences / Products lanes)
  • Lock /trips as primary homepage lane with landing V2.
  • Use app/trips/ae-lander-v2/page.tsx as the main reference/template source, but merge it into the current /trips builder-backed landing instead of replacing the route wholesale.
  • Keep the current /trips route as canonical, then import the strongest visual/editorial sections and motion language from ae-lander-v2.
  • Prefer MarketingSlider with bytTourOperator2 as the Trips hero direction when promoted into the canonical Trips surface.
  • Keep the original Trips landing section logic and missing commercial sections, then add selected v2 improvements where they strengthen the page:
    • Features
    • VideoSection
    • CTA
    • FAQ
  • Ensure FareHarbor remains isolated in client-only interactive components.
  • Run dual-landing A/B variant for trips (v2 vs alternative) with stable routing and analytics tags.
  • Keep FareHarbor direct booking button+modal as alternative booking path for trips/experiences.
  • Keep Experiences as support inventory (not execution root), but rebuild /experiences as a twin public landing page rather than a starter/editor surface.
  • /experiences should lead with direct featured tours/city-tour booking and then bridge into bundled Trips and trip-planning.
  • /experiences also carries the collaborator/partner lane:
    • local collaborators
    • guides
    • partner resources
    • onboarding interest
    • territorial expansion / integration signals
  • Do not duplicate the full Trips commercial-lane story blindly inside Experiences; keep the emphasis reversed:
    • Experiences first
    • bundled Trips second
  • Keep a clear business-development extension lane inside Experiences without turning it into a second execution root.
  • Move starter/editor/scaffolding concerns to supporting routes such as /experiences/test or dashboard/editor lanes when needed.
  • Adapt experiences and product pricing adapters so both feed the same downstream economic contract:
    • source entity -> LineItems -> Offer -> Booking/Payment -> Order.
  • Finish Trips, Experiences, and Products landing pages to production + campaign launch level before Spaces seeding.
H2Surface-engine note
  • Treat MarketingSlider as a reusable universal hero engine.
  • Keep multiple slider configs registered in ae-lander-v2/sections/index.tsx.
  • Use configName as the swap boundary instead of creating new hero components per page.
  • Reuse this pattern later for Trips variants, Experiences variants, and future marketing pages.
H2Phase A — Domain normalization
  • Define status enums and transitions for:
    • Offer: draft | sent | partially_paid | paid | expired | cancelled
    • Order: pending | processing | partially_paid | paid | failed | cancelled
    • Payment: pending | succeeded | failed | refunded
  • Define one transition map in app layer (single source for allowed transitions).
H2Phase B — Booking alignment
  • Treat Booking as payment intent context over an existing Offer/Order economic base.
  • Stop treating generic booking creation as isolated order authoring.
  • Ensure every booking references:
    • offerId (if offer-based),
    • orderId,
    • relevant LineItem scope/snapshot key.
H2Phase C — Stripe integration closure
  • Ensure Stripe metadata always includes:
    • orderId
    • offerId (when present)
    • paymentId
    • idempotencyKey
  • Enforce partial-payment reconciliation:
    • compute paid sum from successful Payment rows,
    • derive remaining balance,
    • mark partially_paid vs paid deterministically.
H2Phase D — Confirmation and sync
  • On successful payment webhook:
    • update Payment status,
    • reconcile Order status,
    • reconcile Offer status from same economic state,
    • trigger first confirmation actions/communications (Office layer) without mutating truth.

Acceptance criteria:

  • Re-running payment webhook logic remains idempotent.
  • Offer/Order status always reflects Payment aggregate.
  • LineItems remain unchanged as economic source unless explicitly edited upstream.
  • Trips/Experiences/Products all converge to the same commercial conversion pipeline contract.
H2FareHarbor policy (Goal 1 companion)
  • Trips and Experiences keep FareHarbor as fast-route booking option (modal-first, no forced redirect away from app).
  • Molino in-app booking remains canonical for custom trips/custom services and full operational control.
  • FareHarbor calendar/API sync is a later stage, optional per client/manager context.
  • Near-term external FH bookings can remain manual-sync or no-sync where operationally unnecessary.

H24) Goal 2 Plan: Generic Office Adapter/Bundler (inside Molino first)
H2V1 module shape (extractable)
  • app/(office)/office/types/office.ts
  • app/(office)/office/validation/officeSchemas.ts
  • app/(office)/office/clients/appsScriptClient.ts
  • app/(office)/office/actions/projectOfficeBundle.ts
  • app/(office)/office/api/project/route.ts
H2Contract boundary
  • Molino computes business payloads.
  • Office adapter validates, normalizes, retries, orchestrates.
  • Apps Script executes atomic tasks only.
H2Initial supported targets
  • document.create
  • document.pdf
  • calendar.create (with externalKey idempotency)

Deferred targets:

  • advanced drive packaging
  • email automation
  • sheet object projection

Acceptance criteria:

  • One project request can create doc + pdf + calendar safely.
  • Calendar rerun does not duplicate events when same externalKey is used.
  • Projection metadata returns stable references for DB projectionMeta.

H25) Goal 3 Plan: Molino -> Spaces Seeding Bundles

Objective: generate ~10 landing pages (one per commercial niche/lane) from Molino main app via Spaces API.

H2Niche seed set (v1)
  • Trip itineraries / multi-day programs
  • Experiences / tours
  • Services / consulting
  • Coaching plans
  • Digital products / PDF products
  • Code systems / implementation offers
  • Subscriptions / retainers
  • Local business profile pages
  • Partner / affiliate campaigns
  • Event programs (scheduled)
H2Seeding flow

Molino domain data -> seed bundle builder -> Spaces API create/update page -> store page references in Molino projection metadata.

H2Project-to-Spaces printer mode
  • Add project action: Project -> Print to Spaces
  • Allow manual post-edit in Spaces.
  • Keep backlink from Spaces page to Molino entity/project.

Acceptance criteria:

  • At least 10 page seeds generated from real Molino entities.
  • Each seed bundle is deterministic and retry-safe.
  • Spaces references are persisted back in Molino.

H26) Execution Order (Recommended)
  1. Close trips surface: landing V2 + alternative dual landing A/B test + FareHarbor alternative path validation.
  2. Promote the best ae-lander-v2 sections into canonical /trips, rather than replacing /trips with the standalone v2 page.
  3. Rebuild /experiences into the twin public landing with reversed emphasis and proper booking bridges.
  4. Normalize Trip/Offer/Order/Booking/Payment statuses and reconciliation rules.
  5. Refactor booking + Stripe path to align with Offer/Order + LineItems truth.
  6. Align Experiences and Products pricing adapters to the same LineItems-first commerce contract.
  7. Ship Office adapter V1 module (internal-extractable).
  8. Wire confirmation + post-confirmation operational projection hooks (docs/pdf/email/calendar).
  9. Ship Spaces seeding bundle builder + first 10-page seed run.

H29) Immediate Build Queue (Closure Sprint)
  1. Trips landing V2 and alt variant wired for A/B exposure.
  2. Promote selected ae-lander-v2 sections and hero behavior into canonical /trips.
  3. Rebuild /experiences as the twin public landing and move scaffolding/editor concerns out of the public route.
  4. Canonical createOrderFromOfferSnapshot-style flow designated and used by booking/checkout.
  5. Partial payment reconciliation updates Offer + Order statuses deterministically.
  6. Experiences lane bridge to Offer pipeline (without making Experiences a root booking authority).
  7. Products lane bridge to Offer pipeline using LineItems as truth.
  8. Office adapter project endpoint (doc + pdf + calendar minimum set).
  9. Spaces seed run of 10 niches from Molino commercial lanes.
H2Booking lane closure checklist
  • Trips page:
    • direct FareHarbor fast-route modal stays available for suitable public tours
    • in-app custom trip confirmation/payment path stays primary for custom and modular trip requests
  • Experiences page:
    • direct FareHarbor fast-route booking cards for city tours and regular bookable experiences
    • clear bridge from featured experiences into bundled Trips when relevant
  • Offer/Order lane:
    • hidden data-carrier layer remains canonical for payment, confirmation, and projection
  • BookingBundle lane:
    • keep as operations/manual confirmation support, not the main public checkout UX
  • TripJoin lane:
    • keep as join/register intent surface until fully merged with canonical booking/payment flow
  • FareHarbor policy:
    • modal/lightframe preferred over redirect
    • external sync can remain manual until later FH API/calendar integration

H210) Production Closure Definition

Goal 1 is only considered closed when all are true:

  • Trips, Experiences, Products surfaces are production-grade and campaign-ready.
  • All three domains feed a single economic pipeline:
    • LineItems -> Offer -> Booking/partial -> Stripe -> Order -> confirmation.
  • Offer/order confirmation status and payment tracking are deterministic and auditable.
  • Initial confirmation-trigger action list is live (at least one operational projection path enabled).

Goal 2 is only considered closed when:

  • Office adapter module is running inside Molino with strict boundary:
    • Molino computes,
    • adapter orchestrates,
    • Apps Script executes.

Goal 3 is only considered closed when:

  • ~10 Spaces seed pages are created from Molino lanes with retry-safe bundle delivery and backlink persistence to Molino truth entities.

H211) Session Note - 2026-05-06

Implemented the first canonical commerce core slice in code:

  • added a shared order/payment reconciliation helper
  • added canonical createOrderFromOfferSnapshot() flow
  • updated checkout and document-to-order paths to use snapshot cloning instead of recomputing line-item economics
  • updated Stripe webhook/payment intent flow to reconcile order and offer statuses from payment records

This does not finish the whole commercial pipeline yet, but it establishes the base contract for:

  • Offer -> Order as clone/snapshot, not mutation
  • payment-driven order status reconciliation
  • offer status updates from downstream payment state

Document-flow clarification from code inspection:

  • app/documents/components/doc-sidebar/features/TripPlannerSidebarForm.tsx and app/documents/components/folio/lib/tripLineItems.ts still reflect the original document-first trip planning system.
  • app/documents/components/folio/FolioBinder.tsx currently recomputes trip pricing and can sync trip pricing rows into document-owned line items.
  • Keep that document system as a secondary orchestration/projection layer.
  • Do not let it define the main commerce UX for Trips going forward.
  • Future rule: user-facing confirmation and payment should happen from the Trip/Offer/Order surface directly; document generation should follow in the background from canonical Offer/Order data.

Landing-surface progress:

  • Promoted the first ae-lander-v2 editorial slice into canonical /trips through builder-compatible wrapper sections:
    • editorial features
    • story video
    • marketing CTA
    • FAQ
  • Added a native itinerary-style section into the current Trips registry flow so the landing feels more like a route unfolding, not only a collection of cards and CTAs.
  • Weekly agenda booking controls now reuse the shared Studio FareHarbor button behavior instead of a custom popup path.
  • Weekly agenda detail links and the Studio travel list both resolve against the same getStudioJourneySessions() source and the same canonical /studio/travel/{session.id} destination pattern.
  • Tightened the public Trips section order so the route now reads more directly as:
    • featured trips
    • itinerary spine
    • featured experiences
    • featured cities
    • how it works
    • plans
    • editorial/story
    • support and CTA
  • Left legacy banner sections in the registry for admin/editor continuity, but removed them from the main public /trips flow.
  • Rebuilt /experiences from the starter-editor route into the twin public commercial page:
    • direct FareHarbor city-tour booking first
    • bundled Trips bridge second
    • collaborator / partner / territorial-extension lane included
    • editor and mapping flow kept under /experiences/test

H27) Non-Negotiable Rules
  • No business logic in Apps Script.
  • No truth mutation from projection/export layers.
  • LineItems remain economic truth.
  • Idempotency keys required for external side effects.
  • Offer/Order instances are mandatory even when hidden from end users.
  • Documents are not the primary commerce confirmation UI for Trips.
  • Primary user path should be:
    • Trip surface -> design/offer confirmation -> payment -> Order-backed confirmation state.
  • Documents remain secondary/background projections derived from canonical Offer/Order data for sharing, export, portability, and follow-up operations.

Model-use note:

  • Default working model for this project: gpt-5.4.
  • Escalate to gpt-5.5 for harder tasks, especially architecture pivots, cross-domain refactors, critical payment/booking logic, difficult debugging, and pre-release stabilization passes.
  • Use lower-cost models only for lighter cleanup or narrow repetitive tasks when quality risk is low.
  • During implementation, explicitly analyze and advise which model and reasoning level to use when entering critical or high-complexity areas.
  • Preferred reasoning defaults:
    • low for narrow cleanup and simple doc/mechanical work
    • medium for most implementation tasks
    • high for critical-path commerce, projection, state reconciliation, or tricky production bugs

Design system rule:

  • Spaces design system is the direct base layer.
  • Molino editorial theme book is the parent tone layer (technical + philosophical nuance).
  • Trips UI should stay aligned with Spaces design language while preserving the editorial backbone.
  • Commercial/studio surfaces can be livelier, but must still inherit parent editorial bones for coherence.

H28) Session Note (2026-05-05)

This plan consolidates and supersedes fragmented notes for the three active goals:

  • commercial payment pipeline closure,
  • Office adapter planning,
  • Spaces seeding strategy.

Use this file as the execution source until phases are moved to closure docs.