Aravind 3ddacf269a fix(seed): emit the users array the backend seeder reads
The fixture generator was a version behind the seeder, and the gap was
the `users` key.

`internal/seeder` unmarshals `seed.json` into `{demoUser, users,
entities}` and writes every account in `users`, falling back to
`demoUser` alone when the key is absent. `fixtureFrom` never emitted it —
its comment still claimed the Go loader "ignores the rest", which stopped
being true when the seeder gained the field. So `npm run seed:check`
reported stale on every run, and that is the seventh suite failure, the
one that pre-dates the TypeScript migration.

What made this worth investigating rather than regenerating: the
committed fixture was NOT wrong. It carries two accounts — the demo
administrator and `employer@krow.app` — and running `npm run seed:fixture`
against the old generator would have written a fixture without them.
`krow-backend/docs/deploy-9d3192a.md` says so in as many words, and tells
anyone deploying not to run it.

The accounts are not deleted from a live database by that — the only
DELETE in the seeder is the shift-record prune, and `upsertUser`'s ON
CONFLICT deliberately leaves `password_hash` alone. The damage lands on
the next fresh environment, where `user_employer` would simply never be
created, leaving nobody to sign in as to reach the employer console —
which is the exact gap `seeder.go` records the account as having been
added to close.

The matching frontend half already existed, unmerged, on
`feat/krow-employee-pages` (7a4b61d). That branch is a 53-file console
restructure that renames the same files this migration renamed, so it is
not mergeable here. Only the three files that carry the contract are
taken: `EMPLOYER_USER`, `seedData.User` naming both accounts, and the
generator emitting `users`.

The proof is that nothing had to be written. With the generator corrected
its output is byte-identical to the fixture already committed in
krow-backend — 168,293 bytes, `cmp` clean — so `seed.json` was never
opened for writing, and its md5 and mtime are untouched.

  typecheck     0 errors
  seed:check    "seed.json is in step with src/api/seed.js", exit 0
  npm test      1685/1691, up from 1684 — the fixture check now reads
                "24 applications, byte-identical". The remaining 6 are
                exactly the documented dca1842 baseline failures.
  lint          exit 0, 0 errors, 289 warnings
  build         exit 0, bundle 74d17e2d… unchanged

The bundle being unchanged is itself a check: `demoUser.ts` IS in the
production bundle, and `EMPLOYER_USER` is a new export of it. Nothing in
the app imports it, so it is tree-shaken out and not one byte reaches the
shipped code.

No baseline artifact touched. krow-backend not modified.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HBG1wnuRfJKCstGB8Fekr8
2026-09-19 23:54:36 +05:30
2026-08-07 23:53:15 +05:30
2026-08-28 13:52:59 +05:30
2026-09-05 10:46:06 +05:30
2026-08-19 17:36:27 +05:30
2026-08-10 14:37:51 +05:30
2026-08-25 18:56:07 +05:30
2026-08-28 11:02:02 +05:30
2026-08-28 11:02:02 +05:30
2026-08-24 20:06:11 +05:30
2026-08-28 11:02:02 +05:30
2026-08-10 15:53:53 +05:30
2026-08-07 23:53:15 +05:30
2026-08-13 21:41:14 +05:30
2026-08-25 18:56:07 +05:30

KROW Demo

AI-powered hiring for event and hospitality staffing — a standalone demo build of KROW Forge.

Runs with no backend, no API keys and no real login. npm install && npm run dev and the app is fully populated.

npm install
npm run dev      # http://localhost:5173 — opens on /admin/login

Stack

Vite 6 · React 19 · React Router 6 · React Query 5 · Tailwind + shadcn/ui · Framer Motion · Recharts + MUI X Charts · react-hot-toast.

Structure

src/
  main.jsx        entry — mounts <App/>, imports index.css
  App.jsx         providers + the entire route table
  index.css       design tokens (HSL CSS variables) + utility layers

  api/            the backend seam — see below
    base44Client.js   the contract the production app talks to
    store.js          in-memory entity store, mirrored to localStorage
    aiEngine.js       local, deterministic InvokeLLM
    seed.js           demo dataset
    attendanceSeed.js shift/attendance dataset

  lib/            domain logic and data hooks
    krowHooks.js      React Query hooks over the entity store
    krowAi.js         AI workflows
    krowScore.js      score engine
    AuthContext.jsx   auth provider
    admin/            admin session, permissions, position insights
    skills/           the Owliver skill system (registry, resolver, flows)
    agents/           the agent system (registry, runtime, lifecycle)

  skills/         *.md skill definitions   — loaded by import.meta.glob
  agents/         *.md agent definitions   — loaded by import.meta.glob

  components/
    ui/           23 shadcn primitives
    ds/           30 design-system components (the app's real vocabulary)
    admin/        admin page shell + role glyphs
    krow/         domain components (+ talent/, proving/)
    charts/       MUI X Charts wrappers and theme
    agents/       agent configure / canvas / test panel
    forge/        KROW Forge skill + challenge components
    skills/       skill authoring surfaces
    ai-assistant/ Owliver — panel, routing, capabilities, history

  layouts/        AdminLayout — header nav, ⌘K search, assistant panel
  pages/          route components (admin/ holds the live product)
  hooks/          shared hooks
  assets/         brand asset references

Routes

The app opens on /admin/login. Everything else lives under /admin/* behind two guards: ProtectedRoute (auth) and AdminRoute (admin session), rendered inside AdminLayout.

Path Page
/admin/login Admin sign-in — outside the protected boundary
/admin Control Center
/admin/positions, positions/new, positions/:id Positions, Create, Detail
/admin/candidates, candidates/:id Candidates, Candidate Intelligence profile
/admin/hired · /admin/talent-pool Hired History, Talent Pool
/admin/university, university/:id KROW Forge, challenge detail
/admin/analytics · /admin/activity Analytics, Activity
/admin/profile · /admin/settings Profile, Settings
/admin/workspace Workspace hub
/admin/workspace/agents, agents/new, agents/:id Agent list, agent editor
/admin/workspace/skills, skills/new, skills/:id UI skill list and editor
/admin/workspace/skills/owliver/new, owliver/:id Owliver skill editor
/admin/workspace/skill-development Skill Development
* lib/PageNotFound.jsx

Legacy top-level paths (/overview, /positions, /candidates, /hired, /talent-pool, /university, /analytics, /activity, /tracking) all Navigate into their /admin/* equivalent, id preserved. Static route segments are declared before dynamic ones so workspace/agents/new cannot be read as an agent whose id is "new".

Note. App.jsx still imports a set of pre-redesign Employer/Talent pages (Overview, Apply, WorkerProfile, KrowIdentity, EmployeeDashboard, DesignSystem, …) and layouts/Layout.jsx. None of them are mounted on a route — they are unreachable at runtime and retained pending a decision on whether to re-route or remove them.

The backend seam

The production app talks to a Base44 backend through src/api/base44Client.js. This demo keeps that module path, export name and full method contract, and swaps only the transport:

Contract Demo implementation
base44.entities.<Name>.list/filter/get/create/update/delete api/store.js — in-memory records, mirrored to localStorage
base44.integrations.Core.InvokeLLM api/aiEngine.js — local, deterministic
base44.integrations.Core.UploadFile blob URLs, session-scoped
base44.auth.* seeded employer/admin user, always signed in

Because the seam did not move, everything above it — lib/krowHooks.js, lib/krowAi.js, lib/krowScore.js, every page and component — is unchanged from the reference implementation.

The AI engine

Every AI workflow funnels through one call, InvokeLLM({ prompt, response_json_schema }). api/aiEngine.js reimplements it locally: it recognises each workflow by the phrase its prompt opens with, reads the structured fields the prompt already carries (Years Experience: 6, Required Certifications: …, the talent-pool JSON block) and scores them deterministically.

Nine workflows are implemented: candidate screening, job-description generation, résumé building, interview questions, interview evaluation, talent matching, Owliver's conversation, Career DNA building and Proving Ground evaluation. Results respond to the data rather than being canned — the same input always returns the same output.

Skills and agents

Two registries discover their definitions from markdown at build time:

Registry Glob Files
lib/skills/registry.js import.meta.glob('/src/skills/**/*.md') 18 Owliver skills, 5 workforce training skills
lib/agents/registry.js import.meta.glob('/src/agents/**/*.md') 9 agent definitions

These globs are absolute paths. Moving or renaming src/skills/ or src/agents/ makes the registry silently return nothing — no build error, no import failure, just an empty registry. Add definitions by dropping a new .md file into the right folder; nothing else needs to change.

Demo data

Seeded in src/api/seed.js — positions, applicants, AI-scored candidates, interviews, hires, talent-pool profiles, Proving Ground courses and an activity log; shift data in src/api/attendanceSeed.js.

Edits persist to localStorage. To restore the shipped dataset:

// in the browser console
localStorage.removeItem('krow_demo_db'); location.reload();

Bumping STORAGE_VERSION in src/api/store.js (currently 8) invalidates saved snapshots automatically, so changing the seed does not require a manual clear.

Design system

Tokens live in src/index.css as HSL CSS variables consumed by tailwind.config.js.

Token Value
Primary — KROW Blue #0A39DF
Accent — KROW Yellow #F9E547
Pale Yellow #F8E08E
Dark Navy #333F48
Mint #D1E0D7
Radius 0.75rem
Headings Sora
Body Inter

src/components/ds/ is the vocabulary the app actually writes in — Surface, KpiCard, DataTable, PageHeader, Modal, toast and the rest, exported through ds/index.js. src/components/ui/ holds the shadcn primitives those are built on. Surfaces use glass and glass-card; the page background is the gradient-mesh utility.

Toasts go through ds/toast (a wrapper over react-hot-toast), rendered by <HotToaster> in App.jsx.

Scripts

Command Purpose
npm run dev Dev server (honors PORT, default 5173)
npm run build Production build
npm run preview Serve the build
npm run lint ESLint — currently clean
npm run lint:fix ESLint with --fix
npm test scripts/skill-check.mjs — 1691 assertions over the skill and agent systems
npm run typecheck tsc -p ./tsconfig.json — 0 errors across 321 TypeScript files

The test harness

npm test boots a real Vite dev server in middleware mode and ssrLoadModules the actual application modules, so it exercises the real @/ alias and import.meta.glob pipeline rather than mocks. It also diffs Owliver's behaviour across eleven page contexts against a committed snapshot, scripts/__baseline__/owliver-baseline.json; regenerate that deliberately with node scripts/owliver-baseline.mjs --write, never to turn a red check green.

Because it loads modules by absolute path, the harness pins the locations of src/api/, src/lib/, src/lib/skills/, src/lib/agents/, src/components/ai-assistant/, src/App.jsx, src/layouts/AdminLayout.jsx and a handful of agent files. Move any of them and update scripts/owliver-capture.mjs and scripts/skill-check.mjs in the same change.

Known-failing checks

Two checks fail on a clean checkout and are tracked as separate work, not regressions:

  • npm test — 834/835 pass; the seeded overtime climb is found fails.
  • npm run typecheck — 59 errors, all pre-existing JSDoc/inference gaps in lib/krowAi.js, lib/skills/*, lib/positionModel.js and a few components.

Deployment

Dockerfile builds with node:22-alpine (capped at 1 GB heap for small hosts) and serves the static dist/ from nginx:alpine using nginx.conf — gzip, immutable /assets/ caching and an SPA fallback to index.html so client-side routes resolve on refresh.

Description
No description provided
Readme 7.2 MiB
Languages
TypeScript 81.1%
JavaScript 15.7%
HTML 2.6%
CSS 0.5%