diff --git a/backend/apps/b2b-analytics-service/src/b2b-analytics-service.controller.ts b/backend/apps/b2b-analytics-service/src/b2b-analytics-service.controller.ts index 63bf41d..2259803 100644 --- a/backend/apps/b2b-analytics-service/src/b2b-analytics-service.controller.ts +++ b/backend/apps/b2b-analytics-service/src/b2b-analytics-service.controller.ts @@ -6,7 +6,17 @@ export class B2bAnalyticsServiceController { constructor(private readonly b2bAnalyticsServiceService: B2bAnalyticsServiceService) {} @Get() - getHello(): string { - return this.b2bAnalyticsServiceService.getHello(); + getInfo() { + return { + service: 'b2b-analytics-service', + port: 3004, + status: 'online', + description: 'Anonymized FMCG Market Share & Pricing Intelligence Engine', + }; + } + + @Get('health') + getHealth() { + return { status: 'ok', service: 'b2b-analytics-service' }; } } diff --git a/backend/apps/b2b-analytics-service/src/main.ts b/backend/apps/b2b-analytics-service/src/main.ts index aa8e7a5..c818d39 100644 --- a/backend/apps/b2b-analytics-service/src/main.ts +++ b/backend/apps/b2b-analytics-service/src/main.ts @@ -3,7 +3,8 @@ import { B2bAnalyticsServiceModule } from './b2b-analytics-service.module.js'; async function bootstrap() { const app = await NestFactory.create(B2bAnalyticsServiceModule); - const port = process.env.B2B_SERVICE_PORT || process.env.PORT || process.env.port || 3004; + const port = process.env.B2B_SERVICE_PORT || 3004; await app.listen(port, '0.0.0.0'); + console.log(`[b2b-analytics-service] Running on http://localhost:${port}`); } await bootstrap(); diff --git a/backend/apps/catalog-service/src/catalog-service.controller.ts b/backend/apps/catalog-service/src/catalog-service.controller.ts index 820c5cb..1a04ec9 100644 --- a/backend/apps/catalog-service/src/catalog-service.controller.ts +++ b/backend/apps/catalog-service/src/catalog-service.controller.ts @@ -6,7 +6,17 @@ export class CatalogServiceController { constructor(private readonly catalogServiceService: CatalogServiceService) {} @Get() - getHello(): string { - return this.catalogServiceService.getHello(); + getInfo() { + return { + service: 'catalog-service', + port: 3002, + status: 'online', + description: 'Master Philippine Barcode & Product Catalog', + }; + } + + @Get('health') + getHealth() { + return { status: 'ok', service: 'catalog-service' }; } } diff --git a/backend/apps/catalog-service/src/main.ts b/backend/apps/catalog-service/src/main.ts index d02a405..556c0cc 100644 --- a/backend/apps/catalog-service/src/main.ts +++ b/backend/apps/catalog-service/src/main.ts @@ -3,7 +3,8 @@ import { CatalogServiceModule } from './catalog-service.module.js'; async function bootstrap() { const app = await NestFactory.create(CatalogServiceModule); - const port = process.env.CATALOG_SERVICE_PORT || process.env.PORT || process.env.port || 3002; + const port = process.env.CATALOG_SERVICE_PORT || 3002; await app.listen(port, '0.0.0.0'); + console.log(`[catalog-service] Running on http://localhost:${port}`); } await bootstrap(); diff --git a/backend/apps/storefront-service/src/main.ts b/backend/apps/storefront-service/src/main.ts index abf612a..e3d6d1f 100644 --- a/backend/apps/storefront-service/src/main.ts +++ b/backend/apps/storefront-service/src/main.ts @@ -3,7 +3,8 @@ import { StorefrontServiceModule } from './storefront-service.module.js'; async function bootstrap() { const app = await NestFactory.create(StorefrontServiceModule); - const port = process.env.STOREFRONT_SERVICE_PORT || process.env.PORT || process.env.port || 3003; + const port = process.env.STOREFRONT_SERVICE_PORT || 3003; await app.listen(port, '0.0.0.0'); + console.log(`[storefront-service] Running on http://localhost:${port}`); } await bootstrap(); diff --git a/backend/apps/storefront-service/src/storefront-service.controller.ts b/backend/apps/storefront-service/src/storefront-service.controller.ts index a97dc80..0f89b96 100644 --- a/backend/apps/storefront-service/src/storefront-service.controller.ts +++ b/backend/apps/storefront-service/src/storefront-service.controller.ts @@ -6,7 +6,17 @@ export class StorefrontServiceController { constructor(private readonly storefrontServiceService: StorefrontServiceService) {} @Get() - getHello(): string { - return this.storefrontServiceService.getHello(); + getInfo() { + return { + service: 'storefront-service', + port: 3003, + status: 'online', + description: 'Public Web Storefront & Customer Ordering Engine', + }; + } + + @Get('health') + getHealth() { + return { status: 'ok', service: 'storefront-service' }; } } diff --git a/backend/apps/sync-service/src/main.ts b/backend/apps/sync-service/src/main.ts index 6ac9e1e..38a769f 100644 --- a/backend/apps/sync-service/src/main.ts +++ b/backend/apps/sync-service/src/main.ts @@ -3,7 +3,8 @@ import { SyncServiceModule } from './sync-service.module.js'; async function bootstrap() { const app = await NestFactory.create(SyncServiceModule); - const port = process.env.SYNC_SERVICE_PORT || process.env.PORT || process.env.port || 3001; + const port = process.env.SYNC_SERVICE_PORT || 3001; await app.listen(port, '0.0.0.0'); + console.log(`[sync-service] Running on http://localhost:${port}`); } await bootstrap(); diff --git a/backend/apps/sync-service/src/sync-service.controller.ts b/backend/apps/sync-service/src/sync-service.controller.ts index 9a8c40f..515934c 100644 --- a/backend/apps/sync-service/src/sync-service.controller.ts +++ b/backend/apps/sync-service/src/sync-service.controller.ts @@ -6,7 +6,17 @@ export class SyncServiceController { constructor(private readonly syncServiceService: SyncServiceService) {} @Get() - getHello(): string { - return this.syncServiceService.getHello(); + getInfo() { + return { + service: 'sync-service', + port: 3001, + status: 'online', + description: 'Delta Synchronization & Offline Replication Engine', + }; + } + + @Get('health') + getHealth() { + return { status: 'ok', service: 'sync-service' }; } } diff --git a/backend/package-lock.json b/backend/package-lock.json index 4506f20..12f005d 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -32,6 +32,7 @@ "@types/node": "^24.0.0", "@types/supertest": "^7.0.0", "@vitest/coverage-v8": "^4.1.2", + "concurrently": "^10.0.6", "oxlint": "^1.58.0", "prettier": "^3.4.2", "prisma": "^6.19.3", @@ -3413,6 +3414,106 @@ "node": ">= 12" } }, + "node_modules/cliui": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz", + "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.4.0.tgz", + "integrity": "sha512-KzTVk2tCWAHtYrvvvaP8bJKJq2pVinhLcGEQdtLIYPbmNGNyYe8QwNaTUYQp2J7/vIsUKt5QCqAfUkYyG9DkOw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/cliui/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/clone": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", @@ -3490,6 +3591,57 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/concurrently": { + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-10.0.6.tgz", + "integrity": "sha512-qgICXXFp2/3nAebRLmxcINKEXM1mLK3ij/y31P02VTs/KIkddIeC05n73DxOXsXMB9LFSqNU1/na3lDlOhcbIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "5.6.2", + "rxjs": "7.8.2", + "shell-quote": "1.12.0", + "supports-color": "10.2.2", + "tree-kill": "1.2.2", + "yargs": "18.0.0" + }, + "bin": { + "conc": "dist/bin/index.js", + "concurrently": "dist/bin/index.js" + }, + "engines": { + "node": ">=22" + }, + "funding": { + "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" + } + }, + "node_modules/concurrently/node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/concurrently/node_modules/supports-color": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-10.2.2.tgz", + "integrity": "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, "node_modules/confbox": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.4.tgz", @@ -3861,6 +4013,16 @@ "tests/browser-compat" ] }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -4258,6 +4420,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, "node_modules/get-east-asian-width": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.7.0.tgz", @@ -6115,6 +6287,19 @@ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "license": "ISC" }, + "node_modules/shell-quote": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.12.0.tgz", + "integrity": "sha512-PcByqNyT/38F2kDNi006HAMRJaULuBzq/FOsw3qdZvX/GA9W/jamDaRskgHjubHiftXK5sIFxLNkvrXUwcof6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/side-channel": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz", @@ -6523,6 +6708,16 @@ "url": "https://github.com/sponsors/Borewit" } }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, "node_modules/tsconfig-paths": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", @@ -6973,6 +7168,98 @@ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "license": "ISC" }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.0.0.tgz", + "integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^9.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "string-width": "^7.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^22.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, + "node_modules/yargs-parser": { + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz", + "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.4.0.tgz", + "integrity": "sha512-KzTVk2tCWAHtYrvvvaP8bJKJq2pVinhLcGEQdtLIYPbmNGNyYe8QwNaTUYQp2J7/vIsUKt5QCqAfUkYyG9DkOw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "dev": true, + "license": "MIT" + }, + "node_modules/yargs/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/yoctocolors": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.2.0.tgz", diff --git a/backend/package.json b/backend/package.json index f75d6a3..784e6ae 100644 --- a/backend/package.json +++ b/backend/package.json @@ -21,6 +21,7 @@ "start:catalog": "nest start catalog-service --watch", "start:storefront": "nest start storefront-service --watch", "start:b2b": "nest start b2b-analytics-service --watch", + "start:all": "concurrently -n gateway,sync,catalog,storefront,b2b -c blue,green,yellow,magenta,cyan \"npm run start\" \"npm run start:sync\" \"npm run start:catalog\" \"npm run start:storefront\" \"npm run start:b2b\"", "prisma:generate": "prisma generate", "prisma:push": "prisma db push", "prisma:migrate": "prisma migrate dev", @@ -55,6 +56,7 @@ "@types/node": "^24.0.0", "@types/supertest": "^7.0.0", "@vitest/coverage-v8": "^4.1.2", + "concurrently": "^10.0.6", "oxlint": "^1.58.0", "prettier": "^3.4.2", "prisma": "^6.19.3",