Convert Beenvoice to a Turborepo monorepo

This commit is contained in:
2026-08-16 22:13:42 -04:00
parent d057ba208d
commit 6c74436092
54 changed files with 4140 additions and 4147 deletions
+57 -71
View File
@@ -1,95 +1,81 @@
# beenvoice workspace
# beenvoice
Local development layout for the **beenvoice** product: a freelancer/small-business invoicing platform with a Next.js web app and an Expo mobile companion.
Beenvoice is a freelancer and small-business invoicing platform with a Next.js web application/API and an Expo mobile companion. The repository is a Bun workspace orchestrated by Turborepo.
```
beenvoice-meta/
├── beenvoice-web/ # Web API + dashboard (Next.js 16, tRPC, PostgreSQL)
├── beenvoice-app/ # Mobile app (Expo, React Native, dev client)
── beenvoice.icon/ # iOS app icon asset (icon composer)
## Workspace map
```text
beenvoice/
── apps/
│ ├── web/ # Next.js dashboard, tRPC API, PostgreSQL/Drizzle
│ └── mobile/ # Expo Router mobile app and iOS widgets
├── packages/
│ └── domain/ # Platform-neutral shared rules and parsing
├── Dockerfile
├── docker-compose*.yml
├── package.json
└── turbo.json
```
Each subdirectory is its own git repository. This folder is a convenience layout for working on both clients against one API.
The mobile app consumes the same tRPC API and Better Auth sessions as the web app. It imports the server router type at compile time, while runtime-safe shared behavior lives in `@beenvoice/domain`.
| Repo | Remote |
|------|--------|
| Web | [git.soconnor.dev/soconnor/beenvoice-web](https://git.soconnor.dev/soconnor/beenvoice-web) |
| Mobile | [git.soconnor.dev/soconnor/beenvoice-app](https://git.soconnor.dev/soconnor/beenvoice-app) |
## Quick start (full stack)
## Quick start
```bash
# 1. API + database
cd beenvoice-web
cp .env.example .env.local # edit DATABASE_URL, AUTH_SECRET, etc.
docker compose -f docker-compose.dev.yml up -d
bun install && bun run db:push
bun run dev # http://localhost:3000
# 2. Mobile (simulator)
cd ../beenvoice-app
cp .env.example .env # EXPO_PUBLIC_API_URL=http://localhost:3000
bun install
bun run ios # Metro on :8082, native dev build
cp apps/web/.env.example apps/web/.env.local
cp apps/mobile/.env.example apps/mobile/.env
bun run --filter @beenvoice/web docker:up
bun run --filter @beenvoice/web db:push
bun run dev
```
Physical iPhone: set `EXPO_PUBLIC_API_URL` to your Mac's LAN IP; ensure `beenvoice-web` has `BETTER_AUTH_URL` matching a host the device can reach (trusted origins are derived from `BETTER_AUTH_URL` / `NEXT_PUBLIC_APP_URL`).
`bun run dev` starts Next.js on port 3000 and Expo Metro on port 8082. For a physical iPhone, set `EXPO_PUBLIC_API_URL` in `apps/mobile/.env` to a host the device can reach and configure the web app's canonical/auth URLs consistently.
## Production deploy (Docker)
From `beenvoice-web` with `.env` configured (see [beenvoice-web/README.md](./beenvoice-web/README.md#docker-deployment-app--database)):
Useful workspace commands:
```bash
cd beenvoice-web
git pull
./scripts/docker-deploy.sh # rebuild app image + restart (not docker-compose.dev.yml)
bun run typecheck
bun run lint
bun run test
bun run build
bun run check
```
Plain `docker compose up -d` without `--build` reuses the existing local image and will not pick up code from `git pull`.
Run an app-specific command with a workspace filter:
## How the pieces connect
```bash
bun run --filter @beenvoice/web db:migrate
bun run --filter @beenvoice/mobile ios
bun run --filter @beenvoice/mobile ios:release:upload
```
| Layer | Repo | Transport | Auth |
|-------|------|-----------|------|
| Web UI | `beenvoice-web` | tRPC `/api/trpc` (cookies) | better-auth session |
| Mobile UI | `beenvoice-app` | tRPC `/api/trpc` (cookie header) | better-auth + `@better-auth/expo` → SecureStore |
| Automation | `beenvoice-web` MCP `/api/mcp` | JSON-RPC | API key (`bv_…`) only |
| Public invoices | `beenvoice-web` `/i/[token]` | HTTP | unauthenticated token |
## Production Docker deployment
Mobile imports **tRPC router types** from `beenvoice-web/src/server/api/root` via `tsconfig` path mapping — keep API changes type-checked in both repos.
Keep production web configuration in `apps/web/.env`, then run from the repository root:
## Documentation map
```bash
git pull
./scripts/docker-deploy.sh
```
| Doc | Contents |
|-----|----------|
| [beenvoice-web/README.md](./beenvoice-web/README.md) | Web setup, Docker deploy, scripts |
| [beenvoice-web/docs/ARCHITECTURE.md](./beenvoice-web/docs/ARCHITECTURE.md) | Server architecture (dense) |
| [beenvoice-app/README.md](./beenvoice-app/README.md) | Mobile setup, troubleshooting |
| [beenvoice-app/docs/ARCHITECTURE.md](./beenvoice-app/docs/ARCHITECTURE.md) | Mobile architecture (dense) |
| [beenvoice-web/docs/](./beenvoice-web/docs/) | UI guides (forms, tables, breadcrumbs, email) |
The root Dockerfile installs the frozen Bun workspace lockfile, builds the Next.js app under Node, and runs migrations plus the web server under Bun.
## Shared domain concepts
## Documentation
- **Clients** — billable contacts with optional default hourly rate
- **Businesses** — sender profiles (logo, address, Resend email config)
- **Invoices** — draft → sent → paid; line items; PDF + email; public share token
- **Time entries** — clock in/out; one running timer per user; auto-attach to open invoice
- **Recurring invoices**, **expenses**, **payments**, **templates** — full web support; mobile covers a core CRUD subset
- [Web setup](./apps/web/README.md)
- [Web architecture](./apps/web/docs/ARCHITECTURE.md)
- [Mobile setup](./apps/mobile/README.md)
- [Mobile architecture](./apps/mobile/docs/ARCHITECTURE.md)
- [Shared domain package](./packages/domain/README.md)
## Environment cheat sheet
## Product concepts
| Variable | Where | Purpose |
|----------|-------|---------|
| `DATABASE_URL` | beenvoice-web | PostgreSQL |
| `AUTH_SECRET`, `BETTER_AUTH_URL` | beenvoice-web | better-auth |
| `EXPO_PUBLIC_API_URL` | beenvoice-app | API base for mobile |
| `DISABLE_SIGNUPS` | beenvoice-web | `true` blocks new registrations |
| `RESEND_*` | beenvoice-web | Invoice / reset email |
## Ports
| Service | Default port |
|---------|----------------|
| Next.js (beenvoice-web) | 3000 |
| Postgres (dev compose) | 5432 |
| Metro (beenvoice-app) | **8082** (intentionally not 8081) |
- Clients with optional default hourly rates
- Businesses and sender branding
- Draft, sent, paid, and overdue invoices
- Time tracking and invoice attachment
- Recurring invoices, expenses, payments, and templates
- Public invoice links and API-key-authenticated automation