Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 566d5f4b55 | |||
| 2c928ca4d7 | |||
| af75fecb66 | |||
| 2d4df6fe1e | |||
| db10320c8f | |||
| 40a4023c65 | |||
| d598511b75 | |||
| e714200b71 | |||
| 1e70e01046 | |||
| 83d7fecdd3 |
@@ -202,20 +202,20 @@ jobs:
|
|||||||
echo "Updating dev overlay image tags to: $TAG"
|
echo "Updating dev overlay image tags to: $TAG"
|
||||||
echo "Updating migration/seed Job names with SHA: $SHORT_SHA"
|
echo "Updating migration/seed Job names with SHA: $SHORT_SHA"
|
||||||
cd /tmp/infra
|
cd /tmp/infra
|
||||||
DEV_KUST="apps/groombook/overlays/dev/kustomization.yaml"
|
DEV_KUST="apps/overlays/dev/kustomization.yaml"
|
||||||
yq -i '(.images[] | select(.name == "ghcr.io/groombook/api")).newTag = env(TAG)' "$DEV_KUST"
|
yq -i '(.images[] | select(.name == "ghcr.io/groombook/api")).newTag = env(TAG)' "$DEV_KUST"
|
||||||
yq -i '(.images[] | select(.name == "ghcr.io/groombook/migrate")).newTag = env(TAG)' "$DEV_KUST"
|
yq -i '(.images[] | select(.name == "ghcr.io/groombook/migrate")).newTag = env(TAG)' "$DEV_KUST"
|
||||||
yq -i '(.images[] | select(.name == "ghcr.io/groombook/seed")).newTag = env(TAG)' "$DEV_KUST"
|
yq -i '(.images[] | select(.name == "ghcr.io/groombook/seed")).newTag = env(TAG)' "$DEV_KUST"
|
||||||
yq -i '(.images[] | select(.name == "ghcr.io/groombook/reset")).newTag = env(TAG)' "$DEV_KUST"
|
yq -i '(.images[] | select(.name == "ghcr.io/groombook/reset")).newTag = env(TAG)' "$DEV_KUST"
|
||||||
|
|
||||||
MIGRATE_JOB="apps/groombook/base/migrate-job.yaml"
|
MIGRATE_JOB="apps/base/migrate-job.yaml"
|
||||||
if [ -f "$MIGRATE_JOB" ]; then
|
if [ -f "$MIGRATE_JOB" ]; then
|
||||||
yq -i '.metadata.name = "migrate-schema-" + env(SHORT_SHA)' "$MIGRATE_JOB"
|
yq -i '.metadata.name = "migrate-schema-" + env(SHORT_SHA)' "$MIGRATE_JOB"
|
||||||
yq -i '.metadata.annotations."groombook.app/deploy-version" = env(TAG)' "$MIGRATE_JOB"
|
yq -i '.metadata.annotations."groombook.app/deploy-version" = env(TAG)' "$MIGRATE_JOB"
|
||||||
yq -i '.spec.ttlSecondsAfterFinished = (.spec.ttlSecondsAfterFinished // 86400)' "$MIGRATE_JOB"
|
yq -i '.spec.ttlSecondsAfterFinished = (.spec.ttlSecondsAfterFinished // 86400)' "$MIGRATE_JOB"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
SEED_JOB="apps/groombook/base/seed-job.yaml"
|
SEED_JOB="apps/base/seed-job.yaml"
|
||||||
if [ -f "$SEED_JOB" ]; then
|
if [ -f "$SEED_JOB" ]; then
|
||||||
yq -i '.metadata.name = "seed-test-data-" + env(SHORT_SHA)' "$SEED_JOB"
|
yq -i '.metadata.name = "seed-test-data-" + env(SHORT_SHA)' "$SEED_JOB"
|
||||||
yq -i '.metadata.annotations."groombook.app/deploy-version" = env(TAG)' "$SEED_JOB"
|
yq -i '.metadata.annotations."groombook.app/deploy-version" = env(TAG)' "$SEED_JOB"
|
||||||
@@ -237,7 +237,7 @@ jobs:
|
|||||||
git config user.name "groombook-engineer[bot]"
|
git config user.name "groombook-engineer[bot]"
|
||||||
git config user.email "3141748+groombook-engineer[bot]@users.noreply.github.com"
|
git config user.email "3141748+groombook-engineer[bot]@users.noreply.github.com"
|
||||||
git checkout -b "chore/update-image-tags-${TAG}"
|
git checkout -b "chore/update-image-tags-${TAG}"
|
||||||
git add apps/groombook/overlays/dev/ apps/groombook/base/migrate-job.yaml apps/groombook/base/seed-job.yaml
|
git add apps/overlays/dev/ apps/base/migrate-job.yaml apps/base/seed-job.yaml
|
||||||
git commit -m "chore: update image tags and migration/seed Job names to ${TAG}"
|
git commit -m "chore: update image tags and migration/seed Job names to ${TAG}"
|
||||||
|
|
||||||
git push -u origin "chore/update-image-tags-${TAG}"
|
git push -u origin "chore/update-image-tags-${TAG}"
|
||||||
|
|||||||
+2
-2
@@ -3,7 +3,7 @@ RUN corepack enable && corepack prepare pnpm@9.15.4 --activate
|
|||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
FROM base AS deps
|
FROM base AS deps
|
||||||
COPY package.json pnpm-lock.yaml ./
|
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
|
||||||
COPY apps/api/package.json apps/api/
|
COPY apps/api/package.json apps/api/
|
||||||
RUN pnpm install --frozen-lockfile
|
RUN pnpm install --frozen-lockfile
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@ RUN corepack enable && corepack prepare pnpm@9.15.4 --activate
|
|||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
ENV NODE_ENV=production
|
ENV NODE_ENV=production
|
||||||
|
|
||||||
COPY package.json pnpm-lock.yaml ./
|
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
|
||||||
COPY --from=builder /app/apps/api/package.json apps/api/
|
COPY --from=builder /app/apps/api/package.json apps/api/
|
||||||
COPY --from=builder /app/apps/api/dist apps/api/dist
|
COPY --from=builder /app/apps/api/dist apps/api/dist
|
||||||
RUN pnpm install --frozen-lockfile --prod
|
RUN pnpm install --frozen-lockfile --prod
|
||||||
|
|||||||
+27
-6
@@ -94,11 +94,6 @@ function pick<T>(arr: T[]): T {
|
|||||||
return arr[Math.floor(rand() * arr.length)]!;
|
return arr[Math.floor(rand() * arr.length)]!;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return n distinct random elements from an array. */
|
|
||||||
function pickN<T>(arr: T[], n: number): T[] {
|
|
||||||
const shuffled = [...arr].sort(() => rand() - 0.5);
|
|
||||||
return shuffled.slice(0, n);
|
|
||||||
}
|
|
||||||
|
|
||||||
function randInt(min: number, max: number): number {
|
function randInt(min: number, max: number): number {
|
||||||
return Math.floor(rand() * (max - min + 1)) + min;
|
return Math.floor(rand() * (max - min + 1)) + min;
|
||||||
@@ -459,6 +454,32 @@ async function seedKnownUsers() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── Staff: UAT Tester (oidcSub from SEED_UAT_TESTER_OIDC_SUB env var) ──
|
||||||
|
const uatTesterOidcSub = process.env.SEED_UAT_TESTER_OIDC_SUB;
|
||||||
|
if (uatTesterOidcSub) {
|
||||||
|
const UAT_TESTER_STAFF_ID = "00000000-0000-0000-0000-000000000007";
|
||||||
|
const [existingUatTester] = await db
|
||||||
|
.select()
|
||||||
|
.from(schema.staff)
|
||||||
|
.where(eq(schema.staff.email, "uat-tester@groombook.dev"))
|
||||||
|
.limit(1);
|
||||||
|
|
||||||
|
if (existingUatTester) {
|
||||||
|
console.log(`✓ Staff 'UAT Tester' already exists — skipping`);
|
||||||
|
} else {
|
||||||
|
await db.insert(schema.staff).values({
|
||||||
|
id: UAT_TESTER_STAFF_ID,
|
||||||
|
name: "UAT Tester",
|
||||||
|
email: "uat-tester@groombook.dev",
|
||||||
|
oidcSub: uatTesterOidcSub,
|
||||||
|
role: "groomer",
|
||||||
|
isSuperUser: false,
|
||||||
|
active: true,
|
||||||
|
});
|
||||||
|
console.log(`✓ Created staff 'UAT Tester' (oidcSub: ${uatTesterOidcSub})`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ── Staff: UAT Groomer Personas (SEED_UAT_GROOMER_EMAILS + SEED_UAT_GROOMER_NAMES) ──
|
// ── Staff: UAT Groomer Personas (SEED_UAT_GROOMER_EMAILS + SEED_UAT_GROOMER_NAMES) ──
|
||||||
const groomerEmails = process.env.SEED_UAT_GROOMER_EMAILS?.split(",").map((e) => e.trim()).filter(Boolean) ?? [];
|
const groomerEmails = process.env.SEED_UAT_GROOMER_EMAILS?.split(",").map((e) => e.trim()).filter(Boolean) ?? [];
|
||||||
const groomerNames = process.env.SEED_UAT_GROOMER_NAMES?.split(",").map((n) => n.trim()).filter(Boolean) ?? [];
|
const groomerNames = process.env.SEED_UAT_GROOMER_NAMES?.split(",").map((n) => n.trim()).filter(Boolean) ?? [];
|
||||||
@@ -1079,7 +1100,7 @@ async function seed() {
|
|||||||
const groomer = pick(groomers);
|
const groomer = pick(groomers);
|
||||||
const bather = bathers.length > 0 && rand() < 0.6 ? pick(bathers) : null;
|
const bather = bathers.length > 0 && rand() < 0.6 ? pick(bathers) : null;
|
||||||
|
|
||||||
let startTime = randDate(appointmentsBackDate, now);
|
const startTime = randDate(appointmentsBackDate, now);
|
||||||
startTime.setHours(randInt(8, 16), pick([0, 15, 30, 45]), 0, 0);
|
startTime.setHours(randInt(8, 16), pick([0, 15, 30, 45]), 0, 0);
|
||||||
const endTime = new Date(startTime.getTime() + svc.dur * 60 * 1000);
|
const endTime = new Date(startTime.getTime() + svc.dur * 60 * 1000);
|
||||||
const effectivePrice = svc.price;
|
const effectivePrice = svc.price;
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import { searchRouter } from "./routes/search.js";
|
|||||||
import { getObject } from "./lib/s3.js";
|
import { getObject } from "./lib/s3.js";
|
||||||
import { calendarRouter } from "./routes/calendar.js";
|
import { calendarRouter } from "./routes/calendar.js";
|
||||||
import { setupRouter } from "./routes/setup.js";
|
import { setupRouter } from "./routes/setup.js";
|
||||||
import { getDb, businessSettings, eq, staff } from "./db";
|
import { getDb, businessSettings, eq, staff } from "./db/index.js";
|
||||||
import { authMiddleware } from "./middleware/auth.js";
|
import { authMiddleware } from "./middleware/auth.js";
|
||||||
import { resolveStaffMiddleware, requireRole, requireRoleOrSuperUser, requireSuperUser } from "./middleware/rbac.js";
|
import { resolveStaffMiddleware, requireRole, requireRoleOrSuperUser, requireSuperUser } from "./middleware/rbac.js";
|
||||||
import { devRouter } from "./routes/dev.js";
|
import { devRouter } from "./routes/dev.js";
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { betterAuth } from "better-auth";
|
import { betterAuth } from "better-auth";
|
||||||
import { drizzleAdapter } from "better-auth/adapters/drizzle";
|
import { drizzleAdapter } from "better-auth/adapters/drizzle";
|
||||||
import { genericOAuth } from "better-auth/plugins";
|
import { genericOAuth } from "better-auth/plugins";
|
||||||
import { getDb, authProviderConfig, eq } from "./db";
|
import { getDb, authProviderConfig, eq } from "../db/index.js";
|
||||||
import { decryptSecret } from "./db";
|
import { decryptSecret } from "../db/index.js";
|
||||||
import { sendEmail } from "../services/email.js";
|
import { sendEmail } from "../services/email.js";
|
||||||
|
|
||||||
const BETTER_AUTH_SECRET = process.env.BETTER_AUTH_SECRET;
|
const BETTER_AUTH_SECRET = process.env.BETTER_AUTH_SECRET;
|
||||||
@@ -97,6 +97,9 @@ export async function initAuth(): Promise<void> {
|
|||||||
window: 10,
|
window: 10,
|
||||||
storage: "memory",
|
storage: "memory",
|
||||||
customRules: {
|
customRules: {
|
||||||
|
"/sign-in/social": { max: 10, window: 60 },
|
||||||
|
"/sign-in/email": { max: 10, window: 60 },
|
||||||
|
"/sign-up/email": { max: 5, window: 60 },
|
||||||
"/get-session": false,
|
"/get-session": false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -247,6 +250,9 @@ export async function initAuth(): Promise<void> {
|
|||||||
window: 10,
|
window: 10,
|
||||||
storage: "memory",
|
storage: "memory",
|
||||||
customRules: {
|
customRules: {
|
||||||
|
"/sign-in/social": { max: 10, window: 60 },
|
||||||
|
"/sign-in/email": { max: 10, window: 60 },
|
||||||
|
"/sign-up/email": { max: 5, window: 60 },
|
||||||
"/get-session": false,
|
"/get-session": false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { MiddlewareHandler } from "hono";
|
import type { MiddlewareHandler } from "hono";
|
||||||
import { getDb, impersonationAuditLogs } from "../db";
|
import { getDb, impersonationAuditLogs } from "../db/index.js";
|
||||||
import type { PortalEnv } from "./portalSession.js";
|
import type { PortalEnv } from "./portalSession.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { MiddlewareHandler } from "hono";
|
import type { MiddlewareHandler } from "hono";
|
||||||
import { and, eq, getDb, impersonationSessions } from "../db";
|
import { and, eq, getDb, impersonationSessions } from "../db/index.js";
|
||||||
|
|
||||||
export interface PortalEnv {
|
export interface PortalEnv {
|
||||||
Variables: {
|
Variables: {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { MiddlewareHandler } from "hono";
|
import type { MiddlewareHandler } from "hono";
|
||||||
import { and, eq, getDb, sql, staff } from "../db";
|
import { and, eq, getDb, sql, staff } from "../db/index.js";
|
||||||
|
|
||||||
export type StaffRole = "groomer" | "receptionist" | "manager";
|
export type StaffRole = "groomer" | "receptionist" | "manager";
|
||||||
export type StaffRow = typeof staff.$inferSelect;
|
export type StaffRow = typeof staff.$inferSelect;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { Hono } from "hono";
|
import { Hono } from "hono";
|
||||||
import { eq, getDb, staff, clients, pets, services } from "./db";
|
import { eq, getDb, staff, clients, pets, services } from "../../db/index.js";
|
||||||
|
|
||||||
export const adminSeedRouter = new Hono();
|
export const adminSeedRouter = new Hono();
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import {
|
|||||||
pets,
|
pets,
|
||||||
services,
|
services,
|
||||||
staff,
|
staff,
|
||||||
} from "../db";
|
} from "../db/index.js";
|
||||||
import type { AppEnv } from "../middleware/rbac.js";
|
import type { AppEnv } from "../middleware/rbac.js";
|
||||||
|
|
||||||
export const appointmentGroupsRouter = new Hono<AppEnv>();
|
export const appointmentGroupsRouter = new Hono<AppEnv>();
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import {
|
|||||||
reminderLogs,
|
reminderLogs,
|
||||||
services,
|
services,
|
||||||
staff,
|
staff,
|
||||||
} from "../db";
|
} from "../db/index.js";
|
||||||
import { buildConfirmationEmail, sendEmail } from "../services/email.js";
|
import { buildConfirmationEmail, sendEmail } from "../services/email.js";
|
||||||
import { notifyWaitlistForAppointment } from "../services/waitlistNotify.js";
|
import { notifyWaitlistForAppointment } from "../services/waitlistNotify.js";
|
||||||
import type { AppEnv } from "../middleware/rbac.js";
|
import type { AppEnv } from "../middleware/rbac.js";
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Hono } from "hono";
|
import { Hono } from "hono";
|
||||||
import { zValidator } from "@hono/zod-validator";
|
import { zValidator } from "@hono/zod-validator";
|
||||||
import { z } from "zod/v3";
|
import { z } from "zod/v3";
|
||||||
import { eq, getDb, authProviderConfig, encryptSecret } from "../db";
|
import { eq, getDb, authProviderConfig, encryptSecret } from "../db/index.js";
|
||||||
import { requireSuperUser } from "../middleware/rbac.js";
|
import { requireSuperUser } from "../middleware/rbac.js";
|
||||||
import { reinitAuth } from "../lib/auth.js";
|
import { reinitAuth } from "../lib/auth.js";
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import {
|
|||||||
appointments,
|
appointments,
|
||||||
clients,
|
clients,
|
||||||
pets,
|
pets,
|
||||||
} from "../db";
|
} from "../db/index.js";
|
||||||
import {
|
import {
|
||||||
generateAvailableSlots,
|
generateAvailableSlots,
|
||||||
BUSINESS_START_HOUR,
|
BUSINESS_START_HOUR,
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import {
|
|||||||
pets,
|
pets,
|
||||||
services,
|
services,
|
||||||
staff,
|
staff,
|
||||||
} from "../db";
|
} from "../db/index.js";
|
||||||
|
|
||||||
export const calendarRouter = new Hono();
|
export const calendarRouter = new Hono();
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Hono } from "hono";
|
import { Hono } from "hono";
|
||||||
import { zValidator } from "@hono/zod-validator";
|
import { zValidator } from "@hono/zod-validator";
|
||||||
import { z } from "zod/v3";
|
import { z } from "zod/v3";
|
||||||
import { and, eq, exists, getDb, or, clients, appointments } from "../db";
|
import { and, eq, exists, getDb, or, clients, appointments } from "../db/index.js";
|
||||||
import type { AppEnv } from "../middleware/rbac.js";
|
import type { AppEnv } from "../middleware/rbac.js";
|
||||||
|
|
||||||
export const clientsRouter = new Hono<AppEnv>();
|
export const clientsRouter = new Hono<AppEnv>();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Hono } from "hono";
|
import { Hono } from "hono";
|
||||||
import { getDb, staff, clients, eq, sql } from "../db";
|
import { getDb, staff, clients, eq, sql } from "../db/index.js";
|
||||||
|
|
||||||
const devRouter = new Hono();
|
const devRouter = new Hono();
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Hono } from "hono";
|
import { Hono } from "hono";
|
||||||
import { zValidator } from "@hono/zod-validator";
|
import { zValidator } from "@hono/zod-validator";
|
||||||
import { z } from "zod/v3";
|
import { z } from "zod/v3";
|
||||||
import { and, desc, eq, getDb, groomingVisitLogs, appointments, or } from "../db";
|
import { and, desc, eq, getDb, groomingVisitLogs, appointments, or } from "../db/index.js";
|
||||||
import type { AppEnv } from "../middleware/rbac.js";
|
import type { AppEnv } from "../middleware/rbac.js";
|
||||||
|
|
||||||
export const groomingLogsRouter = new Hono<AppEnv>();
|
export const groomingLogsRouter = new Hono<AppEnv>();
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import {
|
|||||||
impersonationAuditLogs,
|
impersonationAuditLogs,
|
||||||
clients,
|
clients,
|
||||||
desc,
|
desc,
|
||||||
} from "../db";
|
} from "../db/index.js";
|
||||||
import type { AppEnv } from "../middleware/rbac.js";
|
import type { AppEnv } from "../middleware/rbac.js";
|
||||||
|
|
||||||
export const impersonationRouter = new Hono<AppEnv>();
|
export const impersonationRouter = new Hono<AppEnv>();
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import {
|
|||||||
services,
|
services,
|
||||||
clients,
|
clients,
|
||||||
sql,
|
sql,
|
||||||
} from "../db";
|
} from "../db/index.js";
|
||||||
import type { AppEnv } from "../middleware/rbac.js";
|
import type { AppEnv } from "../middleware/rbac.js";
|
||||||
|
|
||||||
export const invoicesRouter = new Hono<AppEnv>();
|
export const invoicesRouter = new Hono<AppEnv>();
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Hono } from "hono";
|
import { Hono } from "hono";
|
||||||
import { zValidator } from "@hono/zod-validator";
|
import { zValidator } from "@hono/zod-validator";
|
||||||
import { z } from "zod/v3";
|
import { z } from "zod/v3";
|
||||||
import { and, eq, exists, getDb, or, pets, appointments } from "../db";
|
import { and, eq, exists, getDb, or, pets, appointments } from "../db/index.js";
|
||||||
import type { AppEnv } from "../middleware/rbac.js";
|
import type { AppEnv } from "../middleware/rbac.js";
|
||||||
import {
|
import {
|
||||||
getPresignedUploadUrl,
|
getPresignedUploadUrl,
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { Hono } from "hono";
|
import { Hono } from "hono";
|
||||||
import { zValidator } from "@hono/zod-validator";
|
import { zValidator } from "@hono/zod-validator";
|
||||||
import { z } from "zod/v3";
|
import { z } from "zod/v3";
|
||||||
import { eq, inArray } from "../db";
|
import { eq, inArray } from "../db/index.js";
|
||||||
import { getDb, appointments, impersonationSessions, waitlistEntries, clients, pets, services, staff, invoices, invoiceLineItems } from "../db";
|
import { getDb, appointments, impersonationSessions, waitlistEntries, clients, pets, services, staff, invoices, invoiceLineItems } from "../db/index.js";
|
||||||
import { validatePortalSession } from "../middleware/portalSession.js";
|
import { validatePortalSession } from "../middleware/portalSession.js";
|
||||||
import { portalAudit } from "../middleware/portalAudit.js";
|
import { portalAudit } from "../middleware/portalAudit.js";
|
||||||
import type { PortalEnv } from "../middleware/portalSession.js";
|
import type { PortalEnv } from "../middleware/portalSession.js";
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import {
|
|||||||
invoiceTipSplits,
|
invoiceTipSplits,
|
||||||
services,
|
services,
|
||||||
staff,
|
staff,
|
||||||
} from "../db";
|
} from "../db/index.js";
|
||||||
|
|
||||||
export const reportsRouter = new Hono();
|
export const reportsRouter = new Hono();
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Hono } from "hono";
|
import { Hono } from "hono";
|
||||||
import { and, eq, getDb, clients, ilike, or, pets } from "../db";
|
import { and, eq, getDb, clients, ilike, or, pets } from "../db/index.js";
|
||||||
|
|
||||||
export const searchRouter = new Hono();
|
export const searchRouter = new Hono();
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Hono } from "hono";
|
import { Hono } from "hono";
|
||||||
import { zValidator } from "@hono/zod-validator";
|
import { zValidator } from "@hono/zod-validator";
|
||||||
import { z } from "zod/v3";
|
import { z } from "zod/v3";
|
||||||
import { eq, getDb, services } from "../db";
|
import { eq, getDb, services } from "../db/index.js";
|
||||||
|
|
||||||
export const servicesRouter = new Hono();
|
export const servicesRouter = new Hono();
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Hono } from "hono";
|
import { Hono } from "hono";
|
||||||
import { zValidator } from "@hono/zod-validator";
|
import { zValidator } from "@hono/zod-validator";
|
||||||
import { z } from "zod/v3";
|
import { z } from "zod/v3";
|
||||||
import { eq, getDb, businessSettings } from "../db";
|
import { eq, getDb, businessSettings } from "../db/index.js";
|
||||||
import { getPresignedUploadUrl, deleteObject, putObject, getObject } from "../lib/s3.js";
|
import { getPresignedUploadUrl, deleteObject, putObject, getObject } from "../lib/s3.js";
|
||||||
import { requireSuperUser } from "../middleware/rbac.js";
|
import { requireSuperUser } from "../middleware/rbac.js";
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Hono } from "hono";
|
import { Hono } from "hono";
|
||||||
import { zValidator } from "@hono/zod-validator";
|
import { zValidator } from "@hono/zod-validator";
|
||||||
import { z } from "zod/v3";
|
import { z } from "zod/v3";
|
||||||
import { and, eq, getDb, sql, staff, businessSettings, authProviderConfig, encryptSecret } from "../db";
|
import { and, eq, getDb, sql, staff, businessSettings, authProviderConfig, encryptSecret } from "../db/index.js";
|
||||||
import type { AppEnv } from "../middleware/rbac.js";
|
import type { AppEnv } from "../middleware/rbac.js";
|
||||||
|
|
||||||
const RATE_LIMIT_WINDOW_MS = 60_000;
|
const RATE_LIMIT_WINDOW_MS = 60_000;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { Hono } from "hono";
|
|||||||
import { zValidator } from "@hono/zod-validator";
|
import { zValidator } from "@hono/zod-validator";
|
||||||
import { z } from "zod/v3";
|
import { z } from "zod/v3";
|
||||||
import { randomBytes } from "node:crypto";
|
import { randomBytes } from "node:crypto";
|
||||||
import { and, eq, getDb, ne, staff, appointments } from "../db";
|
import { and, eq, getDb, ne, staff, appointments } from "../db/index.js";
|
||||||
import type { AppEnv } from "../middleware/rbac.js";
|
import type { AppEnv } from "../middleware/rbac.js";
|
||||||
|
|
||||||
export const staffRouter = new Hono<AppEnv>();
|
export const staffRouter = new Hono<AppEnv>();
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Hono } from "hono";
|
import { Hono } from "hono";
|
||||||
import Stripe from "stripe";
|
import Stripe from "stripe";
|
||||||
import { z } from "zod/v3";
|
import { z } from "zod/v3";
|
||||||
import { eq, getDb, invoices } from "../db";
|
import { eq, getDb, invoices } from "../db/index.js";
|
||||||
import { getStripeClient } from "../services/payment.js";
|
import { getStripeClient } from "../services/payment.js";
|
||||||
|
|
||||||
export const webhooksRouter = new Hono();
|
export const webhooksRouter = new Hono();
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import {
|
|||||||
clients,
|
clients,
|
||||||
pets,
|
pets,
|
||||||
services,
|
services,
|
||||||
} from "../db";
|
} from "../db/index.js";
|
||||||
import type { AppEnv } from "../middleware/rbac.js";
|
import type { AppEnv } from "../middleware/rbac.js";
|
||||||
|
|
||||||
export const waitlistRouter = new Hono<AppEnv>();
|
export const waitlistRouter = new Hono<AppEnv>();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import Stripe from "stripe";
|
import Stripe from "stripe";
|
||||||
import { getDb, clients, eq, inArray, invoices } from "../db";
|
import { getDb, clients, eq, inArray, invoices } from "../db/index.js";
|
||||||
|
|
||||||
let _stripe: Stripe | null | undefined;
|
let _stripe: Stripe | null | undefined;
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import {
|
|||||||
staff,
|
staff,
|
||||||
reminderLogs,
|
reminderLogs,
|
||||||
session,
|
session,
|
||||||
} from "../db";
|
} from "../db/index.js";
|
||||||
import {
|
import {
|
||||||
buildReminderEmail,
|
buildReminderEmail,
|
||||||
sendEmail,
|
sendEmail,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { and, eq, getDb, waitlistEntries, clients, pets, services } from "../db";
|
import { and, eq, getDb, waitlistEntries, clients, pets, services } from "../db/index.js";
|
||||||
import { buildWaitlistNotificationEmail, sendEmail } from "./email.js";
|
import { buildWaitlistNotificationEmail, sendEmail } from "./email.js";
|
||||||
|
|
||||||
export async function notifyWaitlistForAppointment(
|
export async function notifyWaitlistForAppointment(
|
||||||
|
|||||||
@@ -1,3 +1,2 @@
|
|||||||
packages:
|
packages:
|
||||||
- "apps/*"
|
- "apps/*"
|
||||||
- "packages/*"
|
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||||
|
"extends": ["config:recommended", ":pinAllExceptPeerDependencies", "helpers:pinGitHubActionDigests"],
|
||||||
|
"labels": ["dependencies"],
|
||||||
|
"prConcurrentLimit": 5,
|
||||||
|
"packageRules": [
|
||||||
|
{"matchUpdateTypes": ["minor", "patch"], "groupName": "minor and patch dependencies", "automerge": false},
|
||||||
|
{"matchDepTypes": ["devDependencies"], "matchUpdateTypes": ["minor", "patch"], "automerge": true, "automergeType": "pr"}
|
||||||
|
]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user