@dooer/dooer-test-env 1.2.2 → 1.3.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.
@@ -74,12 +74,16 @@ module.exports = {
74
74
  },
75
75
  })
76
76
  .command({
77
- command: 'deploy <name> <version>',
78
- describe: 'switch a service to a published registry version (upgrade/downgrade)',
77
+ // NB: the positional is `tag`, NOT `version` — a positional named `version` collides with yargs's
78
+ // built-in --version flag (enabled in cli.js), which made argv resolve to the boolean `true`.
79
+ command: 'deploy <name> <tag>',
80
+ describe: 'switch a service to a published registry version/tag (upgrade/downgrade)',
79
81
  handler: (a) => {
82
+ if (!a.tag || typeof a.tag !== 'string')
83
+ throw new Error('missing image tag, e.g. `service deploy <name> 1.2.3`')
80
84
  const base = imageFor(a.name, rt.SERVICES_DIR)
81
85
  if (!base) throw new Error(`unknown service ${a.name} (no manifest image)`)
82
- const image = `${base.replace(/:[^:/]+$/, '')}:${a.version}`
86
+ const image = `${base.replace(/:[^:/]+$/, '')}:${a.tag}`
83
87
  // merge into the override compose file
84
88
  let ov = { services: {} }
85
89
  if (fs.existsSync(rt.OVERRIDE_FILE))
@@ -18,6 +18,7 @@ const AUTH_PRIVATE_KEY_PEM = Buffer.from(AUTH_PRIVATE_KEY_B64, 'base64').toStrin
18
18
 
19
19
  // The narrower `booking` profile — the minimum set to drive a booking end to end.
20
20
  const BOOKING_PROFILE_SERVICES = [
21
+ 'public-facade', // the browser-facing entrypoint (GraphQL + REST passthrough) — frontends need it
21
22
  'service-graphql',
22
23
  'service-core-objects',
23
24
  'service-accounts',
@@ -101,6 +102,12 @@ const SERVICE_ENV_OVERRIDES = {
101
102
  // library's built-in TEST cert (appapi2.test.bankid.com). Present → `up` also sets IS_PRODUCTION=true, so
102
103
  // local login uses PRODUCTION BankID exactly like staging (@dooer/config env override beats the
103
104
  // per-environment `local:false`). See lib/bankid.js.
105
+ 'public-facade': {
106
+ // The manifest ships DOOER_HOST_PROTOCOL="" — an EMPTY value that overrides the config default
107
+ // ("http"), so @dooer/facade builds protocol-less upstream URLs and falls back to port 80
108
+ // (ECONNREFUSED ::1:80 → 502 on every proxied route). Restore the default explicitly.
109
+ DOOER_HOST_PROTOCOL: 'http',
110
+ },
104
111
  'service-accounts': {
105
112
  // service-accounts is the only token SIGNER — give it the LOCAL dev private key matching the public key
106
113
  // forced on every verifier (GLOBAL_OVERRIDES.DOOER_AUTH_PUBLIC_KEY). Non-secret dev material.
@@ -292,7 +299,11 @@ function infraServices() {
292
299
  }
293
300
 
294
301
  // Host ports published so the BROWSER (and dev) can reach things on localhost.
295
- const GATEWAY_HOST_PORT = 4000 // service-graphql (the public GraphQL facade the frontends' browsers call)
302
+ // public-facade is the browser-facing entrypoint (api.dooer.com / api.s-e032.com): it serves GraphQL AND
303
+ // the REST passthrough (e.g. /v1/companies/:org/documents/:doc/pages/:page image URLs). service-graphql is
304
+ // an internal backend it fronts — NOT the facade — so it gets its own port for direct dev access.
305
+ const FACADE_HOST_PORT = 4000 // public-facade → DOOER_PUBLIC_FACADE_HOST / DOOER_GRAPHQL_HOST
306
+ const GRAPHQL_HOST_PORT = 4001 // service-graphql (direct access; frontends go through the facade)
296
307
  const HQ_HOST_PORT = 8080 // frontend-hq
297
308
 
298
309
  // host port for a frontend: HQ is pinned to 8080; the rest get 8081+ in sorted order.
@@ -327,7 +338,9 @@ const FRONTEND_URL_ENV = {
327
338
  // cross-frontend base URL → its frontend's own host port. Only rewrites keys already present (from the
328
339
  // manifest) whose target frontend has a known port. Applied to services AND frontends.
329
340
  function rewriteBrowserUrls(env, portMap) {
330
- if ('DOOER_PUBLIC_FACADE_HOST' in env) env.DOOER_PUBLIC_FACADE_HOST = `http://localhost:${GATEWAY_HOST_PORT}`
341
+ // Both point at public-facade (on staging both are https://api.s-e032.com) not at service-graphql.
342
+ if ('DOOER_PUBLIC_FACADE_HOST' in env) env.DOOER_PUBLIC_FACADE_HOST = `http://localhost:${FACADE_HOST_PORT}`
343
+ if ('DOOER_GRAPHQL_HOST' in env) env.DOOER_GRAPHQL_HOST = `http://localhost:${FACADE_HOST_PORT}`
331
344
  for (const [key, frontendName] of Object.entries(FRONTEND_URL_ENV)) {
332
345
  if (key in env && portMap[frontendName]) env[key] = `http://localhost:${portMap[frontendName]}`
333
346
  }
@@ -357,8 +370,9 @@ function buildCompose(services, frontends, { profile } = {}) {
357
370
  // (Consul path) which hangs on consul-template.
358
371
  command: svc.command || ['./CMD-OPF.sh'],
359
372
  environment: rewriteBrowserUrls({ ...buildServiceEnv(svc), ...(SERVICE_ENV_OVERRIDES[svc.name] || {}) }, portMap),
360
- // publish the GraphQL gateway on the host so the frontends' browsers can reach it at localhost
361
- ...(svc.name === 'service-graphql' ? { ports: [`${GATEWAY_HOST_PORT}:3000`] } : {}),
373
+ // publish the browser-facing facade (4000) and service-graphql (4001) on the host
374
+ ...(svc.name === 'public-facade' ? { ports: [`${FACADE_HOST_PORT}:3000`] } : {}),
375
+ ...(svc.name === 'service-graphql' ? { ports: [`${GRAPHQL_HOST_PORT}:3000`] } : {}),
362
376
  // legacy-name DNS aliases (e.g. service-periods → service-closing), so callers resolving the old name
363
377
  // reach this container on the compose network.
364
378
  ...(SERVICE_ALIASES[svc.name] ? { networks: { default: { aliases: SERVICE_ALIASES[svc.name] } } } : {}),
@@ -382,7 +396,7 @@ function buildCompose(services, frontends, { profile } = {}) {
382
396
  // Repoint the facade + every cross-frontend link at the right local ports. Each base URL points at the
383
397
  // frontend that SERVES it (e.g. DOOER_PUBLIC_FRONTEND_BASE_URL → frontend-sumify-neue's port), never at
384
398
  // this app's own port — that was the bug that sent HQ's "open go.dooer.com" button to localhost:8080.
385
- if (!('DOOER_PUBLIC_FACADE_HOST' in env)) env.DOOER_PUBLIC_FACADE_HOST = `http://localhost:${GATEWAY_HOST_PORT}`
399
+ if (!('DOOER_PUBLIC_FACADE_HOST' in env)) env.DOOER_PUBLIC_FACADE_HOST = `http://localhost:${FACADE_HOST_PORT}`
386
400
  rewriteBrowserUrls(env, portMap)
387
401
  composeServices[fe.name] = {
388
402
  image: fe.image,
@@ -19,6 +19,11 @@ const DEFAULT_SERVICES_DIR = path.resolve(
19
19
 
20
20
  const SERVICE_FILE_RE = /^service-.*\.yaml$/
21
21
  const FRONTEND_FILE_RE = /^frontend-.*\.yaml$/
22
+ // Backend services whose manifest filename doesn't match `service-*.yaml` but which are real runnable
23
+ // Deployments we must include. public-facade is the browser-facing REST+GraphQL entrypoint
24
+ // (DOOER_PUBLIC_FACADE_HOST); without it, document page images (/v1/…/pages/…) and other REST passthrough
25
+ // 404. (Jimmy 2026-09-03.)
26
+ const EXTRA_SERVICE_FILES = ['public-facade.yaml']
22
27
 
23
28
  // Pull the application container out of a Deployment doc. Containers are named
24
29
  // `node` across the fleet; fall back to the first container defensively.
@@ -67,7 +72,7 @@ function listServices(servicesDir) {
67
72
  const dir = servicesDir || DEFAULT_SERVICES_DIR
68
73
  return fs
69
74
  .readdirSync(dir)
70
- .filter((f) => SERVICE_FILE_RE.test(f))
75
+ .filter((f) => SERVICE_FILE_RE.test(f) || EXTRA_SERVICE_FILES.includes(f))
71
76
  .sort()
72
77
  .map((f) => parseManifestFile(path.join(dir, f)))
73
78
  .filter(Boolean)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dooer/dooer-test-env",
3
- "version": "1.2.2",
3
+ "version": "1.3.0",
4
4
  "description": "Run the whole Dooer backend locally (staging DB minus customers), copy/purge customers between environments, and shred — one CLI.",
5
5
  "license": "UNLICENSED",
6
6
  "repository": "Dooer/cli-dooer-test-env",