{ "phase": "master-task-backlog-phase3.3-finalized", "repositoryHead": "715873b2ecc3a72ba974bb2a2be87c5ba82bd4e7", "canonicalFindingsSource": "docs/audit/20-verified-findings-index.json", "architectureSplit": { "storefront": "Next.js (SSR / SEO capabilities)", "adminPanel": "Standalone React SPA (Security, Performance, Lazy Loading)" }, "counts": { "totalVerifiedFindings": 14, "totalImplementationTasks": 9, "totalVerificationTasks": 1, "totalProductDecisions": 2, "totalFutureScopeItems": 1, "byPriority": { "P0": 4, "P1": 3, "P2": 2, "P3": 1 } }, "tasks": [ { "taskId": "TASK-SEC-001", "title": "Mandatory Dual-Secret Startup Enforcement (JWT_ACCESS_SECRET & JWT_REFRESH_SECRET)", "status": "READY_FOR_IMPLEMENTATION", "priority": "P0", "severity": "HIGH", "category": "Security / Cryptographic Hardening", "type": "IMPLEMENTATION", "sourceFindings": ["SEC-001"], "objective": "Ensure NestJS application fails startup (process.exit(1)) if EITHER JWT_ACCESS_SECRET OR JWT_REFRESH_SECRET is missing, empty, or less than 32 characters.", "rootCauseAddressed": "Developer fallback string embedded in jwt.strategy.ts and auth.module.ts instead of validating environment variables during startup.", "currentState": "jwt.strategy.ts line 12 uses secretOrKey: process.env.JWT_SECRET || 'super-secret-key'.", "requiredChanges": [ "Remove fallback strings from jwt.strategy.ts and auth.module.ts.", "Implement bootstrap validation in main.ts checking both JWT_ACCESS_SECRET and JWT_REFRESH_SECRET length >= 32 chars before app.listen().", "Update .env.example with placeholders for both secrets." ], "affectedFiles": [ "backend/src/main.ts", "backend/src/auth/jwt.strategy.ts", "backend/src/auth/auth.module.ts", "backend/.env.example" ], "dependencies": [], "blockedBy": [], "riskAssessment": "LOW technical risk. Operational: Application fails on boot without both secrets set.", "testingRequirements": [ "Unit test verifying JwtStrategy throws when either secret is undefined.", "Integration test confirming application boots with both valid secrets." ], "validationCommands": [ "cd backend && npm run test -- backend/src/auth/jwt.strategy.spec.ts", "cd backend && cross-env JWT_ACCESS_SECRET= npm run start:dev" ], "acceptanceCriteria": [ "Zero occurrences of fallback secret strings in codebase.", "Backend startup terminates with process exit code 1 when either secret is missing or < 32 chars." ], "definitionOfDone": "Code updated, unit tests passing, dual-secret startup validation verified." }, { "taskId": "TASK-SEC-002", "title": "Cryptographically Secure OTP Generation & Response Payload Hardening", "status": "READY_FOR_IMPLEMENTATION", "priority": "P0", "severity": "HIGH", "category": "Security / Authentication Hardening", "type": "IMPLEMENTATION", "sourceFindings": ["SEC-002", "SEC-003"], "objective": "Re-engineer NestJS SMS OTP generation to use Node.js CSPRNG (crypto.randomInt), separate OTP generation from delivery via IOtpDeliveryService abstraction, and remove plaintext OTP code disclosure from public API response payloads.", "rootCauseAddressed": "Math.random() used for OTP code generation and AuthController returning code directly in JSON response payload.", "currentState": "AuthService uses Math.random() and sendOtp returns { success: true, code: '12345' }.", "requiredChanges": [ "Replace Math.random() with crypto.randomInt(10000, 100000).toString().", "Create IOtpDeliveryService token with ConsoleOtpDeliveryService and SmsGatewayOtpDeliveryService.", "Remove code property from return value of sendOtp in AuthService and AuthController." ], "affectedFiles": [ "backend/src/auth/auth.service.ts", "backend/src/auth/auth.controller.ts", "backend/src/auth/auth.service.spec.ts", "backend/src/auth/otp-delivery.service.ts" ], "dependencies": [], "blockedBy": [], "riskAssessment": "LOW risk. Highly isolated changes within AuthService.", "testingRequirements": [ "Unit test verifying CSPRNG usage via crypto.randomInt.", "Unit test asserting sendOtp response payload omits code property." ], "validationCommands": [ "cd backend && npm run test -- backend/src/auth/auth.service.spec.ts" ], "acceptanceCriteria": [ "sendOtp API response body strictly contains { success: boolean, message: string }.", "OTP generation relies on crypto.randomInt." ], "definitionOfDone": "CSPRNG integrated, response payload sanitized, unit tests passing." }, { "taskId": "TASK-SEC-003", "title": "Role-Based Access Control (RBAC) Enforcement on Administrative Settings API", "status": "READY_FOR_IMPLEMENTATION", "priority": "P0", "severity": "HIGH", "category": "Security / Authorization & Access Control", "type": "IMPLEMENTATION", "sourceFindings": ["ADM-001"], "objective": "Protect all administrative settings endpoints (/api/settings/*) with RolesGuard and @Roles('Admin') decorator.", "rootCauseAddressed": "SettingsController applied JwtAuthGuard without RolesGuard or Admin role check. RolesGuard and @Roles decorator missing from codebase.", "currentState": "SettingsController allows any authenticated user role to modify system settings.", "requiredChanges": [ "Create backend/src/common/decorators/roles.decorator.ts.", "Create backend/src/common/guards/roles.guard.ts using Reflector to validate req.user.role === 'Admin'.", "Apply @UseGuards(JwtAuthGuard, RolesGuard) and @Roles('Admin') to SettingsController." ], "affectedFiles": [ "backend/src/common/decorators/roles.decorator.ts", "backend/src/common/guards/roles.guard.ts", "backend/src/settings/settings.controller.ts", "backend/src/settings/settings.controller.spec.ts" ], "dependencies": [], "blockedBy": [], "riskAssessment": "LOW technical risk. Restricts administrative settings to authorized personnel.", "testingRequirements": [ "Unit test asserting 403 Forbidden for User_PetOwner token.", "Unit test asserting 200 OK for Admin token." ], "validationCommands": [ "cd backend && npm run test -- backend/src/settings/settings.controller.spec.ts" ], "acceptanceCriteria": [ "Non-admin JWT tokens receive 403 Forbidden on settings endpoints.", "Admin JWT tokens are authorized successfully." ], "definitionOfDone": "RBAC guards created and applied, unit tests passing." }, { "taskId": "TASK-FIN-001", "title": "Arbitrary-Precision Decimal Accounting & Prisma.Decimal Payload Serialization", "status": "READY_FOR_IMPLEMENTATION", "priority": "P0", "severity": "HIGH", "category": "Backend / Financial Integrity & Database Optimization", "type": "IMPLEMENTATION", "sourceFindings": ["BE-001", "BE-002"], "objective": "Fix monetary calculation floating-point precision loss, eliminate N+1 database queries in OrdersService.create, and enforce global Prisma.Decimal serialization to prevent client-side parsing crashes.", "rootCauseAddressed": "Conversion of Prisma Decimal values to JS numbers, iterative findUnique queries in loop, and un-serialized Decimal objects in JSON payloads.", "currentState": "OrdersService.create executes N+1 findUnique queries and calculates total with primitive number arithmetic.", "requiredChanges": [ "Batch product queries via prisma.product.findMany with in filter.", "Map products by ID; throw 404 for missing products, 400 for duplicate IDs or invalid quantities.", "Use Prisma Decimal for monetary accumulation via Decimal.add() and mul(). Example: 19.99 * 3 + 5.01 = 64.98.", "Implement global NestJS DecimalInterceptor to convert all Prisma.Decimal fields into formatted Strings/Numbers in outbound JSON payloads." ], "affectedFiles": [ "backend/src/orders/orders.service.ts", "backend/src/orders/orders.service.spec.ts", "backend/src/common/interceptors/decimal.interceptor.ts", "backend/src/main.ts" ], "dependencies": [], "blockedBy": [], "riskAssessment": "MEDIUM risk. Core financial order pipeline and response serialization.", "testingRequirements": [ "Unit test verifying single product batch query.", "Unit test asserting exact decimal calculation 19.99 * 3 + 5.01 = 64.98.", "Interceptor unit test verifying Prisma.Decimal property serialization to exact Strings/Numbers." ], "validationCommands": [ "cd backend && npm run test -- backend/src/orders/orders.service.spec.ts" ], "acceptanceCriteria": [ "Zero Number(product.priceValue) conversions in order calculation.", "Single database query executed for product lookup during checkout.", "Order total accumulated using Decimal arithmetic (19.99 * 3 + 5.01 = 64.98).", "All Prisma.Decimal fields in API JSON response payloads are serialized as exact Strings/Numbers." ], "definitionOfDone": "Decimal math implemented, DecimalInterceptor registered, query batching verified." }, { "taskId": "TASK-BUILD-001", "title": "NestJS Compiler Diagnostic Remediation & Spec Return Type Alignment", "status": "READY_FOR_IMPLEMENTATION", "priority": "P1", "severity": "MEDIUM", "category": "Code Quality / Compilation & Test Suite Stability", "type": "IMPLEMENTATION", "sourceFindings": ["TS-002", "TS-003", "TEST-001"], "objective": "Fix TypeScript compilation errors in seed.ts and metrics.controller.ts and resolve spec test suite failure caused by stale property assertions.", "rootCauseAddressed": "Missing slug property in seed payload, non-type-only Response import under isolatedModules, and obsolete spec assertions checking for result.success.", "currentState": "seed.ts and metrics.controller.ts trigger TS errors; controller specs fail compilation.", "requiredChanges": [ "Add slug field to products in backend/prisma/seed.ts.", "Use import type { Response } in backend/src/common/metrics.controller.ts.", "Update pets, settings, and users controller spec assertions to match raw entity returns." ], "affectedFiles": [ "backend/prisma/seed.ts", "backend/src/common/metrics.controller.ts", "backend/src/pets/pets.controller.spec.ts", "backend/src/settings/settings.controller.spec.ts", "backend/src/users/users.controller.spec.ts" ], "dependencies": [], "blockedBy": [], "riskAssessment": "LOW risk. Fixes broken compilation and stale tests.", "testingRequirements": [ "Backend tsc compilation check.", "Backend full Jest test suite execution." ], "validationCommands": [ "cd backend && npx tsc --noEmit", "cd backend && npm run test" ], "acceptanceCriteria": [ "Backend tsc --noEmit completes with 0 errors.", "Backend Jest test suite runs 100% green." ], "definitionOfDone": "tsc clean, unit spec tests passing." }, { "taskId": "TASK-AUTH-001", "title": "Dual-Token Auth Contract Integration for Standalone Admin Panel", "status": "BLOCKED_BY_DEPENDENCY", "priority": "P1", "severity": "HIGH", "category": "Architecture / Auth Integration", "type": "IMPLEMENTATION", "sourceFindings": ["ARCH-001"], "objective": "Re-architect authentication state and login flow specifically for the standalone Admin Panel SPA to consume NestJS auth endpoints per ADR-AUTH-001 (Dual-Token Hybrid: In-Memory Access Token + HttpOnly refreshToken Cookie signed with JWT_REFRESH_SECRET).", "rootCauseAddressed": "Application used mock auth state and vulnerable localStorage token storage.", "currentState": "Storefront uses Next.js (SSR/SEO); Admin Panel requires standalone dual-token auth SPA integration.", "requiredChanges": [ "Implement Dual-Token Hybrid architecture per ADR-AUTH-001 for Admin Panel SPA.", "Configure Axios client with withCredentials: true and add background silent token refresh interceptor on 401 response.", "Build Admin Login component collecting credentials and OTP verification code." ], "affectedFiles": [ "src/store/adminAuthStore.ts", "src/components/AdminLogin.tsx", "src/services/adminAuthService.ts", "src/services/api.ts" ], "dependencies": ["TASK-SEC-002"], "blockedBy": ["TASK-SEC-002"], "riskAssessment": "MEDIUM risk. Admin Panel authentication boundary.", "testingRequirements": [ "Unit test adminAuthStore state machine transitions and token handling.", "Component integration test for Admin Login." ], "validationCommands": [ "npm run test", "npm run build" ], "acceptanceCriteria": [ "Admin Panel login triggers NestJS backend auth endpoints successfully.", "Access token is held in-memory and automatically attached to api request headers.", "Session persists seamlessly across page refreshes via background refresh with refreshToken HttpOnly cookie." ], "definitionOfDone": "Admin Panel dual-token auth flow fully functional per ADR-AUTH-001, unit tests passing, build clean." }, { "taskId": "TASK-FE-001", "title": "Admin Panel Router Architecture (createBrowserRouter), Lazy Loading & Type Safety", "status": "READY_FOR_IMPLEMENTATION", "priority": "P2", "severity": "MEDIUM", "category": "Admin SPA / Routing & Performance", "type": "IMPLEMENTATION", "sourceFindings": ["FE-001", "TS-001"], "objective": "Implement react-router-dom (createBrowserRouter) specifically for the standalone Admin Panel SPA to enable Lazy Loading, optimize performance for heavy admin modules, and enforce strict Type Safety. (SEO is completely irrelevant for Admin Panel).", "rootCauseAddressed": "Legacy state-driven view rendering caused navigation failures and explicit any type annotations.", "currentState": "Storefront is Next.js; Admin Panel SPA requires dedicated router setup.", "requiredChanges": [ "Configure react-router-dom createBrowserRouter for Admin Panel matching frontend-route-map.md.", "Implement React Suspense lazy-loading for heavy administrative module chunks.", "Define explicit TypeScript interfaces for all admin route parameters, eliminating all any annotations." ], "affectedFiles": [ "src/App.tsx", "src/routes/adminRoutes.tsx", "src/types/admin.ts", "package.json" ], "dependencies": [], "blockedBy": [], "riskAssessment": "MEDIUM risk. Admin SPA routing architecture.", "testingRequirements": [ "Unit test admin component route navigation and lazy loading.", "Typecheck validation (npx tsc --noEmit)." ], "validationCommands": [ "npx tsc --noEmit", "npm run build" ], "acceptanceCriteria": [ "Admin Panel routes render target views directly on page refresh via createBrowserRouter.", "Admin modules are lazy-loaded via dynamic imports (lazy()).", "Zero explicit any type declarations in Admin Panel codebase." ], "definitionOfDone": "React Router createBrowserRouter integrated for Admin Panel per frontend-route-map.md, lazy loading verified, 0 type errors." }, { "taskId": "TASK-DEVOPS-001", "title": "Continuous Integration Pipeline & Automated Quality Gate Setup", "status": "BLOCKED_BY_DEPENDENCY", "priority": "P2", "severity": "MEDIUM", "category": "DevOps / Continuous Integration Workflow", "type": "IMPLEMENTATION", "sourceFindings": ["DEVOPS-001"], "objective": "Create committed Gitea/GitHub Actions workflow (.github/workflows/ci.yml) enforcing build, lint, typecheck, and test checks on PRs.", "rootCauseAddressed": "Absence of committed CI pipeline configuration in repository.", "currentState": "No .github/workflows directory exists.", "requiredChanges": [ "Create .github/workflows/ci.yml with frontend (lint, tsc, build) and backend (tsc, test) quality gate jobs." ], "affectedFiles": [ ".github/workflows/ci.yml" ], "dependencies": ["TASK-BUILD-001"], "blockedBy": ["TASK-BUILD-001"], "riskAssessment": "LOW risk. Additive DevOps configuration.", "testingRequirements": [ "Workflow YAML syntax validation.", "Execution on PR trigger." ], "validationCommands": [ "npx actionlint .github/workflows/ci.yml" ], "acceptanceCriteria": [ ".github/workflows/ci.yml is committed and syntactically valid.", "Automated CI workflow executes build, lint, typecheck, and unit test checks on PRs." ], "definitionOfDone": "CI workflow created, validated, passing on pull requests." }, { "taskId": "TASK-DOC-001", "title": "OpenAPI Documentation Synchronization & Automated Schema Export", "status": "READY_FOR_IMPLEMENTATION", "priority": "P3", "severity": "MEDIUM", "category": "Documentation / API Specification Alignment", "type": "IMPLEMENTATION", "sourceFindings": ["DOC-001"], "objective": "Reconcile static swagger.yml with active NestJS Auth controllers and configure automated OpenAPI spec generation via a non-listener CLI tool.", "rootCauseAddressed": "swagger.yml documents obsolete login/register endpoints created prior to SMS OTP implementation.", "currentState": "swagger.yml out of sync with active backend auth routes.", "requiredChanges": [ "Create non-listener CLI script backend/scripts/generate-openapi.ts.", "Add npm run docs:generate script in backend/package.json.", "Update swagger.yml to document POST /api/auth/send-otp and POST /api/auth/verify-otp." ], "affectedFiles": [ "swagger.yml", "backend/scripts/generate-openapi.ts", "backend/package.json" ], "dependencies": [], "blockedBy": [], "riskAssessment": "LOW risk. Documentation synchronization.", "testingRequirements": [ "OpenAPI YAML syntax validation." ], "validationCommands": [ "cd backend && npm run docs:generate && git diff --exit-code ../swagger.yml" ], "acceptanceCriteria": [ "swagger.yml accurately reflects NestJS controller endpoints 100%.", "npm run docs:generate completes without opening a live HTTP listening port." ], "definitionOfDone": "swagger.yml updated, script configured, validation clean." }, { "taskId": "TASK-VERIFY-001", "title": "End-to-End Authentication, Authorization, Order, and Regression Verification", "status": "BLOCKED_BY_DEPENDENCY", "priority": "P1", "severity": "INFO", "category": "Verification / Automated Integration & E2E Suite", "type": "VERIFICATION", "sourceFindings": [ "ARCH-001", "ADM-001", "BE-001", "BE-002", "SEC-001", "SEC-002", "SEC-003", "TEST-001", "FE-001", "TS-001", "TS-002", "TS-003", "DEVOPS-001", "DOC-001" ], "objective": "Execute a 7-domain behavior-oriented verification matrix across all 14 verified findings after implementation tasks complete.", "rootCauseAddressed": "Cross-cutting verification ensuring all 14 findings are remediated and zero regressions introduced.", "currentState": "Post-remediation verification suite.", "requiredChanges": [ "Create and execute automated 7-domain behavior-oriented E2E integration test suite in backend/test/app-audit-verification.e2e-spec.ts." ], "affectedFiles": [ "backend/test/app-audit-verification.e2e-spec.ts" ], "dependencies": [ "TASK-SEC-001", "TASK-SEC-002", "TASK-SEC-003", "TASK-FIN-001", "TASK-BUILD-001", "TASK-AUTH-001" ], "blockedBy": ["TASK-AUTH-001", "TASK-SEC-003", "TASK-FIN-001"], "riskAssessment": "LOW risk. Verification script execution only.", "testingRequirements": [ "7-Domain behavior-oriented E2E test suite execution." ], "validationCommands": [ "cd backend && npm run test:e2e" ], "acceptanceCriteria": [ "All 14 verified findings pass 7-domain verification assertions 100% green.", "Zero findings remain in OPEN status." ], "definitionOfDone": "Verification report generated, 100% pass rate confirmed." } ], "productDecisions": [ { "id": "DECISION-001", "title": "SMS Gateway Provider Selection", "category": "PRODUCT_DECISION", "status": "PENDING_PRODUCT_INPUT", "description": "Selection of production SMS gateway provider for NestJS AuthService.sendOtp." }, { "id": "DECISION-003", "title": "Storefront vs Admin Sub-Application Architecture Roadmap", "category": "FINALIZED_PRODUCT_DECISION", "status": "FINALIZED_PRODUCT_DECISION", "description": "The Admin Panel is a completely standalone, isolated application (React SPA) and will NOT be hosted within the main Storefront (Next.js SSR/SEO)." } ], "futureScope": [ { "id": "DECISION-002", "title": "Live Payment Gateway Provider Selection", "category": "FUTURE_SCOPE", "status": "FUTURE_SCOPE", "description": "Selection of merchant payment gateway provider for wallet deposits and orders. Unrelated to active audit findings." } ] }