From ab088f69e47d2bebe959759bbae11f23e29cafaa Mon Sep 17 00:00:00 2001 From: Janarthanan Soundhararajan Date: Mon, 31 Aug 2026 20:16:59 +0530 Subject: [PATCH 1/4] chore: establish baseline quality --- .../(dashboard)/availability/page.tsx | 1 - .../[locale]/(dashboard)/bookings/page.tsx | 2 +- .../components/availability/schedule-form.tsx | 2 - apps/app/eslint.config.mjs | 1 + apps/app/hooks/use-mobile.ts | 28 +- apps/app/package.json | 1 + apps/marketing/eslint.config.mjs | 17 + apps/marketing/package.json | 4 +- docs/domain-model-current.md | 4 +- docs/domain-model-proposed.md | 6 +- docs/feature-inventory.md | 10 +- package.json | 2 +- pnpm-lock.yaml | 411 +++++++++++------- pnpm-workspace.yaml | 1 + 14 files changed, 293 insertions(+), 197 deletions(-) create mode 100644 apps/marketing/eslint.config.mjs diff --git a/apps/app/app/[locale]/(dashboard)/availability/page.tsx b/apps/app/app/[locale]/(dashboard)/availability/page.tsx index f7c3a3d..3b42ba0 100644 --- a/apps/app/app/[locale]/(dashboard)/availability/page.tsx +++ b/apps/app/app/[locale]/(dashboard)/availability/page.tsx @@ -61,7 +61,6 @@ export default async function AvailabilityPage() { return (

- "{booking.guestNotes}" + “{booking.guestNotes}”

)} diff --git a/apps/app/components/availability/schedule-form.tsx b/apps/app/components/availability/schedule-form.tsx index 2dcf84d..a425331 100644 --- a/apps/app/components/availability/schedule-form.tsx +++ b/apps/app/components/availability/schedule-form.tsx @@ -77,7 +77,6 @@ export interface DaySchedule { } export interface ScheduleFormProps { - userId?: string; initialData: { timeZone: string; schedule: DaySchedule[]; @@ -89,7 +88,6 @@ export interface ScheduleFormProps { } export function ScheduleForm({ - userId: _userId, initialData, onSubmit, }: ScheduleFormProps) { diff --git a/apps/app/eslint.config.mjs b/apps/app/eslint.config.mjs index 05e726d..fdb6994 100644 --- a/apps/app/eslint.config.mjs +++ b/apps/app/eslint.config.mjs @@ -9,6 +9,7 @@ const eslintConfig = defineConfig([ globalIgnores([ // Default ignores of eslint-config-next: ".next/**", + "coverage/**", "out/**", "build/**", "next-env.d.ts", diff --git a/apps/app/hooks/use-mobile.ts b/apps/app/hooks/use-mobile.ts index 2b0fe1d..a1125b1 100644 --- a/apps/app/hooks/use-mobile.ts +++ b/apps/app/hooks/use-mobile.ts @@ -1,19 +1,23 @@ import * as React from "react" const MOBILE_BREAKPOINT = 768 +const MOBILE_QUERY = `(max-width: ${MOBILE_BREAKPOINT - 1}px)` -export function useIsMobile() { - const [isMobile, setIsMobile] = React.useState(undefined) +function subscribe(callback: () => void) { + const mediaQuery = window.matchMedia(MOBILE_QUERY) + + mediaQuery.addEventListener("change", callback) + return () => mediaQuery.removeEventListener("change", callback) +} - React.useEffect(() => { - const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`) - const onChange = () => { - setIsMobile(window.innerWidth < MOBILE_BREAKPOINT) - } - mql.addEventListener("change", onChange) - setIsMobile(window.innerWidth < MOBILE_BREAKPOINT) - return () => mql.removeEventListener("change", onChange) - }, []) +function getSnapshot() { + return window.matchMedia(MOBILE_QUERY).matches +} - return !!isMobile +function getServerSnapshot() { + return false +} + +export function useIsMobile() { + return React.useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) } diff --git a/apps/app/package.json b/apps/app/package.json index 38e1832..4235f39 100644 --- a/apps/app/package.json +++ b/apps/app/package.json @@ -14,6 +14,7 @@ "dependencies": { "@base-ui/react": "^1.6.0", "@hookform/resolvers": "^5.7.1", + "@prisma/client": "^7.9.1", "@radix-ui/react-label": "^2.1.15", "@radix-ui/react-slot": "^1.3.3", "@react-email/components": "^1.0.12", diff --git a/apps/marketing/eslint.config.mjs b/apps/marketing/eslint.config.mjs new file mode 100644 index 0000000..3c4c3d9 --- /dev/null +++ b/apps/marketing/eslint.config.mjs @@ -0,0 +1,17 @@ +import { defineConfig, globalIgnores } from "eslint/config"; +import nextVitals from "eslint-config-next/core-web-vitals"; +import nextTs from "eslint-config-next/typescript"; + +const eslintConfig = defineConfig([ + ...nextVitals, + ...nextTs, + globalIgnores([ + ".next/**", + "coverage/**", + "out/**", + "build/**", + "next-env.d.ts", + ]), +]); + +export default eslintConfig; diff --git a/apps/marketing/package.json b/apps/marketing/package.json index c0b039d..2249b09 100644 --- a/apps/marketing/package.json +++ b/apps/marketing/package.json @@ -17,6 +17,8 @@ "@types/node": "^20", "@types/react": "^19", "@types/react-dom": "^19", - "typescript": "^5" + "eslint": "^9.39.5", + "eslint-config-next": "16.2.12", + "typescript": "^5.9.3" } } diff --git a/docs/domain-model-current.md b/docs/domain-model-current.md index a478416..085f498 100644 --- a/docs/domain-model-current.md +++ b/docs/domain-model-current.md @@ -2,7 +2,7 @@ **Document status:** Current-state analysis **Schema source:** `packages/db/prisma/schema.prisma` on the documentation branch -**Reviewed:** 2026-08-29 +**Reviewed:** 2026-08-31 ## Purpose @@ -426,7 +426,7 @@ The existing indexes also do not exactly match the main conflict predicate, whic - Guest details are embedded because a guest entity does not exist. - No idempotency key protects repeated logical submissions. - No version field protects concurrent lifecycle changes. -- On the documented schema baseline, no persistent notification status or stable ICS UID exists. The email-invitation feature branch introduces related changes and must update this model when merged. +- `icsUid` provides a stable, optional, unique identifier for calendar invitations. Persistent notification delivery status is not yet modeled. ### Business rules enforced diff --git a/docs/domain-model-proposed.md b/docs/domain-model-proposed.md index 0a82e51..0ec3283 100644 --- a/docs/domain-model-proposed.md +++ b/docs/domain-model-proposed.md @@ -770,7 +770,7 @@ Query plans and data volume should be measured before final index selection. For | `Booking` | `Meeting` + `DirectBooking` + participants + initial event | Backfill one meeting per booking; preserve legacy ID mapping | | `Booking.status` | `Meeting.status` | Map accepted/pending/cancelled through explicit migration policy | | `googleMeetLink` / general meeting URL branch fields | Meeting location or external integration reference | Classify URL/provider; retain unknown as custom URL | -| `icsUid` from email feature branch | Stable calendar identity/external reference | Preserve existing UID during migration | +| `Booking.icsUid` | Stable calendar identity/external reference | Preserve existing UID during migration | | `Poll` | `Poll` | Add workspace, lifecycle, access, duration, timezone, deadline, version | | `TimeSlot` | `PollCandidate` | Preserve IDs where practical; validate intervals/duplicates | | Repeated `Availability` vote rows | `PollParticipant` + `PollPreference` | Group by poll and participant identity heuristic; detect collisions | @@ -803,9 +803,9 @@ Existing data must be scanned for overlaps before adding an exclusion/reservatio Changing from cascade to restrict can fail while orphaning assumptions exist in application flows. Delete actions must be changed before the constraint cutover. -### Feature-branch divergence +### Reconciled email baseline -Email-invitation schema changes such as stable ICS identity and general meeting provider fields must be merged or reconciled before writing the final migration. Do not design migration from an outdated branch snapshot. +Stable ICS identity and general meeting provider fields are present in the current schema. Preserve and map them when writing the final migration. ## Incremental migration phases diff --git a/docs/feature-inventory.md b/docs/feature-inventory.md index 2f032ad..55044c1 100644 --- a/docs/feature-inventory.md +++ b/docs/feature-inventory.md @@ -1,7 +1,7 @@ # Feature Inventory **Document status:** Initial draft -**Last reviewed against repository:** 2026-08-29 +**Last reviewed against repository:** 2026-08-31 This inventory separates implemented behavior from proposals. It is not a marketing feature list. @@ -48,10 +48,10 @@ This inventory separates implemented behavior from proposals. It is not a market | Capability | Status | Notes | | --- | --- | --- | -| Guest confirmation email | Partial | Implemented with React Email and Resend on the email-invitation feature branch; pending baseline reconciliation. | -| ICS attachment | Partial | Stable booking UID and attachment generation exist on the email-invitation feature branch; pending baseline reconciliation. | -| Guest-timezone email formatting | Partial | Implemented on the email-invitation feature branch; pending baseline reconciliation. | -| Separate booking and email outcomes | Partial | Implemented on the email-invitation feature branch; durable delivery state remains proposed. | +| Guest confirmation email | Current | Implemented with React Email and Resend in the reconciled baseline. | +| ICS attachment | Current | Stable booking UID and attachment generation are implemented in the reconciled baseline. | +| Guest-timezone email formatting | Current | Confirmation times are formatted in the guest's submitted timezone. | +| Separate booking and email outcomes | Current | Booking success is reported independently from the email result; durable delivery state remains proposed. | | Persisted notification status | Proposed | Needed for delivery history, retries, and operational visibility. | | Retry failed notification | Proposed | Must include authorization, idempotency, and abuse controls. | | Host notification | Proposed | Host should receive or configure booking notifications. | diff --git a/package.json b/package.json index 50ed118..fd67a9e 100644 --- a/package.json +++ b/package.json @@ -12,5 +12,5 @@ "@types/node": "^26.1.2", "turbo": "^2.10.8" }, - "packageManager": "pnpm@9.0.0" + "packageManager": "pnpm@11.24.0" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a0cf084..933e9e0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -22,7 +22,10 @@ importers: version: 1.6.0(@date-fns/tz@1.5.0)(@types/react@19.2.17)(date-fns@4.4.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@hookform/resolvers': specifier: ^5.7.1 - version: 5.7.1(@standard-schema/spec@1.1.0)(ajv-formats@3.0.1(ajv@8.20.0))(ajv@8.20.0)(effect@3.20.0)(react-hook-form@7.84.0(react@19.2.4))(valibot@1.4.2(typescript@5.9.3))(yup@1.7.1)(zod@4.4.3) + version: 5.7.1(@standard-schema/spec@1.1.0)(ajv-formats@2.1.1(ajv@8.20.0))(ajv@8.20.0)(effect@3.20.0)(react-hook-form@7.84.0(react@19.2.4))(valibot@1.4.2(typescript@5.9.3))(yup@1.7.1)(zod@4.4.3) + '@prisma/client': + specifier: ^7.9.1 + version: 7.9.1(prisma@7.9.1(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(magicast@0.5.4)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(typescript@5.9.3) '@radix-ui/react-label': specifier: ^2.1.15 version: 2.1.15(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -58,13 +61,13 @@ importers: version: 1.28.0(react@19.2.4) next: specifier: 16.2.12 - version: 16.2.12(@babel/core@7.29.7)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + version: 16.2.12(@babel/core@7.29.7(supports-color@7.2.0))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) next-auth: specifier: 5.0.0-beta.32 - version: 5.0.0-beta.32(next@16.2.12(@babel/core@7.29.7)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react@19.2.4) + version: 5.0.0-beta.32(next@16.2.12(@babel/core@7.29.7(supports-color@7.2.0))(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react@19.2.4) next-intl: specifier: ^4.13.4 - version: 4.13.4(@swc/helpers@0.5.15)(next@16.2.12(@babel/core@7.29.7)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react@19.2.4)(typescript@5.9.3) + version: 4.13.4(next@16.2.12(@babel/core@7.29.7(supports-color@7.2.0))(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react@19.2.4)(typescript@5.9.3) next-themes: specifier: ^0.4.6 version: 0.4.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -85,7 +88,7 @@ importers: version: 6.22.0(@react-email/render@2.1.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)) shadcn: specifier: ^4.16.1 - version: 4.16.1(typescript@5.9.3) + version: 4.16.1(supports-color@7.2.0)(typescript@5.9.3) tailwind-merge: specifier: ^3.6.0 version: 3.6.0 @@ -125,10 +128,10 @@ importers: version: 4.1.10(vitest@4.1.10) eslint: specifier: ^9 - version: 9.39.5(jiti@2.7.0) + version: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) eslint-config-next: specifier: 16.2.12 - version: 16.2.12(@typescript-eslint/parser@8.65.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3))(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3) + version: 16.2.12(@typescript-eslint/parser@8.65.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) happy-dom: specifier: ^20.11.1 version: 20.11.1 @@ -149,7 +152,7 @@ importers: dependencies: next: specifier: 16.2.12 - version: 16.2.12(@babel/core@7.29.7)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + version: 16.2.12(@babel/core@7.29.7(supports-color@7.2.0))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) react: specifier: 19.2.4 version: 19.2.4 @@ -166,8 +169,14 @@ importers: '@types/react-dom': specifier: ^19 version: 19.2.3(@types/react@19.2.17) + eslint: + specifier: ^9.39.5 + version: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) + eslint-config-next: + specifier: 16.2.12 + version: 16.2.12(@typescript-eslint/parser@8.65.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) typescript: - specifier: ^5 + specifier: ^5.9.3 version: 5.9.3 packages/db: @@ -847,89 +856,105 @@ packages: resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==} cpu: [arm64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-arm@1.2.4': resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==} cpu: [arm] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-ppc64@1.2.4': resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==} cpu: [ppc64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-riscv64@1.2.4': resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==} cpu: [riscv64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-s390x@1.2.4': resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==} cpu: [s390x] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-x64@1.2.4': resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==} cpu: [x64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linuxmusl-arm64@1.2.4': resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==} cpu: [arm64] os: [linux] + libc: [musl] '@img/sharp-libvips-linuxmusl-x64@1.2.4': resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==} cpu: [x64] os: [linux] + libc: [musl] '@img/sharp-linux-arm64@0.34.5': resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] + libc: [glibc] '@img/sharp-linux-arm@0.34.5': resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm] os: [linux] + libc: [glibc] '@img/sharp-linux-ppc64@0.34.5': resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [ppc64] os: [linux] + libc: [glibc] '@img/sharp-linux-riscv64@0.34.5': resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [riscv64] os: [linux] + libc: [glibc] '@img/sharp-linux-s390x@0.34.5': resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [s390x] os: [linux] + libc: [glibc] '@img/sharp-linux-x64@0.34.5': resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] + libc: [glibc] '@img/sharp-linuxmusl-arm64@0.34.5': resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] + libc: [musl] '@img/sharp-linuxmusl-x64@0.34.5': resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] + libc: [musl] '@img/sharp-wasm32@0.34.5': resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==} @@ -1014,24 +1039,28 @@ packages: engines: {node: '>= 10'} cpu: [arm64] os: [linux] + libc: [glibc] '@next/swc-linux-arm64-musl@16.2.12': resolution: {integrity: sha512-0qjhiYBaKAqF63LA1ZWAAnKTzFUguAaZiRa5etMLGGPj/B6uEVjtIZldIzFEp3wHlB0koK6aTzqPtSdplTCjoA==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] + libc: [musl] '@next/swc-linux-x64-gnu@16.2.12': resolution: {integrity: sha512-7A3q26W+h7gnA15uqBToNuDqBEFZZcqh0mW2mn4AJh/G5pdg2RVE3n4slzLEliASZFG3NmsbEzng/x2Sh09mBg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [glibc] '@next/swc-linux-x64-musl@16.2.12': resolution: {integrity: sha512-qSjL/uppm+cbh21s72Ss8gkiOhQ4dExWHNGOWy6eZV7STj5WsKehgxT61beSsOj+YYQuTplL376lOCdMQU5T8w==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [musl] '@next/swc-win32-arm64-msvc@16.2.12': resolution: {integrity: sha512-X6hzsOUJac/e7AWSbn9gQ9nzHld1xWP5iyjHpYWvud8pufB679O1xg4JDyKr8Xd69Jvd+kM2Der6uftiZCmjYA==} @@ -1096,36 +1125,42 @@ packages: engines: {node: '>= 10.0.0'} cpu: [arm] os: [linux] + libc: [glibc] '@parcel/watcher-linux-arm-musl@2.6.0': resolution: {integrity: sha512-9c6AUHgHoG+IY88MRIHupztQiQnrbqHYQjkM2btA+Bf/wQnQMuiD0Wfk1EVv3TlNT3x41uU71rn6E4xh/+zvkw==} engines: {node: '>= 10.0.0'} cpu: [arm] os: [linux] + libc: [musl] '@parcel/watcher-linux-arm64-glibc@2.6.0': resolution: {integrity: sha512-yHRqS2owEXe6Hic9z6Mh1ECsCd+ODVOGvZDyciqRd21+v+o+DnXMOrw50DSpIG2sb8GPEaPPmfeCAWKPJdq46g==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [linux] + libc: [glibc] '@parcel/watcher-linux-arm64-musl@2.6.0': resolution: {integrity: sha512-WhB2e/V7rqdHHWZusBSPuy5Ei8S6lSz6FE5TKKQz5h3a0O+C+mhY7vxU9b/stqvMb8beLnPY82ZrFTLKs+SrKA==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [linux] + libc: [musl] '@parcel/watcher-linux-x64-glibc@2.6.0': resolution: {integrity: sha512-ulGE6x6Oz6iAwg75T8YQSoguBWasniIbX+QWpaYPcCnDOpdWX3k+4xbEYPZVLxOuoJI+svJJPD3sEj8G7lrQ3A==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [linux] + libc: [glibc] '@parcel/watcher-linux-x64-musl@2.6.0': resolution: {integrity: sha512-tkBYKt7YQrjIJWYDnto2YgO8MRkjlMTSNoRHzsXinBqbLdeOM3L32wPZJvIZxqaLMfSlS/4sUjH/6STVP/XDLw==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [linux] + libc: [musl] '@parcel/watcher-win32-arm64@2.6.0': resolution: {integrity: sha512-gIZAP23jaHjGWasY/TY6yL7NHFClf0Ga7FN+iINvk+KN94rhm94lYZhFsbYFNcA04/onvGD9kKmiJLJB2HbNwQ==} @@ -1545,36 +1580,42 @@ packages: engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] + libc: [glibc] '@rolldown/binding-linux-arm64-musl@1.2.2': resolution: {integrity: sha512-B5G/zJdHaoJn9vD50eGHWkiWfmq8Uhi3IiLPJTzmZTrAalk1bztUikSXo0qga18ibE0IXboyeMUnhPjhAJ45wQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] + libc: [musl] '@rolldown/binding-linux-ppc64-gnu@1.2.2': resolution: {integrity: sha512-6mC/awzKka8W6EoekjegpfGkjz8jXWDX63pqu/HYVpyKtZfu65Jsh4QAH3Kej3CAv/c1oGX7psTmFEbr0mDxLA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] + libc: [glibc] '@rolldown/binding-linux-s390x-gnu@1.2.2': resolution: {integrity: sha512-412MX9fJLdA1IK28EZnc8jYv2HRTleOZgfLQumJ5zy7OeJLZlg/CETwFaXjNmGVxG51cFHpKLqb5LKvBC+HsHA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] + libc: [glibc] '@rolldown/binding-linux-x64-gnu@1.2.2': resolution: {integrity: sha512-Q/+HI/ToJafZ1iCqGgVQXUEkIjufHCTF0gBQ2a5o3cg7GJ2h0qyq3nvvSmU+bGda2/7ygXpTY4TM6gO9OhQ0ZA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] + libc: [glibc] '@rolldown/binding-linux-x64-musl@1.2.2': resolution: {integrity: sha512-ZKp/w41n6wCvxzxQHtQSbuphfX3Y4cCvbjkKHusrLx4lh+JWLTU7StSltO/DKARISzbj368d+qUaCjI8K2wzXw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] + libc: [musl] '@rolldown/binding-openharmony-arm64@1.2.2': resolution: {integrity: sha512-pxE6xD4KS3eAROkKK5yrhB9/3+vhlhVGMvlQLbdpzrBGDbKrnzx3RLwPaHvasLo6jgaiBLn7e04Df9C4tYhjmA==} @@ -1645,36 +1686,42 @@ packages: engines: {node: '>=10'} cpu: [arm64] os: [linux] + libc: [glibc] '@swc/core-linux-arm64-musl@1.15.47': resolution: {integrity: sha512-3Yu3Uq/VgytqsPjTMbkPU1ExADytbdWbruJYhA584E9jrpE2Ki+R6VVPoZCeAVk1Cb7QxcRTgblw6bSa6a/R+w==} engines: {node: '>=10'} cpu: [arm64] os: [linux] + libc: [musl] '@swc/core-linux-ppc64-gnu@1.15.47': resolution: {integrity: sha512-wfdMi5IaOaNtmh2/6geRoxIdNfqylUZFdtzTKS655y1axWfIWyx7As74vv0wVdjeCIZ3WmCI9odDd4rUttXOSQ==} engines: {node: '>=10'} cpu: [ppc64] os: [linux] + libc: [glibc] '@swc/core-linux-s390x-gnu@1.15.47': resolution: {integrity: sha512-3hHYBY0yx8Ez7GMRrkhXHQzMdR5IZA6Wq5Ee4svlgwvSECLpnAJ9+0AimEGUFDvuLwE7nV/2+PYe8+Nm4rvNcQ==} engines: {node: '>=10'} cpu: [s390x] os: [linux] + libc: [glibc] '@swc/core-linux-x64-gnu@1.15.47': resolution: {integrity: sha512-TjfhjgP/jGCfFHYC3JQPhJA1HwErbIJ9JfREDc1KNkvY6P0LodCgKVIlQ5deeTbkG7ih3bF5PHJLuLpaZjdRyQ==} engines: {node: '>=10'} cpu: [x64] os: [linux] + libc: [glibc] '@swc/core-linux-x64-musl@1.15.47': resolution: {integrity: sha512-CQpS8Ge/avfjZd0UEwG/sds83Uu32deQXcV1Jo3jD0mmvQQqtYAjpsDZXugmheeAwmt+YIuoVtVHro8LMYHqsQ==} engines: {node: '>=10'} cpu: [x64] os: [linux] + libc: [musl] '@swc/core-win32-arm64-msvc@1.15.47': resolution: {integrity: sha512-0W8IKHsUTYiT7G2RqtOoVWk+89yzZikIiDUb/sCK6BmQDBhN91hQSfyUtW12jhEWLzYgcfmisfsZrmZE+84U1A==} @@ -1750,24 +1797,28 @@ packages: engines: {node: '>= 20'} cpu: [arm64] os: [linux] + libc: [glibc] '@tailwindcss/oxide-linux-arm64-musl@4.3.3': resolution: {integrity: sha512-Md44bD6veX/PC5iyF8cDVnw4HBIANZepRZZ7a8DQOvkfo5WUBwcp6iAuCUz23u+4SUkhJlD3eL7hNdW8ezd/kA==} engines: {node: '>= 20'} cpu: [arm64] os: [linux] + libc: [musl] '@tailwindcss/oxide-linux-x64-gnu@4.3.3': resolution: {integrity: sha512-tx7us1muwOKAKWao2v/GaafFeQboE6aj88vC6ziN2NCGcRm8gWUhwjzg+YdVB1e4boAtdtma4L43onunI6NS4w==} engines: {node: '>= 20'} cpu: [x64] os: [linux] + libc: [glibc] '@tailwindcss/oxide-linux-x64-musl@4.3.3': resolution: {integrity: sha512-SJxX60smvHgasZoBy11dX6YRjXJFovwWBoedhbQPOBzgFWBHGB+TVPWB9BxzR7TTxU8FQZAI2AyiNCMzFm8Img==} engines: {node: '>= 20'} cpu: [x64] os: [linux] + libc: [musl] '@tailwindcss/oxide-wasm32-wasi@4.3.3': resolution: {integrity: sha512-jx1+rPhY/5Ympkktd656HBWEBLxP7dH06losBLjjf5vgCODXvi9KhtftWcMIwTFIDqBr7cRnQkdLnAG+IOlGvQ==} @@ -2045,51 +2096,61 @@ packages: resolution: {integrity: sha512-zJc0H99FEPoFfSrNpa91HYfxzfAJCr502oxNK1cfdC9hlaFI43RT+JFCann9JUgZmLzzntChHyn13Sgn9ljHNg==} cpu: [arm64] os: [linux] + libc: [glibc] '@unrs/resolver-binding-linux-arm64-musl@1.12.2': resolution: {integrity: sha512-KQ3Lki6l+Pz1k/eBipN41ES+YUK30beLGb9YqcB1O542cyLCNE6GaxrfcY3T6EezmGGk84wb5XyO9loTM9tkcA==} cpu: [arm64] os: [linux] + libc: [musl] '@unrs/resolver-binding-linux-loong64-gnu@1.12.2': resolution: {integrity: sha512-3SJGEh1DborhG6pyxvhPzCT4bbSIVihsvgJc13P1bHG7KLdNDaF9T3gsTwFc7Jw/5Y5/iWOjkEx7Zy0NvCGX3Q==} cpu: [loong64] os: [linux] + libc: [glibc] '@unrs/resolver-binding-linux-loong64-musl@1.12.2': resolution: {integrity: sha512-jiuG/Obbel7uw1PwHNFfrkiKhLAF6mnyZ6aWlOAVN9WqKm8v0OFGnciJIHu8+CMvXLQ8AD51LPzAoUfT21D5Ew==} cpu: [loong64] os: [linux] + libc: [musl] '@unrs/resolver-binding-linux-ppc64-gnu@1.12.2': resolution: {integrity: sha512-q7xRvVpmcfeL+LlZg8Pbbo6QaTZwDU5BaGZbwfhkEsXJn3Was8xYfE0RBH266xZt0rM6B7i8xAYIvjthuUIWHg==} cpu: [ppc64] os: [linux] + libc: [glibc] '@unrs/resolver-binding-linux-riscv64-gnu@1.12.2': resolution: {integrity: sha512-0CVdx6lcnT3Q9inOH8tsMIOJ6ImndllMjqJHg8RLVdB7Vq4SfkEXl9mCSsVNuNA4MCYycRicCUxPCabVHJRr6A==} cpu: [riscv64] os: [linux] + libc: [glibc] '@unrs/resolver-binding-linux-riscv64-musl@1.12.2': resolution: {integrity: sha512-iOwlRo9vnp6R6ohHQS11n0NnfdXx/omhkocmIfaPRpQhKZ+3BDMkkdRVh53qjkFkpPddf+FETA28NwGN7l5l+w==} cpu: [riscv64] os: [linux] + libc: [musl] '@unrs/resolver-binding-linux-s390x-gnu@1.12.2': resolution: {integrity: sha512-HYJtLfXq94q8iZNFT1lknx258wlkkWhZeUXJRqzKBBUJ00CvZ+N33zgbCqimLjsyw5Va6uUxhVa12mI+kaveEw==} cpu: [s390x] os: [linux] + libc: [glibc] '@unrs/resolver-binding-linux-x64-gnu@1.12.2': resolution: {integrity: sha512-mPsUhunKKDih5O96Y6enDQyHc1SqBPlY1E/SfMWDM3EdJ95Z9CArPeCVwCCqbP45ljvivdEk8Fxn+SIb1rDAJQ==} cpu: [x64] os: [linux] + libc: [glibc] '@unrs/resolver-binding-linux-x64-musl@1.12.2': resolution: {integrity: sha512-azrt6+5ydLd8Vt210AAFis/lZevSfPw93EJRIJG+xPu4WCJ8K0kppCTpMyLPcKT7H15M4Jnt2tMp5bOvCkRC6A==} cpu: [x64] os: [linux] + libc: [musl] '@unrs/resolver-binding-openharmony-arm64@1.12.2': resolution: {integrity: sha512-YZ9hP4O0X9PQb8eO980qmLNGH4zT3I9+SZTdt0Pr0YyuGQhYKoOZkV02VzrzyOZJ5xIJ3UFIenKkUkGg8GjgWQ==} @@ -2946,6 +3007,7 @@ packages: eslint@9.39.5: resolution: {integrity: sha512-DgZS62aPLXKlnxILS/AYCoRvHaZeXceIzlXPkkGGzJWSow1aEk0lbTlxUSlyjC8jcaKxAdOnTDz+o1JFSBsyjw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. hasBin: true peerDependencies: jiti: '*' @@ -3706,48 +3768,56 @@ packages: engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [glibc] lightningcss-linux-arm64-gnu@1.33.0: resolution: {integrity: sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [glibc] lightningcss-linux-arm64-musl@1.32.0: resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [musl] lightningcss-linux-arm64-musl@1.33.0: resolution: {integrity: sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [musl] lightningcss-linux-x64-gnu@1.32.0: resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [glibc] lightningcss-linux-x64-gnu@1.33.0: resolution: {integrity: sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [glibc] lightningcss-linux-x64-musl@1.32.0: resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [musl] lightningcss-linux-x64-musl@1.33.0: resolution: {integrity: sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [musl] lightningcss-win32-arm64-msvc@1.32.0: resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} @@ -5114,20 +5184,20 @@ snapshots: '@babel/compat-data@7.29.7': {} - '@babel/core@7.29.7': + '@babel/core@7.29.7(supports-color@7.2.0)': dependencies: '@babel/code-frame': 7.29.7 '@babel/generator': 7.29.7 '@babel/helper-compilation-targets': 7.29.7 - '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7) + '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7(supports-color@7.2.0))(supports-color@7.2.0) '@babel/helpers': 7.29.7 '@babel/parser': 7.29.7 '@babel/template': 7.29.7 - '@babel/traverse': 7.29.7 + '@babel/traverse': 7.29.7(supports-color@7.2.0) '@babel/types': 7.29.7 '@jridgewell/remapping': 2.3.5 convert-source-map: 2.0.0 - debug: 4.4.3 + debug: 4.4.3(supports-color@7.2.0) gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -5154,41 +5224,41 @@ snapshots: lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-create-class-features-plugin@7.29.7(@babel/core@7.29.7)': + '@babel/helper-create-class-features-plugin@7.29.7(@babel/core@7.29.7(supports-color@7.2.0))(supports-color@7.2.0)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@7.2.0) '@babel/helper-annotate-as-pure': 7.29.7 - '@babel/helper-member-expression-to-functions': 7.29.7 + '@babel/helper-member-expression-to-functions': 7.29.7(supports-color@7.2.0) '@babel/helper-optimise-call-expression': 7.29.7 - '@babel/helper-replace-supers': 7.29.7(@babel/core@7.29.7) - '@babel/helper-skip-transparent-expression-wrappers': 7.29.7 - '@babel/traverse': 7.29.7 + '@babel/helper-replace-supers': 7.29.7(@babel/core@7.29.7(supports-color@7.2.0))(supports-color@7.2.0) + '@babel/helper-skip-transparent-expression-wrappers': 7.29.7(supports-color@7.2.0) + '@babel/traverse': 7.29.7(supports-color@7.2.0) semver: 6.3.1 transitivePeerDependencies: - supports-color '@babel/helper-globals@7.29.7': {} - '@babel/helper-member-expression-to-functions@7.29.7': + '@babel/helper-member-expression-to-functions@7.29.7(supports-color@7.2.0)': dependencies: - '@babel/traverse': 7.29.7 + '@babel/traverse': 7.29.7(supports-color@7.2.0) '@babel/types': 7.29.7 transitivePeerDependencies: - supports-color - '@babel/helper-module-imports@7.29.7': + '@babel/helper-module-imports@7.29.7(supports-color@7.2.0)': dependencies: - '@babel/traverse': 7.29.7 + '@babel/traverse': 7.29.7(supports-color@7.2.0) '@babel/types': 7.29.7 transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.29.7(@babel/core@7.29.7)': + '@babel/helper-module-transforms@7.29.7(@babel/core@7.29.7(supports-color@7.2.0))(supports-color@7.2.0)': dependencies: - '@babel/core': 7.29.7 - '@babel/helper-module-imports': 7.29.7 + '@babel/core': 7.29.7(supports-color@7.2.0) + '@babel/helper-module-imports': 7.29.7(supports-color@7.2.0) '@babel/helper-validator-identifier': 7.29.7 - '@babel/traverse': 7.29.7 + '@babel/traverse': 7.29.7(supports-color@7.2.0) transitivePeerDependencies: - supports-color @@ -5198,18 +5268,18 @@ snapshots: '@babel/helper-plugin-utils@7.29.7': {} - '@babel/helper-replace-supers@7.29.7(@babel/core@7.29.7)': + '@babel/helper-replace-supers@7.29.7(@babel/core@7.29.7(supports-color@7.2.0))(supports-color@7.2.0)': dependencies: - '@babel/core': 7.29.7 - '@babel/helper-member-expression-to-functions': 7.29.7 + '@babel/core': 7.29.7(supports-color@7.2.0) + '@babel/helper-member-expression-to-functions': 7.29.7(supports-color@7.2.0) '@babel/helper-optimise-call-expression': 7.29.7 - '@babel/traverse': 7.29.7 + '@babel/traverse': 7.29.7(supports-color@7.2.0) transitivePeerDependencies: - supports-color - '@babel/helper-skip-transparent-expression-wrappers@7.29.7': + '@babel/helper-skip-transparent-expression-wrappers@7.29.7(supports-color@7.2.0)': dependencies: - '@babel/traverse': 7.29.7 + '@babel/traverse': 7.29.7(supports-color@7.2.0) '@babel/types': 7.29.7 transitivePeerDependencies: - supports-color @@ -5229,43 +5299,43 @@ snapshots: dependencies: '@babel/types': 7.29.7 - '@babel/plugin-syntax-jsx@7.29.7(@babel/core@7.29.7)': + '@babel/plugin-syntax-jsx@7.29.7(@babel/core@7.29.7(supports-color@7.2.0))': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@7.2.0) '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.7)': + '@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.7(supports-color@7.2.0))': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@7.2.0) '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-transform-modules-commonjs@7.29.7(@babel/core@7.29.7)': + '@babel/plugin-transform-modules-commonjs@7.29.7(@babel/core@7.29.7(supports-color@7.2.0))(supports-color@7.2.0)': dependencies: - '@babel/core': 7.29.7 - '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7) + '@babel/core': 7.29.7(supports-color@7.2.0) + '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7(supports-color@7.2.0))(supports-color@7.2.0) '@babel/helper-plugin-utils': 7.29.7 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-typescript@7.29.7(@babel/core@7.29.7)': + '@babel/plugin-transform-typescript@7.29.7(@babel/core@7.29.7(supports-color@7.2.0))(supports-color@7.2.0)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@7.2.0) '@babel/helper-annotate-as-pure': 7.29.7 - '@babel/helper-create-class-features-plugin': 7.29.7(@babel/core@7.29.7) + '@babel/helper-create-class-features-plugin': 7.29.7(@babel/core@7.29.7(supports-color@7.2.0))(supports-color@7.2.0) '@babel/helper-plugin-utils': 7.29.7 - '@babel/helper-skip-transparent-expression-wrappers': 7.29.7 - '@babel/plugin-syntax-typescript': 7.29.7(@babel/core@7.29.7) + '@babel/helper-skip-transparent-expression-wrappers': 7.29.7(supports-color@7.2.0) + '@babel/plugin-syntax-typescript': 7.29.7(@babel/core@7.29.7(supports-color@7.2.0)) transitivePeerDependencies: - supports-color - '@babel/preset-typescript@7.29.7(@babel/core@7.29.7)': + '@babel/preset-typescript@7.29.7(@babel/core@7.29.7(supports-color@7.2.0))(supports-color@7.2.0)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@7.2.0) '@babel/helper-plugin-utils': 7.29.7 '@babel/helper-validator-option': 7.29.7 - '@babel/plugin-syntax-jsx': 7.29.7(@babel/core@7.29.7) - '@babel/plugin-transform-modules-commonjs': 7.29.7(@babel/core@7.29.7) - '@babel/plugin-transform-typescript': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-syntax-jsx': 7.29.7(@babel/core@7.29.7(supports-color@7.2.0)) + '@babel/plugin-transform-modules-commonjs': 7.29.7(@babel/core@7.29.7(supports-color@7.2.0))(supports-color@7.2.0) + '@babel/plugin-transform-typescript': 7.29.7(@babel/core@7.29.7(supports-color@7.2.0))(supports-color@7.2.0) transitivePeerDependencies: - supports-color @@ -5277,7 +5347,7 @@ snapshots: '@babel/parser': 7.29.7 '@babel/types': 7.29.7 - '@babel/traverse@7.29.7': + '@babel/traverse@7.29.7(supports-color@7.2.0)': dependencies: '@babel/code-frame': 7.29.7 '@babel/generator': 7.29.7 @@ -5285,7 +5355,7 @@ snapshots: '@babel/parser': 7.29.7 '@babel/template': 7.29.7 '@babel/types': 7.29.7 - debug: 4.4.3 + debug: 4.4.3(supports-color@7.2.0) transitivePeerDependencies: - supports-color @@ -5481,17 +5551,17 @@ snapshots: '@esbuild/win32-x64@0.28.1': optional: true - '@eslint-community/eslint-utils@4.10.1(eslint@9.39.5(jiti@2.7.0))': + '@eslint-community/eslint-utils@4.10.1(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))': dependencies: - eslint: 9.39.5(jiti@2.7.0) + eslint: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.2': {} - '@eslint/config-array@0.21.2': + '@eslint/config-array@0.21.2(supports-color@7.2.0)': dependencies: '@eslint/object-schema': 2.1.7 - debug: 4.4.3 + debug: 4.4.3(supports-color@7.2.0) minimatch: 3.1.5 transitivePeerDependencies: - supports-color @@ -5504,10 +5574,10 @@ snapshots: dependencies: '@types/json-schema': 7.0.15 - '@eslint/eslintrc@3.3.6': + '@eslint/eslintrc@3.3.6(supports-color@7.2.0)': dependencies: ajv: 6.15.0 - debug: 4.4.3 + debug: 4.4.3(supports-color@7.2.0) espree: 10.4.0 globals: 14.0.0 ignore: 5.3.2 @@ -5562,14 +5632,14 @@ snapshots: dependencies: hono: 4.12.33 - '@hookform/resolvers@5.7.1(@standard-schema/spec@1.1.0)(ajv-formats@3.0.1(ajv@8.20.0))(ajv@8.20.0)(effect@3.20.0)(react-hook-form@7.84.0(react@19.2.4))(valibot@1.4.2(typescript@5.9.3))(yup@1.7.1)(zod@4.4.3)': + '@hookform/resolvers@5.7.1(@standard-schema/spec@1.1.0)(ajv-formats@2.1.1(ajv@8.20.0))(ajv@8.20.0)(effect@3.20.0)(react-hook-form@7.84.0(react@19.2.4))(valibot@1.4.2(typescript@5.9.3))(yup@1.7.1)(zod@4.4.3)': dependencies: '@standard-schema/utils': 0.3.0 react-hook-form: 7.84.0(react@19.2.4) optionalDependencies: '@standard-schema/spec': 1.1.0 ajv: 8.20.0 - ajv-formats: 3.0.1(ajv@8.20.0) + ajv-formats: 2.1.1(ajv@8.20.0) effect: 3.20.0 valibot: 1.4.2(typescript@5.9.3) yup: 1.7.1 @@ -5707,7 +5777,7 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 - '@modelcontextprotocol/sdk@1.30.0(zod@3.25.76)': + '@modelcontextprotocol/sdk@1.30.0(supports-color@7.2.0)(zod@3.25.76)': dependencies: '@hono/node-server': 2.0.12(hono@4.12.33) ajv: 8.20.0 @@ -5717,8 +5787,8 @@ snapshots: cross-spawn: 7.0.6 eventsource: 3.0.7 eventsource-parser: 3.1.0 - express: 5.2.1 - express-rate-limit: 8.6.1(express@5.2.1) + express: 5.2.1(supports-color@7.2.0) + express-rate-limit: 8.6.1(express@5.2.1(supports-color@7.2.0))(supports-color@7.2.0) hono: 4.12.33 jose: 6.2.4 json-schema-typed: 8.0.2 @@ -6264,7 +6334,7 @@ snapshots: '@swc/core-win32-x64-msvc@1.15.47': optional: true - '@swc/core@1.15.47(@swc/helpers@0.5.15)': + '@swc/core@1.15.47': dependencies: '@swc/counter': 0.1.3 '@swc/types': 0.1.28 @@ -6281,7 +6351,6 @@ snapshots: '@swc/core-win32-arm64-msvc': 1.15.47 '@swc/core-win32-ia32-msvc': 1.15.47 '@swc/core-win32-x64-msvc': 1.15.47 - '@swc/helpers': 0.5.15 '@swc/counter@0.1.3': {} @@ -6499,15 +6568,15 @@ snapshots: dependencies: '@types/node': 20.19.43 - '@typescript-eslint/eslint-plugin@8.65.0(@typescript-eslint/parser@8.65.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3))(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@8.65.0(@typescript-eslint/parser@8.65.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.65.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3) + '@typescript-eslint/parser': 8.65.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) '@typescript-eslint/scope-manager': 8.65.0 - '@typescript-eslint/type-utils': 8.65.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3) - '@typescript-eslint/utils': 8.65.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3) + '@typescript-eslint/type-utils': 8.65.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) + '@typescript-eslint/utils': 8.65.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) '@typescript-eslint/visitor-keys': 8.65.0 - eslint: 9.39.5(jiti@2.7.0) + eslint: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) ignore: 7.0.6 natural-compare: 1.4.0 ts-api-utils: 2.5.0(typescript@5.9.3) @@ -6515,23 +6584,23 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.65.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3)': + '@typescript-eslint/parser@8.65.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3)': dependencies: '@typescript-eslint/scope-manager': 8.65.0 '@typescript-eslint/types': 8.65.0 - '@typescript-eslint/typescript-estree': 8.65.0(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.65.0(supports-color@7.2.0)(typescript@5.9.3) '@typescript-eslint/visitor-keys': 8.65.0 - debug: 4.4.3 - eslint: 9.39.5(jiti@2.7.0) + debug: 4.4.3(supports-color@7.2.0) + eslint: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.65.0(typescript@5.9.3)': + '@typescript-eslint/project-service@8.65.0(supports-color@7.2.0)(typescript@5.9.3)': dependencies: '@typescript-eslint/tsconfig-utils': 8.65.0(typescript@5.9.3) '@typescript-eslint/types': 8.65.0 - debug: 4.4.3 + debug: 4.4.3(supports-color@7.2.0) typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -6545,13 +6614,13 @@ snapshots: dependencies: typescript: 5.9.3 - '@typescript-eslint/type-utils@8.65.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3)': + '@typescript-eslint/type-utils@8.65.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3)': dependencies: '@typescript-eslint/types': 8.65.0 - '@typescript-eslint/typescript-estree': 8.65.0(typescript@5.9.3) - '@typescript-eslint/utils': 8.65.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3) - debug: 4.4.3 - eslint: 9.39.5(jiti@2.7.0) + '@typescript-eslint/typescript-estree': 8.65.0(supports-color@7.2.0)(typescript@5.9.3) + '@typescript-eslint/utils': 8.65.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) + debug: 4.4.3(supports-color@7.2.0) + eslint: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) ts-api-utils: 2.5.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: @@ -6559,13 +6628,13 @@ snapshots: '@typescript-eslint/types@8.65.0': {} - '@typescript-eslint/typescript-estree@8.65.0(typescript@5.9.3)': + '@typescript-eslint/typescript-estree@8.65.0(supports-color@7.2.0)(typescript@5.9.3)': dependencies: - '@typescript-eslint/project-service': 8.65.0(typescript@5.9.3) + '@typescript-eslint/project-service': 8.65.0(supports-color@7.2.0)(typescript@5.9.3) '@typescript-eslint/tsconfig-utils': 8.65.0(typescript@5.9.3) '@typescript-eslint/types': 8.65.0 '@typescript-eslint/visitor-keys': 8.65.0 - debug: 4.4.3 + debug: 4.4.3(supports-color@7.2.0) minimatch: 10.2.6 semver: 7.8.5 tinyglobby: 0.2.17 @@ -6574,13 +6643,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.65.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3)': + '@typescript-eslint/utils@8.65.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3)': dependencies: - '@eslint-community/eslint-utils': 4.10.1(eslint@9.39.5(jiti@2.7.0)) + '@eslint-community/eslint-utils': 4.10.1(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0)) '@typescript-eslint/scope-manager': 8.65.0 '@typescript-eslint/types': 8.65.0 - '@typescript-eslint/typescript-estree': 8.65.0(typescript@5.9.3) - eslint: 9.39.5(jiti@2.7.0) + '@typescript-eslint/typescript-estree': 8.65.0(supports-color@7.2.0)(typescript@5.9.3) + eslint: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -6957,11 +7026,11 @@ snapshots: dependencies: require-from-string: 2.0.2 - body-parser@2.3.0: + body-parser@2.3.0(supports-color@7.2.0): dependencies: bytes: 3.1.2 content-type: 2.0.0 - debug: 4.4.3 + debug: 4.4.3(supports-color@7.2.0) http-errors: 2.0.1 iconv-lite: 0.7.3 on-finished: 2.4.1 @@ -7224,13 +7293,17 @@ snapshots: dependencies: mimic-fn: 3.1.0 - debug@3.2.7: + debug@3.2.7(supports-color@7.2.0): dependencies: ms: 2.1.3 + optionalDependencies: + supports-color: 7.2.0 - debug@4.4.3: + debug@4.4.3(supports-color@7.2.0): dependencies: ms: 2.1.3 + optionalDependencies: + supports-color: 7.2.0 decimal.js@10.6.0: {} @@ -7512,18 +7585,18 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-next@16.2.12(@typescript-eslint/parser@8.65.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3))(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3): + eslint-config-next@16.2.12(@typescript-eslint/parser@8.65.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3): dependencies: '@next/eslint-plugin-next': 16.2.12 - eslint: 9.39.5(jiti@2.7.0) - eslint-import-resolver-node: 0.3.10 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.5(jiti@2.7.0)) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.65.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5(jiti@2.7.0)) - eslint-plugin-jsx-a11y: 6.10.2(eslint@9.39.5(jiti@2.7.0)) - eslint-plugin-react: 7.37.5(eslint@9.39.5(jiti@2.7.0)) - eslint-plugin-react-hooks: 7.1.1(eslint@9.39.5(jiti@2.7.0)) + eslint: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) + eslint-import-resolver-node: 0.3.10(supports-color@7.2.0) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.65.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0) + eslint-plugin-jsx-a11y: 6.10.2(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0)) + eslint-plugin-react: 7.37.5(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0)) + eslint-plugin-react-hooks: 7.1.1(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0) globals: 16.4.0 - typescript-eslint: 8.65.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3) + typescript-eslint: 8.65.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: @@ -7532,52 +7605,52 @@ snapshots: - eslint-plugin-import-x - supports-color - eslint-import-resolver-node@0.3.10: + eslint-import-resolver-node@0.3.10(supports-color@7.2.0): dependencies: - debug: 3.2.7 + debug: 3.2.7(supports-color@7.2.0) is-core-module: 2.16.2 resolve: 2.0.0-next.7 transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.5(jiti@2.7.0)): + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0): dependencies: '@nolyfill/is-core-module': 1.0.39 - debug: 4.4.3 - eslint: 9.39.5(jiti@2.7.0) + debug: 4.4.3(supports-color@7.2.0) + eslint: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) get-tsconfig: 4.14.0 is-bun-module: 2.0.0 stable-hash: 0.0.5 tinyglobby: 0.2.17 unrs-resolver: 1.12.2 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.65.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5(jiti@2.7.0)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.65.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0) transitivePeerDependencies: - supports-color - eslint-module-utils@2.14.0(@typescript-eslint/parser@8.65.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.5(jiti@2.7.0)))(eslint@9.39.5(jiti@2.7.0)): + eslint-module-utils@2.14.0(@typescript-eslint/parser@8.65.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10(supports-color@7.2.0))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0): dependencies: - debug: 3.2.7 + debug: 3.2.7(supports-color@7.2.0) optionalDependencies: - '@typescript-eslint/parser': 8.65.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3) - eslint: 9.39.5(jiti@2.7.0) - eslint-import-resolver-node: 0.3.10 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.5(jiti@2.7.0)) + '@typescript-eslint/parser': 8.65.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) + eslint: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) + eslint-import-resolver-node: 0.3.10(supports-color@7.2.0) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0) transitivePeerDependencies: - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.65.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5(jiti@2.7.0)): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.65.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 array.prototype.findlastindex: 1.2.6 array.prototype.flat: 1.3.3 array.prototype.flatmap: 1.3.3 - debug: 3.2.7 + debug: 3.2.7(supports-color@7.2.0) doctrine: 2.1.0 - eslint: 9.39.5(jiti@2.7.0) - eslint-import-resolver-node: 0.3.10 - eslint-module-utils: 2.14.0(@typescript-eslint/parser@8.65.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.5(jiti@2.7.0)))(eslint@9.39.5(jiti@2.7.0)) + eslint: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) + eslint-import-resolver-node: 0.3.10(supports-color@7.2.0) + eslint-module-utils: 2.14.0(@typescript-eslint/parser@8.65.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10(supports-color@7.2.0))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0) hasown: 2.0.4 is-core-module: 2.16.2 is-glob: 4.0.3 @@ -7589,13 +7662,13 @@ snapshots: string.prototype.trimend: 1.0.10 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.65.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3) + '@typescript-eslint/parser': 8.65.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - eslint-plugin-jsx-a11y@6.10.2(eslint@9.39.5(jiti@2.7.0)): + eslint-plugin-jsx-a11y@6.10.2(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0)): dependencies: aria-query: 5.3.2 array-includes: 3.1.9 @@ -7605,7 +7678,7 @@ snapshots: axobject-query: 4.1.0 damerau-levenshtein: 1.0.8 emoji-regex: 9.2.2 - eslint: 9.39.5(jiti@2.7.0) + eslint: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) hasown: 2.0.4 jsx-ast-utils: 3.3.5 language-tags: 1.0.9 @@ -7614,18 +7687,18 @@ snapshots: safe-regex-test: 1.1.0 string.prototype.includes: 2.0.1 - eslint-plugin-react-hooks@7.1.1(eslint@9.39.5(jiti@2.7.0)): + eslint-plugin-react-hooks@7.1.1(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0): dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@7.2.0) '@babel/parser': 7.29.7 - eslint: 9.39.5(jiti@2.7.0) + eslint: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) hermes-parser: 0.25.1 zod: 4.4.3 zod-validation-error: 4.0.2(zod@4.4.3) transitivePeerDependencies: - supports-color - eslint-plugin-react@7.37.5(eslint@9.39.5(jiti@2.7.0)): + eslint-plugin-react@7.37.5(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0)): dependencies: array-includes: 3.1.9 array.prototype.findlast: 1.2.5 @@ -7633,7 +7706,7 @@ snapshots: array.prototype.tosorted: 1.1.4 doctrine: 2.1.0 es-iterator-helpers: 1.4.0 - eslint: 9.39.5(jiti@2.7.0) + eslint: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) estraverse: 5.3.0 hasown: 2.0.4 jsx-ast-utils: 3.3.5 @@ -7658,14 +7731,14 @@ snapshots: eslint-visitor-keys@5.0.1: {} - eslint@9.39.5(jiti@2.7.0): + eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0): dependencies: - '@eslint-community/eslint-utils': 4.10.1(eslint@9.39.5(jiti@2.7.0)) + '@eslint-community/eslint-utils': 4.10.1(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0)) '@eslint-community/regexpp': 4.12.2 - '@eslint/config-array': 0.21.2 + '@eslint/config-array': 0.21.2(supports-color@7.2.0) '@eslint/config-helpers': 0.4.2 '@eslint/core': 0.17.0 - '@eslint/eslintrc': 3.3.6 + '@eslint/eslintrc': 3.3.6(supports-color@7.2.0) '@eslint/js': 9.39.5 '@eslint/plugin-kit': 0.4.1 '@humanfs/node': 0.16.8 @@ -7675,7 +7748,7 @@ snapshots: ajv: 6.15.0 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.4.3 + debug: 4.4.3(supports-color@7.2.0) escape-string-regexp: 4.0.0 eslint-scope: 8.4.0 eslint-visitor-keys: 4.2.1 @@ -7760,28 +7833,28 @@ snapshots: expect-type@1.4.0: {} - express-rate-limit@8.6.1(express@5.2.1): + express-rate-limit@8.6.1(express@5.2.1(supports-color@7.2.0))(supports-color@7.2.0): dependencies: - debug: 4.4.3 - express: 5.2.1 + debug: 4.4.3(supports-color@7.2.0) + express: 5.2.1(supports-color@7.2.0) ip-address: 10.4.0 transitivePeerDependencies: - supports-color - express@5.2.1: + express@5.2.1(supports-color@7.2.0): dependencies: accepts: 2.0.0 - body-parser: 2.3.0 + body-parser: 2.3.0(supports-color@7.2.0) content-disposition: 1.1.0 content-type: 1.0.5 cookie: 0.7.2 cookie-signature: 1.2.2 - debug: 4.4.3 + debug: 4.4.3(supports-color@7.2.0) depd: 2.0.0 encodeurl: 2.0.0 escape-html: 1.0.3 etag: 1.8.1 - finalhandler: 2.1.1 + finalhandler: 2.1.1(supports-color@7.2.0) fresh: 2.0.0 http-errors: 2.0.1 merge-descriptors: 2.0.0 @@ -7792,9 +7865,9 @@ snapshots: proxy-addr: 2.0.7 qs: 6.15.3 range-parser: 1.3.0 - router: 2.2.0 - send: 1.2.1 - serve-static: 2.2.1 + router: 2.2.0(supports-color@7.2.0) + send: 1.2.1(supports-color@7.2.0) + serve-static: 2.2.1(supports-color@7.2.0) statuses: 2.0.2 type-is: 2.1.0 vary: 1.1.2 @@ -7859,9 +7932,9 @@ snapshots: dependencies: to-regex-range: 5.0.1 - finalhandler@2.1.1: + finalhandler@2.1.1(supports-color@7.2.0): dependencies: - debug: 4.4.3 + debug: 4.4.3(supports-color@7.2.0) encodeurl: 2.0.0 escape-html: 1.0.3 on-finished: 2.4.1 @@ -8637,22 +8710,22 @@ snapshots: negotiator@1.0.0: {} - next-auth@5.0.0-beta.32(next@16.2.12(@babel/core@7.29.7)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react@19.2.4): + next-auth@5.0.0-beta.32(next@16.2.12(@babel/core@7.29.7(supports-color@7.2.0))(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react@19.2.4): dependencies: '@auth/core': 0.41.3 - next: 16.2.12(@babel/core@7.29.7)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + next: 16.2.12(@babel/core@7.29.7(supports-color@7.2.0))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) react: 19.2.4 next-intl-swc-plugin-extractor@4.13.4: {} - next-intl@4.13.4(@swc/helpers@0.5.15)(next@16.2.12(@babel/core@7.29.7)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react@19.2.4)(typescript@5.9.3): + next-intl@4.13.4(next@16.2.12(@babel/core@7.29.7(supports-color@7.2.0))(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react@19.2.4)(typescript@5.9.3): dependencies: '@formatjs/intl-localematcher': 0.8.13 '@parcel/watcher': 2.6.0 - '@swc/core': 1.15.47(@swc/helpers@0.5.15) + '@swc/core': 1.15.47 icu-minify: 4.13.4 negotiator: 1.0.0 - next: 16.2.12(@babel/core@7.29.7)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + next: 16.2.12(@babel/core@7.29.7(supports-color@7.2.0))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) next-intl-swc-plugin-extractor: 4.13.4 po-parser: 2.1.1 react: 19.2.4 @@ -8667,7 +8740,7 @@ snapshots: react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - next@16.2.12(@babel/core@7.29.7)(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + next@16.2.12(@babel/core@7.29.7(supports-color@7.2.0))(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: '@next/env': 16.2.12 '@swc/helpers': 0.5.15 @@ -8676,7 +8749,7 @@ snapshots: postcss: 8.4.31 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - styled-jsx: 5.1.6(@babel/core@7.29.7)(react@19.2.4) + styled-jsx: 5.1.6(@babel/core@7.29.7(supports-color@7.2.0))(react@19.2.4) optionalDependencies: '@next/swc-darwin-arm64': 16.2.12 '@next/swc-darwin-x64': 16.2.12 @@ -9134,9 +9207,9 @@ snapshots: '@rolldown/binding-win32-arm64-msvc': 1.2.2 '@rolldown/binding-win32-x64-msvc': 1.2.2 - router@2.2.0: + router@2.2.0(supports-color@7.2.0): dependencies: - debug: 4.4.3 + debug: 4.4.3(supports-color@7.2.0) depd: 2.0.0 is-promise: 4.0.0 parseurl: 1.3.3 @@ -9191,9 +9264,9 @@ snapshots: semver@7.8.5: {} - send@1.2.1: + send@1.2.1(supports-color@7.2.0): dependencies: - debug: 4.4.3 + debug: 4.4.3(supports-color@7.2.0) encodeurl: 2.0.0 escape-html: 1.0.3 etag: 1.8.1 @@ -9209,12 +9282,12 @@ snapshots: seq-queue@0.0.5: {} - serve-static@2.2.1: + serve-static@2.2.1(supports-color@7.2.0): dependencies: encodeurl: 2.0.0 escape-html: 1.0.3 parseurl: 1.3.3 - send: 1.2.1 + send: 1.2.1(supports-color@7.2.0) transitivePeerDependencies: - supports-color @@ -9242,14 +9315,14 @@ snapshots: setprototypeof@1.2.0: {} - shadcn@4.16.1(typescript@5.9.3): + shadcn@4.16.1(supports-color@7.2.0)(typescript@5.9.3): dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@7.2.0) '@babel/parser': 7.29.7 - '@babel/plugin-transform-typescript': 7.29.7(@babel/core@7.29.7) - '@babel/preset-typescript': 7.29.7(@babel/core@7.29.7) + '@babel/plugin-transform-typescript': 7.29.7(@babel/core@7.29.7(supports-color@7.2.0))(supports-color@7.2.0) + '@babel/preset-typescript': 7.29.7(@babel/core@7.29.7(supports-color@7.2.0))(supports-color@7.2.0) '@dotenvx/dotenvx': 1.75.1 - '@modelcontextprotocol/sdk': 1.30.0(zod@3.25.76) + '@modelcontextprotocol/sdk': 1.30.0(supports-color@7.2.0)(zod@3.25.76) '@types/validate-npm-package-name': 4.0.2 browserslist: 4.28.7 commander: 14.0.3 @@ -9467,12 +9540,12 @@ snapshots: strip-json-comments@3.1.1: {} - styled-jsx@5.1.6(@babel/core@7.29.7)(react@19.2.4): + styled-jsx@5.1.6(@babel/core@7.29.7(supports-color@7.2.0))(react@19.2.4): dependencies: client-only: 0.0.1 react: 19.2.4 optionalDependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@7.2.0) supports-color@7.2.0: dependencies: @@ -9613,13 +9686,13 @@ snapshots: possible-typed-array-names: 1.1.0 reflect.getprototypeof: 1.0.10 - typescript-eslint@8.65.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3): + typescript-eslint@8.65.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.65.0(@typescript-eslint/parser@8.65.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3))(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3) - '@typescript-eslint/parser': 8.65.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3) - '@typescript-eslint/typescript-estree': 8.65.0(typescript@5.9.3) - '@typescript-eslint/utils': 8.65.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3) - eslint: 9.39.5(jiti@2.7.0) + '@typescript-eslint/eslint-plugin': 8.65.0(@typescript-eslint/parser@8.65.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3))(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) + '@typescript-eslint/parser': 8.65.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.65.0(supports-color@7.2.0)(typescript@5.9.3) + '@typescript-eslint/utils': 8.65.0(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@5.9.3) + eslint: 9.39.5(jiti@2.7.0)(supports-color@7.2.0) typescript: 5.9.3 transitivePeerDependencies: - supports-color diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 31793f2..4155ad2 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -6,6 +6,7 @@ allowBuilds: "@parcel/watcher": false "@prisma/engines": false "@swc/core": false + esbuild: true prisma: false sharp: false unrs-resolver: false From d4139fca4d6d673292402012ddfd106576f0460c Mon Sep 17 00:00:00 2001 From: Janarthanan Soundhararajan Date: Mon, 31 Aug 2026 20:22:28 +0530 Subject: [PATCH 2/4] docs: record M0 baseline audit --- .gitignore | 1 + apps/app/.env.example | 12 +++ apps/app/.gitignore | 1 + docs/README.md | 1 + docs/baseline-m0.md | 181 +++++++++++++++++++++++++++++++++++ docs/domain-model-current.md | 8 +- docs/feature-inventory.md | 2 +- packages/db/.env.example | 2 + packages/db/.gitignore | 1 + 9 files changed, 205 insertions(+), 4 deletions(-) create mode 100644 apps/app/.env.example create mode 100644 docs/baseline-m0.md create mode 100644 packages/db/.env.example diff --git a/.gitignore b/.gitignore index 46cf26d..7b279e0 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,7 @@ yarn-error.log* # env files (can opt-in for committing if needed) .env* +!**/.env.example # vercel .vercel diff --git a/apps/app/.env.example b/apps/app/.env.example new file mode 100644 index 0000000..c033024 --- /dev/null +++ b/apps/app/.env.example @@ -0,0 +1,12 @@ +# Product application runtime +DATABASE_URL="postgresql://USER:PASSWORD@HOST/DATABASE?sslmode=require" +AUTH_SECRET="replace-with-a-random-secret" + +# Auth.js identity providers +AUTH_GITHUB_ID="github-oauth-client-id" +AUTH_GITHUB_SECRET="github-oauth-client-secret" +AUTH_GOOGLE_ID="google-oauth-client-id" +AUTH_GOOGLE_SECRET="google-oauth-client-secret" + +# Transactional booking email +RESEND_API_KEY="re_replace_me" diff --git a/apps/app/.gitignore b/apps/app/.gitignore index 45254b6..bf8d094 100644 --- a/apps/app/.gitignore +++ b/apps/app/.gitignore @@ -32,6 +32,7 @@ yarn-error.log* # env files (can opt-in for committing if needed) .env* +!.env.example # vercel .vercel diff --git a/docs/README.md b/docs/README.md index d5b2fc3..66cd9c9 100644 --- a/docs/README.md +++ b/docs/README.md @@ -38,6 +38,7 @@ Statements about current behavior should be verifiable in code. Proposed behavio | [System architecture](./system-architecture.md) | Modular runtime boundaries, request and transaction flows, durable work, integrations, security, and sequences | Proposed runtime design | | [Deployment architecture](./deployment-architecture.md) | Environments, deployable units, database, releases, secrets, observability, backups, and recovery | Proposed deployment design | | [Roadmap](./roadmap.md) | Vertical delivery milestones, dependencies, decision gates, and completion evidence | Proposed delivery plan | +| [M0 baseline reconciliation](./baseline-m0.md) | Validation evidence, environment contracts, migration gaps, data-quality queries, and Server Action conventions | Current baseline | | [Content opportunities](./content-opportunities.md) | Reusable learning and publishing ideas discovered during development | Active backlog | ## Articles diff --git a/docs/baseline-m0.md b/docs/baseline-m0.md new file mode 100644 index 0000000..7489fa5 --- /dev/null +++ b/docs/baseline-m0.md @@ -0,0 +1,181 @@ +# M0 Baseline Reconciliation + +**Status:** Current baseline evidence +**Baseline commit:** `ab088f6` on `chore/baseline-quality` +**Reviewed:** 2026-08-31 + +## Purpose + +This document records the evidence and known gaps for roadmap milestone M0. It is safe to commit: environment values, provider credentials, user data, and production identifiers are intentionally excluded. + +## Validation evidence + +The following commands passed from the monorepo root with pnpm 11.24.0 and Node.js 24.18.1: + +```text +pnpm --filter db db:generate Prisma Client 7.9.1 generated +pnpm lint 2 workspace lint tasks passed +pnpm --filter app test 11 files, 45 tests passed +pnpm build 3 Turbo tasks passed; both Next.js apps built +``` + +The production build requires network access because `next/font` downloads Geist and Geist Mono during compilation. Next.js 16.2.12 also warns that the `middleware.ts` filename is deprecated in favor of `proxy.ts`; this warning does not fail the build. + +## Authentication baseline and environment contract + +Auth.js uses JWT sessions with the Prisma adapter. Both providers use identity/login consent only; future Google Calendar authorization requires a separate consent and token contract. + +| Capability | Required variables | Current evidence | Status | +| --- | --- | --- | --- | +| Auth.js session signing | `AUTH_SECRET` | Referenced implicitly by Auth.js and present by key in the local product environment | Current | +| GitHub OAuth | `AUTH_GITHUB_ID`, `AUTH_GITHUB_SECRET` | Provider is configured and the product UI calls `signIn("github")` | Current; live callback still requires provider-console verification | +| Google OAuth | `AUTH_GOOGLE_ID`, `AUTH_GOOGLE_SECRET` | Provider is configured, but the custom sign-in UI exposes only GitHub and the local environment has no Google keys | Partial | +| Database-backed identity | `DATABASE_URL` | Required eagerly by `@repo/db` and Prisma CLI configuration | Current | +| Booking confirmation email | `RESEND_API_KEY` | Checked at delivery time; absence preserves booking success and returns failed email delivery | Current | + +Provider-console verification must confirm these deployment-specific values before claiming a live OAuth smoke test: + +- GitHub callback: `/api/auth/callback/github` +- Google callback: `/api/auth/callback/google` +- Auth.js trusted/canonical product origin for each environment +- Preview credentials and callback URLs are isolated from production + +Committed templates live in `apps/app/.env.example` and `packages/db/.env.example`. Real values remain uncommitted. + +## Prisma schema and migration reconciliation + +`packages/db/prisma/schema.prisma` matches the entities described by the current-domain document after correcting the booking provider fields: + +- Auth.js: `User`, `Account`, `Session`, `VerificationToken` +- Direct scheduling: `EventType`, `UserAvailability`, `Booking` +- Polling: `Poll`, `TimeSlot`, `Availability` +- Email baseline: optional unique `Booking.icsUid` +- Meeting location baseline: optional `Booking.meetingUrl` and `Booking.meetingProvider` + +`packages/db/prisma.config.ts` declares `prisma/migrations`, but that directory does not exist. Therefore: + +- Prisma Client generation is reproducible from the schema. +- Database creation and evolution are not reproducible from committed migration history. +- M1/M2 schema work must not invent a baseline migration without first identifying the authoritative database and deciding whether to baseline it or create a clean initial migration. + +## Pre-migration data-quality queries + +Run these read-only queries against an explicitly selected development or staging database before designing stricter constraints. Do not run them implicitly against whichever `DATABASE_URL` happens to be loaded. + +### Invalid booking intervals + +```sql +SELECT id, "hostId", "startTime", "endTime" +FROM "Booking" +WHERE "endTime" <= "startTime"; +``` + +### Overlapping active bookings for one host + +```sql +SELECT + left_booking.id AS left_id, + right_booking.id AS right_id, + left_booking."hostId" +FROM "Booking" AS left_booking +JOIN "Booking" AS right_booking + ON left_booking."hostId" = right_booking."hostId" + AND left_booking.id < right_booking.id + AND left_booking.status IN ('PENDING', 'ACCEPTED') + AND right_booking.status IN ('PENDING', 'ACCEPTED') + AND left_booking."startTime" < right_booking."endTime" + AND left_booking."endTime" > right_booking."startTime"; +``` + +### Booking host/event-type ownership mismatch + +```sql +SELECT booking.id, booking."hostId", event_type."userId" AS event_type_owner +FROM "Booking" AS booking +JOIN "EventType" AS event_type ON event_type.id = booking."eventTypeId" +WHERE booking."hostId" <> event_type."userId"; +``` + +### Invalid or duplicate poll candidates + +```sql +SELECT id, "pollId", "startTime", "endTime" +FROM "TimeSlot" +WHERE "endTime" <= "startTime"; + +SELECT "pollId", "startTime", "endTime", COUNT(*) +FROM "TimeSlot" +GROUP BY "pollId", "startTime", "endTime" +HAVING COUNT(*) > 1; +``` + +### Cross-poll vote references + +```sql +SELECT availability.id, availability."pollId", slot."pollId" AS slot_poll_id +FROM "Availability" AS availability +JOIN "TimeSlot" AS slot ON slot.id = availability."timeSlotId" +WHERE availability."pollId" <> slot."pollId"; +``` + +### Inconsistent participant identity within a poll + +```sql +SELECT + "pollId", + LOWER(TRIM("participantName")) AS normalized_name, + COUNT(DISTINCT LOWER(TRIM(COALESCE("participantEmail", '')))) AS email_count +FROM "Availability" +GROUP BY "pollId", LOWER(TRIM("participantName")) +HAVING COUNT(DISTINCT LOWER(TRIM(COALESCE("participantEmail", '')))) > 1; +``` + +## Server Action result convention + +New or materially changed Server Actions should return an explicit discriminated result for expected outcomes: + +```ts +type ActionResult = + | { success: true; data: T } + | { + success: false; + error: { + code: string; + message: string; + fieldErrors?: Partial>; + }; + }; +``` + +Conventions: + +1. Authentication, validation, conflicts, and expected persistence failures return `success: false` rather than mixing thrown errors and return values. +2. Unexpected errors are logged server-side with safe context and returned as a generic coded failure. +3. Redirecting form actions may use a dedicated form-state type, but their error object follows the same code/message/field-error categories. +4. Successful mutation actions return `success: true` consistently, including delete actions. +5. Provider outcomes remain nested secondary results when internal state has already committed, as implemented by booking email delivery. +6. User-facing text may be localized from stable error codes; provider messages and sensitive values are not returned directly. + +Current actions predate this convention and expose known deviations: + +| Action | Current deviation | +| --- | --- | +| `createBooking` | Closest to the target, but errors are strings and field errors are top-level | +| `createPoll` | Uses form-state `errors` and redirects on success | +| `submitPollVotes` | Returns an untyped string-error result | +| `createEventType` | May return `undefined` after an unexpected database error | +| `deleteEventType` | Returns `undefined` on success | +| `updateAvailability` | Throws for authentication/validation and performs multiple writes without one transaction | + +Refactor these actions when their user journey is next changed; avoid a broad mechanical rewrite during M0. + +## Known baseline limitations + +- Google OAuth is not exposed in the current custom sign-in UI and lacks local configuration evidence. +- OAuth callback behavior still needs a manual smoke test in an environment with registered provider callbacks. +- No committed Prisma migration history exists. +- Public booking overlap protection is query-then-insert and is not concurrency-safe. +- Poll votes can structurally reference a candidate belonging to another poll. +- Several links and redirects do not preserve locale. +- Next.js reports the `middleware.ts` to `proxy.ts` deprecation. +- Durable email delivery state and retry are proposed, not current. diff --git a/docs/domain-model-current.md b/docs/domain-model-current.md index 085f498..dd2789e 100644 --- a/docs/domain-model-current.md +++ b/docs/domain-model-current.md @@ -376,7 +376,9 @@ Represents a guest reservation for one host and one event type. | `startTime` | Yes | Timestamp | Scheduled absolute start | | `endTime` | Yes | Timestamp | Scheduled absolute end | | `status` | Yes | Defaults `ACCEPTED` | `PENDING`, `ACCEPTED`, or `CANCELLED` | -| `googleMeetLink` | No | None | Provider-specific meeting URL | +| `meetingUrl` | No | None | Provider meeting or location URL | +| `meetingProvider` | No | `MeetingProvider` enum | Optional provider classification | +| `icsUid` | No | Unique when present | Stable calendar invitation identifier | ### Keys and indexes @@ -422,7 +424,7 @@ The existing indexes also do not exactly match the main conflict predicate, whic - `status` is an enum but permitted transitions are not modeled. - `endTime > startTime` is not a database constraint. -- `googleMeetLink` couples the booking model to one conferencing provider. +- `meetingUrl` and `meetingProvider` are general provider fields, but provider lifecycle state is not modeled separately. - Guest details are embedded because a guest entity does not exist. - No idempotency key protects repeated logical submissions. - No version field protects concurrent lifecycle changes. @@ -731,7 +733,7 @@ The proposed model must evaluate access patterns before normalizing. | `TimeSlot` | Generic name currently scoped to poll candidates | `PollCandidate` | | `responses` relation | Contains vote rows, not participant response aggregates | `votes` until response entity exists | | `Booking` | Could mean reservation request or final meeting | Requires domain decision | -| `googleMeetLink` | Couples core record to one provider | General location/provider reference | +| `meetingUrl` / `meetingProvider` | Provider details remain on the core booking record | Separate integration reference when provider lifecycle behavior is implemented | Renaming should follow accepted domain decisions and migrations, not happen only for stylistic consistency. diff --git a/docs/feature-inventory.md b/docs/feature-inventory.md index 55044c1..2c725d5 100644 --- a/docs/feature-inventory.md +++ b/docs/feature-inventory.md @@ -21,7 +21,7 @@ This inventory separates implemented behavior from proposals. It is not a market | GitHub OAuth authentication | Current | Implemented with Auth.js. First OAuth login also acts as account creation. | | Protected dashboard pages | Current | Availability, event types, and bookings verify the authenticated session. | | New-user onboarding | Proposed | Username, timezone, initial availability, and first scheduling action. | -| Google OAuth authentication | Current | Implemented with Auth.js; identity scopes must remain separate from future Google Calendar permissions. | +| Google OAuth authentication | Partial | The Auth.js provider is configured, but the custom sign-in UI and local environment currently expose only GitHub; identity scopes must remain separate from future Google Calendar permissions. | | Email magic-link login | Exploratory | A possible alternative for users without supported OAuth providers. | | Password authentication | Out of scope | Adds password storage, reset, verification, and abuse-prevention responsibilities without current product value. | | Personal workspace | Proposed | Created automatically for each user without exposing unnecessary organization UI. | diff --git a/packages/db/.env.example b/packages/db/.env.example new file mode 100644 index 0000000..fbb3074 --- /dev/null +++ b/packages/db/.env.example @@ -0,0 +1,2 @@ +# Prisma CLI and @repo/db runtime +DATABASE_URL="postgresql://USER:PASSWORD@HOST/DATABASE?sslmode=require" diff --git a/packages/db/.gitignore b/packages/db/.gitignore index 46cf26d..842cb60 100644 --- a/packages/db/.gitignore +++ b/packages/db/.gitignore @@ -33,6 +33,7 @@ yarn-error.log* # env files (can opt-in for committing if needed) .env* +!.env.example # vercel .vercel From d2e98b76f71b49282b0457a5b5574b4d121375ea Mon Sep 17 00:00:00 2001 From: Janarthanan Soundhararajan Date: Mon, 31 Aug 2026 20:32:06 +0530 Subject: [PATCH 3/4] feat: expose Google sign-in --- apps/app/components/auth-components.tsx | 78 +++++++++++++++++++------ docs/baseline-m0.md | 4 +- docs/feature-inventory.md | 2 +- 3 files changed, 63 insertions(+), 21 deletions(-) diff --git a/apps/app/components/auth-components.tsx b/apps/app/components/auth-components.tsx index de695f1..58d3bba 100644 --- a/apps/app/components/auth-components.tsx +++ b/apps/app/components/auth-components.tsx @@ -3,26 +3,68 @@ import { signIn, signOut } from "@/auth"; export function SignIn() { return ( -
{ - "use server"; - await signIn("github"); - }} - > - -
+ + Sign in with Google + + + +
{ + "use server"; + await signIn("github"); + }} + > + +
+ ); } diff --git a/docs/baseline-m0.md b/docs/baseline-m0.md index 7489fa5..2069193 100644 --- a/docs/baseline-m0.md +++ b/docs/baseline-m0.md @@ -29,7 +29,7 @@ Auth.js uses JWT sessions with the Prisma adapter. Both providers use identity/l | --- | --- | --- | --- | | Auth.js session signing | `AUTH_SECRET` | Referenced implicitly by Auth.js and present by key in the local product environment | Current | | GitHub OAuth | `AUTH_GITHUB_ID`, `AUTH_GITHUB_SECRET` | Provider is configured and the product UI calls `signIn("github")` | Current; live callback still requires provider-console verification | -| Google OAuth | `AUTH_GOOGLE_ID`, `AUTH_GOOGLE_SECRET` | Provider is configured, but the custom sign-in UI exposes only GitHub and the local environment has no Google keys | Partial | +| Google OAuth | `AUTH_GOOGLE_ID`, `AUTH_GOOGLE_SECRET` | Provider is configured and the product UI calls `signIn("google")`; the local environment still needs Google keys | Current in code; live callback still requires provider-console verification | | Database-backed identity | `DATABASE_URL` | Required eagerly by `@repo/db` and Prisma CLI configuration | Current | | Booking confirmation email | `RESEND_API_KEY` | Checked at delivery time; absence preserves booking success and returns failed email delivery | Current | @@ -171,7 +171,7 @@ Refactor these actions when their user journey is next changed; avoid a broad me ## Known baseline limitations -- Google OAuth is not exposed in the current custom sign-in UI and lacks local configuration evidence. +- Google OAuth is exposed in the custom sign-in UI, but local credentials and a live callback smoke test are still required. - OAuth callback behavior still needs a manual smoke test in an environment with registered provider callbacks. - No committed Prisma migration history exists. - Public booking overlap protection is query-then-insert and is not concurrency-safe. diff --git a/docs/feature-inventory.md b/docs/feature-inventory.md index 2c725d5..30fe662 100644 --- a/docs/feature-inventory.md +++ b/docs/feature-inventory.md @@ -21,7 +21,7 @@ This inventory separates implemented behavior from proposals. It is not a market | GitHub OAuth authentication | Current | Implemented with Auth.js. First OAuth login also acts as account creation. | | Protected dashboard pages | Current | Availability, event types, and bookings verify the authenticated session. | | New-user onboarding | Proposed | Username, timezone, initial availability, and first scheduling action. | -| Google OAuth authentication | Partial | The Auth.js provider is configured, but the custom sign-in UI and local environment currently expose only GitHub; identity scopes must remain separate from future Google Calendar permissions. | +| Google OAuth authentication | Current | Implemented with Auth.js and exposed in the sign-in UI; deployment requires registered callback URLs and provider credentials. Identity scopes remain separate from future Google Calendar permissions. | | Email magic-link login | Exploratory | A possible alternative for users without supported OAuth providers. | | Password authentication | Out of scope | Adds password storage, reset, verification, and abuse-prevention responsibilities without current product value. | | Personal workspace | Proposed | Created automatically for each user without exposing unnecessary organization UI. | From 7227fc0ee6a2eabe6c523a0bd020b98cfe2f5ffb Mon Sep 17 00:00:00 2001 From: Janarthanan Soundhararajan Date: Mon, 31 Aug 2026 22:08:32 +0530 Subject: [PATCH 4/4] chore: pass runtime environment through turbo --- turbo.json | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/turbo.json b/turbo.json index 97ee815..1cf4907 100644 --- a/turbo.json +++ b/turbo.json @@ -7,11 +7,27 @@ "inputs": ["$TURBO_DEFAULT$", ".env*"], "outputs": [".next/**", "!.next/cache/**", "dist/**"] }, + "app#build": { + "dependsOn": ["^build", "^db:generate"], + "inputs": ["$TURBO_DEFAULT$", ".env*"], + "env": [ + "DATABASE_URL", + "AUTH_SECRET", + "AUTH_GITHUB_ID", + "AUTH_GITHUB_SECRET", + "AUTH_GOOGLE_ID", + "AUTH_GOOGLE_SECRET", + "RESEND_API_KEY" + ], + "outputs": [".next/**", "!.next/cache/**", "dist/**"] + }, "db:generate": { - "cache": false + "cache": false, + "env": ["DATABASE_URL"] }, "db:push": { - "cache": false + "cache": false, + "env": ["DATABASE_URL"] }, "lint": { "dependsOn": ["^lint"] @@ -19,6 +35,19 @@ "dev": { "cache": false, "persistent": true + }, + "app#dev": { + "cache": false, + "env": [ + "DATABASE_URL", + "AUTH_SECRET", + "AUTH_GITHUB_ID", + "AUTH_GITHUB_SECRET", + "AUTH_GOOGLE_ID", + "AUTH_GOOGLE_SECRET", + "RESEND_API_KEY" + ], + "persistent": true } } }