Frontend Overview
The IPFOS web app lives in the ipfos-web/ repository. It is a TanStack Start application — a full-stack React meta-framework — that renders the internal operations portal: ticketing, users & departments, projects, meals, and notifications.
Tech stack
| Concern | Technology |
|---|---|
| Framework | TanStack Start (React 19, React Compiler enabled) |
| Build / server | Vite 7, Nitro server runtime (production runs node .output/server/index.mjs) |
| Routing | TanStack Router, file-based (src/routes/, generated tree in src/routeTree.gen.ts) |
| Server state | TanStack Query 5 (with SSR integration) |
| Tables | TanStack Table 8 |
| Forms | React Hook Form + Zod 4 |
| Styling | Tailwind CSS v4 (CSS-first config, global styles in src/styles.css) |
| UI primitives | Base UI, cmdk, react-day-picker, react-dropzone, motion |
| Rich text | TipTap 3 with DOMPurify sanitization |
| Icons | Solar icons (preferred, import from @solar-icons/react/ssr), Lucide as fallback |
| HTTP | axios wrapped by r3-utils/http-client |
| Lint / format | oxlint + oxfmt (not ESLint/Prettier), enforced by Husky + lint-staged |
| Tests | Vitest + jsdom |
| Package manager | pnpm — do not use npm or yarn |
Folder structure
The import alias is @/* → src/*.
| Directory | Purpose |
|---|---|
src/components/ | Global reusable UI components (avatar, button, combobox, modal, table, tiptap-editor, form-controls, …) |
src/routes/ | File-based routes — this is also the map of the app's feature areas |
src/hooks/ | Global custom hooks (use-debounce, use-search-params-state, use-route-dialog, …) |
src/libs/ | Cross-cutting libraries: auth/, access-control/, http-client/. Each sub-folder exports through an index.ts |
src/providers/ | React context providers (app-provider, confirmation modals, dialogs) |
src/layout/ | Layout shells |
src/utils/ | Utilities (cn, date/error/string utils, reusable Zod schemas in zod-common/) |
src/constants/ | Static constants |
Inside a feature route folder, the team uses --prefixed folders (excluded from routing):
-api/or-resources/— query options, Zod schemas, types-sections/— page-specific presentational components-layout/— feature-scoped layout piecesroute.tsxis the layout/guard wrapper,index.tsxis the page content
Naming and code conventions
- kebab-case for all files and folders, except hook files (named after the hook) and Zod schema files (
PascalCase...Schema.ts). - Component categories: compound (folder +
index.tsx, sub-elements prefixed with the parent name, e.g.ComboboxTrigger), grouped (e.g.form-controls/), and singular (one file). - Always import through the
@/alias; avoidany; type every function and component. - Object/type keys are sorted ascending — oxfmt enforces this, so let the formatter do it.
- Prefer TSDoc for reusable utils, hooks, and components.
The components playground
src/routes/components-playground/ is an internal showcase of the component library (buttons, form controls, tables, modals, slide-overs). It is not a product feature — but it is the fastest way for a new developer to discover which components already exist before building new ones.