Product
📌 Accomodations
- Status
- scoping
- Phase
- backlog
- Priority
- P0
- Owner
- kj
- Complexity
- high
- Estimate
- 2d
- Updated
- March 21st 2026
Notes
Quick thoughts, scribbles, links—capture the idea fast, flesh out later
Accommodations was chosen as the entity name instead of lodges because our taxonomy includes a vast number of stay types. One organization can have many lodges, which can have one or more rooms.
Page Components
Accommodation pages are profiles of each lodge where users can explore their amenities, activities and book stays. Self explanatory. We'll have at least two templates to begin with that differentiate our luxe inventory from our standard fishing lodge inventory. Later we may customize our templates to differentiate between verified/paid lodges and unverified/free lodges.
Breadcrumbs
- Two Types
- Lists out the destination hierarchy.
- EG: North America / United States / Wyoming / Yellowstone National Park
- Lists out the accommodations hierarchy
- EG: Fishing Lodges > Log Cabins > Al's Log Cabin
Media
- Images
- Video
Title, Subtitle & Location
- Carefully construct location—could by
City, StateorCity, Coutrydepending on context.- EG if user is viewing in english or in the United States they're recognize Bozeman, Montana. But if they're viewing somewhere in Iceland they'll want City, Country.
Primary Chips & Tags
- Lodge Type Chips—limit to ~4 w/ show more
- Eg: Eco-Lodge, Luxury, Kid Friendly, Mountains, Fly Fishing
- HasGuides? HasHunting? Seasonality? Species—highest level, highest priority info at the top–at a glance answers: "should I keep scrolling"
Share & Favorite
- Share Button
- Favorite Button
Fishiness Rating (Deferred)
How fishing-oriented is this accommodation? Is it exclusively a “fishing lodge” or is it a lodge that happens to offer fishing opportunities? This is a key differentiator we'll implement at scale after learning more from our data.
Proposed 1-5 scale:
- 5 — Fishing-First: Fishing is the reason this property exists. Purpose-built lodge, guides on staff, tackle room, fishing-focused meals and schedules.
- 4 — Fishing-Focused: Fishing is the primary activity but the property offers a broader experience. High-quality guide access, gear available, but also other amenities.
- 3 — Fishing-Forward: Fishing is a prominent offering among several activities. Guided trips available, but the property markets itself more broadly.
- 2 — Fishing-Friendly: Fishing is available but not central to the experience. Near fishable water, may arrange guides on request.
- 1 — Fishing-Adjacent: The property is near fishable water but fishing isn't part of the offering. Guests can fish on their own.
The rating would be AI-assigned during pipeline enrichment based on property descriptions, services offered, and proximity to water bodies, then validated by the lodge owner during onboarding. Deferred for now — will need to do this at scale after we learn more from the pipeline data.
Overview
High level description of the accommodations.
Why Book?
What's compelling about this lodge? What do we love about it? What do we dislike? This is our chance to add editorial flare, in our unique voice, from our perspective. Highly opinionated.
What's Included?
Explicitly included in pricing. This is a big differentiator. We may even want to structure and standardizes these items to extract market knowledge we could use to differentiate, inform our partners (the lodges), and educate clients.
What's Not Included
Explicit items that aren't included: - tips for guides or lodge staff (what are expectations?) - fishing gear? (waders, boots, rods, reels, rain gear?) - flights, transfers, taxis, shuttles? - meals, breakfast, dinner? - brainstorm items and ensure we have good ux in our lodge onboarding and dashboard that nudges the user to consider these items during profile creation, or updates.
Recommended Gear & Tackle
Overview of what anglers should bring with them. Packing lists. Downloadable PDFs, opt-ins that generate leads, maybe some affiliate play here. Not sure.
Guided Trips
Availability of guides, guide pricing, and details.
Rates, Packages, Deals, Pricing
Pricing, packages, and special offers. Number of nights + days.
Seasons
Information about seasonality including peak season, etc.
Terms & Conditions
Fine print, terms, legalese, etc.
Groups & Events
Weddings, corporate retreats, group events—this section is dedicated to event information and can deep link to each lodge’s website page for events/group information. (deep linking for paid listings only).
Cancellation & Refund Policy
May be a link with a modal that pops up. Probably more prominent once we add booking.
Getting There
Logistics & Transportation—nearest airport, high level overview of how to get to the lodge.
Non-Angling Activities & Things to Do
Section for other non-fishing things to do in the area.
Frequently Asked Questions
What type of traveler is best suited for this destination? Where is this lodge located? Is this lodge located near fishable waters? How do I get to this lodge? What time of year should I visit? What fishing styles does this lodge cater to? Is there wade fishing? Will we be fishing from a boat? Where will I be fishing? What type of fish will I catch? How many fish will I catch? Will I see other anglers on the water? What are the fishing guides like? What are the physical demands? Are the fishing areas handicap accessible? Does the lodge provide equipment? Is there cell phone service at the lodge? Is there wifi at the lodge? Are there other activities at this lodge? Will my wife/significant other who doesn’t fish enjoy this lodge? Do I need a passport of visa to visit this lodge?
Schema Overview
The accommodation system is built around a central accommodation entity (which we use interchangably with the word lodge in this documentation) with related entities radiating outward. The key architectural decision is how lodges connect to the spatial/destination layer — through explicit foreign keys or dynamic geo queries.
Entity Relationships
Organization → Accommodation (one-to-many) An organization is the business entity that owns and operates lodges. One organization can own multiple lodges (e.g., a fishing resort group with properties in Montana, Alaska, and Belize). This matters for the multi-location flag in the pipeline — multi-property operators are high-value acquisition targets because one relationship yields several listings.
Accommodation (central entity) The lodge is the primary record — the thing an angler searches for, compares, and books. It carries 33+ structured fields from the pipeline: name, location (coordinates), contact info, species, amenities, fishing types, price range, seasons, quality tier, best-for tags, editorial pitch, and enrichment flags. Every other entity connects back to the lodge.
Accommodation → Room (one-to-many) Lodges have rooms with their own attributes — type, capacity, pricing, availability. This is the bookable inventory layer. A lodge might have 8 rooms across 3 room types (riverside cabin, main lodge suite, bunkhouse). Room-level data enables availability search and pricing comparison.
Accommodation → Review (one-to-many) Guest reviews with ratings, text, date, and verified-stay status. Reviews are the trust layer — the reason Hatch.travel with 1 review per listing loses to a platform with hundreds. Reviews feed the quality scoring system and the AI search ranking.
Accommodation → Staff (one-to-many) Lodge staff profiles — managers, hosts, chefs. Secondary to guides but useful for editorial depth on premier listings ("Chef Maria sources all ingredients from the Bitterroot Valley").
Accommodation → Guide (one-to-many) Guides are both lodge-attached and independent entities. A lodge can employ multiple guides, but guides can also exist as standalone records (independent guides not affiliated with a lodge). Guide profiles include: specialties, species expertise, certifications, years of experience, languages, and their own reviews. The guide entity bridges the lodge system and the future 🔒📌 Guides system.
Accommodation ↔ Destination (many-to-many, spatially resolved) This is the most important architectural decision. A lodge can be relevant to multiple destinations (a lodge near the Madison River is also near Yellowstone National Park, also in Montana, also in the Greater Yellowstone Ecosystem). Rather than maintaining explicit foreign key relationships between every lodge and every destination — which creates a maintenance nightmare and breaks whenever a new destination is added — the primary relationship should be resolved spatially at query time using PostGIS.
How it works: both lodges and destinations have coordinates. When someone searches "lodges near the Madison River," the system runs a spatial proximity query (ST_DWithin) rather than looking up a join table. This means:
- Adding a new destination automatically surfaces nearby lodges — no manual linking required
- Proximity queries ("within 30 minutes") work without pre-computed relationships
- The pipeline can enrich lodges and destinations independently — they connect through geography, not foreign keys
- Edge cases (a lodge relevant to 5+ destinations) are handled naturally
When to use explicit FKs instead: For curated relationships that don't map to proximity — e.g., "featured lodge for this destination" or "official lodge partner." These are editorial decisions, not geographic facts, and should be stored as explicit links.
Other edge cases: How will we match on location types where a bounded box would be used vs a centroid? Eg. how will I know lodge A should show up in North America, United States, New York, and Delaware County, Catskill Mountains, Catskill State Park (example for a Catskills lodge)? We need to really carefully define our enrichment needs for all destination types. Bounding boxes will be important.
Status Pipeline
Accommodations move through a lifecycle that tracks how they were discovered and how complete their data is. See đź”’Projects/Meridia/Data Pipeline/Data Pipeline for the full pipeline architecture.
| Status | Description |
|---|---|
discovered | Created by the data pipeline. Has name, source URL, and basic metadata from SERP scraping + AI classification. Not visible to users. |
enriched | Pipeline has crawled the property's website and extracted structured data: description, location, photos, amenities, pricing signals. Still not visible. |
claimed | A lodge owner has claimed this listing and is filling in the onboarding flow. May be partially complete. |
verified | Owner has completed onboarding and Meridia has verified the listing. Ready for review. |
published | Live on the platform. Appears in search results, destination pages, and API responses. |
Shadow listings: The pipeline can create "shadow" listings from discovered accommodations that haven't been claimed — these show basic information with a "Claim this listing" CTA to drive lodge owner acquisition.
Taxonomy Architecture
Every searchable, filterable, browsable attribute in the system falls into one of four types. This framework determines how data is stored, how it relates to entities, and what routes/pages it generates.
Taxonomy Types
| Type | Behavior | Cardinality | Example |
|---|---|---|---|
| Entity | Own table, own page, own rich data, own relationships | N/A | Destination, Accommodation, Species, Guide |
| Enum | Controlled vocabulary, dedicated column | Single-select | Lodge Type |
| Boolean | Dedicated column, prominent UI placement | True/False | has_guides, has_hunting, is_luxury |
| Tag | Many-to-many via join table, organized by tag category | Multi-select | Fishing Style, Theme, Activity, Amenity, etc. |
Decision rules:
- Entity → Does it have enough data for its own page? Can users search for it directly?
- Enum → Can the accommodation only be ONE of these? Is it a core classification?
- Boolean → Is this a yes/no question that 80%+ of users care about immediately?
- Tag → Can the accommodation have MANY of these? Is it descriptive, not classificatory?
Entities
Entities that relate to accommodations. Each has its own table, its own page, and its own spec document.
| Entity | Relationship to Accommodation | Spec |
|---|---|---|
| Destination | Many-to-many (spatially resolved via PostGIS) | 📌 Destinations |
| Species | Many-to-many (on both accommodations AND destinations) | 🔒📌 Species Library |
| Guide | Many-to-many (guides can be lodge-attached or independent) | 🔒📌 Guides |
| Organization | One-to-many (org owns lodges) | — |
| Room | One-to-many (lodge has rooms) | — |
| Review | One-to-many (lodge has reviews) | — |
| SEO | One-to-many (centralized SEO table, keyed by entity+pageType) | — |
Note on Water Bodies: Water bodies (rivers, lakes, etc.) are a type of destination, not a separate entity. A river IS a destination in the destination hierarchy. See 📌 Destinations.
Note on Species: Species relate to BOTH destinations, accommodations, and guides. A destination might have 20 fishable species, but a specific lodge may only target 5 of them. Both relationships matter — destination-level species power discovery (“what can I catch in the Seychelles?”), accommodation-level species power filtering (“which lodges target permit?”). Accommodations with many species (ocean, Great Lakes) need a way to prioritize and surface the most relevant ones. Also noteworthy is that species have a sense of seasonality as well. The tarpon runs in May, the Trout peak season is April - July 4. And so on. Important that we note the seasonality in terms of ecology, operations, and regulations.
Note on Seasons: Seasons exist independently on BOTH destinations and accommodations—and guides in the future. A destination's seasonal data is ecological — when do species run, what are conditions like, is the water body open by regulation. An accommodation's seasonal data is operational — when is the lodge open, when is peak season, what are holiday events. Regulations can also determine seasonality. Different questions, different data owners. Season tags are the coarse filter; detailed seasonality lives on each record independently.
Seasonality Relevance:
- Accommodation: are you open in January? Yes/no per month. That's it.
Note on SEO: SEO metadata is managed through a centralized seo table rather than columns on individual entity tables. The seo table is keyed by (entityType, entityId, pageType) — enabling separate SEO records for an accommodation's main page, its fishing-lodges listing appearance, etc. Fields include: title, description, h1 override, canonical URL, robots, Open Graph tags, Twitter card, focus keyword, secondary keywords, sitemap priority/changefreq, custom meta, redirect URL, and breadcrumb label. Legacy seoTitle/seoDescription columns on accommodation and destination tables should be removed in favor of this centralized approach.
Note on Charters: Charter operations (boat-based, primarily saltwater/deep sea) are a guide type, not an accommodation type. Charters will be related to accommodations via the guide entity when hasGuides is true. The charter ↔ accommodation relationship is deferred to a later version. See 🔒📌 Guides.
Enum: Lodge Type
The highest-level classification for an accommodation. Each lodge gets ONE primary type. This is the answer to “what kind of place is this?” — a cabin, a resort, a campground. It determines the fundamental expectation a traveler has before they read anything else.
Each lodge type generates its own landing page and can be combined with destination routes.
Values:
- Fishing Lodge
- Cabin
- Log Cabin
- Hostel
- Outpost
- Resort
- Dude Ranch
- Ranch
- Eco Lodge
- Wellness Lodge
- Campground
- Safari Lodge
- RV Resort / RV Park
- Retreat
- Historic Property
- Bungalow
- Camp
Edge case: Some places are genuinely two types (a resort with a campground). The primary type is the enum. Secondary types can be expressed as tags — a resort tagged “campground” means they HAVE camping, but they ARE a resort.
Strategic question: How extensive should our type enum be? Too many types and they lose meaning — users stop using them as a mental model. Too few and they don't represent 20K+ lodges well. The current list of 17 types needs validation against pipeline data. Once we have more enriched accommodations we should analyze the distribution and consolidate types with very few entries. Types like “Log Cabin” vs “Cabin” and “Camp” vs “Campground” may be candidates for merging.
Booleans
Mission-critical true/false flags that deserve dedicated DB columns and prominent UI placement. These are the “at a glance” signals that answer “should I keep scrolling?” in the first 2 seconds of viewing a listing. The pipeline classifiers set these automatically during enrichment.
| Boolean | Question It Answers |
|---|---|
has_guides | Can I get a guided trip from this lodge? |
has_hunting | Does this lodge offer hunting in addition to fishing? |
is_luxury | Is this a premier/luxury property? (Drives template selection) |
Everything else that was previously a boolean (Spa, Wifi, Dining, etc.) is a tag. Booleans are reserved for the 3-5 most critical signals. Don’t promote something to a boolean unless it fundamentally changes the search result or the user’s decision to click.
Tag System
Tags are many-to-many labels organized by tag category (stored as a tag_type enum). An accommodation can have many tags across multiple categories. Tag categories are the facets in filtered navigation. The same tag system applies to both accommodations and destinations where noted.
Architecture: Tags are stored in a dedicated tags table with a tag_type enum column — not as flat arrays on the entity. Each tag has a join table relationship to accommodations (and destinations where applicable). This enables:
- Clean expansion of tag categories without schema changes
- Proper faceted filtering and counting per category
- Tag-level metadata (slug, display name, description, sort order)
Routable flag: Each tag has an is_routable boolean that controls whether it generates a programmatic landing page. This prevents frivolous tags from creating thin pages while enabling high-value long-tail landers like "Fishing Lodges with a Spa" or "Best Fishing Lodges for Couples." Tags are routable by default; set is_routable = false for tags that are useful for filtering but don't warrant their own page (low search volume, too niche).
Tag Category: Fishing Style
What types of fishing can you do from this lodge? Applies to both accommodations AND destinations.
- Fly Fishing
- Deep Sea Fishing
- Inshore Fishing
- Nearshore Fishing
- Offshore Fishing
- Wade Fishing
- Flats Fishing
- Bay Fishing
- Lake Fishing
- Ice Fishing
- Trolling
- Spear Fishing
Tag Category: Activity
Non-fishing things to do at or near this lodge. Accommodation-only.
- Horseback Riding
- Birdwatching
- Snorkeling
- Scuba Diving
- Swimming
- Canoeing / Kayaking
- Sea Kayaking
- Kite Surfing
- Hiking
- Whale Watching
- Duck Hunting
- Upland Hunting
- Big Game Hunting
- Safari
- Wilderness Tours
- Treks & Expeditions
- Bush Flying
- Heli Trips / Heli-Fishing
- Eco Tours
- Golf
- Yoga
- Culinary Experiences
- Pool / Billiards
- Boating
- Boat Trips
Tag Category: Amenity
Facilities and services available at the lodge. Accommodation-only.
- Wifi
- Pool
- Spa
- Dining / Restaurant
- Bar
- Hot Tub
- Gear Shop / Outfitter
- Gear Rental
- Tackle Shop / Fly Shop
- Laundry
- Gym / Fitness
- Airport Transfer
- Boat Launch / Dock
- Parking
- EV Charging
- Accessible
Tag Category: Theme
Descriptive labels that capture the vibe or positioning of a lodge. Themes are a tag type (not computed) — stored as tags with tag_type = 'theme'. Applies to both accommodations AND destinations.
- Pet Friendly
- Kid Friendly
- Family Friendly
- Adults Only
- Luxury
- Best Value
- Eco-Friendly
- Culinary
- Wellness
- All-Inclusive
- Remote / Off-Grid
- Riverside
- Lakeside
- Oceanfront
- Long-Term Trips
Tag Category: Best For
Trip context — who is this lodge ideal for? Powers long-tail SEO pages (“Best Fishing Lodges for Bachelor Parties”). Accommodation-only.
- Big Groups
- Couples / Honeymoons
- Solo Travelers
- Corporate Retreats
- Families with Kids
- Weddings
- Bachelor / Bachelorette Parties
- First-Time Anglers
- Non-Fishing Partners
Tag Category: Climate
The environment around this lodge. Applies to both accommodations AND destinations.
- Tropical
- Desert
- Mountains
- Rainforest
- Arctic / Subarctic
- Temperate
- Coastal
- Arid
- Alpine
Tag Category: Ability
What experience level is this lodge best suited for? Applies to both accommodations AND destinations.
- Beginner
- Intermediate
- Advanced
- Expert
Tag Category: Season
When is this lodge open or optimal to visit? Multi-select (a lodge can be great in multiple seasons). Applies to both accommodations AND destinations.
- Spring
- Summer
- Autumn
- Winter
- Year-Round
Seasonality note: Beyond basic season tags, accommodations need richer seasonal data — peak season dates, off-season closures, holiday events, species-specific timing (e.g., “tarpon: May-July”). Season tags are the coarse filter; detailed seasonality lives in the accommodation record itself.
Route Architecture
Tags and enums generate programmatic pages that power SEO and browsable discovery. Every tag category creates a filterable facet, and every combination creates a potential landing page targeting long-tail search queries.
Accommodation routes leverage the destination URL hierarchy — lodges live under their parent destination, consistent with how we handle /fishing-conditions and other sub-entities. This gives us SEO-rich URLs and clear context.
Trade-off: Because of our flat destination taxonomy, each lodge displays under only one parent destination in its canonical URL. The lodge is still spatially discoverable from multiple destinations, but its canonical route nests under its primary destination.
Lodge Routes (destination-scoped)
/{destination-slug}/fishing-lodges → All lodges in destination
/{destination-slug}/fishing-lodges/{lodge-slug} → Individual lodge page
/upper-madison-river/fishing-lodges/slide-inn → Slide Inn profile
/catskill-mountains/fishing-lodges/trout-town-lodge → Trout Town Lodge profile
Tag Routes (destination-scoped)
/{destination-slug}/fishing-lodges/{tag-category}/{tag} → Filtered by tag in destination
/seychelles/fishing-lodges/amenities/spa → “Fishing Lodges with Spas in Seychelles”
/montana/fishing-lodges/style/fly-fishing → “Fly Fishing Lodges in Montana”
/alaska/fishing-lodges/best-for/big-groups → “Best Fishing Lodges for Big Groups in Alaska”
Standalone Tag Routes (global)
/fishing-lodges/{tag-category}/{tag-slug} → Global filtered list
/fishing-lodges/amenities/spa → “Fishing Lodges with Spas”
/fishing-lodges/best-for/couples → “Best Fishing Lodges for Couples”
/fishing-lodges/style/fly-fishing → “Fly Fishing Lodges”
/fishing-lodges/ability/beginner → “Fishing Lodges for Beginners”
Note on standalone routes: These generate a long tail of landing pages — only tags with is_routable = true produce pages. High-value examples: “fishing lodges with a spa”, “best fishing lodges for couples.” Low-value tags that are useful for filtering but not worth a dedicated page should have is_routable = false.
Collection Routes (by enum)
/fishing-lodges/type/{lodge-type} → “All Eco-Lodges”
/fishing-lodges/type/eco-lodge
Editorial Routes
/journal/{slug} → Editorial articles, guides, deep-dives
/journal/best-fishing-lodges-delaware-river
/journal/complete-guide-to-catskills-fishing
SEO play: Each of these routes is a programmatic landing page targeting a real search query. The tag system generates hundreds of pages automatically as data is added — no manual content creation needed. Keyword research determines which combinations to prioritize for content investment (editorial intro, featured lodges, etc.).
Reviews System
We need a clever way to bootstrap our lodge reviews so our platform has some value beyond just discover. The buyer journey always includes reading customer reviews, editorial content from a trusted media source, and even viewing social media websites.
Bootstrapping Lodge Reviews
- Email your list of past customers and ask them to write reviews—incentivized reviews for our platform by providing a simple system that allows lodge operators to quickly and easily request reviews on our platform from previous customers.
- This might be our number one priority—we need to find a way to get platform data that differentiates and add value during the customer journey.
Onboarding Experience
What does the final state of a perfect lodge profile look like? The purpose of this onboarding process is to gather every bit of data a user might need and build out a database we can use to build front-end search, faceted nav, and sorting and filtering capabilities.
Onboarding Questions
What type of lodge are you? Date Founded/Opened Awards & Accreditations Where are you located? Detailed location information including mailing and physical address, GPS coordinates. What local cities, colloquial regions or places do you service?
Eg. some lodges in the hudson valley may take guests to the catskills Other lodges may be located in “town x” but guests are searching for lodges “near region Y” This question is designed to build the lodge profile relationships—which will determine what searches (destinations) the lodge appears in. What’s Included What’s Not Included What adventures or activities do you offer? What rivers, streams, lakes, or bodies of water do you cater to? Autocomplete search/combobox dropdown UI element allows lodge owners to add a handful of local bodies of water. This will show them on landing pages for each body of water. Enables lodges to show up in search results for particular destinations. Pricing Packages/Programs Rates Deals Seasons What seasons are you open? Do you host special Holiday or calendar year events? Contact Details Email Phone Name of point of contact. Room Options Total number of rooms/cabins/etc. Room Name Bed size Sleeps (1, 2, 3, 4, etc) Bathroom Amenities Special features / View / Etc Gear Section Do you recommend specific gear for your guests? Do you provide all gear or a limited selection of gear to guests? Do you have an outfitter onsite where guests can purchase gear? Provide a comprehensive gear checklist for guests Sunscreet, sunglasses, etc. etc. — comprehensive
B2B Pricing
Our primary marketing strategy is to sell advertising packages to lodges, stating with premium listings and working toward establishing a digital agency that builds and manages advertising and media for this particular niche.
Standard Profile
- Profile Photos (up to 25)
- Location
- Fish Species
- Fishing Techniques (Lure, Bait, Fly, Ice, Salt, Etc)
- Amenities / Activities
- Starting Cost
- Seasonality
- Basic Travel Requirements
- Message
- Similar Lodges
Premium Profile
- Includes all standard information
- Voyager Deals / Special Offers
- Video Content
- Premium Placement—ranked higher in search results and on destination pages.
- Turns off “Similar Lodges” included in Standard Profile
- Individual Room Profiles.
Living Profile Pages
Most booking platforms treat accommodation profiles as static listings — a description, some photos, a price, and a booking button. Meridia accommodation profiles are fundamentally different. Because every accommodation is spatially linked to destinations, and those destinations carry structured data about species, seasonality, real-time conditions, and regulations, the accommodation profile becomes a living, data-rich fishing intelligence page.
The core question a living profile answers: "If I book this lodge for the week of September 15th, what will the fishing be like?"
What the Living Profile Surfaces
Data is inherited spatially from linked destinations — not through foreign keys, but through location proximity. The accommodation doesn't duplicate stream gauge data or regulation info. It inherits that through its linked destinations via PostGIS spatial queries.
Real-Time Fishing Conditions
For accommodations near river/stream destinations with USGS stream gauge data:
- Current flow (CFS), water temperature, gauge height for nearby water bodies
- Historical average for the same period (10-year avg) — "The Madison is running 12% above average for late September"
- Trend indicator — rising, falling, stable
- AI-generated fishing outlook — "Good. Flows are stable and temps are in the ideal range for brown trout dry fly activity."
- Data refreshes every 15 minutes from the USGS NWIS API
These are displayed as cards on the accommodation page indicating conditions, whether the season is open, and our fish conditions rating — is it fishable right now? This differentiates accommodation operational data from our enriched destination data (regulation open/closed status, conditions data from our PoC).
Species Timing Intelligence
From destination species seasonality data, the profile shows:
- Which species are fishable right now, rated by current-month quality (poor/fair/good/excellent)
- What techniques are working for each species in the current season
- When peak windows are coming up — "Brown trout hopper fishing peaks in 3 weeks"
- A 12-month species calendar showing the best windows for each target species
Nearby Water Bodies & Access
From spatial proximity queries (not FK relationships):
- All fishable water bodies within configurable drive time, with distance and relationship type
- For each water body: species present, current conditions (if gauged), access type (public/private)
- Map view showing the property's position relative to surrounding water bodies
Example: A lodge on the Madison River might show: "0.2 mi to Upper Madison (on water), 12 mi to the Gallatin River, 18 mi to the Jefferson River, 25 mi to the Yellowstone River." Each links to the destination landing page.
Regulation Snapshot
From parsed state regulation data mapped to nearby water body sections:
- Current season status (open/closed) for each linked water body
- Catch limits, gear restrictions, and special regulations
- License requirements for the relevant state/jurisdiction
Why This Matters
- SEO: A profile page with real-time data updates frequently, signaling freshness. Google can't find this data compiled this way anywhere else.
- AI citation: When someone asks an AI "What's the fishing like at Slide Inn right now?", Meridia has a structured, current answer. Static profiles don't.
- User retention: Anglers return to check conditions and species timing even when they're not booking.
- Lodge owners: The living profile is a premium feature that justifies paid tiers. No other platform can offer "your profile page shows real-time conditions on the rivers your guests fish."
- Data moat: This ties accommodation profiles directly to the PostGIS spatial layer. Competitors can't replicate without the same infrastructure.
Implementation
The living profile doesn't require new data infrastructure — it surfaces data already being collected:
- Real-time conditions → USGS stream gauge API (cached at 15-minute intervals, already built in PoC)
- Species timing →
destination_speciesseasonality data, already in schema - Nearby water bodies → spatial proximity queries via PostGIS (not a relationship table)
- Regulations → parsed state regulation data mapped to destination sections
As the spatial data layer matures, the living profile automatically gets richer — no manual profile updates needed.
Editorial Content Strategy
The Cannibalization Problem
An obvious content opportunity is editorial pages like "Top 10 Fishing Lodges on the Delaware River" or "Best Fly Fishing Lodges in Montana." These are high-value SEO targets. But they risk cannibalizing the destination landing pages (e.g., /delaware-river/fishing-lodges) that the spatial engine generates programmatically.
The solution is to clearly differentiate intent and content:
Destination Pages (Programmatic)
- Route:
/{destination-slug}/fishing-lodges - Intent: transactional — user wants to see and filter all lodges near this water body
- Content: complete inventory, spatial data, filtering, booking actions. Data-driven, comprehensive, updated automatically.
Editorial Pages (Curated)
- Route:
/journal/{slug} - Intent: informational/navigational — user wants an expert opinion, a shortlist, a recommendation
- Content: editorial voice, ranked list, detailed write-ups explaining why each pick was chosen. Opinionated and selective.
How They Reinforce Each Other
Instead of competing, these page types create an internal linking flywheel:
- The editorial "Top 10" page links to each featured lodge's profile AND the destination page — passing authority to both
- The destination page features a "Meridia Picks" callout linking to the editorial piece
- Lodge profiles display badges like "Meridia Top 10 Delaware River" linking to the editorial page (premium value-add)
The destination page answers "show me everything." The editorial page answers "tell me which ones are best." Different intent, complementary authority.
Editorial Content Types
- Destination deep-dives: "The Complete Guide to Fishing the Catskills" — links to multiple destination and lodge pages
- Species guides: "Where to Catch Permit on Fly: The Definitive Guide" — links across regions
- Seasonal guides: "The 8 Best September Fly Fishing Trips in America" — captures seasonal search intent
- Trip comparison: "Montana vs. Idaho: Which Has Better Trout Fishing?" — targets comparison queries
- Ambassador curated lists: "Top Lodges Picked by [Ambassador Name]" — leverages the 🔒Council of Ambassadors concept
Each editorial piece is editorially crafted but backed by the same structured data that powers programmatic pages — species seasonality, spatial proximity, conditions data. This makes our editorial more authoritative than competitors writing from general knowledge.
Pricing Model
Fishing lodge pricing is one of the hardest normalization problems in travel. A $150/night cabin in the Ozarks and a $7,500/person all-inclusive week in the Seychelles need to live in the same schema, be filterable against each other, and make sense to the traveler comparing them. This section defines the full conceptual model — we'll implement incrementally.
Why This Is Hard
Lodge pricing varies across every possible dimension simultaneously:
- Unit of sale: per-night, per-person-per-night, per-package (multi-day), per-trip (flat)
- Inclusions: room-only, room + meals, all-inclusive (room + meals + guides + gear), guided-trip-only (no lodging)
- Occupancy: single, double, group rates, whole-lodge buyouts
- Seasonality: peak, shoulder, off-season — sometimes 3x price swings
- Currency: USD, local currency, or both
- Add-ons: guides, gear rental, airport transfers, fishing licenses — sometimes included, sometimes extra
The pipeline currently captures price_range as a single field. That's enough for a card but not enough for comparison, filtering, or booking.
Core Pricing Entities
pricing_model (on Accommodation)
Each accommodation declares HOW it prices — this determines how the rest of the pricing data is interpreted.
| Field | Type | Description |
|---|---|---|
pricing_type | enum | per_night, per_person_per_night, per_package, per_trip, inquiry_only |
currency | string | ISO 4217 code (USD, EUR, BZD, etc.) |
tax_included | boolean | Is tax/VAT included in displayed prices? |
gratuity_included | boolean | Are guide/staff tips included? |
deposit_required | boolean | Is a deposit required to hold a booking? |
deposit_amount | decimal | Fixed deposit amount (if applicable) |
deposit_percent | integer | Deposit as % of total (if applicable) |
minimum_stay | integer | Minimum nights required (null = no minimum) |
price_floor | decimal | Lowest possible price in any season/config — powers "from $X" on cards |
price_ceiling | decimal | Highest possible price — powers price range display |
price_note | text | Free-text pricing context ("Prices quoted per person, based on double occupancy") |
inquiry_only handles lodges that don't publish rates — common for ultra-premium and international properties. We still capture price_floor/price_ceiling from pipeline enrichment even if the lodge doesn't list exact rates.
rate (Rate Table)
The core rate record. Each accommodation has one or more rates representing different ways to buy a stay.
| Field | Type | Description |
|---|---|---|
id | uuid | Primary key |
accommodation_id | fk | Parent accommodation |
name | string | Display name — "Standard Package", "Peak Season Rate", "Wade-Only Special" |
rate_type | enum | nightly, package, guided_day, whole_lodge |
price | decimal | Base price |
price_per | enum | per_person, per_room, per_group, per_lodge |
occupancy_base | integer | Base occupancy this price assumes (e.g., 2 for double occupancy) |
occupancy_max | integer | Max occupancy for this rate |
additional_person_price | decimal | Cost per additional person beyond base occupancy |
nights | integer | Number of nights (for packages, null for nightly rates) |
guided_days | integer | Number of guided fishing days included (null if none/not applicable) |
meals_included | enum | none, breakfast, half_board, full_board, all_inclusive |
gear_included | boolean | Is fishing gear (rods, reels, tackle) included? |
guide_included | boolean | Are guide services included in this rate? |
transfer_included | boolean | Are airport/location transfers included? |
is_default | boolean | Is this the rate shown on cards / in search results? |
sort_order | integer | Display order on profile page |
description | text | What's included, what to expect, any fine print |
status | enum | active, draft, archived |
Example rates for a single lodge:
| Name | Type | Price | Per | Nights | Guides | Meals |
|---|---|---|---|---|---|---|
| Peak Season All-Inclusive | package | $5,800 | per_person | 5 | 4 days | all_inclusive |
| Shoulder Season All-Inclusive | package | $3,200 | per_person | 5 | 4 days | all_inclusive |
| Lodging Only (Peak) | nightly | $450 | per_room | — | — | breakfast |
| Whole Lodge Buyout (Peak) | whole_lodge | $18,000 | per_lodge | 5 | 4 days | all_inclusive |
rate_season (Seasonal Pricing)
Links rates to date ranges. A rate can have multiple seasonal windows.
| Field | Type | Description |
|---|---|---|
id | uuid | Primary key |
rate_id | fk | Parent rate |
season_name | string | "Peak", "Shoulder", "Off-Season", "Holiday", "Tarpon Run" |
start_date | date | Season start (month-day, recurring annually) |
end_date | date | Season end |
price_override | decimal | Overrides the rate's base price for this season (null = use base) |
price_modifier | decimal | Multiplier on base price (e.g., 1.25 for 25% premium) — alternative to override |
minimum_stay_override | integer | Some lodges require longer minimums in peak season |
available | boolean | Is this rate available during this season? (false = blacked out) |
Why both price_override and price_modifier? Some lodges think in absolute numbers ("peak is $5,800, shoulder is $3,200"). Others think in percentages ("off-season is 20% off"). Support both — exactly one should be set.
rate_addon (Add-On Services)
Priced extras that can be added to any rate.
| Field | Type | Description |
|---|---|---|
id | uuid | Primary key |
accommodation_id | fk | Parent accommodation |
name | string | "Half-Day Guide", "Airport Transfer", "Gear Rental Package", "Fly Fishing Lesson" |
addon_type | enum | guide, transport, gear, activity, meal, other |
price | decimal | Add-on price |
price_per | enum | per_person, per_group, per_day, per_trip, flat |
max_quantity | integer | Max purchasable (null = unlimited) |
description | text | Details |
is_recommended | boolean | Lodge flags this as "most guests add this" |
Example add-ons:
| Name | Type | Price | Per |
|---|---|---|---|
| Full-Day Guide Service | guide | $600 | per_person per_day |
| Airport Transfer (Bozeman) | transport | $150 | per_group |
| Gear Rental (rod + reel + waders) | gear | $75 | per_person per_day |
| Fly Tying Class | activity | $50 | per_person |
| Sack Lunch | meal | $25 | per_person per_day |
rate_special (Deals & Promotions)
Time-bound or conditional discounts. Powers the "Deals" section on the profile and "Voyager Deals" for Hemingway's Passport members.
| Field | Type | Description |
|---|---|---|
id | uuid | Primary key |
accommodation_id | fk | Parent accommodation |
rate_id | fk | Applies to specific rate (null = all rates) |
name | string | "Early Bird 2027", "Last-Minute October", "Return Guest Discount" |
discount_type | enum | percent, fixed, nights_free, addon_included |
discount_value | decimal | 15 (for 15%), $500 (for fixed), 1 (for 1 night free) |
addon_id | fk | If addon_included, which add-on is free |
valid_from | date | Promotion start |
valid_until | date | Promotion end |
booking_window_start | date | Must book between these dates (null = anytime) |
booking_window_end | date | |
travel_window_start | date | Must travel between these dates |
travel_window_end | date | |
min_nights | integer | Minimum stay to qualify |
min_guests | integer | Minimum group size to qualify |
passport_exclusive | boolean | Only visible to Hemingway's Passport members |
code | string | Promo code (null = automatic) |
description | text | Terms and details |
status | enum | active, scheduled, expired |
Example specials:
| Name | Type | Value | Window |
|---|---|---|---|
| Early Bird 2027 | percent | 15% off | Book by Jan 31 for any 2027 travel |
| 5th Night Free | nights_free | 1 | Book 5+ nights, shoulder season |
| Passport Deal: Free Transfer | addon_included | Airport Transfer | Hemingway's Passport members only |
| Last Minute October | percent | 25% off | Travel Oct 15-31, book after Sep 15 |
Normalized Display Price
For search results, cards, and filtering, we need a single normalized number. The price_floor on the accommodation record serves this purpose, but we also compute a normalized per-person-per-night value for apples-to-apples comparison.
| Field | Type | Description |
|---|---|---|
display_price | decimal | Lowest current rate, in the lodge's native pricing format |
display_price_label | string | Generated: "from $450/night", "from $3,200/person (5 nights)", "$18K/week (whole lodge)" |
normalized_ppn | decimal | Computed: per-person-per-night equivalent at base occupancy. For a $5,800 package / 5 nights / 1 person = $1,160 ppn |
price_tier | enum | budget (<$200 ppn), mid ($200-500), premium ($500-1000), luxury ($1000+) |
normalized_ppn is the magic number. It lets a traveler filter "under $500/night" and correctly compare a $450/night room-only cabin against a $2,500/person 5-night all-inclusive ($500/night equivalent). The traveler never sees this number directly — it powers the filter math.
price_tier is a coarse bucket for quick filtering and card display. Thresholds will need calibration against actual pipeline data.
What's Included Matrix
This deserves special treatment because it's the #1 source of confusion and the #1 differentiator between lodges. Rather than burying it in rate descriptions, we surface a structured inclusion matrix.
| Inclusion Item | Values |
|---|---|
| Lodging | included, not_included, varies_by_rate |
| Meals — Breakfast | included, not_included, available_for_purchase |
| Meals — Lunch | included, not_included, available_for_purchase |
| Meals — Dinner | included, not_included, available_for_purchase |
| Alcoholic Beverages | included, not_included, available_for_purchase |
| Guided Fishing | included, not_included, available_for_purchase |
| Fishing Gear (rod/reel) | included, not_included, available_for_purchase, available_for_rent |
| Waders & Boots | included, not_included, available_for_purchase, available_for_rent |
| Flies / Terminal Tackle | included, not_included, available_for_purchase |
| Fishing License | included, not_included, arranged_by_lodge |
| Airport Transfer | included, not_included, available_for_purchase |
| Gratuities | included, not_included, expected |
This powers a clean comparison UI: two lodges side by side, green checks and red X's, immediately visible. Also feeds the AI search layer — "show me all-inclusive lodges where I don't have to think about anything" becomes a structured query.
Implementation Phases
Phase 1 (Now — Pipeline Enrichment)
- Extract
price_floor,price_ceiling,pricing_type, andcurrencyduring pipeline enrichment - Compute
price_tierfrom extracted data - Display "from $X/night" or "from $X/person" on cards — enough to filter and compare
Phase 2 (Lodge Onboarding)
- Rate table UI in lodge dashboard — owners enter their actual rates, packages, seasons
- Inclusion matrix as a checklist during onboarding
- Add-on configuration
- Compute
normalized_ppnfrom entered rates
Phase 3 (Deals & Booking)
- Specials/promotions system
- Hemingway's Passport exclusive deals
- Availability calendar (room-level)
- Inquiry-to-booking flow (even if booking happens off-platform initially)
- Trip cost estimator: rate + add-ons + estimated extras = "your trip will cost approximately $X"
Phase 4 (Transactional Booking)
- Real-time availability
- Payment processing
- Deposit/cancellation enforcement
- Dynamic pricing (yield management for sophisticated operators)
Cancellation & Refund Policy
Stored per-accommodation, not per-rate — most lodges have one policy across all rates.
| Field | Type | Description |
|---|---|---|
cancellation_type | enum | flexible, moderate, strict, custom |
full_refund_days | integer | Days before arrival for full refund |
partial_refund_days | integer | Days before arrival for partial refund |
partial_refund_percent | integer | What % is refunded in partial window |
deposit_refundable | boolean | Is the deposit refundable at all? |
cancellation_policy_text | text | Full policy text (for custom policies) |
trip_protection_eligible | boolean | Can guests purchase trip protection through Meridia? (Phase 3 affiliate play) |
Open Questions
- Currency display: Show in lodge's native currency with USD equivalent? Or normalize everything to USD for US-market launch?
- Commission model: If/when we take a booking commission, does it come off the lodge's rate or does the traveler pay a service fee on top? This affects how we display prices.
- Price verification: How do we prevent stale pricing from pipeline-enriched (unclaimed) listings? Confidence flag? "Prices may be outdated" disclaimer?
- Group pricing: Some lodges have radically different group structures (minimum 4 rods, maximum 8, whole-lodge-only in peak). How flexible does the rate table need to be?
- Guided vs. unguided: Some lodges are ONLY all-inclusive guided. Others are lodging-only with optional guides. The
rate_typehandles this but the UX needs to make it crystal clear what you're buying.
Page Checklist
Every question the page needs to answer, organized by where the traveler is in their decision journey.
Before I Click (Search Results / Card)
- [ ] What kind of place is this? (lodge type)
- [ ] Where exactly is it? (location with smart formatting)
- [ ] What's the price range? (starting cost or per-night range)
- [ ] Is it a "real" fishing lodge or a hotel near water? (fishiness signal)
- [ ] Does it match my trip type? (guided? family? luxury? remote?)
First 5 Seconds on Page ("Should I keep scrolling?")
- [ ] Do the photos look like the trip I want?
- [ ] What fishing styles are available here? (fly, deep sea, wade, etc.)
- [ ] What species can I target?
- [ ] Does it have guides?
- [ ] Is it open when I want to go?
- [ ] Is it within my budget range?
Building Conviction ("This might be the one")
- [ ] What makes this place special vs. the 10 other lodges I'm comparing? (Why Book / editorial pitch)
- [ ] What do past guests say? (reviews, ratings, verified stays)
- [ ] What's included in the price? (meals, guides, gear, transfers — the #1 hidden cost question)
- [ ] What's NOT included? (tips, flights, gear rental — where will I get surprised?)
- [ ] What are the actual packages/rates? (nights x days, group pricing, seasonal pricing)
- [ ] What does a typical day look like at this lodge?
- [ ] Can I see the rooms? (room types, capacity, what they look like)
Planning the Trip ("I'm going — now what?")
- [ ] When should I go? (peak season, species timing calendar, off-season deals)
- [ ] What are conditions like RIGHT NOW? (living profile: flows, temps, species activity)
- [ ] How do I get there? (nearest airport, transfer logistics, drive time)
- [ ] What gear should I bring? (packing list, what the lodge provides vs. what I need)
- [ ] Do I need a fishing license? What are the regulations?
- [ ] Do I need a passport or visa?
- [ ] What's the cancellation policy?
Traveling with Others ("Will my partner/kids/group be happy?")
- [ ] Is there stuff to do for non-anglers? (activities, spa, hiking, etc.)
- [ ] Is it kid-friendly? Family-friendly? Accessible?
- [ ] Can it handle my group size? (corporate retreats, weddings, bachelor parties)
- [ ] Will my non-fishing partner enjoy this place?
- [ ] Is there wifi / cell service? (the "will I survive" question)
Trust & Logistics ("Can I actually rely on this info?")
- [ ] Is this listing verified or scraped? (claimed vs. shadow listing — set expectations)
- [ ] How fresh is this data? (last updated, real-time conditions timestamps)
- [ ] How do I contact the lodge directly?
- [ ] What are the terms & conditions?
- [ ] Are there similar lodges I should compare? (or is this the only game in town?)
Open Questions
- [ ] "What does it cost, total?" — What's Included/Not Included exists, but no explicit total trip cost estimator or even a range. Travelers mentally calculate: lodging + flights + guides + tips + gear. Can we surface a ballpark all-in estimate?
- [ ] "Show me the water" — Nearby Water Bodies section exists in Living Profile, but is it prominent enough? The map showing lodge-to-water relationships might be the single most valuable visual on the page.
- [ ] "What's the fishing like THIS week?" — Living Profile covers this, but how do we handle it for lodges where we don't have gauge data (saltwater, international)?
- [ ] "Who are the guides?" — Guide profiles are an entity, but how prominently do they surface on the lodge page? For many anglers, the guide IS the trip.
- [ ] "Can I book right now?" — Page content doesn't have a clear booking CTA section. Is it "Message" only for now? Inquiry form? External link? The call-to-action hierarchy matters.
- [ ] "What's the lodge's vibe?" — Photos and editorial help, but is there a structured way to convey atmosphere? (rustic vs. polished, social vs. private, rowdy vs. quiet)
Links & References
- Meridia Strategy — revenue model, premier tier positioning
- 📌 Destinations — destination entity and hierarchy
- 🔒📌 Species Library — species entity and taxonomy
- 🔒📌 Guides — guide entity
- 🔒Projects/Meridia/Data Pipeline/Data Pipeline — pipeline architecture, AI search examples
- 🔒AI Natural Language Search — how tags/enums power natural language queries