Inspiration

We set out to fix a common pain: planning where to eat or building food‑led trips often devolves into endless scrolling through popularity‑biased lists that don’t understand who you are. We wanted a system that grasps cultural taste and shifting moods — the bridge between “I love Beyoncé, sci‑fi, and minimalist design” and “I want something comforting tonight.” Qloo’s Taste AI™ looked like the cultural graph we needed, and modern LLMs (DeepSeek) felt like the natural‑language glue. That was the spark, and it still is.

What it does

FlavorJourney aims to deliver personalized local dining and travel recommendations by combining:

  • Qloo’s Taste AI™ for taste‑based affinity and entity recommendations (places, destinations).
  • DeepSeek for translating mood and generating narrative content (culinary itineraries, summaries).

Users can provide structured preferences (cuisines, place types, price) or a free‑form mood. The intended flow returns curated restaurants and, for travel, an LLM‑generated culinary itinerary with an AI‑powered “Top 5” summary to quickly recap highlights.

Note: Due to time and other factors (including integration friction and API constraints), we did not fully finish the build. The MVP experience exists in parts, but several flows remain incomplete or stubbed. For example, while basic Qloo entity fetching is implemented (as seen in src/routes/entity-test/+page.server.ts and src/routes/entity-test/+page.svelte), integrating complex taste-based filtering and dynamically generated user input fully remains a challenge. Similarly, authentication components are present (src/lib/server/auth.ts, src/lib/server/oauth.ts), but their seamless integration into all application flows for personalized experiences is still in progress.

How we built it

  • Frontend: SvelteKit 5 with runes, Tailwind, and shadcn‑svelte for a fast, accessible UI. We followed SvelteKit’s routing conventions with co‑located server loaders/actions where applicable.
  • Backend/Server: SvelteKit endpoints to orchestrate third‑party calls:
    • Qloo API:
    • /search for entity ID resolution.
    • /v2/insights with filter.type=urn:entity:place (and other types), plus signals (tags/entities) and location/price constraints.
    • Strict full tag URNs (e.g., urn:tag:cuisine:italian) enforced via hardcoded mapping to reduce 400s.
    • DeepSeek:
    • Interprets mood into intents/attributes, which we map into Qloo tags/entities.
    • Generates culinary itineraries and the “Top 5” summary.
  • Data: Browser LocalStorage for short‑term preferences in the MVP; Prisma + PostgreSQL planned where persistence is required (auth/sessions).
  • Authentication: Minimal custom approach to move quickly. Planned Google OAuth with Prisma‑backed sessions; we avoided Lucia for scope/time reasons.
  • Product focus: A streamlined Results Page — submit → hide form → show results → quick “Start New Search.” Portions are implemented; end‑to‑end reliability wasn’t achieved in time.

Challenges we ran into

  • Documentation that diverged from behavior. Endpoint semantics, parameter constraints, and examples were often ambiguous or incomplete. Practical behavior sometimes contradicted the docs, leading to trial‑and‑error and slower iteration.
  • Rigid, brittle API surfaces. Small deviations in parameter shape, ID provenance, or URN namespaces frequently produced 404 or opaque errors instead of clear validation feedback. We resorted to strict pre‑validation, URN normalizers, and defensive request builders to make calls predictable.
  • Opaque error signaling. 404s often represented “request rejected due to hidden constraints,” not true resource absence. This forced additional logging, correlation IDs, and our own failure‑explanation layer just to debug.
  • Fragile tag/URN hygiene. Despite implied flexibility, the real system required exact, fully‑qualified URNs and verified IDs. Anything less yielded 4xxs. We created a hardcoded mapping/sanitizer to avoid spurious errors — workable, but not ideal for maintainability.
  • Mood‑to‑structure impedance mismatch. Translating free‑form mood into the exact tags/entities accepted by the API was lossy and brittle. While LLMs helped, we still needed constrained decoding, post‑processing, and graceful fallbacks to narrative‑only output when deterministic mapping failed.
  • Time and scope constraints. The hackathon window plus integration friction meant postponing community features, richer filters, robust persistence, and broader trip planning. We centered effort on the results experience but didn’t fully complete the build due to time and the above technical headwinds.
  • Authentication/session trade‑offs. To move fast, we limited auth complexity. That restricted cross‑session personalization and data continuity. The intended Prisma‑backed sessions and hardened OAuth path are defined but not fully implemented.
  • Unfinished features due to integration complexity. Despite our best efforts, the dynamic integration of Qloo's taste signals with user mood input proved more complex than anticipated. We have a working entity-test route that successfully fetches Qloo entities, but connecting this seamlessly to a dynamic user interface that allows for nuanced taste-based filtering and personalized recommendations remains a significant challenge. The initial +page.svelte is primarily a landing page, and the core recommendation logic and display are still under heavy development.

Accomplishments that we’re proud of

  • A compelling blend of cultural taste signals (Qloo) with natural‑language understanding/generation (DeepSeek), validated in prototypes and partial flows.
  • An MVP‑first UX philosophy: crisp input → immediate narrative context → concise “Top 5” highlights. While unfinished, the direction felt right in user walk‑throughs.
  • A rigorous tag‑URN strategy and input guards that significantly reduced common 4xxs when applied, providing a path to a more reliable integration.
  • Svelte 5 with shadcn‑svelte yielded rapid UI iteration, good accessibility, and a maintainable component baseline.
  • Successful initial integration with Qloo API for basic entity fetching, demonstrating the potential for taste-based recommendations.

What we learned

  • Cultural graphs + LLMs are complementary: Qloo models taste; DeepSeek makes it human. The challenge is enforcing structure without losing nuance.
  • Strict parameter hygiene is non‑negotiable for Qloo: valid IDs, full URNs, correct filter.type/operators, and deterministic mapping.
  • Svelte 5 runes ($state, $derived, $effect) improve clarity and reduce foot‑guns in reactivity during fast iteration.
  • Focus matters, but integration friction can erase time savings. Clearer API contracts and better examples would have accelerated delivery.
  • We did not finish the build. The incomplete state is attributable to compounded factors: strict/opaque API constraints, documentation gaps, and limited time for hardening and end‑to‑end testing.

What’s next for FlavorJourney

  • Funded stability and developer UX:
    • A first‑party client SDK with schema‑validated builders, URN/ID normalizers, and pre‑flight diagnostics to catch issues before the network.
    • Clear error taxonomy, idempotent retries, exponential backoff, circuit breakers, and structured logs/traces for fast recovery and observability.
  • Robust mood‑to‑tags compiler:
    • Constrained decoding, evaluation datasets, confidence scoring, and graceful degradation so “vibes in → valid structured queries out” is reliable.
  • Product expansion (post‑funding):
    • Accounts & Profiles: Prisma‑backed sessions, saved preferences, persistent lists.
    • Community: Reviews, ratings, photos, shared lists (e.g., “Top 5 Cozy Cafes”).
    • Travel Depth: Richer itineraries, offline PDFs, “Pay‑What‑You‑Can” exports.
    • Monetization: Freemium tiers, clearly labeled affiliate/sponsored inventory, privacy‑first ads.
    • Data Integrations: Menus, availability/bookings, events, map overlays.
    • Scale & Ops: Caching (Qloo/DeepSeek), rate‑limit strategies, monitoring, and cost controls.

In short: the concept proved strong and the direction felt right, but we did not complete the build due to time and integration hurdles.

Built With

  • google-gemini-(llm)
  • google-oauth
  • heroku/render-(backend)
  • node.js-(sveltekit-server-endpoints/express-style-handlers)
  • postgresql
  • prisma
  • qloo-taste-ai?-api-(/search
  • shadcn-svelte
  • sveltekit-5
  • tailwind-css
  • typescript
  • v2/insights)
  • vercel-(frontend)
Share this project:

Updates