gitignore + readme
This commit is contained in:
commit
33789b13d1
52
.gitignore
vendored
Normal file
52
.gitignore
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
# dependencies
|
||||
node_modules/
|
||||
.pnpm-store/
|
||||
|
||||
# build output
|
||||
dist/
|
||||
build/
|
||||
out/
|
||||
.next/
|
||||
.turbo/
|
||||
*.tsbuildinfo
|
||||
next-env.d.ts
|
||||
|
||||
# environment
|
||||
.env
|
||||
.env.local
|
||||
.env.*.local
|
||||
!.env.example
|
||||
|
||||
# logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
# testing
|
||||
coverage/
|
||||
playwright-report/
|
||||
playwright/.cache/
|
||||
test-results/
|
||||
.playwright/
|
||||
|
||||
# editor
|
||||
.vscode/
|
||||
!.vscode/extensions.json
|
||||
!.vscode/settings.json.example
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Prisma
|
||||
packages/db/prisma/*.db
|
||||
packages/db/prisma/*.db-journal
|
||||
|
||||
# misc
|
||||
*.pem
|
||||
.cache/
|
||||
172
README.md
Normal file
172
README.md
Normal file
@ -0,0 +1,172 @@
|
||||
# FieldOps
|
||||
|
||||
Modular industrial SaaS monorepo. **This is the scaffold phase** — no business
|
||||
features yet. The goal of this branch is to prove the end-to-end wiring:
|
||||
client → tRPC → Prisma → Postgres, with multi-tenancy enforced from day zero.
|
||||
|
||||
## What's here
|
||||
|
||||
```
|
||||
apps/
|
||||
operator-pwa/ Next 15 — operator console (port 3000)
|
||||
admin-web/ Next 15 — backoffice placeholder (port 3001)
|
||||
packages/
|
||||
db/ Prisma 6 schema + tenant-scoping extension
|
||||
api/ tRPC v11 routers
|
||||
ui/ Shared shadcn-style components
|
||||
domain/ Pure domain logic (empty in this phase)
|
||||
config/ tsconfig / eslint / tailwind presets
|
||||
e2e/ Playwright smoke test
|
||||
```
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- **Node.js 22+** (use `nvm use` or install matching `.nvmrc`)
|
||||
- **pnpm 11+** (`corepack enable pnpm` or `npm i -g pnpm`)
|
||||
- **Docker Desktop** with the engine running (provides Postgres)
|
||||
- **Git**
|
||||
|
||||
## From-zero setup
|
||||
|
||||
These steps assume a fresh clone with no `node_modules`, no Docker volumes,
|
||||
no `.env`. Run them in order from the repo root.
|
||||
|
||||
```sh
|
||||
# 1. environment
|
||||
cp .env.example .env
|
||||
# Open .env and set AUTH_DEV_AUTOLOGIN="true" for local development.
|
||||
# (Default is "false" on purpose — see "Auth" below.)
|
||||
|
||||
# 2. install
|
||||
pnpm install
|
||||
|
||||
# 3. start Postgres
|
||||
docker compose up -d
|
||||
|
||||
# 4. apply the schema
|
||||
pnpm db:migrate
|
||||
|
||||
# 5. seed the demo tenant
|
||||
pnpm db:seed
|
||||
|
||||
# 6. start the operator app
|
||||
pnpm --filter @repo/operator-pwa dev
|
||||
```
|
||||
|
||||
Open <http://localhost:3000> — you should see a **Connected** card with
|
||||
`Tenant: Demo Factory`.
|
||||
|
||||
### Run the E2E
|
||||
|
||||
In a separate shell (with the dev server NOT running, or with
|
||||
`reuseExistingServer` left on — Playwright handles either):
|
||||
|
||||
```sh
|
||||
pnpm --filter @repo/e2e install-browsers # one-time, downloads Chromium
|
||||
pnpm test:e2e
|
||||
```
|
||||
|
||||
The Playwright config force-sets `AUTH_DEV_AUTOLOGIN=true` for the dev server
|
||||
it launches, so the test does not depend on the developer's `.env`.
|
||||
|
||||
## Auth
|
||||
|
||||
This scaffold has **no real authentication**. Auth.js v5 is wired up with a
|
||||
single Credentials provider that accepts any email present in the seeded
|
||||
`User` table — no password check.
|
||||
|
||||
The `AUTH_DEV_AUTOLOGIN` env flag controls a server-side fallback:
|
||||
|
||||
- **`AUTH_DEV_AUTOLOGIN=false`** (default in `.env.example`) — requests with
|
||||
no Auth.js session are unauthenticated. `protectedProcedure` returns 401.
|
||||
- **`AUTH_DEV_AUTOLOGIN=true`** — requests with no session silently resolve
|
||||
to the seeded `admin@demo.local` user, skipping the login UI.
|
||||
|
||||
> ⚠️ **Never set `AUTH_DEV_AUTOLOGIN=true` in production.** The fallback is a
|
||||
> back door intended only for local dev and CI. The chokepoint is
|
||||
> `apps/operator-pwa/lib/auth.ts → resolveUser()`. Replace it with real
|
||||
> authentication before any non-dev deployment.
|
||||
|
||||
## Multi-tenancy
|
||||
|
||||
Every Prisma model except `Tenant` has a `tenantId` column. Tenant scoping is
|
||||
enforced at runtime by an extension in
|
||||
`packages/db/src/tenant-extension.ts` — read the header comment in that file
|
||||
for the full list of operations it covers and the operations it does **not**
|
||||
(`$queryRaw`, interactive `$transaction` with external clients, etc.).
|
||||
|
||||
Call sites get the scoped client from the tRPC context: `ctx.db.*`. The
|
||||
unscoped root client (`ctx.prisma`) is available for the rare cross-tenant
|
||||
case but should be a red flag at PR review.
|
||||
|
||||
## tRPC
|
||||
|
||||
The operator app uses both tRPC paths:
|
||||
|
||||
- **RSC caller** — `apps/operator-pwa/lib/trpc/server.ts` — direct in-process
|
||||
invocation from Server Components. Default for reads.
|
||||
- **Client hooks** — `apps/operator-pwa/lib/trpc/client.ts` —
|
||||
`@trpc/react-query` against `/api/trpc`. Default for mutations and
|
||||
client-rendered reads.
|
||||
|
||||
The home page exercises both: the `Connected` card is rendered server-side;
|
||||
the `Client-side ping` card uses `useQuery`. Both must succeed for the
|
||||
hybrid wiring to be considered green.
|
||||
|
||||
## Common commands
|
||||
|
||||
| Command | What it does |
|
||||
| --- | --- |
|
||||
| `pnpm install` | Install all workspace deps |
|
||||
| `docker compose up -d` | Start Postgres |
|
||||
| `docker compose down` | Stop Postgres (data persists) |
|
||||
| `docker compose down -v` | Stop Postgres **and drop the volume** |
|
||||
| `pnpm dev` | Run all dev tasks via Turbo |
|
||||
| `pnpm --filter @repo/operator-pwa dev` | Operator app only |
|
||||
| `pnpm --filter @repo/admin-web dev` | Admin app only (port 3001) |
|
||||
| `pnpm db:migrate` | Apply pending Prisma migrations |
|
||||
| `pnpm db:reset` | Drop, recreate, migrate, seed |
|
||||
| `pnpm db:seed` | Re-seed the demo tenant (idempotent) |
|
||||
| `pnpm db:studio` | Open Prisma Studio |
|
||||
| `pnpm typecheck` | Typecheck every package |
|
||||
| `pnpm test:e2e` | Run Playwright |
|
||||
| `pnpm format` | Prettier write |
|
||||
|
||||
## Versions of note
|
||||
|
||||
| Package | Version | Why |
|
||||
| --- | --- | --- |
|
||||
| Node | 22 LTS | Required by Next 15 |
|
||||
| pnpm | 11 | Workspace + `allowBuilds` security feature |
|
||||
| Next.js | 15 | App Router, React 19 |
|
||||
| React | 19 | |
|
||||
| Prisma | 6 | Kept on 6.x — Prisma 7 mandates the new `prisma-client` ESM generator, which is a separate migration |
|
||||
| Auth.js (next-auth) | 5.0 beta | v5 split-config pattern (edge-safe middleware + Node providers) |
|
||||
| tRPC | 11 | Stable on the v11 series |
|
||||
| Tailwind | 3 | Conservative choice; v4 swap is a separate spike |
|
||||
| shadcn/ui | components inlined | Not the CLI scaffold — components live in `packages/ui/src/components` |
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**`ERR_PNPM_IGNORED_BUILDS` after adding a dep** — pnpm 11 blocks postinstall
|
||||
scripts unless approved. Edit `pnpm-workspace.yaml` `allowBuilds:` and set
|
||||
the offending package to `true` (or `false` if you don't want its
|
||||
postinstall to run).
|
||||
|
||||
**Page loads but says `UNAUTHORIZED`** — your `.env` has
|
||||
`AUTH_DEV_AUTOLOGIN=false` (the default). Flip it to `true` for local dev,
|
||||
or sign in through Auth.js.
|
||||
|
||||
**Page errors with `Tenant not found`** — the seeded tenant was wiped.
|
||||
Run `pnpm db:seed` again.
|
||||
|
||||
**Migration fails with `Environment variable not found: DATABASE_URL`** —
|
||||
make sure `.env` exists at the repo root and Docker Postgres is running.
|
||||
|
||||
**Playwright complains the port is busy** — kill any leftover dev servers:
|
||||
on Windows `Get-Process node | Stop-Process -Force`; macOS/Linux
|
||||
`pkill -f 'next dev'`.
|
||||
|
||||
## License
|
||||
|
||||
Internal. All rights reserved.
|
||||
Loading…
x
Reference in New Issue
Block a user