Trip planning is twelve tabs pretending to be one decision.
Researching destinations, comparing flights, evaluating hotels and assembling a coherent itinerary each live in different tools, and none of them know your preferences. Aidventure coordinates all of it behind one conversation: describe the trip, refine it over multiple turns, and the plan — flights, hotels, day-by-day schedule — assembles itself as you talk.
- Natural-language planning: multi-turn chat that iteratively refines the plan.
- Real data: Travelpayouts for flights, LiteAPI for hotels, Geoapify for attractions, OpenWeatherMap for weather.
- A profile that learns — preferences and history feed future recommendations.

Three tiers, one distinct AI layer.
Next.js 14 frontend, FastAPI backend, PostgreSQL — with the AI layer as its own component inside the backend: spaCy for entity recognition, Mistral for generation, a context builder that injects live weather and points-of-interest into prompts, and a scikit-learn recommender for destination scoring. JWT auth on every protected request; async httpx for all outbound API calls.
“JWT auth on every protected request; async httpx for all outbound API calls.”
- FastAPI + Uvicorn for async request handling; SQLAlchemy 2.0 + Alembic for the data layer.
- python-jose JWTs, bcrypt password hashing, keys never exposed to the client.
- Docker Compose for local Postgres provisioning.

Message in — entities, context, streamed plan out.
Every chat message runs through a pipeline I built: spaCy NER pulls out destination, dates, budget and travel style; the context service fetches current weather and attractions for the detected destination; Mistral generates the reply, streamed to the browser as Server-Sent Events so text appears as it's written. In parallel the message and learned preferences persist to Postgres, and a live plan-preview panel fills in as entities are extracted.
- spaCy (en_core_web_sm) for entity extraction, stored as JSONB per message.
- Mistral Small via the official SDK — prompts enriched with live external data.
- SSE streaming end-to-end: the UI never blocks on generation.

Six tables, JSONB where the shape isn't fixed.
The schema centers on users — credentials plus a learned preferences profile — with travel_plans, chat_history, flights, hotels, and a curated destinations catalogue around it. UUID primary keys throughout; JSONB columns hold the semi-structured parts: preferences, extracted entities, itineraries, destination metadata. Conversations link to the plans they helped create via a conversation id.
“UUID primary keys throughout; JSONB columns hold the semi-structured parts: preferences, extracted entities, itineraries, destination metadata.”

Two people, clear ownership, one contract.
This was a two-person build with clean boundaries: I owned authentication, the chat experience, NER, the Mistral integration, plan management and the dashboard; my teammate owned flight search, hotel search, destination exploration and the recommender. The backend foundation, database schema and design system were shared — which forced us to agree on API contracts early and keep them stable.

built by one person · case study written by the same person
