xtablo-source/.planning/codebase/STRUCTURE.md
2026-05-14 16:01:31 +02:00

12 KiB

Structure

Last updated: 2026-05-14

Directory layout, conventions, and where to look for things in the xtablo-source monorepo.

Top-Level Layout

xtablo-source/
├── apps/              # Deployable applications
│   ├── main/          # Authenticated dashboard SPA (Vite + CF Workers)
│   ├── external/      # Public booking widget (Vite)
│   ├── clients/       # Client portal (Vite + CF Workers)
│   ├── admin/         # Internal admin tools (Vite + CF Workers)
│   ├── api/           # Hono REST API (Node, GCP Cloud Run)
│   └── chat-worker/   # Cloudflare Durable Object worker for chat
├── packages/          # Shared workspace packages (source-only)
│   ├── shared/        # Contexts, hooks, API client, toast, supabase client
│   ├── ui/            # Radix + Tailwind component library
│   ├── shared-types/  # Pure TypeScript types (zero runtime deps)
│   ├── auth-ui/       # Auth screens (login/register shells)
│   ├── chat-ui/       # Chat-specific UI components
│   └── tablo-views/   # Tablo detail / sections components
├── backend/           # Legacy / auxiliary backend code
├── go-backend/        # Go services (separate stack)
├── frontend_v2/       # Frontend v2 prototype
├── xtablo-expo/       # React Native (Expo) app
├── supabase/          # Supabase project (migrations, config)
├── infra/             # Infrastructure-as-code
├── docs/              # Architecture, deployment, integration docs
├── prompts/           # Prompt templates
├── scripts/           # Repo scripts
├── CLAUDE.md          # Claude Code guidance (root)
├── DEVELOPMENT.md     # Dev guide
├── turbo.json         # Turborepo pipeline config
├── pnpm-workspace.yaml
└── package.json

Apps

apps/main (@xtablo/main)

Primary dashboard. Internal layout:

apps/main/src/
├── main.tsx                 # Vite entry
├── App.tsx                  # Root component, providers
├── i18n.ts                  # i18next setup
├── main.css                 # Tailwind entry
├── components/              # UI components (Modals, Sections, Cards, ...)
├── contexts/                # App-local React contexts (UpgradeBlockContext, ...)
├── hooks/                   # Feature hooks (tablos, events, tasks, stripe, ...)
├── lib/
│   ├── api.ts               # API client wrapper
│   ├── supabase.ts          # Supabase client re-export
│   ├── routes.tsx           # Protected routes
│   ├── publicRoutes.tsx     # Public/auth routes
│   ├── billing.ts           # Stripe-related helpers
│   ├── env.ts               # Env validation
│   └── rum.ts               # Datadog RUM init
├── pages/                   # Route page components
├── providers/
│   └── UserStoreProvider.tsx # Zustand user store
├── locales/                 # i18n JSON
├── utils/
└── assets/

apps/external (@xtablo/external)

Embeddable booking widget. Internal layout:

apps/external/src/
├── main.tsx
├── routes.tsx
├── EmbeddedBookingPage.tsx
├── FloatingBookingWidget.tsx
├── CustomModal.tsx
├── UserStoreProvider.tsx
├── lib/
└── locales/

Mode is driven by query string: ?mode=embed&eventTypeId=... or ?mode=floating.

apps/clients (@xtablo/clients)

Public-facing client portal.

apps/clients/src/
├── main.tsx
├── App.tsx
├── routes.tsx
├── components/
├── hooks/
├── lib/
├── pages/
├── locales/
└── test/

apps/admin (@xtablo/admin)

Internal admin app.

apps/admin/src/
├── main.tsx
├── App.tsx
├── routes.tsx
├── components/
├── hooks/
├── lib/
├── pages/
└── registry/

apps/api (@xtablo/api)

Hono REST API. Internal layout:

apps/api/src/
├── index.ts                # Entry: tracer, secrets, server start
├── config.ts               # createConfig(secrets) -> AppConfig
├── secrets.ts              # loadSecrets() (env or GCP Secret Manager)
├── client.ts               # Supabase admin client factory
├── middlewares/
│   ├── middleware.ts       # MiddlewareManager singleton + supabase/r2/stripe
│   ├── stripeSync.ts       # Stripe<->Supabase sync engine
│   └── transporter.ts      # Email transport middleware
├── routers/
│   ├── index.ts            # getMainRouter — composition + ordering
│   ├── public.ts           # Unauthenticated endpoints
│   ├── authRouter.ts       # Requires JWT
│   ├── maybeAuthRouter.ts  # Optional auth (booking-aware)
│   ├── tablo.ts            # Tablo CRUD
│   ├── tablo_data.ts       # Tablo content blocks
│   ├── tasks.ts            # Tasks
│   ├── notes.ts            # Notes
│   ├── events.ts (in user.ts/tablo_data.ts)
│   ├── stripe.ts           # Stripe webhook + ops
│   ├── revenuecat.ts       # RevenueCat webhook
│   ├── invite.ts           # Tablo invites
│   ├── user.ts             # User profile / settings
│   ├── admin*.ts           # admin.ts, adminActions.ts, adminAuth.ts,
│   │                       # adminDatasets.ts, adminOverview.ts, adminTables.ts
│   ├── clientAuth.ts       # Client portal magic-link auth
│   ├── clientPortal.ts     # Client portal endpoints
│   └── clientInvites.ts    # Public client invites
├── helpers/
├── types/                  # BaseEnv, app.types.ts
└── __tests__/

apps/chat-worker

apps/chat-worker/src/
├── index.ts                # Worker entry
├── durable-objects/        # Durable Object classes
└── lib/

Packages

packages/shared (@xtablo/shared)

Public surface via packages/shared/src/index.ts.

packages/shared/src/
├── index.ts                # Barrel
├── contexts/
│   ├── SessionContext.tsx  # Supabase session listener
│   └── ThemeContext.tsx
├── hooks/
│   ├── auth.ts             # useSignIn / useSignOut / useSession ...
│   ├── book.ts             # Booking hooks
│   ├── public.ts           # Public data hooks
│   └── useClickOutside.ts
├── lib/
│   ├── api.ts              # HTTP client w/ Bearer token
│   ├── supabase.ts         # Supabase JS client
│   ├── toast.ts            # toast.add() wrapper (sonner)
│   └── cn.ts               # clsx + tailwind-merge
├── types/                  # Re-exported domain types
└── utils/
    └── helpers.ts

packages/ui (@xtablo/ui)

Radix UI + Tailwind component library. Source-only.

packages/ui/src/
├── components/             # button.tsx, dialog.tsx, select.tsx,
│                           # popover.tsx, tabs.tsx, dropdown-menu.tsx, ...
├── hooks/
└── styles/

packages/shared-types (@xtablo/shared-types)

Zero-dependency TypeScript types — safe to import from API and frontend.

packages/shared-types/src/
├── index.ts
├── database.types.ts       # Auto-generated by supabase gen types
├── tablos.types.ts
├── tablo-data.types.ts
├── events.types.ts
├── kanban.types.ts
├── stripe.types.ts
├── admin.types.ts
└── utils.ts

packages/auth-ui (@xtablo/auth-ui)

Auth screens shared between apps: AuthCardShell.tsx, AuthEmailPasswordForm.tsx, AuthInfoBanner.tsx.

packages/chat-ui (@xtablo/chat-ui)

Chat-specific UI (components/, hooks.ts, security.ts, types.ts, chat-ui.css).

packages/tablo-views (@xtablo/tablo-views)

Tablo detail sections and shell: TabloDetailsShell.tsx, TabloEventsSection.tsx, TabloFilesSection.tsx, TabloTasksSection.tsx, TabloDiscussionSection.tsx, TabloHeaderActions.tsx, EtapesSection.tsx, RoadmapSection.tsx, plus single-tablo/, components/, hooks/, styles/.

Naming Conventions

  • Modals: *Modal.tsx — e.g. apps/main/src/components/CreateTabloModal.tsx, EventDetailsModal.tsx.
  • Sections: *Section.tsx — e.g. packages/tablo-views/src/TabloFilesSection.tsx.
  • Cards: *Card.tsx — e.g. apps/main/src/components/EventTypeCard.tsx, AvailabilityCard.tsx.
  • Pages: live in apps/<app>/src/pages/, lowercased file names matching the route (planning.tsx, events.tsx, login.tsx).
  • Tests: co-located as *.test.tsx / *.test.ts next to the source (AvailabilityCard.test.tsx, auth.signup.test.ts).
  • Hooks: lowercase domain file in hooks/ (tablos.ts, events.ts, tasks.ts); each exports multiple named hooks.
  • UI primitives: lowercase in packages/ui/src/components/ (button.tsx, select.tsx).

Key File Locations (Cheatsheet)

Concern Path
Main app routes (protected) apps/main/src/lib/routes.tsx
Main app public routes apps/main/src/lib/publicRoutes.tsx
External app routes apps/external/src/routes.tsx
Clients app routes apps/clients/src/routes.tsx
Admin app routes apps/admin/src/routes.tsx
Session context packages/shared/src/contexts/SessionContext.tsx
User store (Zustand) apps/main/src/providers/UserStoreProvider.tsx
HTTP API client packages/shared/src/lib/api.ts
Supabase client (browser) packages/shared/src/lib/supabase.ts
API entry apps/api/src/index.ts
API router composition apps/api/src/routers/index.ts
API middleware singleton apps/api/src/middlewares/middleware.ts
API config apps/api/src/config.ts
API secrets loader apps/api/src/secrets.ts
Auto-generated DB types packages/shared-types/src/database.types.ts
Shared barrel export packages/shared/src/index.ts
UI component barrel packages/ui/src/components/index.ts
Turborepo pipeline turbo.json
Workspace definition pnpm-workspace.yaml
Root Claude guidance CLAUDE.md

Adding New Features (5-Step Flow)

From CLAUDE.md, the canonical workflow for a new feature is:

  1. Define types in packages/shared-types/src/ (or run npx supabase gen types typescript > packages/shared-types/src/database.types.ts if you changed the DB schema).
  2. Add API endpoint in apps/api/src/routers/ — pick the right router (public.ts, maybeAuthRouter.ts, authRouter.ts, or a domain router like tasks.ts). Mount it in apps/api/src/routers/index.ts if it's new.
  3. Create a React Query hook in either packages/shared/src/hooks/ (cross-app) or apps/main/src/hooks/ (app-local). Use the hierarchical query-key convention so mutations can invalidate predictably.
  4. Build the UI using primitives from @xtablo/ui and patterns from @xtablo/tablo-views / @xtablo/chat-ui where applicable. Follow the *Modal.tsx / *Section.tsx / *Card.tsx naming convention and co-locate a *.test.tsx.
  5. Wire the route in apps/main/src/lib/routes.tsx (or the equivalent in the relevant app) so the new page is reachable.

Testing Locations

  • API tests: apps/api/src/__tests__/ (Vitest, mock Supabase).
  • Frontend tests: co-located *.test.tsx next to source, run via pnpm test per app (apps/main/src/setupTests.ts configures happy-dom + Testing Library).
  • Docs on testing: docs/API_TESTS.md, docs/MIDDLEWARE_TESTS.md.

Documentation Index (in docs/)

  • DEVELOPMENT.md — broad dev guide.
  • API_*.md — API testing and integration.
  • STRIPE_*.md — Stripe integration deep-dives.
  • AUTH_*.md — Authentication patterns.
  • DOCKER_*.md — Docker build optimization.
  • CLOUD_BUILD_*.md — GCP Cloud Build setup.