Files
sar/nx.json
julian a1a852c44d feat(c6): notificações e push — Web Push VAPID, badge dinâmico, Share API
FR-6.1/6.2: Sandra recebe push quando pedido entra em pending_approval;
Rafael recebe quando pedido é aprovado ou recusado. Service worker registrado
em background (PWA-ready via public/sw.js).

FR-6.3: Badge na Topbar busca GET /notifications/pending-count (supervisores
veem count de pending_approval; reps veem 0). Intervalo de 30s.

FR-6.4: Botão Compartilhar no OrderDetailPage para pedidos approved/invoiced
(apenas reps). Usa navigator.share() com texto formatado para WhatsApp.

Infra: modelo PushSubscription (Prisma), NotificationsModule (subscribe/
unsubscribe/pending-count + PushService VAPID), VAPID keys em .env,
integração no OrdersService (create → supervisores, approve/reject → repId).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-28 12:31:13 +00:00

122 lines
3.0 KiB
JSON

{
"$schema": "./node_modules/nx/schemas/nx-schema.json",
"namedInputs": {
"default": ["{projectRoot}/**/*", "sharedGlobals"],
"production": [
"default",
"!{projectRoot}/.eslintrc.json",
"!{projectRoot}/eslint.config.{js,cjs,mjs,ts}",
"!{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)?(.snap)",
"!{projectRoot}/tsconfig.spec.json",
"!{projectRoot}/jest.config.[jt]s",
"!{projectRoot}/vitest.config.[jt]s",
"!{projectRoot}/src/test-setup.[jt]s",
"!{projectRoot}/test-setup.[jt]s",
"!{projectRoot}/eslint.config.mjs"
],
"sharedGlobals": ["{workspaceRoot}/tsconfig.base.json", "{workspaceRoot}/.prettierrc.json"]
},
"targetDefaults": {
"build": {
"cache": true,
"dependsOn": ["^build"],
"inputs": ["production", "^production"]
},
"test": {
"cache": true,
"inputs": ["default", "^production"]
},
"lint": {
"cache": true,
"inputs": [
"default",
"{workspaceRoot}/.eslintrc.json",
"{workspaceRoot}/eslint.config.js",
"{workspaceRoot}/tools/eslint-rules/**/*"
]
},
"e2e": {
"cache": true,
"inputs": ["default", "^production"]
},
"@nx/js:tsc": {
"cache": true,
"dependsOn": ["^build"],
"inputs": ["production", "^production"]
}
},
"defaultBase": "main",
"plugins": [
{
"plugin": "@nx/webpack/plugin",
"options": {
"buildTargetName": "build",
"serveTargetName": "serve",
"previewTargetName": "preview",
"buildDepsTargetName": "build-deps",
"watchDepsTargetName": "watch-deps",
"serveStaticTargetName": "serve-static"
}
},
{
"plugin": "@nx/eslint/plugin",
"options": {
"targetName": "lint"
}
},
{
"plugin": "@nx/jest/plugin",
"options": {
"targetName": "test"
},
"exclude": ["apps/api-e2e/**/*"]
},
{
"plugin": "@nx/vite/plugin",
"options": {
"buildTargetName": "build",
"testTargetName": "test",
"serveTargetName": "serve",
"devTargetName": "dev",
"previewTargetName": "preview",
"serveStaticTargetName": "serve-static",
"typecheckTargetName": "typecheck",
"buildDepsTargetName": "build-deps",
"watchDepsTargetName": "watch-deps"
}
},
{
"plugin": "@nx/vitest",
"options": {
"testTargetName": "test",
"ciTargetName": "test-ci",
"testMode": "watch"
}
},
{
"plugin": "@nx/playwright/plugin",
"options": {
"targetName": "e2e"
}
}
],
"generators": {
"@nx/react": {
"application": {
"babel": true,
"style": "css",
"linter": "eslint",
"bundler": "vite"
},
"component": {
"style": "css"
},
"library": {
"style": "css",
"linter": "eslint"
}
}
},
"analytics": true
}