# Project export: NurseFlow AI

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: OpenAI Build Week
- Tagline: Turn nurse requests into validated, explainable ICU schedule candidates with human approval built in.
- Devpost: https://devpost.com/software/ai-nurse-shift-schedules
- GitHub: https://github.com/SuphakornP/nurseflow-ai-scheduler
- Video: https://www.youtube.com/embed/8IuxhrK1RVA?enablejsapi=1&hl=en_US&rel=0&start=&version=3&wmode=transparent
- Team: 1 GitHub contributor(s) — Suphakorn Palathai (10 commits)

## Devpost submission (written by the team)

### Inspiration

Nurse schedules are high-stakes operational documents assembled from staffing rules, skill mix, leave, education, and individual requests. The work is repetitive, difficult to audit, and still requires an experienced human decision-maker. We built NurseFlow AI to make that workflow faster and more explainable without pretending AI should make the final staffing decision.

### What it does

NurseFlow imports pseudonymous nurse request sheets, normalizes ambiguous request values for human review, and creates multiple ICU roster candidates. It supports the supplied MICU form while discarding employee codes and notes before the normalized dataset reaches the browser workflow, solver, OpenAI, or exports. Every candidate is checked by an independent validator against coverage, skill-mix, request, sequence, and workload constraints. Schedulers can compare trade-offs, inspect assignment evidence, confirm one version, and export a review-ready workbook. When Supabase has a matching staged period roster, confirmation also saves an immutable schedule-version history. The application is admin-only. Public examples use synthetic nicknames and no patient data. The configured administrator email is never written to scheduling records.

### How we built it

The interface and server boundary use Next.js, React, and TypeScript. A private FastAPI service models the roster with Google OR-Tools CP-SAT. Supabase stores confirmed versions and validation evidence, while ExcelJS and openpyxl produce exports. GPT-5.6 is used through the OpenAI Responses API with Structured Outputs to suggest normalization for ambiguous request tokens and to explain solver evidence. It does not generate the roster: CP-SAT creates assignments, a separate deterministic validator checks them, and a human scheduler approves the result. Codex accelerated architecture exploration, implementation across TypeScript and Python, admin authentication, security hardening, test generation, browser QA, documentation, and release preparation. We used Codex to challenge design decisions and verify boundaries rather than simply generate an unchecked prototype. Challenges The hardest part was keeping feasibility, privacy, and explainability aligned. We had to encode real scheduling constraints, bound every import and solver input, distinguish AI suggestions from deterministic decisions, and make complex trade-offs readable in one workspace. Accomplishments End-to-end prototype path for import, review, optimization, validation, comparison, confirmation, and export Immutable candidate history when Supabase has a matching staged period roster Independent validation of every generated candidate Admin-only JWT session and protected server-to-server solver boundary Formula-safe spreadsheet exports and bounded runtime inputs 117 web test cases, 58 solver tests, clean dependency audits, and responsive browser QA Public, reproducible repository with synthetic pseudonymous sample data

### What we learned

AI is most useful here at the ambiguous edges: interpreting messy request notation and translating structured evidence into clear explanations. Constraint solving and validation remain the right tools for schedule correctness, while the final decision remains human.

### What's next

Before any hospital pilot, we would move identity to managed authentication with MFA, add shared abuse controls and session revocation, introduce stable pseudonymous employee identity and transactional roster synchronization, harden deployment and spreadsheet decompression limits, and validate the workflow with real scheduling teams under an approved privacy and governance process.

## README (from the GitHub repository)

# NurseFlow AI

Admin-only, privacy-aware nurse scheduling decision support built for OpenAI
Build Week. NurseFlow turns a pseudonymous nurse request sheet into validated
ICU roster candidates, explains trade-offs, records the selected version, and
exports a review-ready workbook. The supplied MICU form is supported, but its
employee-code and notes columns are discarded during import. Shift cells are
treated as nurse preferences; staffing safety, skill mix, and sequence rules
remain hard constraints.

> **Project status:** public hackathon prototype. The source is open, but the
> admin workspace is not anonymously accessible, and solver work endpoints
> require private ingress. NurseFlow is not a clinical system and must not
> autonomously make staffing decisions.

## Contents

- [Why NurseFlow](#why-nurseflow)
- [Workflow and capabilities](#workflow-and-capabilities)
- [Demo gallery](#demo-gallery)
- [Architecture](#architecture)
- [Built with Codex and OpenAI](#built-with-codex-and-openai)
- [Quick start](#quick-start)
- [Configuration](#configuration)
- [Data and import contract](#data-and-import-contract)
- [Scheduling and validation](#scheduling-and-validation)
- [API surface](#api-surface)
- [Supabase persistence](#supabase-persistence)
- [Testing and quality](#testing-and-quality)
- [Deployment](#deployment)
- [Security and data-use warning](#security-and-data-use-warning)
- [Project structure](#project-structure)
- [Documentation](#documentation)
- [Contributing](#contributing)
- [License](#license)

## Why NurseFlow

Nurse rosters combine daily coverage, skill mix, leave, education, individual
requests, previous-month sequences, and fairness goals. The work is repetitive
and difficult to audit, but the final decision still needs an experienced human.
NurseFlow separates the parts of that workflow by responsibility:

- deterministic parsing handles known request notation;
- GPT-5.6 suggests interpretations only for ambiguous tokens and explains
  structured solver evidence;
- Google OR-Tools CP-SAT creates complete candidate rosters;
- an independent validator recomputes every hard rule;
- an administrator compares candidates and confirms the final decision.

The language model does **not** build the roster, relax hard constraints, or
confirm a schedule.

## Workflow and capabilities

```text
Sign in as administrator
  -> import Google Sheet or .xlsx
  -> normalize request values
  -> review every ambiguous value
  -> generate three CP-SAT candidates
  -> independently validate each candidate
  -> compare fulfilled and unmet requests, balance, and L0 usage
  -> inspect assignment-level and hard-validation evidence
  -> choose and confirm one eligible valid version
  -> persist immutable history when Supabase is configured
  -> export only a validated Excel workbook
```

Key capabilities include:

- a responsive five-step workspace for import, review, generation, comparison,
  and confirmation;
- a built-in synthetic August 2026 MICU dataset with 28 unique nicknames and no
  patient data;
- `.xlsx` upload and import from a Google Sheets export, bounded to 10 MB;
- explicit human review for low-confidence or non-standard request notation;
- three optimization profiles: request-first, balanced, and reduced Member L0
  utilization;
- explicit trade-offs between preference satisfaction and operational goals,
  with assignment evidence, unfulfilled-request explanations, validation
  results, daily coverage, and workload metrics;
- immutable Supabase confirmation history and archive export when persistence is
  configured;
- a deterministic local fallback when OpenAI or Supabase is intentionally absent.

## Demo gallery

These 3:2 frames use the built-in synthetic August 2026 MICU dataset.
They contain no real staff, patient, employee-code, or source-sheet data.

<table>
  <tr>
    <td width="50%"><a href="docs/screenshots/00-admin-login.jpg"><img src="docs/screenshots/00-admin-login.jpg" alt="NurseFlow AI admin-only access checkpoint" width="100%"></a><br><strong>Access checkpoint</strong> - Authenticate as the provisioned administrator before any roster data is shown.</td>
    <td width="50%"><a href="docs/screenshots/01-synthetic-demo-import.jpg"><img src="docs/screenshots/01-synthetic-demo-import.jpg" alt="Synthetic MICU request intake in NurseFlow AI" width="100%"></a><br><strong>1. Synthetic intake</strong> - Load the privacy-safe showcase roster or review a Sheet/XLSX source.</td>
  </tr>
  <tr>
    <td><a href="docs/screenshots/02-request-review.jpg"><img src="docs/screenshots/02-request-review.jpg" alt="NurseFlow AI request policy review" width="100%"></a><br><strong>2. Review request policy</strong> - Verify fixed VAC/ED events, required choices, and soft requests before optimization.</td>
    <td><a href="docs/screenshots/03-candidate-generation.jpg"><img src="docs/screenshots/03-candidate-generation.jpg" alt="NurseFlow AI candidate generation checkpoint" width="100%"></a><br><strong>3. Generate candidates</strong> - Optimize 868 assignments, then run an independent hard-rule validator.</td>
  </tr>
  <tr>
    <td><a href="docs/screenshots/04-candidate-comparison.jpg"><img src="docs/screenshots/04-candidate-comparison.jpg" alt="NurseFlow AI candidate comparison workspace" width="100%"></a><br><strong>4. Compare trade-offs</strong> - Review request fulfillment, workload balance, coverage, and Member L0 use.</td>
    <td><a href="docs/screenshots/05-roster-evidence.jpg"><img src="docs/screenshots/05-roster-evidence.jpg" alt="NurseFlow AI roster with preserved vacation evidence" width="100%"></a><br><strong>5. Inspect evidence</strong> - Trace an assignment to its request type and see that approved vacation remains fixed.</td>
  </tr>
  <tr>
    <td><a href="docs/screenshots/06-hard-validation.jpg"><img src="docs/screenshots/06-hard-validation.jpg" alt="NurseFlow AI hard validation and candidate profiles" width="100%"></a><br><strong>6. Validate safety rules</strong> - Check 22 hard rules and compare all three valid optimization profiles.</td>
    <td><a href="docs/screenshots/07-confirm-export.jpg"><img src="docs/screenshots/07-confirm-export.jpg" alt="NurseFlow AI fail-closed confirmation and export checkpoint" width="100%"></a><br><strong>7. Human approval</strong> - Confirmation and export remain fail-closed until the selected solver result is valid and every hard-validation item passes.</td>
  </tr>
</table>

## Architecture

```mermaid
flowchart LR
    B["Admin browser"] -->|"HttpOnly session"| N["Next.js 16"]
    N --> P["Parser and schemas"]
    N -->|"Ambiguous tokens and evidence"| O["OpenAI Responses API"]
    N -->|"Bearer service token"| F["Private FastAPI service"]
    F --> C["OR-Tools CP-SAT"]
    F --> V["Independent validator"]
    N -->|"Server credentials"| S["Supabase Postgres"]
    F --> X["Validated Excel export"]
```

| Component | Responsibility | Trust boundary |
| --- | --- | --- |
| Next.js | UI, admin session, imports, orchestration, OpenAI calls, persistence | Only browser-facing application service |
| FastAPI | Deterministic demo input, optimization, validation, workbook export | Internal service; work endpoints require a bearer token |
| OpenAI | Structured suggestions and evidence-grounded explanations | Receives bounded, nickname-level context; `store: false` |
| Supabase | Period inputs, candidate versions, validation evidence, confirmation history | Grants and RLS constrain browser access; the privileged server key remains server-only |
| Browser | Human review, candidate comparison, explicit confirmation | Never receives server secrets or calls the solver directly |

Failure is explicit. Missing OpenAI configuration uses deterministic suggestions;
missing Supabase configuration displays confirmation only in the current browser
workspace; solver failures return a service error instead of a fabricated result.

## Built with Codex and OpenAI

GPT-5.6 is called through the OpenAI Responses API with Structu

[README truncated for size]

## Detected evidence (automated analysis)

Indexed codebase: 107 recognized source files, 711 KB.
- CSS (language) — detected in the code
- FastAPI (technology) — detected in the code
- Next.js (technology) — detected in the code
- OpenAI (technology) — detected in the code
- Python (language) — detected in the code
- React (technology) — detected in the code
- SQL (language) — detected in the code
- Supabase (technology) — detected in the code
- TypeScript (language) — detected in the code
- AI coding agent: Codex — evidence: config files committed to the repository

## Codebase structure (from repository index)

### Files (120 of 120)

```
.env.example
.github/workflows/ci.yml
.gitignore
AGENTS.md
app/api/auth/login/route.ts
app/api/auth/logout/route.ts
app/api/confirm/route.ts
app/api/demo/route.ts
app/api/explain/route.ts
app/api/export/route.ts
app/api/generate/route.ts
app/api/health/route.ts
app/api/history/route.ts
app/api/import/route.ts
app/api/normalize/route.ts
app/globals.css
app/layout.tsx
app/login/page.tsx
app/page.tsx
components/admin-login.tsx
components/demo-data.ts
components/nurseflow-workspace.tsx
components/schedule-matrix.tsx
components/sign-out-button.tsx
docs/architecture.md
docs/database.md
docs/devpost-demo-runbook.md
docs/devpost-submission.md
docs/privacy.md
eslint.config.mjs
lib/api-error-sanitization.test.ts
lib/auth/config.test.ts
lib/auth/config.ts
lib/auth/cookie.ts
lib/auth/credentials.ts
lib/auth/endpoints.test.ts
lib/auth/proxy.test.ts
lib/auth/rate-limit.ts
lib/auth/request.ts
lib/auth/route-coverage.test.ts
lib/auth/server-config.ts
lib/auth/session-token.test.ts
lib/auth/session-token.ts
lib/auth/session.ts
lib/auth/types.ts
lib/confirm-route.test.ts
lib/confirmation-eligibility.test.ts
lib/confirmation-eligibility.ts
lib/constants.ts
lib/export-route.test.ts
lib/import-route.test.ts
lib/importer.test.ts
lib/importer.ts
lib/normalization-candidate.test.ts
lib/normalization-candidate.ts
lib/normalizer.test.ts
lib/normalizer.ts
lib/openai-explanation.ts
lib/openai-normalization.ts
lib/request-body.test.ts
lib/request-body.ts
lib/request-semantics.test.ts
lib/request-semantics.ts
lib/schedule-cache.ts
lib/schedule-schema.test.ts
lib/schedule-schema.ts
lib/solver-adapter.test.ts
lib/solver-adapter.ts
lib/solver-client.test.ts
lib/solver-client.ts
lib/source-workbook-cache.test.ts
lib/source-workbook-cache.ts
lib/source-workbook-template.test.ts
lib/source-workbook-template.ts
lib/spreadsheet.test.ts
lib/spreadsheet.ts
lib/supabase/admin.ts
lib/supabase/client.ts
lib/supabase/persisted-export.ts
lib/supabase/persistence.ts
lib/types.ts
lib/utils.ts
lib/xlsx-security.test.ts
lib/xlsx-security.ts
LICENSE
next.config.ts
package.json
proxy.ts
README.md
security_best_practices_report.md
services/solver/.env.example
services/solver/app/__init__.py
services/solver/app/auth.py
services/solver/app/demo.py
services/solver/app/export.py
services/solver/app/main.py
services/solver/app/models.py
services/solver/app/normalization.py
services/solver/app/solver.py
services/solver/app/validation.py
services/solver/ASSUMPTIONS.md
services/solver/Dockerfile
services/solver/pyproject.toml
services/solver/README.md
services/solver/requirements.txt
services/solver/tests/conftest.py
services/solver/tests/test_business_requirements.py
services/solver/tests/test_model_limits.py
services/solver/tests/test_normalization.py
services/solver/tests/test_request_preferences.py
services/solver/tests/test_solver_and_api.py
services/solver/tests/test_validation_boundaries.py
services/solver/uv.lock
supabase/.gitignore
supabase/config.toml
supabase/migrations/20260716065746_nurseflow_initial_schema.sql
supabase/seed.sql
test/server-only.ts
tsconfig.json
vitest.config.ts
```

### Dependencies

- package.json: @supabase/ssr@^0.12.3, @supabase/supabase-js@^2.110.6, @types/node@^26.1.1, @types/react@^19.2.17, @types/react-dom@^19.2.3, clsx@^2.1.1, concurrently@^10.0.3, eslint@^9.39.5, eslint-config-next@^16.2.10, exceljs@^4.4.0, jose@^6.2.3, jszip@^3.10.1, lucide-react@^1.24.0, motion@^12.42.2, next@^16.2.10, openai@^6.47.0, postcss@^8.5.19, react@^19.2.7, react-dom@^19.2.7, tailwind-merge@^3.6.0, typescript@^6.0.3, vitest@^4.1.10, zod@^4.4.3
- services/solver/pyproject.toml: fastapi@>=0.115,<1, httpx@>=0.28,<1, openpyxl@>=3.1,<4, ortools@>=9.11,<10, pydantic@>=2.10,<3, pytest@>=9.0.3,<10, pytest-cov@>=6,<7, uvicorn[standard]@>=0.34,<1
- services/solver/requirements.txt: fastapi@>=0.115,<1, openpyxl@>=3.1,<4, ortools@>=9.11,<10, pydantic@>=2.10,<3, uvicorn[standard]@>=0.34,<1

### Recent commits (newest first)

- Add admin login gallery screenshot
- Add synthetic demo screenshot gallery
- Harden roster request semantics and solver diagnostics
- Treat nurse requests as scheduling preferences (#2)
- Prepare Devpost submission review (#1)
- Harden confirmation and support MICU request sheets
- Expand project documentation and add MIT license
- Add Devpost submission worksheet
- Add repository contributor guidelines
- Initial NurseFlow AI hackathon app

## Key source files (fetched from GitHub, selected and truncated for size)

### AGENTS.md

```markdown
# Repository Guidelines

## Project Structure & Module Organization

The Next.js 16 application lives in `app/`; Route Handlers are under `app/api/`. Reusable React UI belongs in `components/`, while shared contracts, authentication, imports, solver adapters, and Supabase access live in `lib/`. Keep browser and server-only code separated; privileged modules should remain behind the existing `server-only` guard.

The Python scheduling service is in `services/solver/app/`, with pytest coverage in `services/solver/tests/`. Supabase migrations and synthetic seed data are under `supabase/`. Architecture, database, and privacy decisions belong in `docs/`.

## Build, Test, and Development Commands

- `npm install` and `uv sync --directory services/solver --extra dev` install pinned dependencies.
- `npm run dev:all` starts Next.js and FastAPI; use `npm run dev` or `npm run dev:solver` for one service.
- `npm run lint` runs ESLint with Next.js Core Web Vitals and TypeScript rules.
- `npm run typecheck` runs `tsc --noEmit`.
- `npm test` runs Vitest and pytest; target one suite with `npm run test:web` or `npm run test:solver`.
- `npm run build` verifies the production Next.js build.

## Coding Style & Naming Conventions

Use two-space indentation in TypeScript/TSX and four spaces in Python. Prefer strict runtime schemas, explicit types, small functions, and existing helpers over duplicated logic. Use PascalCase for React components, camelCase for TypeScript functions, UPPER_SNAKE_CASE for constants, and snake_case in Python. Component filenames use kebab-case, for example `sign-out-button.tsx`. Follow PEP 8 and add Python type hints. Run lint and typecheck before committing.

## Testing Guidelines

Place TypeScript tests beside their modules as `*.test.ts`; name Python tests `test_*.py`. Add tests for every behavior change, especially authentication, route coverage, validation boundaries, solver constraints, and error sanitization. There is no fixed coverage threshold, but regressions must have a focused test. Run `npm test` before opening a PR.

## Commit & Pull Request Guidelines

Use short, imperative commit subjects, such as `Harden solver export validation`. Keep commits scoped and avoid generated artifacts. PRs should explain what changed and why, list verification commands, link relevant issues, and include screenshots for UI changes. Call out migrations, environment changes, and accepted security trade-offs explicitly.

## Security & Configuration

Copy `.env.example` files to `.env.local`; never commit real credentials. Both services must share `SOLVER_API_TOKEN`, while `AUTH_SECRET` must remain distinct. Keep FastAPI private, deploy over HTTPS, and never add real staff or patient data—fixtures must remain synthetic and nickname-only.

```

### security_best_practices_report.md

```markdown
# NurseFlow AI Security Review

Date: 2026-07-17

## Executive summary

The current repository has no identified Critical or High severity finding. The original unauthenticated-route, public-solver, spreadsheet-injection, and vulnerable-pytest findings have been remediated. The checked-in implementation is suitable for the stated private, single-admin hackathon scope when the Next.js app is the only public service and FastAPI is kept on private ingress.

It is not yet suitable for a hospital pilot or a general internet-facing multi-user service. The remaining risks are centralized abuse protection, managed credential/session lifecycle, a complete production CSP, and container/network hardening.

This review covers the Next.js/React application, FastAPI solver, Supabase migration and local configuration, environment-file handling, dependency manifests, import/export paths, and deployment files. Real values in `.env.local` and `services/solver/.env.local` were parsed only for presence, format, minimum length, token equality, and token separation checks; they were never printed. Randomness and rotation history remain outside this review.

## Residual risks

### SEC-R01: Abuse controls are process-local and expensive actions have no shared quota

- Severity: Medium for an internet-facing deployment; accepted residual risk for the private hackathon deployment.
- Locations: `lib/auth/rate-limit.ts:14`, `lib/auth/rate-limit.ts:35`, `app/api/demo/route.ts:24`, `app/api/generate/route.ts:57`, `app/api/normalize/route.ts:30`, `app/api/explain/route.ts:27`.
- Evidence: login failures are stored in an in-memory process map and keyed by normalized account email. The five-attempt window therefore resets on restart, is not shared across instances, and can be used to temporarily lock the single known account. Demo and generation each launch three solver jobs, while normalization and explanation can consume OpenAI quota. These authenticated work routes do not have a shared rate limit, concurrency limit, or per-session quota.
- Impact: distributed attempts can bypass a per-process control, and a compromised admin session can consume solver capacity or OpenAI budget.
- Recommendation: enforce account-plus-trusted-client rate limits at the platform edge, store counters in a shared backend, add a bounded solver queue or semaphore, and set explicit per-session/per-day OpenAI quotas. Do not trust arbitrary forwarded-IP headers unless the deployment proxy overwrites them.

### SEC-R02: The event authentication model has no MFA or immediate session revocation

- Severity: Medium for production; explicitly accepted for this event build.
- Locations: `lib/auth/config.ts:5`, `lib/auth/session-token.ts:28`, `lib/auth/cookie.ts:1`, `app/api/auth/logout/route.ts:6`, `docs/privacy.md:26`.
- Evidence: one plaintext deployment-secret password is compared server-side, and successful authentication creates a stateless JWT with an absolute eight-hour lifetime. Logout deletes the bro
[truncated — 9834 more characters]
```

### package.json

```
{
  "name": "nurseflow-ai",
  "version": "0.1.0",
  "license": "MIT",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "dev:solver": "uv run --directory services/solver python -m uvicorn app.main:app --env-file .env.local --reload --port 8000",
    "dev:all": "concurrently -k -n web,solver -c cyan,green \"npm:dev\" \"npm:dev:solver\"",
    "build": "next build",
    "start": "next start",
    "lint": "eslint .",
    "typecheck": "tsc --noEmit",
    "test:web": "vitest run",
    "test:solver": "uv run --directory services/solver pytest",
    "test": "npm run test:web && npm run test:solver"
  },
  "dependencies": {
    "@supabase/ssr": "^0.12.3",
    "@supabase/supabase-js": "^2.110.6",
    "clsx": "^2.1.1",
    "exceljs": "^4.4.0",
    "jose": "^6.2.3",
    "jszip": "^3.10.1",
    "lucide-react": "^1.24.0",
    "motion": "^12.42.2",
    "next": "^16.2.10",
    "openai": "^6.47.0",
    "postcss": "^8.5.19",
    "react": "^19.2.7",
    "react-dom": "^19.2.7",
    "tailwind-merge": "^3.6.0",
    "zod": "^4.4.3"
  },
  "devDependencies": {
    "@types/node": "^26.1.1",
    "@types/react": "^19.2.17",
    "@types/react-dom": "^19.2.3",
    "concurrently": "^10.0.3",
    "eslint": "^9.39.5",
    "eslint-config-next": "^16.2.10",
    "typescript": "^6.0.3",
    "vitest": "^4.1.10"
  },
  "overrides": {
    "postcss": "^8.5.19",
    "uuid": "^11.1.1"
  }
}

```

### services/solver/requirements.txt

```
fastapi>=0.115,<1
openpyxl>=3.1,<4
ortools>=9.11,<10
pydantic>=2.10,<3
uvicorn[standard]>=0.34,<1

```

### services/solver/Dockerfile

```
FROM python:3.12-slim

ENV PYTHONDONTWRITEBYTECODE=1 \
    PYTHONUNBUFFERED=1

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY app ./app

EXPOSE 8000

CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]

```

### services/solver/pyproject.toml

```
[project]
name = "nurseflow-solver"
version = "0.1.0"
description = "Deterministic ICU nurse scheduling service for NurseFlow AI"
requires-python = ">=3.11"
dependencies = [
  "fastapi>=0.115,<1",
  "openpyxl>=3.1,<4",
  "ortools>=9.11,<10",
  "pydantic>=2.10,<3",
  "uvicorn[standard]>=0.34,<1",
]

[project.optional-dependencies]
dev = [
  "httpx>=0.28,<1",
  "pytest>=9.0.3,<10",
  "pytest-cov>=6,<7",
]

[tool.pytest.ini_options]
addopts = "-q"
pythonpath = ["."]
testpaths = ["tests"]

```

### app/page.tsx

```typescript
import { redirect } from "next/navigation";

import { NurseFlowWorkspace } from "@/components/nurseflow-workspace";
import { getAdminSession } from "@/lib/auth/session";

export default async function HomePage() {
  const session = await getAdminSession();
  if (!session) redirect("/login");

  return <NurseFlowWorkspace admin={session} />;
}

```

### app/layout.tsx

```typescript
import type { Metadata } from "next";

import "./globals.css";

export const metadata: Metadata = {
  title: "NurseFlow AI | Clinical Schedule Workspace",
  description:
    "A privacy-aware nurse scheduling showcase that turns requests into validated, explainable candidate rosters.",
};

export default function RootLayout({ children }: Readonly<{ children: React.ReactNode }>) {
  return (
    <html lang="en" data-scroll-behavior="smooth">
      <body>{children}</body>
    </html>
  );
}

```

### app/login/page.tsx

```typescript
import type { Metadata } from "next";
import { redirect } from "next/navigation";

import { AdminLogin } from "@/components/admin-login";
import { getAdminSession } from "@/lib/auth/session";

export const metadata: Metadata = {
  title: "Admin sign in | NurseFlow AI",
  description: "Administrator access checkpoint for the NurseFlow AI scheduling workspace.",
};

export default async function LoginPage() {
  const session = await getAdminSession();

  if (session) {
    redirect("/");
  }

  return <AdminLogin />;
}

```

### app/api/health/route.ts

```typescript
import { NextResponse } from "next/server";
import { requireAdminRequest } from "@/lib/auth/request";
import { callSolver } from "@/lib/solver-client";
import { isSupabaseConfigured } from "@/lib/supabase/admin";

export const dynamic = "force-dynamic";

export async function GET(request: Request) {
  const auth = await requireAdminRequest(request);
  if (!auth.ok) return auth.response;

  let solver: { status: string } = { status: "unavailable" };
  try {
    await callSolver<Record<string, unknown>>("/health", undefined, 3_000);
    solver = { status: "ready" };
  } catch {
    solver = { status: "unavailable" };
  }
  return NextResponse.json({
    status: solver.status === "ready" ? "ready" : "degraded",
    services: {
      solver,
      openai: {
        status: process.env.OPENAI_API_KEY ? "configured" : "deterministic_fallback",
        model: process.env.OPENAI_MODEL || "gpt-5.6-terra",
      },
      supabase: {
        status: isSupabaseConfigured() ? "configured" : "local_demo",
      },
    },
  });
}

```

[97 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]