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