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
package/package.json ADDED
@@ -0,0 +1,141 @@
1
+ {
2
+ "name": "adserver-dashboard",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "license": "MIT",
6
+ "engines": {
7
+ "node": ">=20.0.0"
8
+ },
9
+ "scripts": {
10
+ "dev": "vite --host 0.0.0.0 --port 5000",
11
+ "build": "vite build",
12
+ "preview": "vite preview --host 0.0.0.0 --port 5000",
13
+ "check": "tsc",
14
+ "test": "vitest run",
15
+ "test:watch": "vitest",
16
+ "test:coverage": "vitest run --coverage",
17
+ "test:results": "mkdir -p client/public/test-results && vitest run --reporter=json --outputFile=client/public/test-results/results.json || true",
18
+ "test:ui": "vitest --ui",
19
+ "test:e2e": "playwright test",
20
+ "test:e2e:ui": "playwright test --ui",
21
+ "test:e2e:headed": "playwright test --headed",
22
+ "test:e2e:debug": "playwright test --debug",
23
+ "playwright:install": "playwright install chromium",
24
+ "playwright:report": "playwright show-report",
25
+ "i18n:scan": "i18next-scanner --config i18next-scanner.config.cjs"
26
+ },
27
+ "dependencies": {
28
+ "@hookform/resolvers": "^3.10.0",
29
+ "@jridgewell/trace-mapping": "^0.3.25",
30
+ "@mapbox/mapbox-gl-draw": "^1.5.0",
31
+ "@mapbox/mapbox-gl-geocoder": "^5.1.2",
32
+ "@moving-walls/design-system": "^1.0.11",
33
+ "@radix-ui/react-accordion": "^1.2.4",
34
+ "@radix-ui/react-alert-dialog": "^1.1.7",
35
+ "@radix-ui/react-aspect-ratio": "^1.1.3",
36
+ "@radix-ui/react-avatar": "^1.1.4",
37
+ "@radix-ui/react-checkbox": "^1.1.5",
38
+ "@radix-ui/react-collapsible": "^1.1.4",
39
+ "@radix-ui/react-context-menu": "^2.2.7",
40
+ "@radix-ui/react-dialog": "^1.1.7",
41
+ "@radix-ui/react-dropdown-menu": "^2.1.7",
42
+ "@radix-ui/react-hover-card": "^1.1.7",
43
+ "@radix-ui/react-label": "^2.1.3",
44
+ "@radix-ui/react-menubar": "^1.1.7",
45
+ "@radix-ui/react-navigation-menu": "^1.2.6",
46
+ "@radix-ui/react-popover": "^1.1.7",
47
+ "@radix-ui/react-progress": "^1.1.3",
48
+ "@radix-ui/react-radio-group": "^1.2.4",
49
+ "@radix-ui/react-scroll-area": "^1.2.4",
50
+ "@radix-ui/react-select": "^2.1.7",
51
+ "@radix-ui/react-separator": "^1.1.3",
52
+ "@radix-ui/react-slider": "^1.2.4",
53
+ "@radix-ui/react-slot": "^1.2.0",
54
+ "@radix-ui/react-switch": "^1.1.4",
55
+ "@radix-ui/react-tabs": "^1.1.4",
56
+ "@radix-ui/react-toast": "^1.2.7",
57
+ "@radix-ui/react-toggle": "^1.1.3",
58
+ "@radix-ui/react-toggle-group": "^1.1.3",
59
+ "@radix-ui/react-tooltip": "^1.2.0",
60
+ "@reduxjs/toolkit": "^2.11.2",
61
+ "@sentry/react": "^10.32.1",
62
+ "@tanstack/react-query": "^5.60.5",
63
+ "@testing-library/jest-dom": "^6.9.1",
64
+ "@testing-library/react": "^16.3.1",
65
+ "@testing-library/user-event": "^14.6.1",
66
+ "@tolgee/react": "^6.2.7",
67
+ "@types/leaflet": "^1.9.21",
68
+ "@types/mapbox__mapbox-gl-draw": "^1.4.9",
69
+ "@types/papaparse": "^5.5.2",
70
+ "@vitest/coverage-v8": "^4.0.16",
71
+ "@vitest/ui": "^4.0.16",
72
+ "ag-grid-react": "^35.0.1",
73
+ "class-variance-authority": "^0.7.1",
74
+ "clsx": "^2.1.1",
75
+ "cmdk": "^1.1.1",
76
+ "date-fns": "^3.6.0",
77
+ "embla-carousel-react": "^8.6.0",
78
+ "form-data": "^4.0.4",
79
+ "framer-motion": "^11.13.1",
80
+ "i18next": "^25.7.3",
81
+ "i18next-browser-languagedetector": "^8.2.0",
82
+ "i18next-http-backend": "^3.0.2",
83
+ "input-otp": "^1.4.2",
84
+ "jsdom": "^27.4.0",
85
+ "leaflet": "^1.9.4",
86
+ "lucide-react": "^0.453.0",
87
+ "mapbox-gl": "^3.16.0",
88
+ "mapbox-gl-draw-circle": "^1.1.2",
89
+ "mapbox-gl-draw-rectangle-mode": "^1.0.4",
90
+ "next-themes": "^0.4.6",
91
+ "papaparse": "^5.5.3",
92
+ "react": "^18.3.1",
93
+ "react-day-picker": "^8.10.1",
94
+ "react-dom": "^18.3.1",
95
+ "react-hook-form": "^7.55.0",
96
+ "react-i18next": "^16.5.1",
97
+ "react-icons": "^5.4.0",
98
+ "react-leaflet": "^4.2.1",
99
+ "react-markdown": "^10.1.0",
100
+ "react-redux": "^9.2.0",
101
+ "react-resizable-panels": "^2.1.7",
102
+ "recharts": "^2.15.2",
103
+ "remark-gfm": "^4.0.1",
104
+ "tailwind-merge": "^2.6.0",
105
+ "tailwindcss-animate": "^1.0.7",
106
+ "tw-animate-css": "^1.2.5",
107
+ "vaul": "^1.1.2",
108
+ "vitest": "^4.0.16",
109
+ "wouter": "^3.3.5",
110
+ "zod": "^3.24.2",
111
+ "zod-validation-error": "^3.4.0"
112
+ },
113
+ "devDependencies": {
114
+ "@playwright/test": "^1.57.0",
115
+ "@replit/vite-plugin-cartographer": "^0.4.4",
116
+ "@replit/vite-plugin-dev-banner": "^0.1.1",
117
+ "@replit/vite-plugin-runtime-error-modal": "^0.0.3",
118
+ "@tailwindcss/typography": "^0.5.15",
119
+ "@tailwindcss/vite": "^4.1.3",
120
+ "@types/node": "20.16.11",
121
+ "@types/react": "^18.3.11",
122
+ "@types/react-dom": "^18.3.1",
123
+ "@vitejs/plugin-react": "^4.7.0",
124
+ "autoprefixer": "^10.4.20",
125
+ "dotenv": "^17.2.3",
126
+ "i18next-scanner": "^4.6.0",
127
+ "postcss": "^8.4.47",
128
+ "tailwindcss": "^3.4.17",
129
+ "typescript": "5.6.3",
130
+ "vite": "^5.4.20",
131
+ "vite-plugin-pwa": "^1.2.0",
132
+ "workbox-window": "^7.4.0"
133
+ },
134
+ "optionalDependencies": {
135
+ "bufferutil": "^4.0.8"
136
+ },
137
+ "overrides": {
138
+ "minimist": "^1.2.8",
139
+ "underscore": "^1.13.6"
140
+ }
141
+ }
@@ -0,0 +1,93 @@
1
+ import { defineConfig, devices } from '@playwright/test';
2
+ import * as dotenv from 'dotenv';
3
+ import * as path from 'path';
4
+ import { fileURLToPath } from 'url';
5
+
6
+ // Get __dirname equivalent in ESM
7
+ const __filename = fileURLToPath(import.meta.url);
8
+ const __dirname = path.dirname(__filename);
9
+
10
+ // Load .env.test file
11
+ dotenv.config({ path: path.resolve(__dirname, '.env.test') });
12
+
13
+ /**
14
+ * Playwright Configuration for Local Development Testing
15
+ *
16
+ * This configuration is designed for local testing only.
17
+ * The frontend is deployed as a static site in CI/CD, so these tests
18
+ * are not part of the deployment pipeline.
19
+ */
20
+ export default defineConfig({
21
+ testDir: './e2e',
22
+
23
+ // Maximum time one test can run for
24
+ timeout: 30 * 1000,
25
+
26
+ // Run tests in files in parallel
27
+ fullyParallel: true,
28
+
29
+ // Fail the build on CI if you accidentally left test.only in the source code
30
+ forbidOnly: !!process.env.CI,
31
+
32
+ // Retry on CI only
33
+ retries: process.env.CI ? 2 : 0,
34
+
35
+ // Opt out of parallel tests on CI
36
+ workers: process.env.CI ? 1 : undefined,
37
+
38
+ // Reporter to use
39
+ reporter: 'html',
40
+
41
+ // Shared settings for all the projects below
42
+ use: {
43
+ // Base URL to use in actions like `await page.goto('/')`
44
+ baseURL: 'http://localhost:5000',
45
+
46
+ // Collect trace when retrying the failed test
47
+ trace: 'on-first-retry',
48
+
49
+ // Screenshot on failure
50
+ screenshot: 'only-on-failure',
51
+
52
+ // Video on failure
53
+ video: 'retain-on-failure',
54
+ },
55
+
56
+ // Configure projects for major browsers
57
+ projects: [
58
+ {
59
+ name: 'chromium',
60
+ use: { ...devices['Desktop Chrome'] },
61
+ },
62
+
63
+ // Uncomment to test on Firefox
64
+ // {
65
+ // name: 'firefox',
66
+ // use: { ...devices['Desktop Firefox'] },
67
+ // },
68
+
69
+ // Uncomment to test on WebKit (Safari)
70
+ // {
71
+ // name: 'webkit',
72
+ // use: { ...devices['Desktop Safari'] },
73
+ // },
74
+
75
+ // Uncomment to test mobile viewports
76
+ // {
77
+ // name: 'Mobile Chrome',
78
+ // use: { ...devices['Pixel 5'] },
79
+ // },
80
+ // {
81
+ // name: 'Mobile Safari',
82
+ // use: { ...devices['iPhone 12'] },
83
+ // },
84
+ ],
85
+
86
+ // Run your local dev server before starting the tests
87
+ webServer: {
88
+ command: 'npm run dev',
89
+ url: 'http://localhost:5000',
90
+ reuseExistingServer: !process.env.CI,
91
+ timeout: 120 * 1000,
92
+ },
93
+ });
@@ -0,0 +1,6 @@
1
+ export default {
2
+ plugins: {
3
+ tailwindcss: {},
4
+ autoprefixer: {},
5
+ },
6
+ }
package/replit.md ADDED
@@ -0,0 +1,196 @@
1
+ # Ad Server Platform
2
+
3
+ ## Overview
4
+
5
+ The Ad Server Platform is a comprehensive digital advertising solution designed for managing campaigns, screens, creatives, and ad delivery. It offers real-time analytics and geofencing capabilities. The platform aims to streamline ad operations, provide robust reporting, and enable precise targeting for advertisers, enhancing the efficiency and effectiveness of digital out-of-home (DOOH) advertising.
6
+
7
+ ## User Preferences
8
+
9
+ Preferred communication style: Simple, everyday language.
10
+
11
+ ## Demo Status / Changes Log
12
+
13
+ ### Recent Changes (Week of Feb 10–17, 2026)
14
+
15
+ #### Line Item Form - API Payload Cleanup
16
+ - Removed `unlimitedBudget` toggle (UI-only, not in API schema)
17
+ - Removed `signalEnabled` field from payload and UI (not supported by API)
18
+ - Removed generic Signals section (signalId/signalName) — API uses structured signal format
19
+ - Removed `automatedBidding` toggle from Bid Strategy section (not in API schema)
20
+ - Removed Billing section (billable/non-billable) from line item form (handled at deal level)
21
+ - Added `frequencyCap`, `trafficAllocation`, `inventorySource` to line item API payload and builder functions
22
+ - `deliveryTargeting` restricted to DIRECT deals only (API rejects it for PROGRAMMATIC)
23
+
24
+ #### Line Item Form - Weather Signals (DIRECT only)
25
+ - New "Delivery Signals" section with weather targeting matching API format
26
+ - Weather conditions grid: Sunny, Partly Cloudy, Cloudy, Rainy, Stormy, Snowy, Windy, Foggy, Hazy
27
+ - Temperature range: min/max with Celsius/Fahrenheit unit selector
28
+ - Payload format: `deliveryTargeting.signals.weather.conditions[]` + `temperature{min,max,unit}`
29
+ - Section hidden for PROGRAMMATIC deals
30
+
31
+ #### Line Item Form - Geofencing Fix
32
+ - Geofencing payload now sends `lat` and `lng` (required by API), not just location name
33
+ - Handles Point geometries (search/geocoding) and Polygon geometries (drawn areas via centroid)
34
+ - Edit mode properly restores `geoLocations` state from existing line item data
35
+
36
+ #### Line Item Form - Targeting Sections (Side Popover Pattern)
37
+ - SSP/Exchange, Inventory Type, Media Owner, Inventory Format all use consistent Sheet (side popover) pattern
38
+ - Replaced inline Collapsible with Sheet drawers for all targeting sections
39
+ - Venue Type uses recursive tree with unlimited hierarchy depth (API-driven)
40
+ - Real API integrations for companies (`/api/v1/companies?is_ssp=true`), inventory types (`/api/v1/inventory-types`), inventory display formats (`/api/v1/inventory-display-formats`)
41
+ - API queries only fire when drawer is open (`enabled: isSheetOpen`)
42
+
43
+ #### Deal Creation Page
44
+ - Removed description field from programmatic deal creation
45
+ - Removed seller field from deal list and filters
46
+ - Fixed impression multiplier type handling in deal creation payloads
47
+ - Updated deal creation form titles and field arrangements
48
+ - Removed status dropdown from deal creation page
49
+
50
+ #### Line Item Form - Other Improvements
51
+ - Added priority field to line item API payload
52
+ - Custom fees included in line item creation payload
53
+ - Geography map opens directly by clicking the row
54
+ - Form validation errors shown to user on save
55
+ - Bid Strategy and Auction Type hidden for traditional deals
56
+ - Scroll-aware tips in sidebar
57
+ - Form insights section improvements
58
+
59
+ #### DSP & Buyer Management
60
+ - Real API data for DSP and Buyer pages
61
+ - DSP list is read-only; Buyer CRUD operations with real API integration
62
+ - DSP and Buyer management added to side menu
63
+
64
+ #### UI/Layout
65
+ - Sticky sidebar navigation
66
+ - Theme selection in profile dropdown
67
+ - External links for inventory and measure pages in sidebar
68
+ - Custom toggle switch component for better visibility
69
+
70
+ ### Deals List Page
71
+ - Search bar, bordered table card, Type (PD/PG/Traditional), Source (Influence/Activate/Planner), amber badges
72
+
73
+ ### Sidebar & Header
74
+ - "DOOH Adserver" branding with blue "I" icon
75
+
76
+ ### Line Item Creatives Page
77
+ - Breadcrumbs, 4 metric cards, player status bar, search/filter toolbar, table view
78
+ - "Assign Creative" opens full-width side Sheet popover (not page navigation)
79
+
80
+ ### Creative Assignment Page
81
+ - Opens as full-width Sheet/popover overlay from Line Item Creatives page
82
+ - Left sidebar: numbered creative requirements with resolution/duration/type/inventory, drag-and-drop zones
83
+ - Right panel: Content Hub with search, filters, 4-column draggable card grid
84
+ - Sticky footer: Cancel / Save Assignment
85
+
86
+ ### Line Item Form - Base Pricing
87
+ - Programmatic: `bidFloorBase` (original bid floor before custom fees)
88
+ - Direct: `pricing.cpmBase`, `pricing.estimatedCostBase` (original values before custom fees)
89
+
90
+ ### Programmatic Deal Creation (PCM-Aligned)
91
+ - Cascading dependency: Deal Type → DSP → Buyer → Transaction Type → Currency
92
+ - No brand field for programmatic deals (brand only for DIRECT mode)
93
+ - Centralized DSP dropdown (not per-buyer rows); DSP disabled until Deal Type selected
94
+ - Buyer dropdown disabled until DSP selected; adds buyers as removable chips/badges
95
+ - Buyer constraints: single buyer for GUARANTEED/PREFERRED_DEAL, multiple for PRIVATE_AUCTION/EVERGREEN_PMP
96
+ - After buyer selection, DSP and Deal Type fields become locked
97
+ - Auction Type: HIDDEN except for PRIVATE_AUCTION (First Price / Second Price); auto-set to 3 for all others
98
+ - Hard Stop: only visible for GUARANTEED deal type
99
+ - Non-Billable: always visible as checkbox
100
+ - Impression Multiplier Type (MAD/CUSTOM): only visible when transactionType === AUDIENCE
101
+ - Seller section: name, phone, email fields with auto-populate from logged-in user
102
+ - Description textarea for optional notes
103
+ - Remove buyer resets dealType/DSP when last buyer removed
104
+ - Edit mode locks dealType (always), locks DSP when buyers exist
105
+
106
+ ### Deal Page Buyer Management (Legacy)
107
+ - DSP dropdown loads from `getDspDropdownList()` API with flexible field mapping (id/value/code, name/label/description)
108
+ - Buyers load from `listDspBuyers()` API, filtered by both `dspId` and `name` query params
109
+ - Both `activeDspId` and `activeDspName` are tracked; fallback to raw value if DSP not found in options
110
+ - Edit mode maps DSP names to IDs and resolves `buyerId` by matching `seatId` or `buyerName`
111
+
112
+ ### Line Item Form - Targeting Section (Prototype-aligned)
113
+ - Targeting section uses row-based design: flat rows with icon, label, count/status, checkmark
114
+ - Age Groups and Gender are separate expandable rows with inline checkbox grids
115
+ - POI Targeting opens a side drawer with POIs/Categories tabs, search, and checkboxes
116
+ - Venue Type opens a side drawer with search and checkboxes (recursive tree, API-driven)
117
+ - Both drawers have Cancel/Apply sticky footers and manage local state before persisting
118
+ - POI selections stored in `selectedPOIs` form field
119
+
120
+ ### Line Item Detail Page
121
+ - Full-page DV360-style detail view at `/deals/:dealId/line-items/:lineItemId`
122
+ - Shows summary cards (Budget, Impressions, Revenue, Dates), overview, targeting, inventories, creatives
123
+ - Line item row click in deal page navigates to detail page instead of opening side sheet
124
+
125
+ ### Deal Page - History Button
126
+ - Deal History moved from dropdown menu to icon-only button with tooltip next to Filter icon
127
+
128
+ ### Navigation Flow
129
+ - Line Items → Click row → Line Item Detail page → Edit button → Line Item Form
130
+ - Line Items → Creatives list → Assign Creative → Creative Assignment page → Back/Cancel → Creatives list
131
+
132
+ ## System Architecture
133
+
134
+ ### Frontend Architecture
135
+ - **Framework**: React 18 with TypeScript, built using Vite.
136
+ - **Styling**: Tailwind CSS with custom design tokens, leveraging Radix UI primitives, MWDesign System (`@moving-walls/design-system`), and shadcn/ui patterns.
137
+ - **State Management**: TanStack React Query for server state and Redux Toolkit for geofencing map state.
138
+ - **Forms**: React Hook Form with Zod validation.
139
+ - **Maps**: Mapbox GL for interactive geofencing and location features.
140
+ - **Routing**: wouter for client-side routing.
141
+ - **Internationalization**: Tolgee for multi-language support (English, Japanese, Chinese, Arabic) with in-context editing in development.
142
+
143
+ ### Backend Architecture
144
+ - The current deployment is frontend-only (static site via Vite).
145
+ - The frontend interacts with external API endpoints.
146
+ - Authentication is OAuth-based with SSO integration.
147
+
148
+ ### Project Structure
149
+ - `client/src/`: React frontend application (components, pages, hooks, lib).
150
+ - `shared/`: Shared TypeScript types and schemas.
151
+ - `e2e/`: Playwright end-to-end tests.
152
+ - `docs/`: Documentation.
153
+ - `terraform/`: Infrastructure as Code (AWS).
154
+ - `.ci/`: GitLab CI/CD pipelines.
155
+
156
+ ### Design System
157
+ - Utilizes the `@moving-walls/design-system` npm package, offering 50+ React components and 1000+ Lucide icons.
158
+ - Design tokens are managed via CSS custom properties.
159
+
160
+ ### Feature Specifications
161
+ - **Campaign Management**: Supports DIRECT and PROGRAMMATIC deal modes, with mode-aware wizards for deal creation and line item configuration.
162
+ - **DSP/Buyer Management**: Read-only DSP list and CRUD operations for DSP buyers with real API integration.
163
+ - **Line Item Form**: Single-page form with collapsible accordion sections, a two-column layout (form + sidebar for insights/tips/forecast), and dynamic input types (e.g., pill buttons for ad duration). Includes base pricing fields: `bidFloorBase` (programmatic) and `pricing.cpmBase`/`pricing.estimatedCostBase` (direct) for storing original values before custom fees.
164
+ - **Creative Management**: Split-view assignment page with drag-and-drop from Content Hub, grouped creative requirements, and status tracking.
165
+ - **Content Hub**: Unified page (`content-hub.tsx`) with grid/list views, folder cards, creative preview sheet (tags, status actions, download, transcode, delete), filter drawer, and pagination. All API integrations preserved (useFolders, useCreatives, useDeleteCreative, useApproveCreative, useRejectCreative, useUpdateCreative, useTranscodeCreative, useCreateFolder). The `/creatives` route delegates to this page.
166
+ - **Reporting & Analytics**: Dashboard with key metrics, impression delivery progress, and various reports for performance insights.
167
+ - **New Pages**: Integrates pages for Dashboard, Reports, Signals, Proof of Play, and Integrations with SSP/DSP partners.
168
+ - **Configuration Pages**: Settings (11 config sections), Tags (color-coded tag management), and Custom POIs (geolocation management with upload/create). All UI-only with mock data.
169
+ - **Profile Dropdown**: Settings navigates to in-app /settings page instead of external URL.
170
+
171
+ ## External Dependencies
172
+
173
+ ### Maps & Geolocation
174
+ - **Mapbox GL**: Core mapping library.
175
+ - **Mapbox GL Draw**: For creating and editing geofences.
176
+ - **Mapbox GL Geocoder**: For location search functionality.
177
+
178
+ ### UI Component Libraries
179
+ - **Radix UI**: Provides accessible, unstyled UI primitives.
180
+ - **cmdk**: For command palette interface.
181
+ - **embla-carousel-react**: For carousel components.
182
+ - **date-fns**: For date manipulation and formatting.
183
+
184
+ ### Internationalization
185
+ - **@tolgee/react**: For translation management and in-context editing.
186
+
187
+ ### Testing
188
+ - **Vitest**: For unit testing with `@testing-library/react` and `jsdom`.
189
+ - **Playwright**: For end-to-end testing.
190
+
191
+ ### Infrastructure (Terraform)
192
+ - **AWS Services**: CloudFront, S3, WAF, Route53, ACM for deployment and security.
193
+
194
+ ### Environment Configuration
195
+ - Requires Mapbox API tokens.
196
+ - Requires SSO configuration for authentication.
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
package/screenshot.mjs ADDED
@@ -0,0 +1,24 @@
1
+ import { chromium } from 'playwright';
2
+
3
+ const browser = await chromium.launch();
4
+ const page = await browser.newPage({ viewport: { width: 1440, height: 900 } });
5
+
6
+ // Go to login page
7
+ await page.goto('http://localhost:5000/login', { waitUntil: 'networkidle', timeout: 30000 });
8
+ await page.waitForTimeout(1000);
9
+
10
+ // Fill and submit login
11
+ await page.fill('input[type="email"], input[id*="email"], input[name*="email"]', 'jeki@jeki.com');
12
+ await page.fill('input[type="password"], input[id*="password"], input[name*="password"]', 'Jeki@123');
13
+ await page.click('button[type="submit"]');
14
+
15
+ // Quickly capture the loading state
16
+ await page.waitForTimeout(500);
17
+ await page.screenshot({ path: 'screenshot-auth-loader.png' });
18
+ console.log('Auth loader screenshot taken');
19
+
20
+ await page.waitForTimeout(3000);
21
+ await page.screenshot({ path: 'screenshot-auth-loader-2.png' });
22
+ console.log('Auth loader 2nd screenshot taken');
23
+
24
+ await browser.close();
@@ -0,0 +1,185 @@
1
+ #!/bin/bash
2
+ # Deployment script for MW-Influence-Adserver-FE
3
+ # Uses existing S3 bucket: s3://moving-audience-unified/influence-adserver-stg/
4
+ # CloudFront Distribution: MW-Influence-Adserver-FE (based on Inventory-STG reference)
5
+
6
+ set -e
7
+
8
+ echo "======================================"
9
+ echo "MW Influence AdServer - STG Deployment"
10
+ echo "======================================"
11
+
12
+ # Configuration
13
+ S3_BUCKET="moving-audience-unified"
14
+ S3_PREFIX="influence-adserver-stg"
15
+ CLOUDFRONT_DISTRIBUTION_NAME="MW-Influence-Adserver-FE"
16
+ AWS_REGION="${AWS_REGION:-us-east-1}"
17
+
18
+ # Colors for output
19
+ RED='\033[0;31m'
20
+ GREEN='\033[0;32m'
21
+ YELLOW='\033[1;33m'
22
+ NC='\033[0m' # No Color
23
+
24
+ # Function to print colored output
25
+ print_info() {
26
+ echo -e "${GREEN}[INFO]${NC} $1"
27
+ }
28
+
29
+ print_warning() {
30
+ echo -e "${YELLOW}[WARN]${NC} $1"
31
+ }
32
+
33
+ print_error() {
34
+ echo -e "${RED}[ERROR]${NC} $1"
35
+ }
36
+
37
+ # Check if AWS CLI is installed
38
+ if ! command -v aws &> /dev/null; then
39
+ print_error "AWS CLI is not installed. Please install it first."
40
+ exit 1
41
+ fi
42
+
43
+ print_info "AWS CLI version: $(aws --version)"
44
+
45
+ # Check AWS credentials
46
+ print_info "Checking AWS credentials..."
47
+ if ! aws sts get-caller-identity &> /dev/null; then
48
+ print_error "AWS credentials not configured. Run 'aws configure' first."
49
+ exit 1
50
+ fi
51
+
52
+ print_info "AWS Account: $(aws sts get-caller-identity --query Account --output text)"
53
+
54
+ # Step 1: Build MWDesign
55
+ print_info "Building MWDesign component library..."
56
+ cd MWDesign
57
+ if [ ! -d "node_modules" ]; then
58
+ print_info "Installing MWDesign dependencies..."
59
+ npm ci --production=false
60
+ fi
61
+ npm run build:package
62
+ print_info "✅ MWDesign build complete"
63
+ cd ..
64
+
65
+ # Step 2: Build AdServer Frontend
66
+ print_info "Building AdServer frontend..."
67
+ cd adserver
68
+ if [ ! -d "node_modules" ]; then
69
+ print_info "Installing adserver dependencies..."
70
+ npm ci --production=false
71
+ fi
72
+ npm run build:frontend
73
+ print_info "✅ AdServer frontend build complete"
74
+
75
+ # Step 3: Verify build output
76
+ if [ ! -d "dist/client" ]; then
77
+ print_error "Build failed - dist/client directory not found"
78
+ exit 1
79
+ fi
80
+
81
+ print_info "Build output size: $(du -sh dist/client | cut -f1)"
82
+
83
+ # Step 4: Sync to S3
84
+ print_info "Deploying to S3: s3://${S3_BUCKET}/${S3_PREFIX}/"
85
+
86
+ # Sync static assets (JS, CSS, images) with long cache
87
+ print_info "Uploading static assets with cache-control..."
88
+ aws s3 sync dist/client s3://${S3_BUCKET}/${S3_PREFIX}/ \
89
+ --delete \
90
+ --cache-control "public, max-age=31536000, immutable" \
91
+ --exclude "*.html" \
92
+ --exclude "*.json" \
93
+ --exclude "service-worker.js" \
94
+ --region ${AWS_REGION}
95
+
96
+ # Sync HTML and JSON files with no cache
97
+ print_info "Uploading HTML and JSON files without cache..."
98
+ aws s3 sync dist/client s3://${S3_BUCKET}/${S3_PREFIX}/ \
99
+ --cache-control "public, max-age=0, must-revalidate" \
100
+ --exclude "*" \
101
+ --include "*.html" \
102
+ --include "*.json" \
103
+ --include "service-worker.js" \
104
+ --region ${AWS_REGION}
105
+
106
+ print_info "✅ S3 sync complete"
107
+
108
+ # Step 5: Get CloudFront Distribution ID
109
+ print_info "Finding CloudFront distribution ID for ${CLOUDFRONT_DISTRIBUTION_NAME}..."
110
+ DISTRIBUTION_ID=$(aws cloudfront list-distributions \
111
+ --query "DistributionList.Items[?Comment=='${CLOUDFRONT_DISTRIBUTION_NAME}'].Id | [0]" \
112
+ --output text \
113
+ --region us-east-1)
114
+
115
+ if [ "$DISTRIBUTION_ID" == "None" ] || [ -z "$DISTRIBUTION_ID" ]; then
116
+ print_warning "CloudFront distribution '${CLOUDFRONT_DISTRIBUTION_NAME}' not found by comment."
117
+ print_info "Searching by origin domain name..."
118
+
119
+ DISTRIBUTION_ID=$(aws cloudfront list-distributions \
120
+ --query "DistributionList.Items[?Origins.Items[?DomainName=='${S3_BUCKET}.s3.amazonaws.com']].Id | [0]" \
121
+ --output text \
122
+ --region us-east-1)
123
+
124
+ if [ "$DISTRIBUTION_ID" == "None" ] || [ -z "$DISTRIBUTION_ID" ]; then
125
+ print_error "CloudFront distribution not found. Please set CLOUDFRONT_DISTRIBUTION_ID environment variable."
126
+ print_info "You can find it by running: aws cloudfront list-distributions --query 'DistributionList.Items[*].[Id,Comment]'"
127
+
128
+ # If CLOUDFRONT_DISTRIBUTION_ID is set, use it
129
+ if [ ! -z "$CLOUDFRONT_DISTRIBUTION_ID" ]; then
130
+ DISTRIBUTION_ID=$CLOUDFRONT_DISTRIBUTION_ID
131
+ print_info "Using distribution ID from environment: $DISTRIBUTION_ID"
132
+ else
133
+ exit 1
134
+ fi
135
+ fi
136
+ fi
137
+
138
+ print_info "CloudFront Distribution ID: $DISTRIBUTION_ID"
139
+
140
+ # Step 6: Invalidate CloudFront Cache
141
+ print_info "Creating CloudFront invalidation..."
142
+ INVALIDATION_ID=$(aws cloudfront create-invalidation \
143
+ --distribution-id ${DISTRIBUTION_ID} \
144
+ --paths "/*" \
145
+ --query 'Invalidation.Id' \
146
+ --output text \
147
+ --region us-east-1)
148
+
149
+ print_info "Invalidation ID: $INVALIDATION_ID"
150
+ print_info "Waiting for invalidation to complete (this may take a few minutes)..."
151
+
152
+ # Wait for invalidation to complete
153
+ aws cloudfront wait invalidation-completed \
154
+ --distribution-id ${DISTRIBUTION_ID} \
155
+ --id ${INVALIDATION_ID} \
156
+ --region us-east-1 || print_warning "Invalidation is in progress..."
157
+
158
+ print_info "✅ CloudFront cache invalidated"
159
+
160
+ # Step 7: Get CloudFront URL
161
+ CLOUDFRONT_URL=$(aws cloudfront get-distribution \
162
+ --id ${DISTRIBUTION_ID} \
163
+ --query 'Distribution.DomainName' \
164
+ --output text \
165
+ --region us-east-1)
166
+
167
+ # Summary
168
+ echo ""
169
+ echo "======================================"
170
+ echo "Deployment Summary"
171
+ echo "======================================"
172
+ print_info "Environment: STAGING"
173
+ print_info "S3 Bucket: s3://${S3_BUCKET}/${S3_PREFIX}/"
174
+ print_info "CloudFront Distribution: ${CLOUDFRONT_DISTRIBUTION_NAME}"
175
+ print_info "Distribution ID: ${DISTRIBUTION_ID}"
176
+ print_info "CloudFront URL: https://${CLOUDFRONT_URL}"
177
+ print_info "Invalidation ID: ${INVALIDATION_ID}"
178
+ echo ""
179
+ print_info "✅ Deployment completed successfully!"
180
+ echo ""
181
+ print_info "Test your deployment:"
182
+ print_info " curl -I https://${CLOUDFRONT_URL}"
183
+ echo "======================================"
184
+
185
+ cd ..