# help.tauris.app

Free AI-powered HVAC troubleshooting, built by Tauris Tech. Snap a photo of an equipment nameplate, we find the service manual, and you get answers grounded in the actual documentation — not guesswork.

## Stack

- Next.js 15 (App Router) + React 19 + TypeScript (strict)
- Tailwind CSS v4 + shadcn/ui (new-york) + lucide icons
- next-themes for dark/light mode (defaults to dark)
- react-markdown + remark-gfm for assistant message rendering
- date-fns for relative timestamps in the sidebar

## Product flow

1. **Landing (`/`)** — public marketing page with a multi-flow auth modal (login / signup / activation / forgot / reset / business profile).
2. **Auth** — client-only. User JWT and profile are stored in `localStorage` or `sessionStorage` depending on the "Remember me" choice. There is no server middleware; the admin area reads from storage on mount.
3. **Chat (`/chat`)** — gated by the `RequireAuth` client component. Flow:
   - **Identify** — photo upload or text description → `POST /api/equipment/identify` or `/identify-text`.
   - **Confirm** — editable `EquipmentSpec` form with a confidence badge.
   - **Ingest** — `POST /api/equipment/manual/lookup`, then poll `GET /api/files/{file_id}` every 2s up to 3 min. Falls back to an override-URL form on `not_found` / `failed` / `timeout`.
   - **Troubleshoot** — SSE-streaming chat (`POST /api/equipment/troubleshoot` or `/troubleshoot/vision`). Field photos (≤4, JPEG/PNG/WEBP, 10 MB each) can be attached from turn 2 onward. A persistent sidebar lists past sessions (`GET /api/conversations?source=equipment_troubleshoot`) and can rehydrate any of them via `/chat?session=<id>`.

Full API contracts live in `EQUIPMENT_API.md` and `AUTH_SYSTEM.md` at the repository root.

## Local development

```bash
npm install
npm run dev
```

The dev server runs on `http://localhost:3000` (or the next free port). Any changes under `app/`, `components/`, `lib/`, or `hooks/` hot-reload.

Useful scripts:

- `npm run dev` — Turbopack dev server
- `npm run build` — production build (also validates TypeScript)
- `npm run start` — production server (after `build`)
- `npm run lint` — ESLint

## Environment variables

Copy `.env.example` to `.env.local` and fill in what you need.

| Variable               | Required | Purpose                                                                 |
|------------------------|----------|-------------------------------------------------------------------------|
| `NEXT_PUBLIC_SITE_URL` | No\*     | Used for Open Graph tags, `robots.txt`, and `sitemap.xml`. Defaults to `https://help.tauris.app`. Set this on deployed environments (e.g. preview URLs) so crawlers see the right canonical URL. |

\* Nothing else. The external API keys live client-side per the AUTH_SYSTEM.md and EQUIPMENT_API.md conventions — this product is a thin browser client against `api.tauris.app` and `api-videoai.tauris.app`, with no server secrets of its own.

## Project layout

```
app/
  chat/                 # gated chat workspace (layout + page + nested routes)
  privacy/              # privacy policy stub
  terms/                # terms of service stub
  error.tsx             # global error boundary
  not-found.tsx         # 404
  icon.tsx              # generated wrench + brand-gradient favicon
  layout.tsx            # fonts, metadata, ThemeProvider
  page.tsx              # landing page
  robots.ts, sitemap.ts # SEO routes

components/
  auth/                 # AuthModal + RequireAuth
  chat/                 # NewSessionFlow, TroubleshootChat, Sidebar
  layout/               # Navbar, LegalPageShell
  ui/                   # shadcn/ui components

lib/
  api/                  # client, auth, profile, equipment (SSE + types)
  validation.ts         # email/phone/name/password + strength rubric
  theme.ts              # getThemeClasses()
  states-fallback.ts    # 50-state fallback list for profile creation

hooks/
  useAuth.ts            # storage helpers + useAuth()
  useScrollAnimate.ts   # IntersectionObserver → .animate-slide-up
```

## Deployment (Vercel)

1. Push to a GitHub repo.
2. Import into Vercel — framework should auto-detect as Next.js.
3. In **Project Settings → Environment Variables**, set:
   - `NEXT_PUBLIC_SITE_URL=https://help.tauris.app` (or your preview URL for non-production environments).
4. Deploy. Vercel will run `npm run build` and serve the app.

No additional build configuration is required. The app is entirely client-rendered past SSR, so edge / static rendering modes both work.

### Notes for other hosts

- Any host that runs Node 20+ and can serve a standard Next.js build will work (`npm run build && npm run start`).
- If you deploy to a subdomain other than `help.tauris.app`, update `NEXT_PUBLIC_SITE_URL` so `robots.txt`, `sitemap.xml`, and Open Graph tags match.
- CORS: the app talks directly to `api.tauris.app` and `api-videoai.tauris.app` from the browser. Those hosts must allow your deployment's origin.

## Design system

See `UI_STYLE_GUIDE.md` at the repo root. The Tailwind theme (OKLCH tokens, keyframes, utility classes like `.card-hover`, `.btn-primary`, `.nav-item::after` gradient underline, and the `prefers-reduced-motion` fallback) is ported verbatim into `app/globals.css`.

## Accessibility

- Every icon-only button has an `aria-label`.
- Focus rings are visible on all interactive elements (`focus-visible:ring-2 focus-visible:ring-blue-600` or the shadcn equivalent).
- `prefers-reduced-motion` is respected — animations degrade to near-instant.
- Keyboard-only flow: tab from landing hero → sign in → complete signup → type nameplate description → submit → confirm spec → wait for manual → type a question → Enter to send.

## License

© 2026 Tauris Tech. All rights reserved.
