adserver-dashboard 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (525) hide show
  1. package/.ci/staging.yml +191 -0
  2. package/.dockerignore +117 -0
  3. package/.env +40 -0
  4. package/.env.staging +38 -0
  5. package/.gitlab-ci.yml +16 -0
  6. package/DEMO_STATUS.md +579 -0
  7. package/Dockerfile +61 -0
  8. package/Influence-MW-AdServer-12-02-2026/client/index.html +17 -0
  9. package/Influence-MW-AdServer-12-02-2026/client/public/favicon.png +0 -0
  10. package/Influence-MW-AdServer-12-02-2026/client/src/App.tsx +91 -0
  11. package/Influence-MW-AdServer-12-02-2026/client/src/components/advanced-map-drawer.tsx +1131 -0
  12. package/Influence-MW-AdServer-12-02-2026/client/src/components/ai-recommendation-panel.tsx +379 -0
  13. package/Influence-MW-AdServer-12-02-2026/client/src/components/app-sidebar.tsx +183 -0
  14. package/Influence-MW-AdServer-12-02-2026/client/src/components/auto-optimize-button.tsx +184 -0
  15. package/Influence-MW-AdServer-12-02-2026/client/src/components/availability-drawer.tsx +385 -0
  16. package/Influence-MW-AdServer-12-02-2026/client/src/components/brand-insights-panel.tsx +87 -0
  17. package/Influence-MW-AdServer-12-02-2026/client/src/components/create-agency-drawer.tsx +198 -0
  18. package/Influence-MW-AdServer-12-02-2026/client/src/components/create-brand-drawer.tsx +275 -0
  19. package/Influence-MW-AdServer-12-02-2026/client/src/components/creative-assignment.tsx +526 -0
  20. package/Influence-MW-AdServer-12-02-2026/client/src/components/data-table-toolbar.tsx +148 -0
  21. package/Influence-MW-AdServer-12-02-2026/client/src/components/data-table.tsx +158 -0
  22. package/Influence-MW-AdServer-12-02-2026/client/src/components/filter-drawer.tsx +356 -0
  23. package/Influence-MW-AdServer-12-02-2026/client/src/components/form-insights-panel.tsx +82 -0
  24. package/Influence-MW-AdServer-12-02-2026/client/src/components/geography-selector.tsx +699 -0
  25. package/Influence-MW-AdServer-12-02-2026/client/src/components/header-user-menu.tsx +178 -0
  26. package/Influence-MW-AdServer-12-02-2026/client/src/components/history-drawer.tsx +313 -0
  27. package/Influence-MW-AdServer-12-02-2026/client/src/components/inventory-availability-section.tsx +176 -0
  28. package/Influence-MW-AdServer-12-02-2026/client/src/components/inventory-format-drawer.tsx +173 -0
  29. package/Influence-MW-AdServer-12-02-2026/client/src/components/inventory-selector.tsx +401 -0
  30. package/Influence-MW-AdServer-12-02-2026/client/src/components/manual-inventory-drawer.tsx +368 -0
  31. package/Influence-MW-AdServer-12-02-2026/client/src/components/mapbox-map.tsx +368 -0
  32. package/Influence-MW-AdServer-12-02-2026/client/src/components/market-insights-panel.tsx +202 -0
  33. package/Influence-MW-AdServer-12-02-2026/client/src/components/media-owner-drawer.tsx +217 -0
  34. package/Influence-MW-AdServer-12-02-2026/client/src/components/metric-card.tsx +58 -0
  35. package/Influence-MW-AdServer-12-02-2026/client/src/components/page-header.tsx +27 -0
  36. package/Influence-MW-AdServer-12-02-2026/client/src/components/player-status-indicator.tsx +137 -0
  37. package/Influence-MW-AdServer-12-02-2026/client/src/components/poi-targeting-drawer.tsx +298 -0
  38. package/Influence-MW-AdServer-12-02-2026/client/src/components/recommendation-score-badge.tsx +102 -0
  39. package/Influence-MW-AdServer-12-02-2026/client/src/components/recommended-inventories-panel.tsx +248 -0
  40. package/Influence-MW-AdServer-12-02-2026/client/src/components/searchable-combobox.tsx +134 -0
  41. package/Influence-MW-AdServer-12-02-2026/client/src/components/signal-visualizations.tsx +407 -0
  42. package/Influence-MW-AdServer-12-02-2026/client/src/components/status-badge.tsx +35 -0
  43. package/Influence-MW-AdServer-12-02-2026/client/src/components/theme-provider.tsx +73 -0
  44. package/Influence-MW-AdServer-12-02-2026/client/src/components/theme-toggle.tsx +37 -0
  45. package/Influence-MW-AdServer-12-02-2026/client/src/components/traffic-slider.tsx +75 -0
  46. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/accordion.tsx +56 -0
  47. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/alert-dialog.tsx +139 -0
  48. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/alert.tsx +59 -0
  49. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/aspect-ratio.tsx +5 -0
  50. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/avatar.tsx +51 -0
  51. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/badge.tsx +38 -0
  52. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/breadcrumb.tsx +115 -0
  53. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/button.tsx +62 -0
  54. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/calendar.tsx +68 -0
  55. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/card.tsx +85 -0
  56. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/carousel.tsx +260 -0
  57. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/chart.tsx +365 -0
  58. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/checkbox.tsx +28 -0
  59. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/collapsible.tsx +11 -0
  60. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/command.tsx +151 -0
  61. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/context-menu.tsx +198 -0
  62. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/dialog.tsx +122 -0
  63. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/drawer.tsx +118 -0
  64. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/dropdown-menu.tsx +198 -0
  65. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/form.tsx +178 -0
  66. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/hover-card.tsx +29 -0
  67. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/input-otp.tsx +69 -0
  68. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/input.tsx +23 -0
  69. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/label.tsx +24 -0
  70. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/menubar.tsx +256 -0
  71. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/navigation-menu.tsx +128 -0
  72. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/pagination.tsx +117 -0
  73. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/popover.tsx +29 -0
  74. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/progress.tsx +28 -0
  75. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/radio-group.tsx +42 -0
  76. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/resizable.tsx +45 -0
  77. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/scroll-area.tsx +46 -0
  78. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/select.tsx +160 -0
  79. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/separator.tsx +29 -0
  80. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/sheet.tsx +140 -0
  81. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/sidebar.tsx +727 -0
  82. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/skeleton.tsx +15 -0
  83. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/slider.tsx +26 -0
  84. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/switch.tsx +27 -0
  85. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/table.tsx +117 -0
  86. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/tabs.tsx +53 -0
  87. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/textarea.tsx +22 -0
  88. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/toast.tsx +127 -0
  89. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/toaster.tsx +33 -0
  90. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/toggle-group.tsx +61 -0
  91. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/toggle.tsx +43 -0
  92. package/Influence-MW-AdServer-12-02-2026/client/src/components/ui/tooltip.tsx +30 -0
  93. package/Influence-MW-AdServer-12-02-2026/client/src/components/vendor-stores-modal.tsx +336 -0
  94. package/Influence-MW-AdServer-12-02-2026/client/src/components/venue-type-drawer.tsx +359 -0
  95. package/Influence-MW-AdServer-12-02-2026/client/src/components/venue-type-selector.tsx +436 -0
  96. package/Influence-MW-AdServer-12-02-2026/client/src/hooks/use-mobile.tsx +19 -0
  97. package/Influence-MW-AdServer-12-02-2026/client/src/hooks/use-toast.ts +191 -0
  98. package/Influence-MW-AdServer-12-02-2026/client/src/index.css +244 -0
  99. package/Influence-MW-AdServer-12-02-2026/client/src/lib/queryClient.ts +57 -0
  100. package/Influence-MW-AdServer-12-02-2026/client/src/lib/utils.ts +39 -0
  101. package/Influence-MW-AdServer-12-02-2026/client/src/lib/venue-taxonomy.ts +532 -0
  102. package/Influence-MW-AdServer-12-02-2026/client/src/main.tsx +5 -0
  103. package/Influence-MW-AdServer-12-02-2026/client/src/pages/assign-creative.tsx +781 -0
  104. package/Influence-MW-AdServer-12-02-2026/client/src/pages/content-hub.tsx +995 -0
  105. package/Influence-MW-AdServer-12-02-2026/client/src/pages/custom-pois.tsx +431 -0
  106. package/Influence-MW-AdServer-12-02-2026/client/src/pages/dashboard.tsx +620 -0
  107. package/Influence-MW-AdServer-12-02-2026/client/src/pages/deal-detail.tsx +1062 -0
  108. package/Influence-MW-AdServer-12-02-2026/client/src/pages/deal-form.tsx +1570 -0
  109. package/Influence-MW-AdServer-12-02-2026/client/src/pages/deals.tsx +716 -0
  110. package/Influence-MW-AdServer-12-02-2026/client/src/pages/edit-creative-assignment.tsx +1051 -0
  111. package/Influence-MW-AdServer-12-02-2026/client/src/pages/geotargeting.tsx +675 -0
  112. package/Influence-MW-AdServer-12-02-2026/client/src/pages/integrations.tsx +425 -0
  113. package/Influence-MW-AdServer-12-02-2026/client/src/pages/line-item-creatives.tsx +622 -0
  114. package/Influence-MW-AdServer-12-02-2026/client/src/pages/line-item-form.tsx +3132 -0
  115. package/Influence-MW-AdServer-12-02-2026/client/src/pages/line-items.tsx +530 -0
  116. package/Influence-MW-AdServer-12-02-2026/client/src/pages/not-found.tsx +21 -0
  117. package/Influence-MW-AdServer-12-02-2026/client/src/pages/proof-of-play-upload.tsx +479 -0
  118. package/Influence-MW-AdServer-12-02-2026/client/src/pages/proof-of-play.tsx +880 -0
  119. package/Influence-MW-AdServer-12-02-2026/client/src/pages/reports.tsx +235 -0
  120. package/Influence-MW-AdServer-12-02-2026/client/src/pages/settings.tsx +652 -0
  121. package/Influence-MW-AdServer-12-02-2026/client/src/pages/signal-form.tsx +1117 -0
  122. package/Influence-MW-AdServer-12-02-2026/client/src/pages/signals.tsx +366 -0
  123. package/Influence-MW-AdServer-12-02-2026/client/src/pages/tags.tsx +332 -0
  124. package/Influence-MW-AdServer-12-02-2026/client/src/pages/venues.tsx +381 -0
  125. package/Influence-MW-AdServer-12-02-2026/client/src/types/mapbox-gl-draw.d.ts +37 -0
  126. package/Influence-MW-AdServer-12-02-2026/client/src/types/react-simple-maps.d.ts +57 -0
  127. package/Influence-MW-AdServer-12-02-2026/components.json +20 -0
  128. package/Influence-MW-AdServer-12-02-2026/docs/PRD.md +3373 -0
  129. package/Influence-MW-AdServer-12-02-2026/docs/influence-feature-mapping.csv +498 -0
  130. package/Influence-MW-AdServer-12-02-2026/drizzle.config.ts +14 -0
  131. package/Influence-MW-AdServer-12-02-2026/package-lock.json +9672 -0
  132. package/Influence-MW-AdServer-12-02-2026/package.json +118 -0
  133. package/Influence-MW-AdServer-12-02-2026/postcss.config.js +6 -0
  134. package/Influence-MW-AdServer-12-02-2026/replit.md +91 -0
  135. package/Influence-MW-AdServer-12-02-2026/script/build.ts +67 -0
  136. package/Influence-MW-AdServer-12-02-2026/scripts/create-miro-diagrams.cjs +318 -0
  137. package/Influence-MW-AdServer-12-02-2026/scripts/create-remaining-diagrams.cjs +270 -0
  138. package/Influence-MW-AdServer-12-02-2026/server/index.ts +103 -0
  139. package/Influence-MW-AdServer-12-02-2026/server/recommendation-service.ts +319 -0
  140. package/Influence-MW-AdServer-12-02-2026/server/routes.ts +1890 -0
  141. package/Influence-MW-AdServer-12-02-2026/server/static.ts +19 -0
  142. package/Influence-MW-AdServer-12-02-2026/server/storage.ts +2058 -0
  143. package/Influence-MW-AdServer-12-02-2026/server/vite.ts +58 -0
  144. package/Influence-MW-AdServer-12-02-2026/shared/schema.ts +1595 -0
  145. package/Influence-MW-AdServer-12-02-2026/tailwind.config.ts +107 -0
  146. package/Influence-MW-AdServer-12-02-2026/tsconfig.json +23 -0
  147. package/Influence-MW-AdServer-12-02-2026/vite.config.ts +40 -0
  148. package/LINE_ITEM_BUDGET_FIELD_MAPPING.md +178 -0
  149. package/PCM/.env.example +92 -0
  150. package/PCM/README.md +558 -0
  151. package/PCM/docs/TEST_CASES.md +422 -0
  152. package/PCM/index.js +106 -0
  153. package/PCM/package-lock.json +3282 -0
  154. package/PCM/package.json +32 -0
  155. package/PCM/replit.md +64 -0
  156. package/PCM/schema.sql +495 -0
  157. package/PCM/scripts/export-schema.js +183 -0
  158. package/PCM/scripts/seed-comprehensive.js +631 -0
  159. package/PCM/scripts/seed-production.js +477 -0
  160. package/PCM/src/config/db.js +56 -0
  161. package/PCM/src/config/swagger.js +5975 -0
  162. package/PCM/src/dto/EmailRequestDTO.js +166 -0
  163. package/PCM/src/middleware/errorHandler.js +52 -0
  164. package/PCM/src/middleware/logger.js +26 -0
  165. package/PCM/src/migrations/001_add_campaign_mode_fields.sql +36 -0
  166. package/PCM/src/migrations/002_create_deal_id_counters.sql +22 -0
  167. package/PCM/src/migrations/003_update_publishers_column.sql +15 -0
  168. package/PCM/src/migrations/004_add_direct_dealtype_and_advertiser.sql +5 -0
  169. package/PCM/src/migrations/005_add_programmatic_fields_and_update_enums.sql +31 -0
  170. package/PCM/src/migrations/006_add_line_item_programmatic_fields.sql +12 -0
  171. package/PCM/src/migrations/007_add_line_item_direct_fields.sql +15 -0
  172. package/PCM/src/migrations/008_add_inventory_fields.sql +45 -0
  173. package/PCM/src/migrations/009_move_inventory_fields_to_metadata.sql +32 -0
  174. package/PCM/src/migrations/010_add_draft_status_and_line_items_count.sql +23 -0
  175. package/PCM/src/migrations/011_add_planning_field.sql +21 -0
  176. package/PCM/src/migrations/012_fix_inventory_composite_pk.sql +17 -0
  177. package/PCM/src/migrations/013_make_external_id_optional.sql +3 -0
  178. package/PCM/src/migrations/014_create_change_history.sql +38 -0
  179. package/PCM/src/migrations/016_create_publisher_insertion_orders.sql +33 -0
  180. package/PCM/src/migrations/017_fix_line_item_id_fk_reference.sql +86 -0
  181. package/PCM/src/migrations/018_create_approval_tables.sql +44 -0
  182. package/PCM/src/migrations/019_add_encrypted_token_column.sql +2 -0
  183. package/PCM/src/migrations/020_add_rejection_reason_to_deals.sql +10 -0
  184. package/PCM/src/migrations/021_add_publisher_external_id_to_inventories.sql +12 -0
  185. package/PCM/src/migrations/022_add_line_item_extended_fields.sql +24 -0
  186. package/PCM/src/migrations/023_add_base_price_fields.sql +8 -0
  187. package/PCM/src/migrations/run-migrations.js +46 -0
  188. package/PCM/src/models/ApprovalOTP.js +51 -0
  189. package/PCM/src/models/ApprovalToken.js +79 -0
  190. package/PCM/src/models/ChangeHistory.js +107 -0
  191. package/PCM/src/models/Deal.js +186 -0
  192. package/PCM/src/models/DealIdCounter.js +28 -0
  193. package/PCM/src/models/LineItem.js +227 -0
  194. package/PCM/src/models/LineItemCreative.js +89 -0
  195. package/PCM/src/models/LineItemInventory.js +115 -0
  196. package/PCM/src/models/PublisherInsertionOrder.js +93 -0
  197. package/PCM/src/models/TransactionHistory.js +34 -0
  198. package/PCM/src/models/associations.js +81 -0
  199. package/PCM/src/routes/approval.js +321 -0
  200. package/PCM/src/routes/creatives.js +437 -0
  201. package/PCM/src/routes/deals.js +1638 -0
  202. package/PCM/src/routes/digitalSignage.js +242 -0
  203. package/PCM/src/routes/insertionOrders.js +380 -0
  204. package/PCM/src/routes/lineItems.js +926 -0
  205. package/PCM/src/routes/system.js +384 -0
  206. package/PCM/src/services/ApprovalService.js +885 -0
  207. package/PCM/src/services/CampaignImportConverter.js +631 -0
  208. package/PCM/src/services/CampaignModeService.js +273 -0
  209. package/PCM/src/services/CampaignStatusService.js +395 -0
  210. package/PCM/src/services/ChangeHistoryService.js +316 -0
  211. package/PCM/src/services/DealIdService.js +94 -0
  212. package/PCM/src/services/DealResponseFormatter.js +90 -0
  213. package/PCM/src/services/EmailNotificationService.js +315 -0
  214. package/PCM/src/services/LineItemResponseFormatter.js +122 -0
  215. package/PCM/src/services/LineItemStatusService.js +380 -0
  216. package/PCM/src/tests/comprehensiveTestRunner.js +360 -0
  217. package/PCM/src/tests/comprehensiveTests.js +1277 -0
  218. package/PCM/src/tests/dealTypeUnitTests.js +1058 -0
  219. package/PCM/src/tests/testRunner.js +248 -0
  220. package/PCM/src/utils/caseConverter.js +92 -0
  221. package/PCM/src/utils/dealCalculations.js +206 -0
  222. package/PCM/src/utils/lineItemPayloadNormalizer.js +41 -0
  223. package/PCM/src/utils/payloadNormalizer.js +34 -0
  224. package/PCM/src/utils/sourceNormalizer.js +56 -0
  225. package/PCM/src/validators/creativeValidator.js +27 -0
  226. package/PCM/src/validators/dealValidator.js +203 -0
  227. package/PCM/src/validators/lineItemValidator.js +489 -0
  228. package/PCM/tests/approval-flows.test.js +238 -0
  229. package/PCM/tests/approval-workflow.test.js +291 -0
  230. package/PCM/tests/campaign-import-converter.test.js +543 -0
  231. package/PCM/tests/campaign-import-e2e.test.js +520 -0
  232. package/PCM/tests/campaign-status.test.js +539 -0
  233. package/PCM/tests/direct-publisher-split-reimport.test.js +460 -0
  234. package/PCM/tests/e2e/digital-signage.test.js +145 -0
  235. package/PCM/tests/e2e/search-filter-pagination.test.js +399 -0
  236. package/PCM/tests/e2e-comprehensive.test.js +3446 -0
  237. package/PCM/tests/edge-cases.test.js +340 -0
  238. package/PCM/tests/line-item-status.test.js +340 -0
  239. package/PCM/tests/seller-account-external-ids.test.js +877 -0
  240. package/PCM/tests/source-validation.test.js +324 -0
  241. package/PRD.md +3373 -0
  242. package/README.md +186 -0
  243. package/client/index.html +35 -0
  244. package/client/public/DEMO_STATUS.md +579 -0
  245. package/client/public/img/MW-logo-trans_1754045676555.png +0 -0
  246. package/client/public/locales/ar/approval.json +144 -0
  247. package/client/public/locales/ar/buyer.json +61 -0
  248. package/client/public/locales/ar/campaigns.json +1 -0
  249. package/client/public/locales/ar/common.json +218 -0
  250. package/client/public/locales/ar/contentHub.json +266 -0
  251. package/client/public/locales/ar/creatives.json +79 -0
  252. package/client/public/locales/ar/dashboard.json +57 -0
  253. package/client/public/locales/ar/deals.json +886 -0
  254. package/client/public/locales/ar/dsp.json +131 -0
  255. package/client/public/locales/ar/inventory.json +201 -0
  256. package/client/public/locales/ar/lineItems.json +553 -0
  257. package/client/public/locales/ar/navigation.json +48 -0
  258. package/client/public/locales/ar/wizard.json +1 -0
  259. package/client/public/locales/en/approval.json +144 -0
  260. package/client/public/locales/en/buyer.json +65 -0
  261. package/client/public/locales/en/campaigns.json +1 -0
  262. package/client/public/locales/en/common.json +218 -0
  263. package/client/public/locales/en/contentHub.json +266 -0
  264. package/client/public/locales/en/creatives.json +79 -0
  265. package/client/public/locales/en/dashboard.json +57 -0
  266. package/client/public/locales/en/deals.json +886 -0
  267. package/client/public/locales/en/dsp.json +131 -0
  268. package/client/public/locales/en/inventory.json +201 -0
  269. package/client/public/locales/en/lineItems.json +659 -0
  270. package/client/public/locales/en/navigation.json +48 -0
  271. package/client/public/locales/en/wizard.json +1 -0
  272. package/client/public/locales/ja/approval.json +144 -0
  273. package/client/public/locales/ja/buyer.json +61 -0
  274. package/client/public/locales/ja/campaigns.json +1 -0
  275. package/client/public/locales/ja/common.json +218 -0
  276. package/client/public/locales/ja/contentHub.json +266 -0
  277. package/client/public/locales/ja/creatives.json +79 -0
  278. package/client/public/locales/ja/dashboard.json +57 -0
  279. package/client/public/locales/ja/deals.json +886 -0
  280. package/client/public/locales/ja/dsp.json +131 -0
  281. package/client/public/locales/ja/inventory.json +201 -0
  282. package/client/public/locales/ja/lineItems.json +553 -0
  283. package/client/public/locales/ja/navigation.json +48 -0
  284. package/client/public/locales/ja/wizard.json +1 -0
  285. package/client/public/locales/zh/approval.json +144 -0
  286. package/client/public/locales/zh/buyer.json +61 -0
  287. package/client/public/locales/zh/campaigns.json +1 -0
  288. package/client/public/locales/zh/common.json +218 -0
  289. package/client/public/locales/zh/contentHub.json +266 -0
  290. package/client/public/locales/zh/creatives.json +79 -0
  291. package/client/public/locales/zh/dashboard.json +57 -0
  292. package/client/public/locales/zh/deals.json +886 -0
  293. package/client/public/locales/zh/dsp.json +131 -0
  294. package/client/public/locales/zh/inventory.json +201 -0
  295. package/client/public/locales/zh/lineItems.json +553 -0
  296. package/client/public/locales/zh/navigation.json +48 -0
  297. package/client/public/locales/zh/wizard.json +1 -0
  298. package/client/public/manifest.json +36 -0
  299. package/client/src/App.tsx +464 -0
  300. package/client/src/components/app-sidebar.tsx +312 -0
  301. package/client/src/components/approval/approval-decision-form.test.tsx +294 -0
  302. package/client/src/components/approval/approval-decision-form.tsx +326 -0
  303. package/client/src/components/approval/approval-sheet.tsx +631 -0
  304. package/client/src/components/approval/line-item-details-sheet.tsx +371 -0
  305. package/client/src/components/approval/otp-verification.test.tsx +337 -0
  306. package/client/src/components/approval/otp-verification.tsx +180 -0
  307. package/client/src/components/content-hub/bulk-transcode-dialog.tsx +379 -0
  308. package/client/src/components/content-hub/content-hub-manager-v2.tsx +574 -0
  309. package/client/src/components/content-hub/content-hub-manager.tsx +330 -0
  310. package/client/src/components/content-hub/creative-card.tsx +456 -0
  311. package/client/src/components/content-hub/creative-detail-sheet.tsx +685 -0
  312. package/client/src/components/content-hub/creative-filters.tsx +457 -0
  313. package/client/src/components/content-hub/creative-grid.tsx +329 -0
  314. package/client/src/components/content-hub/creative-selector.tsx +415 -0
  315. package/client/src/components/content-hub/creative-upload.tsx +547 -0
  316. package/client/src/components/content-hub/folder-dialogs.tsx +445 -0
  317. package/client/src/components/content-hub/folder-list.tsx +280 -0
  318. package/client/src/components/content-hub/review-dialogs.tsx +268 -0
  319. package/client/src/components/content-hub/transcode-dialog.tsx +226 -0
  320. package/client/src/components/creative-library/creative-details-view.tsx +446 -0
  321. package/client/src/components/creative-library/creative-filters-panel.tsx +203 -0
  322. package/client/src/components/creative-library/creative-list.tsx +360 -0
  323. package/client/src/components/creative-library/creative-status-badge.tsx +71 -0
  324. package/client/src/components/creative-library/folder-card.tsx +78 -0
  325. package/client/src/components/creative-library/index.ts +27 -0
  326. package/client/src/components/creative-library/new-creative-card.tsx +211 -0
  327. package/client/src/components/creative-library/upload-creative-dialog.tsx +261 -0
  328. package/client/src/components/dashboard-overview.tsx +109 -0
  329. package/client/src/components/deals/approval-history-panel.test.tsx +240 -0
  330. package/client/src/components/deals/approval-history-panel.tsx +156 -0
  331. package/client/src/components/deals/deal-status-badge.tsx +92 -0
  332. package/client/src/components/deals/import-from-planner-dialog.tsx +399 -0
  333. package/client/src/components/deals/market-insights-panel.tsx +237 -0
  334. package/client/src/components/deals/reopen-deal-sheet.tsx +191 -0
  335. package/client/src/components/deals/request-approval-sheet.test.tsx +323 -0
  336. package/client/src/components/deals/request-approval-sheet.tsx +136 -0
  337. package/client/src/components/deals/resend-approval-sheet.tsx +201 -0
  338. package/client/src/components/direct-campaigns/campaign-card.tsx +283 -0
  339. package/client/src/components/direct-campaigns/deal-filter-panel.tsx +325 -0
  340. package/client/src/components/inventory/advanced-filters-panel.tsx +273 -0
  341. package/client/src/components/inventory/csv-upload-modal.tsx +639 -0
  342. package/client/src/components/inventory/inventory-availability-view.tsx +486 -0
  343. package/client/src/components/inventory/inventory-details-sheet.tsx +376 -0
  344. package/client/src/components/inventory/inventory-map-view.tsx +596 -0
  345. package/client/src/components/inventory/inventory-settings-menu.tsx +52 -0
  346. package/client/src/components/language-switcher.tsx +53 -0
  347. package/client/src/components/line-items/campaign-forecast-panel.tsx +138 -0
  348. package/client/src/components/line-items/form-insights.tsx +89 -0
  349. package/client/src/components/line-items/geofencing/LocationCsvUploadDrawer.tsx +100 -0
  350. package/client/src/components/line-items/geofencing/POIDropdown.tsx +379 -0
  351. package/client/src/components/line-items/geofencing/SelectedLocationsSidebar.tsx +436 -0
  352. package/client/src/components/line-items/geofencing/ViewFileLocationDrawer.tsx +199 -0
  353. package/client/src/components/line-items/geofencing/components/ExistingFilesTab.tsx +268 -0
  354. package/client/src/components/line-items/geofencing/components/TemplateDownloadSection.tsx +59 -0
  355. package/client/src/components/line-items/geofencing/components/UploadTab.tsx +215 -0
  356. package/client/src/components/line-items/geofencing-map.tsx +1270 -0
  357. package/client/src/components/line-items/inventory-availability-section.tsx +178 -0
  358. package/client/src/components/line-items/line-item-schedule-manager.tsx +313 -0
  359. package/client/src/components/line-items/manual-inventory-drawer.tsx +346 -0
  360. package/client/src/components/line-items/planner-inventory-card.tsx +495 -0
  361. package/client/src/components/line-items/planner-schedule-grid.tsx +495 -0
  362. package/client/src/components/line-items/schedule-rule-editor.tsx +649 -0
  363. package/client/src/components/line-items/schedule-rule-types.ts +122 -0
  364. package/client/src/components/line-items/steps/creatives-step.tsx +681 -0
  365. package/client/src/components/line-items/steps/inventory-schedule-step.tsx +1596 -0
  366. package/client/src/components/line-items/steps/inventory-step.tsx +1533 -0
  367. package/client/src/components/line-items/steps/line-item-details-step.tsx +916 -0
  368. package/client/src/components/line-items/steps/schedule-step.tsx +273 -0
  369. package/client/src/components/line-items/steps/summary-step.tsx +680 -0
  370. package/client/src/components/line-items/steps/targeting-step.tsx +1708 -0
  371. package/client/src/components/product-switcher.tsx +105 -0
  372. package/client/src/components/protected-route.tsx +49 -0
  373. package/client/src/components/skip-link.tsx +22 -0
  374. package/client/src/components/stat-card.tsx +53 -0
  375. package/client/src/components/status-badge.tsx +96 -0
  376. package/client/src/components/ui/hierarchical-venue-selector.tsx +389 -0
  377. package/client/src/components/ui/toaster.tsx +111 -0
  378. package/client/src/contexts/auth-context.tsx +181 -0
  379. package/client/src/contexts/sidebar-state.tsx +50 -0
  380. package/client/src/contexts/theme-context.tsx +66 -0
  381. package/client/src/data/campaign-data.json +107 -0
  382. package/client/src/data/countries.json +22 -0
  383. package/client/src/hooks/use-approval.ts +366 -0
  384. package/client/src/hooks/use-keyboard-shortcuts.ts +74 -0
  385. package/client/src/hooks/use-media-query.ts +46 -0
  386. package/client/src/hooks/use-mobile.tsx +19 -0
  387. package/client/src/hooks/use-page-title.ts +21 -0
  388. package/client/src/hooks/use-toast.ts +195 -0
  389. package/client/src/index.css +694 -0
  390. package/client/src/lib/__tests__/accessibility.test.ts +104 -0
  391. package/client/src/lib/__tests__/date-utils.test.ts +199 -0
  392. package/client/src/lib/__tests__/dsp-buyer-api.test.ts +127 -0
  393. package/client/src/lib/__tests__/dsp-buyer-integration.test.ts +247 -0
  394. package/client/src/lib/__tests__/storage-utils.test.ts +167 -0
  395. package/client/src/lib/__tests__/utils.test.ts +57 -0
  396. package/client/src/lib/accessibility.ts +141 -0
  397. package/client/src/lib/api-config.ts +9 -0
  398. package/client/src/lib/auth-service.ts +209 -0
  399. package/client/src/lib/campaign-creative-api.ts +82 -0
  400. package/client/src/lib/company-api.ts +61 -0
  401. package/client/src/lib/content-hub-api.ts +407 -0
  402. package/client/src/lib/creative-mapper.ts +61 -0
  403. package/client/src/lib/date-utils.ts +119 -0
  404. package/client/src/lib/deal-helpers.ts +220 -0
  405. package/client/src/lib/dsp-buyer-api.ts +196 -0
  406. package/client/src/lib/geo-import-api.ts +151 -0
  407. package/client/src/lib/google-poi-api.ts +305 -0
  408. package/client/src/lib/i18n/__tests__/formatting.test.ts +202 -0
  409. package/client/src/lib/i18n/formatting.ts +130 -0
  410. package/client/src/lib/i18n/index.ts +8 -0
  411. package/client/src/lib/i18n-compat.ts +76 -0
  412. package/client/src/lib/influence-deals-api.ts +896 -0
  413. package/client/src/lib/inventory-api.ts +399 -0
  414. package/client/src/lib/oauth-service.ts +678 -0
  415. package/client/src/lib/poi-types.ts +75 -0
  416. package/client/src/lib/queryClient.ts +144 -0
  417. package/client/src/lib/recommendation-api.ts +380 -0
  418. package/client/src/lib/storage-utils.ts +104 -0
  419. package/client/src/lib/tolgee.ts +85 -0
  420. package/client/src/lib/utils.ts +0 -0
  421. package/client/src/main.tsx +67 -0
  422. package/client/src/mapbox-draw-modes.d.ts +32 -0
  423. package/client/src/pages/all-folders.tsx +203 -0
  424. package/client/src/pages/auth-callback.tsx +115 -0
  425. package/client/src/pages/buyer-form.tsx +339 -0
  426. package/client/src/pages/buyer-list.tsx +622 -0
  427. package/client/src/pages/content-hub.tsx +1358 -0
  428. package/client/src/pages/create-deal.tsx +2093 -0
  429. package/client/src/pages/creative-assignment-page.tsx +548 -0
  430. package/client/src/pages/creatives.tsx +5 -0
  431. package/client/src/pages/custom-pois.tsx +425 -0
  432. package/client/src/pages/dashboard.tsx +615 -0
  433. package/client/src/pages/deal-history.tsx +434 -0
  434. package/client/src/pages/deal-line-items.tsx +1703 -0
  435. package/client/src/pages/demo-status.tsx +113 -0
  436. package/client/src/pages/direct-campaign-details.tsx +361 -0
  437. package/client/src/pages/direct-campaigns-new.tsx +824 -0
  438. package/client/src/pages/dsp-form.tsx +803 -0
  439. package/client/src/pages/dsp-list.tsx +239 -0
  440. package/client/src/pages/folder-content.tsx +336 -0
  441. package/client/src/pages/integrations.tsx +429 -0
  442. package/client/src/pages/line-item-creatives.tsx +789 -0
  443. package/client/src/pages/line-item-detail-page.tsx +684 -0
  444. package/client/src/pages/line-item-form-page.tsx +3261 -0
  445. package/client/src/pages/line-item-wizard.tsx +1207 -0
  446. package/client/src/pages/login.tsx +154 -0
  447. package/client/src/pages/not-found.tsx +23 -0
  448. package/client/src/pages/proof-of-play.tsx +397 -0
  449. package/client/src/pages/public-approval.tsx +551 -0
  450. package/client/src/pages/reports.tsx +231 -0
  451. package/client/src/pages/settings.tsx +760 -0
  452. package/client/src/pages/signals.tsx +389 -0
  453. package/client/src/pages/tags.tsx +318 -0
  454. package/client/src/pages/test-results.tsx +328 -0
  455. package/client/src/store/hooks.ts +5 -0
  456. package/client/src/store/index.ts +15 -0
  457. package/client/src/store/mapMarkerLocationsSlice.ts +241 -0
  458. package/client/src/styles/design-tokens.css +324 -0
  459. package/client/src/test/setup.ts +261 -0
  460. package/client/src/test/test-utils.tsx +40 -0
  461. package/client/src/types/approval.ts +221 -0
  462. package/client/src/types/content-hub.ts +209 -0
  463. package/client/src/types/geofencing.ts +67 -0
  464. package/client/src/types/transcoding.ts +140 -0
  465. package/client/src/vite-env.d.ts +18 -0
  466. package/components.json +20 -0
  467. package/creative-api.json +1 -0
  468. package/docs/AI_REFERENCE.md +459 -0
  469. package/docs/MWDesign-Prompt.md +132 -0
  470. package/docs/MWDesign-System.md +344 -0
  471. package/docs/test-plan.md +277 -0
  472. package/e2e/AUTONOMOUS-TESTING.md +406 -0
  473. package/e2e/README.md +219 -0
  474. package/e2e/autonomous-flow.spec.ts +308 -0
  475. package/e2e/debug-sso.spec.ts +163 -0
  476. package/e2e/direct-campaigns.spec.ts +219 -0
  477. package/e2e/explore-sso.spec.ts +149 -0
  478. package/e2e/fixtures/auth.ts +26 -0
  479. package/e2e/fixtures/enhanced-test.ts +331 -0
  480. package/e2e/pagination.spec.ts +280 -0
  481. package/e2e/view-toggle.spec.ts +312 -0
  482. package/generated-icon.png +0 -0
  483. package/i18next-scanner.config.cjs +46 -0
  484. package/package.json +141 -0
  485. package/playwright.config.ts +93 -0
  486. package/postcss.config.js +6 -0
  487. package/replit.md +196 -0
  488. package/screenshot-after-login.png +0 -0
  489. package/screenshot-contenthub-grid.png +0 -0
  490. package/screenshot-contenthub-list-fixed.png +0 -0
  491. package/screenshot-contenthub-list.png +0 -0
  492. package/screenshot-create-deal.png +0 -0
  493. package/screenshot-dashboard.png +0 -0
  494. package/screenshot-deals.png +0 -0
  495. package/screenshot-login-filled.png +0 -0
  496. package/screenshot-login.png +0 -0
  497. package/screenshot.mjs +24 -0
  498. package/scripts/deploy-stg.sh +185 -0
  499. package/shared/direct-io-schema.ts +383 -0
  500. package/shared/schema.ts +439 -0
  501. package/shared/screen-types.ts +149 -0
  502. package/springdocDefault.json +1 -0
  503. package/swagger-ui-bundle.js +2 -0
  504. package/swagger-ui-init.js +10316 -0
  505. package/tailwind.config.ts +282 -0
  506. package/terraform/README.md +306 -0
  507. package/terraform/cloudfront.tf +289 -0
  508. package/terraform/ecs.tf +727 -0
  509. package/terraform/environments/dev.tfvars +59 -0
  510. package/terraform/environments/production.tfvars +60 -0
  511. package/terraform/main.tf +47 -0
  512. package/terraform/outputs.tf +145 -0
  513. package/terraform/s3.tf +192 -0
  514. package/terraform/variables.tf +226 -0
  515. package/terraform/waf.tf +165 -0
  516. package/terraform-frontend/.terraform.lock.hcl +25 -0
  517. package/terraform-frontend/README.md +85 -0
  518. package/terraform-frontend/cloudfront.tf +125 -0
  519. package/terraform-frontend/main.tf +31 -0
  520. package/terraform-frontend/outputs.tf +24 -0
  521. package/terraform-frontend/terraform.tfvars +12 -0
  522. package/terraform-frontend/variables.tf +53 -0
  523. package/tsconfig.json +23 -0
  524. package/vite.config.ts +226 -0
  525. package/vitest.config.ts +56 -0
@@ -0,0 +1,422 @@
1
+ # DOOH AdServer API - Test Cases Documentation
2
+
3
+ ## Overview
4
+
5
+ This document provides a comprehensive list of all E2E test cases covering the DOOH AdServer API. All tests use source `influence` and cover positive (happy path) and negative (error handling) scenarios.
6
+
7
+ **Total Test Cases: 143**
8
+ - Positive Scenarios: 61
9
+ - Negative Scenarios: 21
10
+ - Workflow/Integration Tests: 39
11
+ - Dual ID Resolution Tests: 22
12
+
13
+ ---
14
+
15
+ ## Test Categories Summary
16
+
17
+ | # | Category | Test Count | Description |
18
+ |---|----------|------------|-------------|
19
+ | 1 | PROGRAMMATIC - GUARANTEED | 18 | Full workflow: create, read, update, creatives |
20
+ | 2 | PROGRAMMATIC - PREFERRED_DEAL | 2 | CPS cost type, auction type verification |
21
+ | 3 | PROGRAMMATIC - PRIVATE_AUCTION | 7 | First price auction, VIDEO creatives |
22
+ | 4 | PROGRAMMATIC - EVERGREEN_PMP | 6 | Second price auction, AUDIO creatives |
23
+ | 5 | DIRECT Mode | 13 | Targeting, planning, aggregation |
24
+ | 6 | Deal List Filtering | 8 | Search, filter, pagination |
25
+ | 7 | Validation Rules | 8 | Schema validation, constraints |
26
+ | 8 | Inventory Assignment | 3 | Inventory creation with line items |
27
+ | 9 | Schedule Array Tests | 3 | Schedule rules validation |
28
+ | 10 | Auto-Calculation | 8 | Metrics aggregation |
29
+ | 11 | DIRECT Targeting Edge Cases | 14 | Demographics, geofencing, deliveryTargeting |
30
+ | 12 | PROGRAMMATIC Targeting | 7 | Targeting acceptance, deliveryTargeting rejection |
31
+ | 13 | Edge Cases - Validation | 11 | Error handling, constraints |
32
+ | 14 | Cleanup | 3 | Archive workflow |
33
+
34
+ ---
35
+
36
+ ## 1. PROGRAMMATIC Mode - GUARANTEED Deal (18 tests)
37
+
38
+ ### Positive Scenarios
39
+ | Test Case | Description |
40
+ |-----------|-------------|
41
+ | should create a GUARANTEED deal | Creates deal with all required fields, buyers, seller |
42
+ | should get deal by dealId with full details | Retrieves deal using generated dealId |
43
+ | should get deal by UUID | Retrieves deal using internal UUID |
44
+ | should create a DISPLAY line item | Creates line item with resolutions, pacing, schedule |
45
+ | should get line item by id with full details | Retrieves line item with all nested data |
46
+ | should update deal status to APPROVED | Status transition for creative assignment |
47
+ | should get line items by dealId | Lists all line items for a deal |
48
+ | should get line item by externalId | Retrieves using external identifier |
49
+ | should update line item | Updates bidFloor, deliveryGoal |
50
+ | should assign DISPLAY creative with matching resolution | Creative assignment workflow |
51
+ | should approve pending creative | Creative approval workflow |
52
+ | should get creatives by dealId | Lists creatives for deal |
53
+ | should get creatives by lineItemId | Lists creatives for line item |
54
+ | should get creative by creativeId | Retrieves by creativeId |
55
+ | should get creative by UUID | Retrieves by internal UUID |
56
+
57
+ ### Negative Scenarios
58
+ | Test Case | Description |
59
+ |-----------|-------------|
60
+ | should reject creative with mismatched resolution | Resolution validation |
61
+ | should reject creative with mismatched type | Type validation (DISPLAY vs VIDEO) |
62
+ | should not allow rejecting approved creative | Status transition constraint |
63
+
64
+ ---
65
+
66
+ ## 2. PROGRAMMATIC Mode - PREFERRED_DEAL (2 tests)
67
+
68
+ | Test Case | Type | Description |
69
+ |-----------|------|-------------|
70
+ | should create a PREFERRED_DEAL with CPS cost type | Positive | CPS allowed for non-guaranteed |
71
+ | should verify PREFERRED_DEAL has auctionType 3 | Positive | Fixed price auction |
72
+
73
+ ---
74
+
75
+ ## 3. PROGRAMMATIC Mode - PRIVATE_AUCTION (7 tests)
76
+
77
+ ### Positive Scenarios
78
+ | Test Case | Description |
79
+ |-----------|-------------|
80
+ | should create a PRIVATE_AUCTION with first price auction | auctionType 1 |
81
+ | should verify PRIVATE_AUCTION has auctionType 1 | Auction type validation |
82
+ | should create VIDEO line item | VIDEO creativeType with duration |
83
+ | should update PRIVATE_AUCTION deal status to APPROVED | Status workflow |
84
+ | should assign VIDEO creative | VIDEO creative assignment |
85
+ | should reject VIDEO creative | Creative rejection workflow |
86
+
87
+ ### Negative Scenarios
88
+ | Test Case | Description |
89
+ |-----------|-------------|
90
+ | should not allow approving rejected creative | Status transition constraint |
91
+
92
+ ---
93
+
94
+ ## 4. PROGRAMMATIC Mode - EVERGREEN_PMP (6 tests)
95
+
96
+ | Test Case | Type | Description |
97
+ |-----------|------|-------------|
98
+ | should create an EVERGREEN_PMP with second price auction | Positive | auctionType 2 |
99
+ | should verify EVERGREEN_PMP has auctionType 2 | Positive | Auction type validation |
100
+ | should update EVERGREEN_PMP deal status to APPROVED | Positive | Status workflow |
101
+ | should create AUDIO line item | Positive | AUDIO creativeType |
102
+ | should assign AUDIO creative (no resolution required) | Positive | AUDIO creative assignment |
103
+ | should approve AUDIO creative | Positive | Approval workflow |
104
+
105
+ ---
106
+
107
+ ## 5. DIRECT Mode (13 tests)
108
+
109
+ ### Positive Scenarios
110
+ | Test Case | Description |
111
+ |-----------|-------------|
112
+ | should create a DIRECT deal | Full DIRECT deal with brand, clientType |
113
+ | should verify DIRECT deal has correct mode and type | Mode/type validation |
114
+ | should create DIRECT line item with comprehensive targeting | Demographics, venueTypes, geofencing |
115
+ | should return comprehensive targeting in DIRECT line item response | Response structure |
116
+ | should update DIRECT line item targeting | Targeting update |
117
+ | should assign creative to DIRECT line item | Creative assignment |
118
+ | should create DIRECT line item with planning data | Capacity, allocation, estimates, pricing |
119
+ | should return planning data in DIRECT line item response | Planning response |
120
+ | should update DIRECT line item planning data | Planning update |
121
+ | should verify updated planning data persisted | Persistence check |
122
+ | should aggregate planning from line items to deal level | Deal-level aggregation |
123
+ | should create second DIRECT line item for aggregation test | Multi-item setup |
124
+ | should correctly aggregate planning from multiple line items | Multiple item aggregation |
125
+
126
+ ---
127
+
128
+ ## 6. Deal List Filtering (8 tests)
129
+
130
+ | Test Case | Type | Description |
131
+ |-----------|------|-------------|
132
+ | should get all deals | Positive | List endpoint |
133
+ | should filter deals by mode=PROGRAMMATIC | Positive | Mode filter |
134
+ | should filter deals by mode=DIRECT | Positive | Mode filter |
135
+ | should filter deals by dealType | Positive | Type filter |
136
+ | should filter deals by status | Positive | Status filter |
137
+ | should search deals by name | Positive | Search functionality |
138
+ | should filter deals by date range | Positive | Date filtering |
139
+ | should paginate deals | Positive | Pagination (limit, offset) |
140
+
141
+ ---
142
+
143
+ ## 7. Validation Rules (8 tests)
144
+
145
+ ### Negative Scenarios
146
+ | Test Case | Description |
147
+ |-----------|-------------|
148
+ | should reject GUARANTEED deal with CPS cost type | CPS not allowed for GUARANTEED |
149
+ | should reject PROGRAMMATIC deal with dealType=DIRECT | Invalid dealType |
150
+ | should reject DIRECT deal with dealType=GUARANTEED | Invalid dealType |
151
+ | should reject line item with invalid creativeType | Enum validation |
152
+ | should reject line item with missing required fields | Required field validation |
153
+ | should reject line item with invalid resolution format | Resolution pattern |
154
+ | should reject deal with missing required fields | Required field validation |
155
+ | should reject invalid mode value | Enum validation |
156
+
157
+ ---
158
+
159
+ ## 8. Inventory Assignment (4 tests)
160
+
161
+ | Test Case | Type | Description |
162
+ |-----------|------|-------------|
163
+ | should create line item with inventories array | Positive | Inventory creation |
164
+ | should return inventories in line item response | Positive | Response includes inventories |
165
+ | should allow same inventory to be assigned to multiple line items | Positive | Shared inventory across line items |
166
+ | should update line item inventories | Positive | Inventory update |
167
+
168
+ ---
169
+
170
+ ## 9. Schedule Array Tests (3 tests)
171
+
172
+ | Test Case | Type | Description |
173
+ |-----------|------|-------------|
174
+ | should accept schedule with DEFAULT rule | Positive | Default schedule |
175
+ | should accept schedule with all rule types | Positive | DEFAULT, WEEKDAY, WEEKEND, CUSTOM |
176
+ | should reject schedule with invalid type | Negative | Type validation |
177
+
178
+ ---
179
+
180
+ ## 10. Auto-Calculation Edge Tests (8 tests)
181
+
182
+ | Test Case | Type | Description |
183
+ |-----------|------|-------------|
184
+ | should create a deal for auto-calculation testing | Positive | Setup |
185
+ | should auto-calculate deal dates from line items | Positive | startDate/endDate aggregation |
186
+ | should auto-calculate lineItemsCount from active line items | Positive | Count aggregation |
187
+ | should auto-calculate timezoneId from first line item | Positive | Timezone inheritance |
188
+ | should auto-calculate unique publishers count | Positive | Publishers aggregation |
189
+ | should auto-calculate programmatic metrics from line items | Positive | impressions, netCost aggregation |
190
+ | should update deal auto-calculated fields when line item archived | Positive | Recalculation on archive |
191
+ | should archive auto-calculation test deal | Positive | Cleanup |
192
+
193
+ ---
194
+
195
+ ## 11. DIRECT Targeting Edge Cases (14 tests)
196
+
197
+ ### Positive Scenarios
198
+ | Test Case | Description |
199
+ |-----------|-------------|
200
+ | should create DIRECT deal for targeting edge tests | Setup |
201
+ | should accept DIRECT line item with empty targeting object | Empty object allowed |
202
+ | should accept DIRECT line item with partial demographics | Partial data allowed |
203
+ | should accept DIRECT line item with venueTypes using dot-notation | Hierarchical venue types |
204
+ | should accept DIRECT line item with geofencing polygon (exclusion zone) | Polygon with included=false |
205
+ | should accept DIRECT line item with weather-based deliveryTargeting | Weather signals |
206
+ | should accept DIRECT line item with metadata version tracking | Metadata fields |
207
+ | should accept partial update of targeting only | Partial PUT |
208
+ | should archive targeting edge test deal | Cleanup |
209
+
210
+ ### Negative Scenarios
211
+ | Test Case | Description |
212
+ |-----------|-------------|
213
+ | should reject DIRECT line item with invalid gender value | Gender enum validation |
214
+ | should reject DIRECT line item with invalid geometry type | Geometry type validation |
215
+ | should reject DIRECT line item with invalid temperature unit | Unit enum validation |
216
+ | should reject DIRECT line item with invalid inventoryFilteredBy value | Array value validation |
217
+ | should reject DIRECT line item with invalid venueTaxonomyFormat | Format validation |
218
+
219
+ ---
220
+
221
+ ## 12. PROGRAMMATIC Mode Targeting (7 tests)
222
+
223
+ ### Positive Scenarios
224
+ | Test Case | Description |
225
+ |-----------|-------------|
226
+ | should create PROGRAMMATIC deal for rejection tests | Setup |
227
+ | should create PROGRAMMATIC line item WITHOUT targeting (baseline) | Baseline creation |
228
+ | should accept targeting for PROGRAMMATIC line item | Demographics, venueTypes, geofencing |
229
+ | should accept PROGRAMMATIC line item with geofencing | Polygon + locations |
230
+ | should update PROGRAMMATIC line item targeting and verify persistence | Update + GET verification |
231
+ | should archive programmatic rejection test deal | Cleanup |
232
+
233
+ ### Negative Scenarios
234
+ | Test Case | Description |
235
+ |-----------|-------------|
236
+ | should reject deliveryTargeting for PROGRAMMATIC line item | DIRECT-only validation |
237
+ | should reject PROGRAMMATIC line item update with deliveryTargeting | Update rejection with error payload |
238
+
239
+ ---
240
+
241
+ ## 13. Edge Cases - Validation & Error Handling (11 tests)
242
+
243
+ ### Positive Scenarios
244
+ | Test Case | Description |
245
+ |-----------|-------------|
246
+ | should create DIRECT deal for inventory planning tests | Setup |
247
+ | should create DIRECT line item with inventory-level planning | Inventory planning |
248
+ | should retrieve line items and verify inventories | Inventory retrieval |
249
+ | should handle empty schedule array | Empty array allowed |
250
+ | should accept schedule with all rule types | Multiple schedule rules |
251
+ | should archive edge test deal | Cleanup |
252
+
253
+ ### Negative Scenarios
254
+ | Test Case | Description |
255
+ |-----------|-------------|
256
+ | should reject DIRECT deal missing required fields | Required validation |
257
+ | should reject invalid dealType for PROGRAMMATIC mode | Type constraint |
258
+ | should reject line item with invalid schedule type | Schedule validation |
259
+ | should reject duplicate externalId with detailed error message | Unique constraint with details |
260
+ | should handle GET non-existent deal | 404 response |
261
+ | should handle GET non-existent line item | 404 response |
262
+
263
+ ---
264
+
265
+ ## 14. Dual ID Resolution - UUID or dealId (22 tests)
266
+
267
+ All endpoints now accept either UUID (`id` field) or dealId (`deal_id` field) for deal lookups.
268
+
269
+ | Test Case | Type | Description |
270
+ |-----------|------|-------------|
271
+ | should create a deal for dual ID testing | Setup | Creates test deal |
272
+ | should GET deal by dealId | Positive | Traditional lookup |
273
+ | should GET deal by UUID (id field) | Positive | UUID lookup |
274
+ | should PUT deal by UUID | Positive | Update via UUID |
275
+ | should create line item for dual ID testing | Setup | Creates test line item |
276
+ | should GET line items using deal UUID | Positive | List via UUID |
277
+ | should GET line item using deal UUID and line item id | Positive | Nested UUID lookup |
278
+ | should GET line item using deal UUID and externalId | Positive | Mixed identifier lookup |
279
+ | should PUT line item using deal UUID | Positive | Update via UUID |
280
+ | should POST creative using deal UUID | Positive | Create via UUID |
281
+ | should GET creatives using deal UUID | Positive | List creatives via UUID |
282
+ | should GET creatives using deal UUID and line item externalId | Positive | Nested list via UUID |
283
+ | should GET single creative using deal UUID | Positive | Single creative via UUID |
284
+ | should GET creative by creative UUID using deal UUID | Positive | Dual UUID lookup |
285
+ | should POST approve creative using deal UUID | Positive | Approve via UUID |
286
+ | should create another creative for reject test | Setup | Creates test creative |
287
+ | should POST reject creative using deal UUID | Positive | Reject via UUID |
288
+ | should create creative for delete test | Setup | Creates test creative |
289
+ | should DELETE creative using deal UUID | Positive | Delete via UUID |
290
+ | should DELETE creative by creative UUID using deal UUID | Positive | Dual UUID delete |
291
+ | should archive deal using UUID | Positive | Archive via UUID |
292
+ | should verify archived deal by UUID | Positive | Verify status via UUID |
293
+
294
+ ---
295
+
296
+ ## 15. Cleanup - Archive Deals (2 tests)
297
+
298
+ | Test Case | Type | Description |
299
+ |-----------|------|-------------|
300
+ | should archive (soft delete) deals | Positive | Soft delete workflow |
301
+ | should verify archived deals have ARCHIVED status | Positive | Status verification |
302
+
303
+ ---
304
+
305
+ ## Test Execution
306
+
307
+ ### Run All Tests
308
+ ```bash
309
+ npm test
310
+ ```
311
+
312
+ ### Run Tests with Verbose Output
313
+ ```bash
314
+ node --test --test-reporter spec tests/e2e-comprehensive.test.js
315
+ ```
316
+
317
+ ### Expected Results
318
+ - All 149 tests should pass
319
+ - No null values in critical fields
320
+ - All workflows covered (create, read, update, archive, approve, reject)
321
+
322
+ ---
323
+
324
+ ## API Workflows Covered
325
+
326
+ | Workflow | Endpoints Tested |
327
+ |----------|------------------|
328
+ | **Create** | POST /deals, POST /line-items, POST /creatives |
329
+ | **Read** | GET /deals, GET /deals/:id, GET /line-items, GET /creatives |
330
+ | **Update** | PUT /deals/:id, PUT /line-items/:id |
331
+ | **List** | GET /deals (with filters, search, pagination) |
332
+ | **Archive** | DELETE /deals/:id (soft delete) |
333
+ | **Assign** | POST /creatives (assignment to line items) |
334
+ | **Approve** | POST /creatives/:id with decision: APPROVED |
335
+ | **Reject** | POST /creatives/:id with decision: REJECTED |
336
+ | **Schedule** | Line item schedule array management |
337
+ | **Planning** | DIRECT mode planning data (capacity, allocation, estimates, pricing) |
338
+ | **Targeting** | Both modes: demographics, venueTypes, geofencing |
339
+ | **DeliveryTargeting** | DIRECT only: weather signals |
340
+
341
+ ---
342
+
343
+ ## Coverage Summary
344
+
345
+ | Feature | PROGRAMMATIC | DIRECT |
346
+ |---------|--------------|--------|
347
+ | Deal CRUD | ✅ | ✅ |
348
+ | Line Item CRUD | ✅ | ✅ |
349
+ | Creative CRUD | ✅ | ✅ |
350
+ | Inventory Assignment | ✅ | ✅ |
351
+ | Targeting | ✅ | ✅ |
352
+ | DeliveryTargeting | ❌ (rejected) | ✅ |
353
+ | Planning | ❌ | ✅ |
354
+ | Schedule Management | ✅ | ✅ |
355
+ | Pacing | ✅ | ✅ |
356
+ | Status Workflow | ✅ | ✅ |
357
+ | Creative Approval | ✅ | ✅ |
358
+ | Creative Rejection | ✅ | ✅ |
359
+ | Auto-Calculation | ✅ | ✅ |
360
+ | Aggregation | ✅ | ✅ |
361
+ | Extended Fields (priority, customFees, frequencyCap, trafficAllocation, inventorySource) | ✅ | ✅ |
362
+ | Base Price Fields (bidFloorBase, pricing.cpmBase, pricing.estimatedCostBase) | ✅ | ✅ |
363
+
364
+ ---
365
+
366
+ ## 15. Line Item Extended Fields (10 tests)
367
+
368
+ ### Positive Scenarios
369
+ | Test Case | Description |
370
+ |-----------|-------------|
371
+ | should create line item with priority field | Priority value 1-10 for scheduling |
372
+ | should create line item with customFees array | Array of fee objects (name, amount, type, invoiced) |
373
+ | should create line item with frequencyCap | Object with period (hour/day/week/month/lifetime) and target |
374
+ | should create line item with trafficAllocation | Percentage field 0-100 for traffic distribution |
375
+ | should create line item with inventorySource | String field for inventory origin tracking |
376
+ | should update line item extended fields | All extended fields can be updated |
377
+ | should return extended fields in GET response | Fields appear in line item detail response |
378
+
379
+ ### Negative Scenarios
380
+ | Test Case | Description |
381
+ |-----------|-------------|
382
+ | should reject priority outside valid range (1-10) | Validation: priority must be 1-10 |
383
+ | should reject percentage fee amount > 100 | Validation: percentage fees max 100% |
384
+ | should reject trafficAllocation outside range (0-100) | Validation: allocation percentage bounds |
385
+
386
+ ---
387
+
388
+ ## 16. Base Price Fields (6 tests)
389
+
390
+ ### Positive Scenarios
391
+ | Test Case | Description |
392
+ |-----------|-------------|
393
+ | should create PROGRAMMATIC line item with bidFloorBase | Base bid floor before custom fees |
394
+ | should create DIRECT line item with pricing.cpmBase | Base CPM before custom fees |
395
+ | should create DIRECT line item with pricing.estimatedCostBase | Base estimated cost before custom fees |
396
+ | should update base price fields | All base price fields can be updated |
397
+ | should return bidFloorBase in programmatic object | Field appears in GET response under programmatic |
398
+ | should return pricing base fields in direct object | cpmBase and estimatedCostBase appear in GET response under direct.pricing |
399
+
400
+ ---
401
+
402
+ ## 17. DIRECT_PUBLISHER_SPLIT Import - Account & Advertiser (10 tests)
403
+
404
+ ### Positive Scenarios
405
+ | Test Case | Description |
406
+ |-----------|-------------|
407
+ | should capture full account and advertiser from import payload | All account (userId, companyName, companyId, externalId) and advertiser (id, seatId, name) fields are persisted on the deal |
408
+ | should persist all 4 account fields and return them via GET | userId, companyName, companyId, externalId all retrievable on deal GET |
409
+ | should persist all 3 advertiser fields and return them via GET | id, seatId, name all retrievable on deal GET |
410
+ | should import with only account (no advertiser) | Deal created successfully, account captured, advertiser defaults to {} |
411
+ | should import with only advertiser (no account) | Deal created successfully, advertiser captured, account is null |
412
+ | should import without account or advertiser | Deal created successfully, both fields absent/default |
413
+ | should capture account/advertiser with multi-publisher inventories | Account and advertiser persisted correctly alongside multiple line items from different publishers |
414
+ | should accept partial account (userId and companyName only) | Missing companyId/externalId still allows import |
415
+ | should accept partial advertiser (id and name, no seatId) | Missing seatId still allows import |
416
+ | should return account/advertiser in convert endpoint preview | Convert endpoint includes both fields in converted deal object |
417
+
418
+ ---
419
+
420
+ *Generated: February 2026*
421
+ *Source: influence*
422
+ *API Version: v1.6.0*
package/PCM/index.js ADDED
@@ -0,0 +1,106 @@
1
+ import express from 'express';
2
+ import cors from 'cors';
3
+ import fs from 'fs';
4
+ import path from 'path';
5
+ import { fileURLToPath } from 'url';
6
+ import swaggerUi from 'swagger-ui-express';
7
+ import swaggerJsdoc from 'swagger-jsdoc';
8
+ import sequelize, { testConnection } from './src/config/db.js';
9
+ import { requestLogger } from './src/middleware/logger.js';
10
+ import { errorHandler } from './src/middleware/errorHandler.js';
11
+ import dealsRouter from './src/routes/deals.js';
12
+ import lineItemsRouter from './src/routes/lineItems.js';
13
+ import creativesRouter from './src/routes/creatives.js';
14
+ import systemRouter from './src/routes/system.js';
15
+ import digitalSignageRouter from './src/routes/digitalSignage.js';
16
+ import approvalRouter from './src/routes/approval.js';
17
+ import { swaggerOptions } from './src/config/swagger.js';
18
+ import { setupAssociations } from './src/models/associations.js';
19
+
20
+ const __filename = fileURLToPath(import.meta.url);
21
+ const __dirname = path.dirname(__filename);
22
+
23
+ const app = express();
24
+ const PORT = process.env.PORT || 5000;
25
+
26
+ const swaggerSpec = swaggerJsdoc(swaggerOptions);
27
+
28
+ app.use(cors());
29
+ app.use(express.json());
30
+
31
+ app.use(requestLogger);
32
+
33
+ app.get('/', (req, res) => {
34
+ res.json({
35
+ message: 'DOOH AdServer API - v1.0',
36
+ status: 'running',
37
+ documentation: {
38
+ swagger: '/api-docs',
39
+ swaggerJson: '/api-docs.json',
40
+ testCases: '/docs/test-cases',
41
+ apiReference: '/docs/api-reference'
42
+ }
43
+ });
44
+ });
45
+
46
+ app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerSpec));
47
+
48
+ // Endpoint to download Swagger spec as JSON
49
+ app.get('/api-docs.json', (req, res) => {
50
+ res.setHeader('Content-Type', 'application/json');
51
+ res.setHeader('Content-Disposition', 'attachment; filename="dooh-adserver-api-spec.json"');
52
+ res.json(swaggerSpec);
53
+ });
54
+
55
+ // Documentation endpoints
56
+ app.get('/docs/test-cases', (req, res) => {
57
+ const filePath = path.join(__dirname, 'docs', 'TEST_CASES.md');
58
+ fs.readFile(filePath, 'utf8', (err, data) => {
59
+ if (err) {
60
+ return res.status(404).json({ error: 'Test cases documentation not found' });
61
+ }
62
+ res.setHeader('Content-Type', 'text/markdown; charset=utf-8');
63
+ res.send(data);
64
+ });
65
+ });
66
+
67
+ app.get('/docs/api-reference', (req, res) => {
68
+ const filePath = path.join(__dirname, 'replit.md');
69
+ fs.readFile(filePath, 'utf8', (err, data) => {
70
+ if (err) {
71
+ return res.status(404).json({ error: 'API reference documentation not found' });
72
+ }
73
+ res.setHeader('Content-Type', 'text/markdown; charset=utf-8');
74
+ res.send(data);
75
+ });
76
+ });
77
+
78
+ app.use('/api/v1/rest', systemRouter);
79
+ app.use('/api/v1/rest/deals', dealsRouter);
80
+ app.use('/api/v1/rest/deals/:dealId/line-items', lineItemsRouter);
81
+ app.use('/api/v1/rest/deals/:dealId/creatives', creativesRouter);
82
+ app.use('/api/v1/rest/deals/:dealId/line-items/:lineItemId/creatives', creativesRouter);
83
+
84
+ app.use('/api/v2/rest/ds', digitalSignageRouter);
85
+
86
+ app.use('/api/v1/public/approval', approvalRouter);
87
+
88
+ app.use(errorHandler);
89
+
90
+ const startServer = async () => {
91
+ try {
92
+ await testConnection();
93
+
94
+ setupAssociations();
95
+
96
+ app.listen(PORT, '0.0.0.0', () => {
97
+ console.log(`DOOH AdServer running on port ${PORT}`);
98
+ console.log(`Base path: /api/v1/rest`);
99
+ });
100
+ } catch (error) {
101
+ console.error('Failed to start server:', error);
102
+ process.exit(1);
103
+ }
104
+ };
105
+
106
+ startServer();