mirror of
https://github.com/vee1e/workorder-desk.git
synced 2026-09-01 09:50:13 +00:00
chore(monorepo): scaffold npm workspaces and tooling
This commit is contained in:
commit
99458eb562
8 changed files with 9397 additions and 0 deletions
83
.env.example
Normal file
83
.env.example
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
# ─────────────────────────────────────────────────────────────────────────────
|
||||||
|
# Field Service Work Order Management — environment template
|
||||||
|
#
|
||||||
|
# Copy to `.env` and fill in real values:
|
||||||
|
# cp .env.example .env
|
||||||
|
# NEVER commit `.env`. Real secrets must never be committed to the repo.
|
||||||
|
# ─────────────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
# ── HTTP / runtime ────────────────────────────────────────────────────────────
|
||||||
|
# Port the Express API listens on (default 4000).
|
||||||
|
PORT=4000
|
||||||
|
|
||||||
|
# development | test | production
|
||||||
|
NODE_ENV=development
|
||||||
|
|
||||||
|
# ── Database ──────────────────────────────────────────────────────────────────
|
||||||
|
# MongoDB connection string (required).
|
||||||
|
MONGODB_URI=mongodb://127.0.0.1:27017/workorders
|
||||||
|
|
||||||
|
# ── Secrets (REQUIRED) ────────────────────────────────────────────────────────
|
||||||
|
# HS256 signing secret for the 15-minute access JWT.
|
||||||
|
# MUST be >= 32 characters and MUST NOT be a placeholder such as "secret",
|
||||||
|
# "changeme", or "replace-me". Rotating it invalidates issued access tokens.
|
||||||
|
JWT_SECRET=0123456789abcdef0123456789abcdef0123456789abcdef
|
||||||
|
|
||||||
|
# Secret used by cookie-parser to sign cookie values (integrity only).
|
||||||
|
# MUST be >= 32 characters. It is NOT authentication.
|
||||||
|
COOKIE_SECRET=fedcba9876543210fedcba9876543210fedcba9876543210
|
||||||
|
|
||||||
|
# NOTE: JWT_SECRET and COOKIE_SECRET must each be at least 32 characters and
|
||||||
|
# must not be placeholder values. Generate real ones with:
|
||||||
|
# openssl rand -hex 32
|
||||||
|
# and never commit them to version control.
|
||||||
|
|
||||||
|
# ── CORS / URLs ───────────────────────────────────────────────────────────────
|
||||||
|
# Comma-separated list of allowed origins. `credentials: true` is set, so "*"
|
||||||
|
# is rejected. Same-origin deployments only need the SPA origin.
|
||||||
|
CORS_ORIGIN=http://localhost:5173
|
||||||
|
|
||||||
|
# Public SPA origin (used for password-reset links and cookie handling).
|
||||||
|
APP_URL=http://localhost:5173
|
||||||
|
|
||||||
|
# ── Mailer ────────────────────────────────────────────────────────────────────
|
||||||
|
# Resend API key (https://resend.com/docs/api-reference/emails/send).
|
||||||
|
# Leave empty to use the log-only mailer (logs a REDACTED reset URL).
|
||||||
|
RESEND_API_KEY=
|
||||||
|
# Verified sender. Defaults to Resend's shared onboarding@resend.dev
|
||||||
|
# (only delivers to the account owner until you verify your own domain).
|
||||||
|
RESEND_FROM=
|
||||||
|
SMTP_URL=smtp://user:pass@localhost:1025
|
||||||
|
|
||||||
|
# ── Proxy / observability ─────────────────────────────────────────────────────
|
||||||
|
# Number of trusted reverse-proxy hops. nginx sets X-Forwarded-* in prod;
|
||||||
|
# keep 0 when the API is reached directly (local dev).
|
||||||
|
TRUST_PROXY_HOPS=0
|
||||||
|
|
||||||
|
# Set to true to return stack traces in 500 responses (dev only, never prod).
|
||||||
|
DEBUG_ERRORS=false
|
||||||
|
|
||||||
|
# pino log level: trace | debug | info | warn | error | fatal
|
||||||
|
LOG_LEVEL=info
|
||||||
|
|
||||||
|
# ── Rate limiting (window in ms, max requests per key) ────────────────────────
|
||||||
|
RATE_LIMIT_WINDOW_MS=60000
|
||||||
|
RATE_LIMIT_MAX=300
|
||||||
|
RATE_LIMIT_LOGIN_MAX=10
|
||||||
|
RATE_LIMIT_FORGOT_MAX=3
|
||||||
|
|
||||||
|
# ── Seed credentials (`npm run seed`, idempotent) ─────────────────────────────
|
||||||
|
SEED_ADMIN_EMAIL=admin@example.com
|
||||||
|
SEED_ADMIN_PASSWORD=Admin1234
|
||||||
|
SEED_USER_EMAIL=user@example.com
|
||||||
|
SEED_USER_PASSWORD=User1234
|
||||||
|
SEED_VIEWER_EMAIL=viewer@example.com
|
||||||
|
SEED_VIEWER_PASSWORD=Viewer1234
|
||||||
|
|
||||||
|
# ── Frontend (Vite, consumed at build time) ───────────────────────────────────
|
||||||
|
# Must match APP_URL.
|
||||||
|
VITE_APP_URL=http://localhost:5173
|
||||||
|
|
||||||
|
# Empty in dev → relative `/api/v1`, proxied by Vite (dev) or nginx (prod).
|
||||||
|
# Set to the API origin only for a split-origin deployment.
|
||||||
|
VITE_API_URL=
|
||||||
13
.gitignore
vendored
Normal file
13
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
node_modules/
|
||||||
|
dist/
|
||||||
|
coverage/
|
||||||
|
*.log
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
!.env.example
|
||||||
|
.DS_Store
|
||||||
|
yarn.lock
|
||||||
|
pnpm-lock.yaml
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
.vercel
|
||||||
1
.nvmrc
Normal file
1
.nvmrc
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
20
|
||||||
15
eslint.config.js
Normal file
15
eslint.config.js
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
const js = require('@eslint/js');
|
||||||
|
const tseslint = require('typescript-eslint');
|
||||||
|
const prettier = require('eslint-config-prettier');
|
||||||
|
|
||||||
|
module.exports = tseslint.config(
|
||||||
|
{ ignores: ['**/dist/**', '**/node_modules/**', '**/coverage/**'] },
|
||||||
|
js.configs.recommended,
|
||||||
|
...tseslint.configs.recommended,
|
||||||
|
prettier,
|
||||||
|
{
|
||||||
|
rules: {
|
||||||
|
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
9225
package-lock.json
generated
Normal file
9225
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
35
package.json
Normal file
35
package.json
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
{
|
||||||
|
"name": "mern-starter-app",
|
||||||
|
"version": "1.2.0",
|
||||||
|
"private": true,
|
||||||
|
"description": "Field Service Work Order Management — production-oriented MERN monorepo",
|
||||||
|
"workspaces": [
|
||||||
|
"packages/shared",
|
||||||
|
"backend",
|
||||||
|
"frontend"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@eslint/js": "^9.9.0",
|
||||||
|
"eslint": "^9.9.0",
|
||||||
|
"eslint-config-prettier": "^9.1.0",
|
||||||
|
"prettier": "^3.3.3",
|
||||||
|
"typescript-eslint": "^8.3.0"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "npm run build -w @workorders/shared && npm run build -w backend && npm run build -w frontend",
|
||||||
|
"dev": "npm run dev -w backend & npm run dev -w frontend & wait",
|
||||||
|
"lint": "npm run lint -w @workorders/shared && npm run lint -w backend && npm run lint -w frontend",
|
||||||
|
"typecheck": "npm run typecheck -w @workorders/shared && npm run typecheck -w backend && npm run typecheck -w frontend",
|
||||||
|
"test": "npm run test -w @workorders/shared && npm run test -w backend && npm run test -w frontend",
|
||||||
|
"seed": "npm run seed -w backend"
|
||||||
|
},
|
||||||
|
"allowScripts": {
|
||||||
|
"mongodb-memory-server": true,
|
||||||
|
"esbuild@0.28.2": true,
|
||||||
|
"esbuild@0.21.5": true,
|
||||||
|
"express-rate-limit": true
|
||||||
|
}
|
||||||
|
}
|
||||||
8
prettier.config.js
Normal file
8
prettier.config.js
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
/** @type {import('prettier').Config} */
|
||||||
|
module.exports = {
|
||||||
|
singleQuote: true,
|
||||||
|
trailingComma: 'all',
|
||||||
|
printWidth: 100,
|
||||||
|
semi: true,
|
||||||
|
tabWidth: 2,
|
||||||
|
};
|
||||||
17
tsconfig.base.json
Normal file
17
tsconfig.base.json
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES2022",
|
||||||
|
"module": "NodeNext",
|
||||||
|
"moduleResolution": "NodeNext",
|
||||||
|
"lib": ["ES2022"],
|
||||||
|
"strict": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"declaration": true,
|
||||||
|
"sourceMap": true,
|
||||||
|
"noUncheckedIndexedAccess": true,
|
||||||
|
"noFallthroughCasesInSwitch": true
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue