The Problem

Teams that rely on Google Calendar or Notion often hit friction when trying to embed calendar data in custom workflows or add AI‑driven assistants. The proprietary APIs limit UI customisation and lock you into vendor‑specific authentication flows.

What This Does

weekday is a self‑hosted calendar UI built with Next.js, tRPC, and Drizzle ORM. The core Google‑Calendar client lives in packages/google-calendar/src/ (e.g., client.ts, resources/calendars/events.ts). UI components such as the month view (apps/web/components/event-calendar/views/month-view.tsx) and AI chat helpers (apps/web/components/ai/*.tsx) render events and let users create, edit, or delete them via the Google Calendar API. Authentication is provided by packages/auth/index.ts (Better Auth) and the data layer by packages/db (PostgreSQL schema in drizzle/schema.ts).

How It Is Wired

Execution starts in the Next.js server entry apps/web/trpc/server.ts, which registers tRPC routers from packages/api/src/routers/*.ts. The primary router (api.ts) exposes endpoints like GET /api/trpc/calendar.list. A request hits packages/api/src/routers/calendar.ts, which calls the Google client:

createGoogleCalendarClient -> packages/google-calendar/src/client.ts (constructor)

From there, client.ts delegates to resource modules, e.g.:

  • packages/google-calendar/src/resources/calendars/events.ts – defines list, create, update, delete.
  • packages/google-calendar/src/resources/calendars/acl.ts – ACL helpers.

The most‑used internal function is cn in apps/web/lib/utils.ts (called from 43 files). The hub module packages/google-calendar/src/internal/request-options.ts is imported by 12 other modules, making it a high‑blast‑radius point.

The import graph contains 19 circular dependencies (e.g., client.ts ↔ core/api-promise.ts ↔ core/resource.ts), which inflate the cognitive load and increase risk when refactoring. Several files exceed 800 lines (client.ts, events.ts, event-dialog.tsx), and deep nesting (up to 9 levels) appears in month-view.tsx and chat tools. These patterns mean a change in one of the hub modules or oversized files can ripple through many components.

Database interaction occurs in packages/auth/index.ts (e.g., this.db.query.account.findFirst) and via the Drizzle ORM in packages/db. The only external side‑effect traced from an entry point is a call chain that eventually reaches the database through methodRequest → request → makeRequestWithRefresh → refreshTokenIfNeeded → getGoogleAccount.

How To Use It

# Clone the fork that this briefing targets
git clone https://github.com/moses-y/weekday.git
cd weekday

# Install (Bun is recommended; npm works as well)
bun install

# Copy environment template and fill required values
cp .env.example .env
# edit .env – set DATABASE_URL, AUTH_SECRET, GOOGLE_CLIENT_ID/SECRET, AI_API_KEY, etc.

# Initialise the PostgreSQL schema
bun run db:push   # defined in package.json scripts

# Start the dev server
bun run dev

A Docker alternative is provided:

docker compose up --build

The docker-compose.yml builds the Next.js app and a PostgreSQL container, using the same .env variables.

Real‑World Use

An internal tool can embed the Weekday UI in an intranet portal, allowing employees to schedule meetings through the familiar Google Calendar flow while an AI assistant (via packages/google-calendar and apps/web/components/ai) suggests optimal times based on free‑slot queries (get-free-slots.tsx). The tRPC API lets other services fetch calendar data without exposing Google credentials directly.

Code Health & Issues

  • High – Dependency advisory: next@16.1.6 has CVE‑2026‑44575. Upgrade to the fixed version and commit a lockfile.
  • High – No test suite: 170 source files, zero test files. Add unit/integration tests for each public entry point.
  • High – No CI pipeline: No .github/workflows or other CI config. Introduce a GitHub Actions workflow that runs bun install, bun run build, and the test suite.
  • High – No build gate for Docker: docker‑compose.yml is never validated. Add a workflow that builds the image and runs a health check.
  • Medium – Missing Dependabot: No auto‑updates for the 8 manifest files. Add .github/dependabot.yml.
  • Low – Missing repo conventions: No .editorconfig, .gitattributes, or formatter config. Add those to enforce consistent line endings and style.
  • High – Import cycles: 19 modules in circular imports (e.g., client.ts, core/api-promise.ts, core/resource.ts). Break cycles by extracting shared types or using lazy imports.
  • High – Oversized files: client.ts (827 LOC) and event-dialog.tsx are hard to maintain; split by responsibility.
  • High – Deep nesting: Max indentation depth of 9 in several UI components; refactor with early returns or extracted helpers.
  • High – Duplicated code: Repeated 6‑line blocks across 23 files; consolidate into shared utilities.

The Bottom Line

weekday delivers a functional, AI‑enhanced calendar UI that can be self‑hosted and extended via a clear tRPC API. The codebase is usable but suffers from import cycles, large monolithic files, and a lack of automated testing and CI. It is suitable for teams comfortable refactoring TypeScript monorepos and willing to invest in test and CI scaffolding before production use.