Files
bri-sandbox-development-pla…/dashboard/out/dashboard/sandboxes.html
T
Achmad 4cab047432 Slice 2: port 3452, nginx sandbox mount, AGENTS.md, docs, deploy script cleanup
- control-plane default listen addr is now :3452 (was :8080). An
  unusual port to avoid collisions on the VM.
- agent-micro and agent-gateway default SDP_CP_URL points at
  ws://localhost:3452/ws/agent. docker-compose.yml updates the
  control plane command, host port mapping, and agent -cp URLs.
- nginx/nginx.conf (the legacy root-mount reference) uses
  127.0.0.1:3452 for the upstream. nginx/sandbox.conf is the new
  deployment config: four location blocks for the /sandbox/credit-card
  mount — _next/static serves cached chunks, /api/ and /ws/ proxy
  to 127.0.0.1:3452, /sandbox/credit-card serves the static
  dashboard with try_files for SPA routing.
- scripts/patch-nginx.sh: deleted. The user configures nginx on 186
  by hand. scripts/deploy.sh no longer calls it.
- AGENTS.md: new file. Documents the build/lint/test commands
  (with the golang:1.24-alpine container — local Go can't fetch
  the toolchain), the wire protocol, the Slice-2 conventions
  (sdp-<repo> container naming, snapshot persistence,
  PreGitReset/AfterStart hooks), the repo-path gotcha, and the
  build-artifacts-in-git rationale.
- dashboard/out: now tracked in git, alongside bin/. The dashboard
  static export is scp'd to 186 on deploy; the VMs have no
  internet so they can't regenerate it. .gitignore comment
  explains this and warns against re-ignoring.
- README.md / REQUIREMENTS.md: status updated to 'Slice 2 done',
  per-feature checklist marked. Erangel repo path corrected to
  /var/www/html/erangel-ocean (was wrongly ~/SDP in earlier docs).
2026-06-24 04:00:49 +00:00

1 line
13 KiB
HTML

<!DOCTYPE html><html lang="en" class="h-full"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="/sandbox/credit-card/_next/static/css/157e72c563f45c59.css" crossorigin="" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/sandbox/credit-card/_next/static/chunks/webpack-2ad4c7491a7ffdcd.js" crossorigin=""/><script src="/sandbox/credit-card/_next/static/chunks/fd9d1056-1672853390c1185d.js" async="" crossorigin=""></script><script src="/sandbox/credit-card/_next/static/chunks/69-657be7a0f758990c.js" async="" crossorigin=""></script><script src="/sandbox/credit-card/_next/static/chunks/main-app-33216aff9efae744.js" async="" crossorigin=""></script><script src="/sandbox/credit-card/_next/static/chunks/504-b386cf1902f7f6c4.js" async=""></script><script src="/sandbox/credit-card/_next/static/chunks/303-30e01c8e944885c6.js" async=""></script><script src="/sandbox/credit-card/_next/static/chunks/792-ff5864056e955fdc.js" async=""></script><script src="/sandbox/credit-card/_next/static/chunks/app/dashboard/sandboxes/page-fa8d8c9854e58bd7.js" async=""></script><script src="/sandbox/credit-card/_next/static/chunks/app/dashboard/layout-49ba819eac821f2e.js" async=""></script><title>SDP</title><meta name="description" content="Sandbox Deployment Platform"/><script src="/sandbox/credit-card/_next/static/chunks/polyfills-c67a75d1b6f99dc8.js" crossorigin="" noModule=""></script></head><body class="h-full bg-background text-foreground antialiased"><div class="min-h-screen bg-zinc-50"><header class="border-b"><div class="container flex h-14 items-center justify-between gap-6"><div class="flex items-center gap-6"><a class="font-semibold tracking-tight" href="/sandbox/credit-card/dashboard">SDP</a><nav class="flex gap-1 text-sm"><a class="rounded-md px-3 py-1.5 transition-colors text-zinc-700 hover:bg-zinc-100" href="/sandbox/credit-card/dashboard">Quick Deploy</a><a class="rounded-md px-3 py-1.5 transition-colors bg-zinc-900 text-zinc-50" href="/sandbox/credit-card/dashboard/sandboxes">Sandboxes</a><a class="rounded-md px-3 py-1.5 transition-colors text-zinc-700 hover:bg-zinc-100" href="/sandbox/credit-card/dashboard/templates">Templates</a><a class="rounded-md px-3 py-1.5 transition-colors text-zinc-700 hover:bg-zinc-100" href="/sandbox/credit-card/dashboard/environments">Environments</a><a class="rounded-md px-3 py-1.5 transition-colors text-zinc-700 hover:bg-zinc-100" href="/sandbox/credit-card/dashboard/history">History</a></nav></div><button class="inline-flex items-center justify-center whitespace-nowrap font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground h-8 rounded-md px-3 text-xs">Logout</button></div></header><main><div class="container py-8 space-y-6"><div><h1 class="text-2xl font-semibold tracking-tight">Sandboxes</h1><p class="text-sm text-muted-foreground">A sandbox groups one gateway branch with a set of microservice overrides. Each route can be pointed at the local stand-in or back at OCP.</p></div><div class="grid gap-4 md:grid-cols-2"><div class="rounded-xl border bg-card text-card-foreground shadow"><div class="flex flex-col space-y-1.5 p-6"><div class="font-semibold leading-none tracking-tight">New sandbox</div><div class="text-sm text-muted-foreground">Pick a gateway branch. Add services after creating.</div></div><div class="p-6 pt-0 space-y-3"><div class="space-y-1.5"><label class="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">Name</label><input class="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50" placeholder="QA-login-error" value=""/></div><div class="space-y-1.5"><label class="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">Gateway branch</label><input class="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50" placeholder="develop" value=""/></div><div class="space-y-1.5"><label class="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">Gateway host port</label><input class="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50" placeholder="8080" value=""/><p class="text-xs text-muted-foreground">Port on the gateway VM that the mobile app points at. One live at a time.</p></div><button class="inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 bg-primary text-primary-foreground shadow hover:bg-primary/90 h-9 px-4 py-2 w-full" disabled="">Create</button></div></div><div class="rounded-xl border bg-card text-card-foreground shadow"><div class="flex flex-col space-y-1.5 p-6"><div class="font-semibold leading-none tracking-tight">Clone from template</div><div class="text-sm text-muted-foreground">Materialize a sandbox from a saved template.</div></div><div class="p-6 pt-0 space-y-3"><div class="space-y-1.5"><label class="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">Template</label><button type="button" role="combobox" aria-expanded="false" aria-autocomplete="none" dir="ltr" data-state="closed" data-placeholder="" class="flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&amp;&gt;span]:line-clamp-1"><span style="pointer-events:none">Pick a template</span><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-chevron-down h-4 w-4 opacity-50" aria-hidden="true"><path d="m6 9 6 6 6-6"></path></svg></button><select aria-hidden="true" tabindex="-1" style="position:absolute;border:0;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;word-wrap:normal"><option value="" selected=""></option></select></div><div class="space-y-1.5"><label class="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">New sandbox name</label><input class="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50" placeholder="QA-login-error" value=""/></div><button class="inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 bg-primary text-primary-foreground shadow hover:bg-primary/90 h-9 px-4 py-2 w-full" disabled="">Clone</button></div></div></div><div class="space-y-2"><p class="text-sm text-muted-foreground">No sandboxes yet.</p></div></div></main></div><script src="/sandbox/credit-card/_next/static/chunks/webpack-2ad4c7491a7ffdcd.js" crossorigin="" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0]);self.__next_f.push([2,null])</script><script>self.__next_f.push([1,"1:HL[\"/sandbox/credit-card/_next/static/css/157e72c563f45c59.css\",\"style\",{\"crossOrigin\":\"\"}]\n0:\"$L2\"\n"])</script><script>self.__next_f.push([1,"3:I[7690,[],\"\"]\n5:I[7831,[],\"\"]\n6:I[7334,[\"504\",\"static/chunks/504-b386cf1902f7f6c4.js\",\"303\",\"static/chunks/303-30e01c8e944885c6.js\",\"792\",\"static/chunks/792-ff5864056e955fdc.js\",\"509\",\"static/chunks/app/dashboard/sandboxes/page-fa8d8c9854e58bd7.js\"],\"\"]\n7:I[5613,[],\"\"]\n8:I[1778,[],\"\"]\n9:I[9534,[\"504\",\"static/chunks/504-b386cf1902f7f6c4.js\",\"792\",\"static/chunks/792-ff5864056e955fdc.js\",\"663\",\"static/chunks/app/dashboard/layout-49ba819eac821f2e.js\"],\"DashboardNav\"]\nb:I[8955,[],\"\"]\nc:[]\n"])</script><script>self.__next_f.push([1,"2:[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/sandbox/credit-card/_next/static/css/157e72c563f45c59.css\",\"precedence\":\"next\",\"crossOrigin\":\"\"}]],[\"$\",\"$L3\",null,{\"buildId\":\"vJ6MiW7DlY0bX8PUKZLrC\",\"assetPrefix\":\"/sandbox/credit-card\",\"initialCanonicalUrl\":\"/dashboard/sandboxes\",\"initialTree\":[\"\",{\"children\":[\"dashboard\",{\"children\":[\"sandboxes\",{\"children\":[\"__PAGE__\",{}]}]}]},\"$undefined\",\"$undefined\",true],\"initialSeedData\":[\"\",{\"children\":[\"dashboard\",{\"children\":[\"sandboxes\",{\"children\":[\"__PAGE__\",{},[\"$L4\",[\"$\",\"$L5\",null,{\"propsForComponent\":{\"params\":{}},\"Component\":\"$6\",\"isStaticGeneration\":true}],null]]},[\"$\",\"$L7\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\",\"dashboard\",\"children\",\"sandboxes\",\"children\"],\"loading\":\"$undefined\",\"loadingStyles\":\"$undefined\",\"loadingScripts\":\"$undefined\",\"hasLoading\":false,\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L8\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"notFoundStyles\":\"$undefined\",\"styles\":null}]]},[null,[\"$\",\"div\",null,{\"className\":\"min-h-screen bg-zinc-50\",\"children\":[[\"$\",\"$L9\",null,{}],[\"$\",\"main\",null,{\"children\":[\"$\",\"$L7\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\",\"dashboard\",\"children\"],\"loading\":\"$undefined\",\"loadingStyles\":\"$undefined\",\"loadingScripts\":\"$undefined\",\"hasLoading\":false,\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L8\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"notFoundStyles\":\"$undefined\",\"styles\":null}]}]]}],null]]},[null,[\"$\",\"html\",null,{\"lang\":\"en\",\"className\":\"h-full\",\"children\":[\"$\",\"body\",null,{\"className\":\"h-full bg-background text-foreground antialiased\",\"children\":[\"$\",\"$L7\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\"],\"loading\":\"$undefined\",\"loadingStyles\":\"$undefined\",\"loadingScripts\":\"$undefined\",\"hasLoading\":false,\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L8\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":\"404\"}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],\"notFoundStyles\":[],\"styles\":null}]}]}],null]],\"initialHead\":[false,\"$La\"],\"globalErrorComponent\":\"$b\",\"missingSlots\":\"$Wc\"}]]\n"])</script><script>self.__next_f.push([1,"a:[[\"$\",\"meta\",\"0\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}],[\"$\",\"meta\",\"1\",{\"charSet\":\"utf-8\"}],[\"$\",\"title\",\"2\",{\"children\":\"SDP\"}],[\"$\",\"meta\",\"3\",{\"name\":\"description\",\"content\":\"Sandbox Deployment Platform\"}]]\n4:null\n"])</script><script>self.__next_f.push([1,""])</script></body></html>