Parth TiwariStart a project
MenuClose

Case 10 / Take-home support assistant

Spur Chat

Spur Chat is a bounded streaming support interface for Lumio, a fictional brand, built as a take-home and presented without pretending its suspended backend is a working live assistant.

Role
Full-stack engineer
Built at
Take-home assignment
Contribution
Interface, API, streaming, retrieval, and recovery
Status
Take-home
The real Spur Chat desktop interface showing Lumio's greeting and support conversation surface
Real interface captureGreeting state, interaction unverified

Measured, with the denominator attached

Proof before polish.
No publishable outcome number

No benchmark, user count, or production support volume was recorded for this take-home project.

Architecture and source evidence onlyReviewed 2026-08-31
What it is

A deliberately small support surface for a fictional brand.

Spur Chat was a take-home project for a fictional direct-to-consumer brand.

It retrieves catalogue and policy context, then streams a bounded support response in the browser.

Built for

A shopper asking catalogue or policy questions inside a small direct-to-consumer support widget, and an evaluator inspecting a bounded take-home implementation.

I built the responsive chat interface, Node and TypeScript API, retrieval scope, PostgreSQL session history, SSE stream parser, request deduplication, failure taxonomy, feedback controls, and deployment documentation.

Contribution record

See the actual product before reading the argument.

Real desktop capture

The real deployed Spur Chat entry state before a successful streamed support answer
The frontend returned HTTP 200 on 2026-08-31. The Render backend reported Service Suspended, so this capture proves only the interface and no successful streamed answer is fabricated.
01
The real Spur Chat mobile interface showing the fictional Lumio support assistant
Enter through the real interface

Desktop and mobile surfaces expose the fictional Lumio assistant, conversation list, input, and recovery affordances.

02
Stream recordPOST over fetch and ReadableStream
Transport
Server-Sent Events over POST
Parser
Buffered line framing
Events
chunk, done, and error
Source: Committed frontend API service at 562ca32
Parse a buffered stream

The frontend reads POST response chunks, buffers incomplete lines, and handles chunk, done, and error SSE events without requiring WebSockets.

03
Live verificationInteraction unavailable
Frontend
HTTP 200
Backend health
Service Suspended
Complete chat turn
Could not run
Source: Read-only checks on 2026-08-31
Report the live failure honestly

The frontend remains available, but health and message requests cannot complete while the backend service is suspended.

A polished chat shell does not prove that the backend can complete a turn.

A generic assistant can answer smoothly while ignoring the catalogue and policy constraints it is supposed to represent.

The useful scope was narrow: show retrieval, response streaming, and a visible boundary without pretending the exercise was a deployed client system.

Frontend
Responsive chat, buffered SSE parsing, typing and error states, session recovery, feedback, and request deduplication.
Backend
Node and TypeScript API, retrieval scope, PostgreSQL history, stream events, health check, and failure handling.
Delivery
Separate Vercel and Render deployment, exact-origin CORS diagnosis, documentation, and truthful live-state reporting.

Research only matters here when it changed a decision.

  1. 01

    SSE versus WebSockets

    The product needs one-way incremental output after a POST body, not a permanent bidirectional socket.

    The client uses fetch plus ReadableStream and parses SSE frames from the POST response.
  2. 02

    Buffered stream parsing tests

    Network chunks do not align with event or line boundaries, so parsing each received chunk independently loses or corrupts data.

    The client carries an incomplete-line buffer and only parses complete data frames.
  3. 03

    Bounded context and session recovery

    A support conversation needs enough history to remain coherent without resending an unbounded transcript.

    History is persisted by session and the model receives a bounded context window.
  4. 04

    Deployment failure taxonomy

    A healthy frontend, suspended backend, exact CORS-origin mismatch, mid-stream loss, and malformed event are different failures.

    User-visible errors and docs distinguish reachability, configuration, and stream completion instead of showing one generic typing state.

Keep retrieval scope visible beside the streamed answer.

The client sends the support question, the backend retrieves the relevant brand material, and the response streams with that scope attached.

The public story names the project as a take-home and makes no user, client, or production-scale claim.

Question to scoped retrieval to buffered SSE to recovered session
  1. 01Chat clientSends a message and optional session identifier
  2. 02Support APIValidates, deduplicates, retrieves bounded Lumio context
  3. 03SSE streamEmits chunk, done, or error events over the POST response
  4. 04Session storePersists messages for refresh and later history recovery
  5. 05FeedbackAttaches an up or down record to an AI message

What I chose, what I rejected, and what the choice costs.

DecisionRejectedTrade-off
Use SSE over a streamed POST response.

Use WebSockets or wait for one blocking JSON reply.

The parser must handle partial frames, while the transport matches one-way answer streaming without socket infrastructure.

Persist sessions and deduplicate requests.

Treat every message as an isolated stateless completion.

The backend and database contract grow, while refresh recovery and duplicate-send handling become possible.

Label the live action as View the interface.

Call the suspended deployment a working demo or fabricate a streamed answer.

The public proof is weaker, while the current live state is accurate.

The interface is reachable. The backend and complete turn are not.

Not measured

No benchmark, user count, or production support volume was recorded for this take-home project.

No publishable outcome or usage denominator

No user, customer, traffic, answer-quality, or support-outcome number is published. Current proof is limited to source architecture, real interface captures, frontend reachability, and a failed backend health check.

The failures are part of the architecture record.

  1. 01

    Frontend and backend were deployed separately

    What I saw
    The interface loaded while the assistant could not complete a reply.
    Why
    Vercel continued serving the client after the Render backend became unavailable and is now suspended.
    What changed
    The public action now says View the interface and the case study labels interaction unverified.
    Still true
    The live assistant remains unusable until a backend and database are restored and checked end to end.
  2. 02

    One trailing slash broke CORS

    What I saw
    Browser requests failed even while the backend health endpoint responded.
    Why
    CORS origin matching is byte-exact, and the configured frontend URL included a trailing slash.
    What changed
    Deployment docs require the exact origin without a trailing slash and separate health from browser-origin checks.
    Still true
    Future domain or preview URLs still need explicit allowed-origin verification.
  3. 03

    A stream could close without done

    What I saw
    The interface could remain in a typing state after the connection ended mid-response.
    Why
    Transport completion was treated as equivalent to receiving a semantic done event.
    What changed
    The parser tracks completion and reports a specific error when the stream closes before done.
    Still true
    The unavailable backend prevented a fresh production completion check in this batch.
Read the end-to-end deployment correction

What the product cannot do yet, beside what may come next.

Current limitations

  • Lumio is fictional, and Spur Chat was a take-home assignment rather than a client product.
  • The frontend returned HTTP 200 on 2026-08-31, but the backend service was suspended and one complete chat turn could not be verified.
  • The current captures show the genuine entry state and do not prove answer quality, retrieval quality, users, customers, or traffic.
  • Separate frontend and backend deployment leaves availability, CORS, and database state as independent failure surfaces.

Deliberate boundaries

  • Imply that the fictional brand was a client.
  • Add a usage number that was never measured.
blocked

Restore backend service

Re-establish the API and PostgreSQL, then rerun health, exact-origin preflight, one complete streamed turn, history recovery, and feedback.

planned

Capture a verified complete turn

Replace the entry-state-only proof after a successful chunk-to-done stream is observed and recorded without private data.

investigating

Co-located deployment

Evaluate whether one deployment boundary would reduce CORS and split-availability failures without overbuilding the take-home.

The systems underneath it, and where this account comes from.

  • TypeScript
  • streaming responses
  • retrieval
  • web client
Audited internallySpur Chat committed repository, tests, and deployment docs
Audited internallyRead-only live health and chat checks