diff --git a/apps/hq-web/index.html b/apps/hq-web/index.html
new file mode 100644
index 0000000..d21cb9e
--- /dev/null
+++ b/apps/hq-web/index.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+ SiMS HQ
+
+
+
+
+
+
diff --git a/apps/hq-web/package.json b/apps/hq-web/package.json
new file mode 100644
index 0000000..e723952
--- /dev/null
+++ b/apps/hq-web/package.json
@@ -0,0 +1,26 @@
+{
+ "name": "@sims/hq-web",
+ "version": "0.1.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "vite build",
+ "preview": "vite preview",
+ "typecheck": "tsc -p tsconfig.json"
+ },
+ "dependencies": {
+ "@sims/domain": "*",
+ "@sims/printing": "*",
+ "@sims/ui": "*",
+ "react": "^19.0.0",
+ "react-dom": "^19.0.0",
+ "react-router-dom": "^7.0.0"
+ },
+ "devDependencies": {
+ "@types/react": "^19.0.0",
+ "@types/react-dom": "^19.0.0",
+ "@vitejs/plugin-react": "^4.3.0",
+ "vite": "^6.0.0"
+ }
+}
diff --git a/apps/hq-web/src/Layout.tsx b/apps/hq-web/src/Layout.tsx
new file mode 100644
index 0000000..ecd14b2
--- /dev/null
+++ b/apps/hq-web/src/Layout.tsx
@@ -0,0 +1,57 @@
+import { useEffect, useState } from 'react'
+import { Navigate, NavLink, Outlet, useNavigate } from 'react-router-dom'
+import { Badge, ThemeSwitcher } from '@sims/ui'
+import { clearSession, displayName, getEmailStatus, hasSession } from './api'
+
+const NAV = [
+ { to: '/', label: 'Clients' },
+ { to: '/modules', label: 'Modules' },
+ { to: '/documents/new', label: 'New Document' },
+]
+
+/** App shell: left nav + top bar + the spec's Gmail-health banner. */
+export function Layout() {
+ const nav = useNavigate()
+ const [gmailDown, setGmailDown] = useState(false)
+
+ useEffect(() => {
+ if (!hasSession()) return
+ getEmailStatus()
+ .then((s) => setGmailDown(!s.connected || s.dead))
+ .catch(() => { /* 401 already redirected; other failures keep the banner hidden */ })
+ }, [])
+
+ if (!hasSession()) return
+
+ return (
+
+
+
+ {gmailDown && (
+
+ Gmail disconnected — sends are queued to manual. Run gmail-connect on the server.
+
+ )}
+
+
+
+ {displayName()}
+
+
+
+
+
+
+
+ )
+}
diff --git a/apps/hq-web/src/Login.tsx b/apps/hq-web/src/Login.tsx
new file mode 100644
index 0000000..67c8155
--- /dev/null
+++ b/apps/hq-web/src/Login.tsx
@@ -0,0 +1,49 @@
+import { useState } from 'react'
+import { useNavigate } from 'react-router-dom'
+import { Button, Field, Notice } from '@sims/ui'
+import { login } from './api'
+
+/** HQ login — email + password against POST /api/auth/login (server-side scrypt). */
+export function Login() {
+ const nav = useNavigate()
+ const [email, setEmail] = useState('')
+ const [pw, setPw] = useState('')
+ const [busy, setBusy] = useState(false)
+ const [error, setError] = useState()
+
+ const submit = async () => {
+ if (busy) return
+ setBusy(true)
+ setError(undefined)
+ try {
+ await login(email.trim(), pw)
+ nav('/')
+ } catch (err) {
+ setError(err instanceof Error ? err.message : String(err))
+ setBusy(false)
+ }
+ }
+
+ return (
+
+ )
+}
diff --git a/apps/hq-web/src/api.ts b/apps/hq-web/src/api.ts
new file mode 100644
index 0000000..5982a5f
--- /dev/null
+++ b/apps/hq-web/src/api.ts
@@ -0,0 +1,63 @@
+/** HQ web ↔ hq-server client; token survives reloads via localStorage['hq.token']. */
+
+const TOKEN_KEY = 'hq.token'
+const NAME_KEY = 'hq.name'
+const ROLE_KEY = 'hq.role'
+
+export function hasSession(): boolean {
+ return (localStorage.getItem(TOKEN_KEY) ?? '') !== ''
+}
+
+export function displayName(): string {
+ return localStorage.getItem(NAME_KEY) ?? ''
+}
+
+/** 'owner' | 'staff' — Modules page renders read-only for staff. */
+export function role(): string {
+ return localStorage.getItem(ROLE_KEY) ?? 'staff'
+}
+
+export function clearSession(): void {
+ localStorage.removeItem(TOKEN_KEY)
+ localStorage.removeItem(NAME_KEY)
+ localStorage.removeItem(ROLE_KEY)
+}
+
+/**
+ * Fetch `/api${path}` with the session bearer token. On 401 (outside the login
+ * call itself) the session is cleared and the app redirects to /login.
+ */
+export async function apiFetch(path: string, opts?: RequestInit): Promise {
+ const token = localStorage.getItem(TOKEN_KEY) ?? ''
+ const res = await fetch(`/api${path}`, {
+ ...opts,
+ headers: {
+ 'content-type': 'application/json',
+ ...(token !== '' ? { authorization: `Bearer ${token}` } : {}),
+ ...(opts?.headers ?? {}),
+ },
+ }).catch(() => undefined)
+ if (res === undefined) throw new Error('HQ server unreachable — is it running on port 5182?')
+ if (res.status === 401 && !path.startsWith('/auth/')) {
+ clearSession()
+ window.location.hash = '#/login'
+ throw new Error('Not signed in')
+ }
+ const body = (await res.json().catch(() => ({}))) as T & { error?: string }
+ if (!res.ok) throw new Error(body.error ?? `Server error HTTP ${res.status}`)
+ return body
+}
+
+export async function login(email: string, password: string): Promise<{ displayName: string; role: string }> {
+ const out = await apiFetch<{ token: string; staff: { id: string; displayName: string; role: string } }>(
+ '/auth/login',
+ { method: 'POST', body: JSON.stringify({ email, password }) },
+ )
+ localStorage.setItem(TOKEN_KEY, out.token)
+ localStorage.setItem(NAME_KEY, out.staff.displayName)
+ localStorage.setItem(ROLE_KEY, out.staff.role)
+ return { displayName: out.staff.displayName, role: out.staff.role }
+}
+
+export interface EmailStatus { connected: boolean; address?: string; dead: boolean }
+export const getEmailStatus = (): Promise => apiFetch('/email/status')
diff --git a/apps/hq-web/src/app.css b/apps/hq-web/src/app.css
new file mode 100644
index 0000000..57cf2ab
--- /dev/null
+++ b/apps/hq-web/src/app.css
@@ -0,0 +1,25 @@
+/* HQ shell — same structure language as the back-office (bo-*) shell. */
+.hq-shell { display: grid; grid-template-columns: 210px 1fr; height: 100vh; }
+.hq-side { background: var(--bg-raised); border-right: 1px solid var(--border); overflow-y: auto; padding: 12px 0; }
+.hq-brand { font-weight: 700; font-size: 16px; padding: 4px 16px 12px; }
+.hq-brand small { display: block; color: var(--text-dim); font-weight: 400; }
+.hq-side a {
+ display: flex; align-items: center; gap: 8px; padding: 7px 16px; color: var(--text);
+ text-decoration: none; font-size: 13.5px;
+}
+.hq-side a:hover { background: var(--bg-hover); }
+.hq-side a.active { background: var(--bg-hover); box-shadow: inset 3px 0 0 var(--accent); }
+.hq-main { display: flex; flex-direction: column; min-width: 0; }
+.hq-banner {
+ padding: 8px 20px; font-size: 13px; color: var(--warn); background: var(--warn-soft);
+ border-bottom: 1px solid color-mix(in srgb, var(--warn) 35%, transparent);
+}
+.hq-top {
+ display: flex; gap: 12px; align-items: center; padding: 8px 20px;
+ border-bottom: 1px solid var(--border); background: var(--bg-raised);
+}
+.hq-content { overflow-y: auto; flex: 1; padding: 4px 20px 20px; }
+
+/* Login */
+.login-wrap { height: 100vh; display: flex; align-items: center; justify-content: center; }
+.login-card { background: var(--bg-raised); border: 1px solid var(--border); border-radius: 12px; padding: 28px; width: 380px; }
diff --git a/apps/hq-web/src/main.tsx b/apps/hq-web/src/main.tsx
new file mode 100644
index 0000000..1c6234b
--- /dev/null
+++ b/apps/hq-web/src/main.tsx
@@ -0,0 +1,35 @@
+import { createRoot } from 'react-dom/client'
+import { HashRouter, Navigate, Route, Routes } from 'react-router-dom'
+import '@fontsource-variable/inter'
+import '@fontsource-variable/jetbrains-mono'
+import '../../../packages/ui/src/tokens.css'
+import './app.css'
+import { initTheme, PageHeader } from '@sims/ui'
+import { Layout } from './Layout'
+import { Login } from './Login'
+
+/** Placeholder pages — Task 16 replaces these with the five real pages. */
+function Placeholder(props: { title: string }) {
+ return
+}
+
+function App() {
+ return (
+
+
+ } />
+ }>
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+
+
+
+ )
+}
+
+initTheme()
+createRoot(document.getElementById('root')!).render()
diff --git a/apps/hq-web/tsconfig.json b/apps/hq-web/tsconfig.json
new file mode 100644
index 0000000..bf5a36d
--- /dev/null
+++ b/apps/hq-web/tsconfig.json
@@ -0,0 +1,4 @@
+{
+ "extends": "../../tsconfig.base.json",
+ "include": ["src/**/*"]
+}
diff --git a/apps/hq-web/vite.config.ts b/apps/hq-web/vite.config.ts
new file mode 100644
index 0000000..1f9104e
--- /dev/null
+++ b/apps/hq-web/vite.config.ts
@@ -0,0 +1,19 @@
+import { defineConfig } from 'vite'
+import react from '@vitejs/plugin-react'
+import { fileURLToPath } from 'node:url'
+
+const p = (rel: string) => fileURLToPath(new URL(rel, import.meta.url))
+
+export default defineConfig({
+ base: './',
+ plugins: [react()],
+ resolve: {
+ alias: {
+ '@sims/domain': p('../../packages/domain/src/index.ts'),
+ '@sims/ui': p('../../packages/ui/src/index.ts'),
+ '@sims/printing': p('../../packages/printing/src/index.ts'),
+ },
+ },
+ // 5182 = apps/hq server (5181 store-server, 5180 backoffice dev).
+ server: { port: 5183, proxy: { '/api': 'http://localhost:5182' } },
+})
diff --git a/package-lock.json b/package-lock.json
index 40ab682..8e9d94a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -23,6 +23,7 @@
"dependencies": {
"@sims/billing-engine": "*",
"@sims/domain": "*",
+ "@sims/printing": "*",
"@sims/scanning": "*",
"@sims/ui": "*",
"react": "^19.0.0",
@@ -36,7 +37,602 @@
"vite": "^6.0.0"
}
},
- "apps/backoffice/node_modules/@esbuild/aix-ppc64": {
+ "apps/backoffice/node_modules/@esbuild/aix-ppc64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz",
+ "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "apps/backoffice/node_modules/@esbuild/android-arm": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz",
+ "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "apps/backoffice/node_modules/@esbuild/android-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz",
+ "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "apps/backoffice/node_modules/@esbuild/android-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz",
+ "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "apps/backoffice/node_modules/@esbuild/darwin-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz",
+ "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "apps/backoffice/node_modules/@esbuild/darwin-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz",
+ "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "apps/backoffice/node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz",
+ "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "apps/backoffice/node_modules/@esbuild/freebsd-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz",
+ "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "apps/backoffice/node_modules/@esbuild/linux-arm": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz",
+ "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "apps/backoffice/node_modules/@esbuild/linux-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz",
+ "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "apps/backoffice/node_modules/@esbuild/linux-ia32": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz",
+ "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "apps/backoffice/node_modules/@esbuild/linux-loong64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz",
+ "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "apps/backoffice/node_modules/@esbuild/linux-mips64el": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz",
+ "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "apps/backoffice/node_modules/@esbuild/linux-ppc64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz",
+ "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "apps/backoffice/node_modules/@esbuild/linux-riscv64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz",
+ "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "apps/backoffice/node_modules/@esbuild/linux-s390x": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz",
+ "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "apps/backoffice/node_modules/@esbuild/linux-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz",
+ "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "apps/backoffice/node_modules/@esbuild/netbsd-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz",
+ "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "apps/backoffice/node_modules/@esbuild/netbsd-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz",
+ "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "apps/backoffice/node_modules/@esbuild/openbsd-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz",
+ "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "apps/backoffice/node_modules/@esbuild/openbsd-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz",
+ "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "apps/backoffice/node_modules/@esbuild/openharmony-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz",
+ "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "apps/backoffice/node_modules/@esbuild/sunos-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz",
+ "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "apps/backoffice/node_modules/@esbuild/win32-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz",
+ "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "apps/backoffice/node_modules/@esbuild/win32-ia32": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz",
+ "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "apps/backoffice/node_modules/@esbuild/win32-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz",
+ "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "apps/backoffice/node_modules/esbuild": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz",
+ "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.25.12",
+ "@esbuild/android-arm": "0.25.12",
+ "@esbuild/android-arm64": "0.25.12",
+ "@esbuild/android-x64": "0.25.12",
+ "@esbuild/darwin-arm64": "0.25.12",
+ "@esbuild/darwin-x64": "0.25.12",
+ "@esbuild/freebsd-arm64": "0.25.12",
+ "@esbuild/freebsd-x64": "0.25.12",
+ "@esbuild/linux-arm": "0.25.12",
+ "@esbuild/linux-arm64": "0.25.12",
+ "@esbuild/linux-ia32": "0.25.12",
+ "@esbuild/linux-loong64": "0.25.12",
+ "@esbuild/linux-mips64el": "0.25.12",
+ "@esbuild/linux-ppc64": "0.25.12",
+ "@esbuild/linux-riscv64": "0.25.12",
+ "@esbuild/linux-s390x": "0.25.12",
+ "@esbuild/linux-x64": "0.25.12",
+ "@esbuild/netbsd-arm64": "0.25.12",
+ "@esbuild/netbsd-x64": "0.25.12",
+ "@esbuild/openbsd-arm64": "0.25.12",
+ "@esbuild/openbsd-x64": "0.25.12",
+ "@esbuild/openharmony-arm64": "0.25.12",
+ "@esbuild/sunos-x64": "0.25.12",
+ "@esbuild/win32-arm64": "0.25.12",
+ "@esbuild/win32-ia32": "0.25.12",
+ "@esbuild/win32-x64": "0.25.12"
+ }
+ },
+ "apps/backoffice/node_modules/vite": {
+ "version": "6.4.3",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.3.tgz",
+ "integrity": "sha512-NTKlcQjlAK7MlQoyb6LgaqHc8sso/pVyUJYWMws3jg21uTJw/LddqIFPcPqP6PzpgbIcZyKI85sFE4HBrQDA8A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "esbuild": "^0.25.0",
+ "fdir": "^6.4.4",
+ "picomatch": "^4.0.2",
+ "postcss": "^8.5.3",
+ "rollup": "^4.34.9",
+ "tinyglobby": "^0.2.13"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
+ "jiti": ">=1.21.0",
+ "less": "*",
+ "lightningcss": "^1.21.0",
+ "sass": "*",
+ "sass-embedded": "*",
+ "stylus": "*",
+ "sugarss": "*",
+ "terser": "^5.16.0",
+ "tsx": "^4.8.1",
+ "yaml": "^2.4.2"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "jiti": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "sass-embedded": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ },
+ "tsx": {
+ "optional": true
+ },
+ "yaml": {
+ "optional": true
+ }
+ }
+ },
+ "apps/hq": {
+ "name": "@sims/hq",
+ "version": "0.1.0",
+ "dependencies": {
+ "@sims/auth": "*",
+ "@sims/billing-engine": "*",
+ "@sims/domain": "*",
+ "better-sqlite3": "^11.7.0",
+ "express": "^4.21.0",
+ "puppeteer": "^23.11.0"
+ },
+ "devDependencies": {
+ "@types/better-sqlite3": "^7.6.11",
+ "@types/express": "^4.17.21",
+ "esbuild": "^0.25.0",
+ "tsx": "^4.19.0"
+ }
+ },
+ "apps/hq-web": {
+ "name": "@sims/hq-web",
+ "version": "0.1.0",
+ "dependencies": {
+ "@sims/domain": "*",
+ "@sims/printing": "*",
+ "@sims/ui": "*",
+ "react": "^19.0.0",
+ "react-dom": "^19.0.0",
+ "react-router-dom": "^7.0.0"
+ },
+ "devDependencies": {
+ "@types/react": "^19.0.0",
+ "@types/react-dom": "^19.0.0",
+ "@vitejs/plugin-react": "^4.3.0",
+ "vite": "^6.0.0"
+ }
+ },
+ "apps/hq-web/node_modules/@esbuild/aix-ppc64": {
"version": "0.25.12",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz",
"integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==",
@@ -53,7 +649,7 @@
"node": ">=18"
}
},
- "apps/backoffice/node_modules/@esbuild/android-arm": {
+ "apps/hq-web/node_modules/@esbuild/android-arm": {
"version": "0.25.12",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz",
"integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==",
@@ -70,7 +666,7 @@
"node": ">=18"
}
},
- "apps/backoffice/node_modules/@esbuild/android-arm64": {
+ "apps/hq-web/node_modules/@esbuild/android-arm64": {
"version": "0.25.12",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz",
"integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==",
@@ -87,7 +683,7 @@
"node": ">=18"
}
},
- "apps/backoffice/node_modules/@esbuild/android-x64": {
+ "apps/hq-web/node_modules/@esbuild/android-x64": {
"version": "0.25.12",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz",
"integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==",
@@ -104,7 +700,7 @@
"node": ">=18"
}
},
- "apps/backoffice/node_modules/@esbuild/darwin-arm64": {
+ "apps/hq-web/node_modules/@esbuild/darwin-arm64": {
"version": "0.25.12",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz",
"integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==",
@@ -121,7 +717,7 @@
"node": ">=18"
}
},
- "apps/backoffice/node_modules/@esbuild/darwin-x64": {
+ "apps/hq-web/node_modules/@esbuild/darwin-x64": {
"version": "0.25.12",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz",
"integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==",
@@ -138,7 +734,7 @@
"node": ">=18"
}
},
- "apps/backoffice/node_modules/@esbuild/freebsd-arm64": {
+ "apps/hq-web/node_modules/@esbuild/freebsd-arm64": {
"version": "0.25.12",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz",
"integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==",
@@ -155,7 +751,7 @@
"node": ">=18"
}
},
- "apps/backoffice/node_modules/@esbuild/freebsd-x64": {
+ "apps/hq-web/node_modules/@esbuild/freebsd-x64": {
"version": "0.25.12",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz",
"integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==",
@@ -172,7 +768,7 @@
"node": ">=18"
}
},
- "apps/backoffice/node_modules/@esbuild/linux-arm": {
+ "apps/hq-web/node_modules/@esbuild/linux-arm": {
"version": "0.25.12",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz",
"integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==",
@@ -189,7 +785,7 @@
"node": ">=18"
}
},
- "apps/backoffice/node_modules/@esbuild/linux-arm64": {
+ "apps/hq-web/node_modules/@esbuild/linux-arm64": {
"version": "0.25.12",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz",
"integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==",
@@ -206,7 +802,7 @@
"node": ">=18"
}
},
- "apps/backoffice/node_modules/@esbuild/linux-ia32": {
+ "apps/hq-web/node_modules/@esbuild/linux-ia32": {
"version": "0.25.12",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz",
"integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==",
@@ -223,7 +819,7 @@
"node": ">=18"
}
},
- "apps/backoffice/node_modules/@esbuild/linux-loong64": {
+ "apps/hq-web/node_modules/@esbuild/linux-loong64": {
"version": "0.25.12",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz",
"integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==",
@@ -240,7 +836,7 @@
"node": ">=18"
}
},
- "apps/backoffice/node_modules/@esbuild/linux-mips64el": {
+ "apps/hq-web/node_modules/@esbuild/linux-mips64el": {
"version": "0.25.12",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz",
"integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==",
@@ -257,7 +853,7 @@
"node": ">=18"
}
},
- "apps/backoffice/node_modules/@esbuild/linux-ppc64": {
+ "apps/hq-web/node_modules/@esbuild/linux-ppc64": {
"version": "0.25.12",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz",
"integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==",
@@ -274,7 +870,7 @@
"node": ">=18"
}
},
- "apps/backoffice/node_modules/@esbuild/linux-riscv64": {
+ "apps/hq-web/node_modules/@esbuild/linux-riscv64": {
"version": "0.25.12",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz",
"integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==",
@@ -291,7 +887,7 @@
"node": ">=18"
}
},
- "apps/backoffice/node_modules/@esbuild/linux-s390x": {
+ "apps/hq-web/node_modules/@esbuild/linux-s390x": {
"version": "0.25.12",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz",
"integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==",
@@ -308,7 +904,7 @@
"node": ">=18"
}
},
- "apps/backoffice/node_modules/@esbuild/linux-x64": {
+ "apps/hq-web/node_modules/@esbuild/linux-x64": {
"version": "0.25.12",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz",
"integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==",
@@ -325,7 +921,7 @@
"node": ">=18"
}
},
- "apps/backoffice/node_modules/@esbuild/netbsd-arm64": {
+ "apps/hq-web/node_modules/@esbuild/netbsd-arm64": {
"version": "0.25.12",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz",
"integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==",
@@ -342,7 +938,7 @@
"node": ">=18"
}
},
- "apps/backoffice/node_modules/@esbuild/netbsd-x64": {
+ "apps/hq-web/node_modules/@esbuild/netbsd-x64": {
"version": "0.25.12",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz",
"integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==",
@@ -359,7 +955,7 @@
"node": ">=18"
}
},
- "apps/backoffice/node_modules/@esbuild/openbsd-arm64": {
+ "apps/hq-web/node_modules/@esbuild/openbsd-arm64": {
"version": "0.25.12",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz",
"integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==",
@@ -376,7 +972,7 @@
"node": ">=18"
}
},
- "apps/backoffice/node_modules/@esbuild/openbsd-x64": {
+ "apps/hq-web/node_modules/@esbuild/openbsd-x64": {
"version": "0.25.12",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz",
"integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==",
@@ -393,7 +989,7 @@
"node": ">=18"
}
},
- "apps/backoffice/node_modules/@esbuild/openharmony-arm64": {
+ "apps/hq-web/node_modules/@esbuild/openharmony-arm64": {
"version": "0.25.12",
"resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz",
"integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==",
@@ -410,7 +1006,7 @@
"node": ">=18"
}
},
- "apps/backoffice/node_modules/@esbuild/sunos-x64": {
+ "apps/hq-web/node_modules/@esbuild/sunos-x64": {
"version": "0.25.12",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz",
"integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==",
@@ -427,7 +1023,7 @@
"node": ">=18"
}
},
- "apps/backoffice/node_modules/@esbuild/win32-arm64": {
+ "apps/hq-web/node_modules/@esbuild/win32-arm64": {
"version": "0.25.12",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz",
"integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==",
@@ -444,7 +1040,7 @@
"node": ">=18"
}
},
- "apps/backoffice/node_modules/@esbuild/win32-ia32": {
+ "apps/hq-web/node_modules/@esbuild/win32-ia32": {
"version": "0.25.12",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz",
"integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==",
@@ -461,7 +1057,7 @@
"node": ">=18"
}
},
- "apps/backoffice/node_modules/@esbuild/win32-x64": {
+ "apps/hq-web/node_modules/@esbuild/win32-x64": {
"version": "0.25.12",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz",
"integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==",
@@ -478,7 +1074,7 @@
"node": ">=18"
}
},
- "apps/backoffice/node_modules/esbuild": {
+ "apps/hq-web/node_modules/esbuild": {
"version": "0.25.12",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz",
"integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==",
@@ -520,7 +1116,7 @@
"@esbuild/win32-x64": "0.25.12"
}
},
- "apps/backoffice/node_modules/vite": {
+ "apps/hq-web/node_modules/vite": {
"version": "6.4.3",
"resolved": "https://registry.npmjs.org/vite/-/vite-6.4.3.tgz",
"integrity": "sha512-NTKlcQjlAK7MlQoyb6LgaqHc8sso/pVyUJYWMws3jg21uTJw/LddqIFPcPqP6PzpgbIcZyKI85sFE4HBrQDA8A==",
@@ -595,24 +1191,6 @@
}
}
},
- "apps/hq": {
- "name": "@sims/hq",
- "version": "0.1.0",
- "dependencies": {
- "@sims/auth": "*",
- "@sims/billing-engine": "*",
- "@sims/domain": "*",
- "better-sqlite3": "^11.7.0",
- "express": "^4.21.0",
- "puppeteer": "^23.11.0"
- },
- "devDependencies": {
- "@types/better-sqlite3": "^7.6.11",
- "@types/express": "^4.17.21",
- "esbuild": "^0.25.0",
- "tsx": "^4.19.0"
- }
- },
"apps/hq/node_modules/@esbuild/aix-ppc64": {
"version": "0.25.12",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz",
@@ -3460,6 +4038,10 @@
"resolved": "apps/hq",
"link": true
},
+ "node_modules/@sims/hq-web": {
+ "resolved": "apps/hq-web",
+ "link": true
+ },
"node_modules/@sims/pos": {
"resolved": "apps/pos",
"link": true
@@ -7136,7 +7718,8 @@
"name": "@sims/printing",
"version": "0.1.0",
"dependencies": {
- "@sims/domain": "*"
+ "@sims/domain": "*",
+ "@sims/scanning": "*"
}
},
"packages/scanning": {