Convert Beenvoice to a Turborepo monorepo
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user