Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Netlify Status Netlify Status

Alexa Lashes

A Turborepo/Bun monorepo for Alexa Lashes, a lash studio business: a public marketing site and an internal admin app, backed by a shared Postgres (Neon) database via Drizzle ORM and Better Auth.

Apps & packages

Apps

  • apps/marketing — public site. React 19 + TanStack Start (file-based routing, SSR) + Vite + Tailwind CSS v4, i18n via Paraglide JS (sk base locale, en/ru prefixed), deployed to Netlify. Reviews are fetched from the DB at build time (bun run generate-reviews) and baked into a static JSON file — not fetched per request.
  • apps/admin — internal admin dashboard (SPA). Same stack, Google OAuth via Better Auth, gated by an allow-list (allowed_email table) — no self-service signup. Currently manages customer reviews (list per locale, create/edit/delete, enable/disable, drag-and-drop reordering) and has a "Deploy marketing site" button to trigger a Netlify rebuild, since marketing's reviews are static at build time (see above). Deployed to Netlify.

Packages

  • packages/db — Drizzle schema (reviews, review_translations, allowed_email, Better Auth's own tables), query functions, and the shared db client (drizzle-orm/neon-http against Neon serverless Postgres).
  • packages/auth — shared Better Auth instance/config, server helpers (getSession, ensureSession) and client helpers (signIn, signOut, ...) for the admin app.
  • packages/ui — shared React components: custom components, shadcn/ui wrappers (built on Base UI), Lucide icons, and the single Tailwind entry (styles.css) both apps import.
  • packages/contracts — hand-written Zod schemas for API/DB input shapes (e.g. createReviewSchema/updateReviewSchema) and their inferred TypeScript types — the single source of truth for validation, shared by packages/db's query layer and the admin app's server functions.
  • packages/types — small, dependency-free shared primitives (currently locales/baseLocale/ Locale) used across packages without creating circular package dependencies.

Tech stack

There is no test suite/framework configured in this repo (no vitest/jest/playwright).

Getting started

Requires Bun 1.3.14 (see mise.toml if you use mise).

bun install

Create a .env file at the repo root (see Environment variables below), then:

bun run dev      # runs all apps in dev mode (marketing + admin on port 3000)
bun run build    # builds all apps/packages, respecting the dependency graph

Scope a command to a single app/package with Turborepo's --filter:

bun run dev --filter=alexa-lashes/admin
bun run build --filter=alexa-lashes/admin

Other root scripts:

bun run lint            # oxlint
bun run format          # oxfmt --check
bun run format:write    # oxfmt (fixes in place)
bun run clean           # remove build outputs, node_modules, and the lockfile everywhere

packages/db has its own scripts (run from packages/db, needs packages/db/.env):

bun run db:generate          # generate a Drizzle migration from schema changes
bun run db:push              # push schema directly to the DB
bun run db:studio            # open Drizzle Studio
bun run better-auth:generate # regenerate auth-schema.ts from packages/auth's config
bun run seed:email           # seed the allowed_email table
bun run seed:review          # seed a sample review

Environment variables

Root .env (loaded via bun --env-file=../../.env) and packages/db/.env (for Drizzle CLI commands run from that package):

  • DATABASE_URL
  • BETTER_AUTH_URL
  • BETTER_AUTH_SECRET
  • GOOGLE_CLIENT_ID
  • GOOGLE_CLIENT_SECRET
  • EMAIL_ADDRESS
  • EMAIL_PASSWORD
  • VITE_GOOGLE_MAPS_API_KEY
  • VITE_GOOGLE_ANALYTICS_API_KEY
  • NETLIFY_MARKETING_BUILD_HOOK_URL — a Netlify build hook URL for the apps/marketing site (site settings → Build hooks there). apps/marketing fetches its reviews from the DB at build time, not at request time, so adding/editing a review in the admin app doesn't go live until this is triggered. The admin dashboard has a "Deploy marketing site" button that posts to it. For production, set this var on the admin Netlify site (not the marketing one).

Branching & deployment

  • Branch names: <type>/<short-description> (e.g. fix/dashboard), same types as commits (below).
  • Deployment is fully automatic via Netlify, no manual/CI deploy step:
    • Pushing to any remote branch triggers a Netlify branch deploy (preview) for both apps.
    • Merging a PR into main triggers a Netlify production deploy for both apps immediately.
  • .github/workflows/codeql.yml runs CodeQL security analysis on push/PR to main and weekly. There is no CI workflow for build/lint/test — those run locally via git hooks.

Commit messages

Enforced by commitlint (lefthook commit-msg hook) — Conventional Commits, restricted to: build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test. Example: feat: added new feature [TICKET-ID].

pre-commit runs oxfmt --fix and oxlint --fix against staged files automatically.

More details

See CLAUDE.md for a deeper architecture walkthrough (server-function/query layer conventions, auth flow, i18n locale strategy, and coding conventions).

This repo also uses Claude Code skills for common workflows (.claude/skills/) — check that directory for the current list, as it grows over time.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages