go-duck-cli 1.0.8 → 1.1.1
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.
- package/README.md +30 -15
- package/generators/ai_docs.js +130 -0
- package/generators/broker.js +63 -0
- package/generators/config.js +149 -7
- package/generators/devops.js +210 -43
- package/generators/docs.js +23 -4
- package/generators/elasticsearch.js +263 -0
- package/generators/kratos.js +229 -41
- package/generators/metering.js +280 -48
- package/generators/migrations.js +92 -198
- package/generators/mqtt.js +2 -39
- package/generators/multitenancy.js +274 -71
- package/generators/nats.js +39 -0
- package/generators/outbox.js +171 -0
- package/generators/postgrest.js +7 -3
- package/generators/postman.js +405 -0
- package/generators/repository.js +27 -0
- package/generators/router.js +27 -0
- package/generators/security.js +95 -14
- package/generators/serverless.js +147 -0
- package/generators/storage.js +589 -0
- package/generators/swagger.js +84 -60
- package/generators/telemetry.js +23 -32
- package/generators/websocket.js +55 -21
- package/index.js +481 -116
- package/package.json +6 -4
- package/parser/gdl.js +163 -24
- package/templates/docs/index.html.hbs +5 -5
- package/templates/docs/layout.hbs +221 -62
- package/templates/docs/pages/audit.hbs +83 -35
- package/templates/docs/pages/cli.hbs +18 -0
- package/templates/docs/pages/configuration.hbs +241 -0
- package/templates/docs/pages/datadog.hbs +46 -0
- package/templates/docs/pages/elasticsearch.hbs +121 -0
- package/templates/docs/pages/federation.hbs +241 -0
- package/templates/docs/pages/gdl-advanced.hbs +91 -0
- package/templates/docs/pages/gdl-annotations.hbs +137 -0
- package/templates/docs/pages/gdl-entities.hbs +134 -0
- package/templates/docs/pages/gdl-relationships.hbs +80 -0
- package/templates/docs/pages/gdl.hbs +60 -204
- package/templates/docs/pages/graphql.hbs +58 -44
- package/templates/docs/pages/grpc.hbs +53 -90
- package/templates/docs/pages/hybrid-store.hbs +127 -0
- package/templates/docs/pages/index.hbs +418 -149
- package/templates/docs/pages/keycloak.hbs +43 -0
- package/templates/docs/pages/legend.hbs +116 -0
- package/templates/docs/pages/mosquitto.hbs +39 -0
- package/templates/docs/pages/multitenancy.hbs +139 -71
- package/templates/docs/pages/otel.hbs +40 -0
- package/templates/docs/pages/realtime.hbs +38 -12
- package/templates/docs/pages/redis.hbs +40 -0
- package/templates/docs/pages/rest.hbs +120 -202
- package/templates/docs/pages/saga.hbs +94 -0
- package/templates/docs/pages/security.hbs +150 -44
- package/templates/docs/pages/serverless.hbs +157 -0
- package/templates/docs/pages/storage.hbs +127 -0
- package/templates/docs/pages/wizard.hbs +683 -0
- package/templates/docs/triple_identity_registry.png +0 -0
- package/templates/go/controller.go.hbs +287 -283
- package/templates/go/entity.go.hbs +17 -15
- package/templates/go/main.go.hbs +47 -180
- package/templates/go/migrator.go.hbs +65 -0
- package/templates/go/router.go.hbs +272 -0
- package/templates/graphql/resolver.go.hbs +53 -34
- package/templates/graphql/schema.graphql.hbs +17 -5
- package/templates/kratos/service.go.hbs +169 -34
- package/templates/proto/entity.proto.hbs +10 -14
- package/test_nested.gdl +21 -0
- package/templates/docs/intro.mp4 +0 -0
- package/test_parser.js +0 -9
|
@@ -0,0 +1,683 @@
|
|
|
1
|
+
<div class="min-h-screen bg-[#f8fafc] text-[#1e293b] font-sans selection:bg-indigo-100 selection:text-indigo-900 overflow-x-hidden">
|
|
2
|
+
<!-- Professional Executive Header -->
|
|
3
|
+
<header class="sticky top-0 z-50 bg-white/90 backdrop-blur-2xl border-b border-slate-200 py-6 px-12 flex items-center justify-between shadow-sm">
|
|
4
|
+
<div class="flex items-center space-x-4">
|
|
5
|
+
<div class="w-12 h-12 bg-gradient-to-tr from-indigo-500 to-indigo-700 rounded-2xl flex items-center justify-center shadow-xl shadow-indigo-200">
|
|
6
|
+
<svg class="w-7 h-7 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
7
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" />
|
|
8
|
+
</svg>
|
|
9
|
+
</div>
|
|
10
|
+
<div>
|
|
11
|
+
<h1 class="text-xl font-black tracking-tight text-slate-900 m-0">GO-DUCK INDUSTRIAL</h1>
|
|
12
|
+
<p class="text-[10px] font-bold text-indigo-600 tracking-[0.4em] uppercase opacity-80 leading-none mt-1">Config Orchestrator v361.Elite</p>
|
|
13
|
+
</div>
|
|
14
|
+
</div>
|
|
15
|
+
<div class="flex items-center space-x-6">
|
|
16
|
+
<div id="status-badge" class="flex items-center space-x-2 px-4 py-2 bg-emerald-50 rounded-full border border-emerald-100">
|
|
17
|
+
<div class="w-2 h-2 bg-emerald-500 rounded-full animate-pulse shadow-[0_0_8px_#10b981]"></div>
|
|
18
|
+
<span class="text-[10px] font-black text-emerald-600 uppercase tracking-widest">System Ready</span>
|
|
19
|
+
</div>
|
|
20
|
+
<button id="main-download-btn" class="px-8 py-3 bg-indigo-600 text-white rounded-xl font-black text-xs uppercase tracking-widest hover:bg-slate-900 hover:scale-[1.02] transition-all duration-300 shadow-xl shadow-indigo-200 group">
|
|
21
|
+
<span class="flex items-center">
|
|
22
|
+
<svg class="w-4 h-4 mr-2 group-hover:translate-y-0.5 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M4 16v1a2 2 0 002 2h12a2 2 0 002-2v-1m-4-4l-4 4m0 0l-4-4m4 4V4" /></svg>
|
|
23
|
+
Commit Blueprint
|
|
24
|
+
</span>
|
|
25
|
+
</button>
|
|
26
|
+
</div>
|
|
27
|
+
</header>
|
|
28
|
+
|
|
29
|
+
<div class="flex h-[calc(100vh-100px)] overflow-hidden">
|
|
30
|
+
<!-- Professional Commands Sidebar -->
|
|
31
|
+
<nav class="w-64 bg-white border-r border-slate-200 p-6 flex flex-col space-y-2 shrink-0 overflow-y-auto custom-scrollbar">
|
|
32
|
+
<h4 class="text-[9px] font-black text-slate-400 uppercase tracking-[0.3em] mb-6 px-4 leading-none">Management Domains</h4>
|
|
33
|
+
<button onclick="switchTab('core')" class="tab-btn active w-full flex items-center space-x-4 px-6 py-4 rounded-2xl transition-all duration-300 group">
|
|
34
|
+
<div class="w-1.5 h-1.5 rounded-full bg-indigo-500 opacity-0 group-[.active]:opacity-100 transition-opacity translate-x-[-10px] group-[.active]:translate-x-0"></div>
|
|
35
|
+
<span class="text-sm font-bold text-slate-500 group-hover:text-indigo-600 group-[.active]:text-indigo-700 transition-colors">Core API Specs</span>
|
|
36
|
+
</button>
|
|
37
|
+
<button onclick="switchTab('datastore')" class="tab-btn w-full flex items-center space-x-4 px-6 py-4 rounded-2xl transition-all duration-300 group hover:bg-slate-50">
|
|
38
|
+
<div class="w-1.5 h-1.5 rounded-full bg-indigo-500 opacity-0 group-[.active]:opacity-100 transition-opacity translate-x-[-10px] group-[.active]:translate-x-0"></div>
|
|
39
|
+
<span class="text-sm font-bold text-slate-500 group-hover:text-indigo-600 group-[.active]:text-indigo-700 transition-colors">Hybrid Datastore</span>
|
|
40
|
+
</button>
|
|
41
|
+
<button onclick="switchTab('security')" class="tab-btn w-full flex items-center space-x-4 px-6 py-4 rounded-2xl transition-all duration-300 group hover:bg-slate-50">
|
|
42
|
+
<div class="w-1.5 h-1.5 rounded-full bg-indigo-500 opacity-0 group-[.active]:opacity-100 transition-opacity translate-x-[-10px] group-[.active]:translate-x-0"></div>
|
|
43
|
+
<span class="text-sm font-bold text-slate-500 group-hover:text-indigo-600 group-[.active]:text-indigo-700 transition-colors">Security & Identity</span>
|
|
44
|
+
</button>
|
|
45
|
+
<button onclick="switchTab('messaging')" class="tab-btn w-full flex items-center space-x-4 px-6 py-4 rounded-2xl transition-all duration-300 group hover:bg-slate-50">
|
|
46
|
+
<div class="w-1.5 h-1.5 rounded-full bg-indigo-500 opacity-0 group-[.active]:opacity-100 transition-opacity translate-x-[-10px] group-[.active]:translate-x-0"></div>
|
|
47
|
+
<span class="text-sm font-bold text-slate-500 group-hover:text-indigo-600 group-[.active]:text-indigo-700 transition-colors">Messaging Bridge</span>
|
|
48
|
+
</button>
|
|
49
|
+
<button onclick="switchTab('infrastructure')" class="tab-btn w-full flex items-center space-x-4 px-6 py-4 rounded-2xl transition-all duration-300 group hover:bg-slate-50">
|
|
50
|
+
<div class="w-1.5 h-1.5 rounded-full bg-indigo-500 opacity-0 group-[.active]:opacity-100 transition-opacity translate-x-[-10px] group-[.active]:translate-x-0"></div>
|
|
51
|
+
<span class="text-sm font-bold text-slate-500 group-hover:text-indigo-600 group-[.active]:text-indigo-700 transition-colors">Universal Storage</span>
|
|
52
|
+
</button>
|
|
53
|
+
<button onclick="switchTab('observability')" class="tab-btn w-full flex items-center space-x-4 px-6 py-4 rounded-2xl transition-all duration-300 group hover:bg-slate-50">
|
|
54
|
+
<div class="w-1.5 h-1.5 rounded-full bg-indigo-500 opacity-0 group-[.active]:opacity-100 transition-opacity translate-x-[-10px] group-[.active]:translate-x-0"></div>
|
|
55
|
+
<span class="text-sm font-bold text-slate-500 group-hover:text-indigo-600 group-[.active]:text-indigo-700 transition-colors">Observability Engine</span>
|
|
56
|
+
</button>
|
|
57
|
+
|
|
58
|
+
<div class="pt-12 mt-auto border-t border-slate-100 px-4 space-y-6">
|
|
59
|
+
<div>
|
|
60
|
+
<span class="text-[8px] font-black text-slate-400 uppercase tracking-widest block mb-3 italic">Industrial Status</span>
|
|
61
|
+
<div class="flex items-center space-x-2">
|
|
62
|
+
<div class="flex-grow h-1.5 bg-slate-100 rounded-full overflow-hidden">
|
|
63
|
+
<div class="w-[88%] h-full bg-indigo-500 shadow-[0_0_8px_rgba(99,102,241,0.5)]"></div>
|
|
64
|
+
</div>
|
|
65
|
+
<span class="text-[8px] font-black text-indigo-600 uppercase">361%</span>
|
|
66
|
+
</div>
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
</nav>
|
|
70
|
+
|
|
71
|
+
<!-- Configuration Canvas -->
|
|
72
|
+
<main class="flex-grow overflow-y-auto bg-slate-50/50 p-12 custom-scrollbar">
|
|
73
|
+
<div class="max-w-4xl mx-auto space-y-12 pb-24">
|
|
74
|
+
|
|
75
|
+
<!-- SECTION: CORE -->
|
|
76
|
+
<section id="tab-core" class="tab-content active space-y-8 animate-in fade-in slide-in-from-bottom-4 duration-700">
|
|
77
|
+
<div class="p-12 bg-white rounded-[3rem] border border-slate-200 shadow-xl shadow-slate-200/50 relative overflow-hidden group">
|
|
78
|
+
<div class="absolute -top-32 -right-32 w-80 h-80 bg-indigo-50 rounded-full blur-[80px] group-hover:scale-125 transition-transform duration-1000"></div>
|
|
79
|
+
<h2 class="text-3xl font-black text-slate-900 italic m-0 mb-10 tracking-tight leading-none decoration-indigo-200 underline underline-offset-[12px] uppercase">Core Orchestration</h2>
|
|
80
|
+
<div class="grid grid-cols-2 gap-8 relative z-10">
|
|
81
|
+
<div class="col-span-2 space-y-3">
|
|
82
|
+
<label class="text-[10px] font-black text-indigo-500 uppercase tracking-[0.2em] ml-2">App Name Identifier</label>
|
|
83
|
+
<input type="text" id="app_name" value="go-duck-master-app" class="w-full bg-slate-50 border-2 border-slate-100 rounded-2xl px-6 py-5 text-sm font-bold text-slate-900 focus:outline-none focus:border-indigo-500/50 transition-all placeholder-slate-400" />
|
|
84
|
+
</div>
|
|
85
|
+
<div class="space-y-3">
|
|
86
|
+
<label class="text-[10px] font-black text-indigo-500 uppercase tracking-[0.2em] ml-2">Blueprint Version</label>
|
|
87
|
+
<input type="text" id="app_version" value="1.0.0" class="w-full bg-slate-50 border-2 border-slate-100 rounded-2xl px-6 py-5 text-sm font-bold text-slate-900 focus:outline-none focus:border-indigo-500/50 transition-all" />
|
|
88
|
+
</div>
|
|
89
|
+
<div class="space-y-3">
|
|
90
|
+
<label class="text-[10px] font-black text-indigo-500 uppercase tracking-[0.2em] ml-2">Primary HTTP Port</label>
|
|
91
|
+
<input type="number" id="server_port" value="8080" class="w-full bg-slate-50 border-2 border-slate-100 rounded-2xl px-6 py-5 text-sm font-bold text-slate-900 focus:outline-none focus:border-indigo-500/50 transition-all" />
|
|
92
|
+
</div>
|
|
93
|
+
</div>
|
|
94
|
+
</div>
|
|
95
|
+
|
|
96
|
+
<div class="p-12 bg-white border border-slate-200 rounded-[3rem] shadow-md relative overflow-hidden group">
|
|
97
|
+
<div class="flex items-center justify-between mb-8">
|
|
98
|
+
<h3 class="text-sm font-black text-slate-900 uppercase tracking-widest flex items-center">
|
|
99
|
+
<div class="w-1.5 h-1.5 bg-indigo-500 rounded-full mr-3 shadow-md"></div>
|
|
100
|
+
Internal Discovery / gRPC Addr
|
|
101
|
+
</h3>
|
|
102
|
+
<span class="text-[9px] font-bold text-slate-300 uppercase tracking-widest italic group-hover:text-indigo-400 transition-colors">Industrial Zero-Trust Interface</span>
|
|
103
|
+
</div>
|
|
104
|
+
<div class="grid grid-cols-2 gap-8">
|
|
105
|
+
<input type="text" id="grpc_addr" value=":9000" class="bg-indigo-50/50 border border-indigo-100 rounded-2xl px-6 py-4 text-xs font-mono text-indigo-700 font-bold" />
|
|
106
|
+
<input type="text" id="grpc_network" value="tcp" class="bg-indigo-50/50 border border-indigo-100 rounded-2xl px-6 py-4 text-xs font-mono text-indigo-700 font-bold text-center" />
|
|
107
|
+
</div>
|
|
108
|
+
</div>
|
|
109
|
+
</section>
|
|
110
|
+
|
|
111
|
+
<!-- SECTION: DATASTORE -->
|
|
112
|
+
<section id="tab-datastore" class="tab-content hidden space-y-8">
|
|
113
|
+
<div class="p-12 bg-white rounded-[3rem] border border-slate-200 shadow-xl shadow-slate-200/40">
|
|
114
|
+
<h2 class="text-3xl font-black text-slate-900 italic m-0 mb-12 tracking-tight leading-none decoration-emerald-200 underline underline-offset-[12px] uppercase">Hybrid-Store Perspective</h2>
|
|
115
|
+
|
|
116
|
+
<div class="space-y-8">
|
|
117
|
+
<div id="pg_card" class="p-10 bg-slate-50 border-2 border-transparent hover:border-emerald-500/20 rounded-[3rem] transition-all relative group shadow-sm">
|
|
118
|
+
<div class="absolute top-10 right-10 flex items-center space-x-3">
|
|
119
|
+
<span class="text-[9px] font-black uppercase tracking-widest text-emerald-600 opacity-60">Postgres Connector</span>
|
|
120
|
+
<input type="checkbox" id="pg_enabled" checked onchange="updateUI()" class="w-5 h-5 text-emerald-600 border-slate-200 rounded-lg bg-white">
|
|
121
|
+
</div>
|
|
122
|
+
<h4 class="text-[10px] font-black text-slate-400 uppercase mb-8 flex items-center">
|
|
123
|
+
<svg class="w-4 h-4 mr-2 text-emerald-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M4 7v10c0 2.21 3.582 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.582 4 8 4s8-1.79 8-4M4 7c0-2.21 3.582-4 8-4s8 1.79 8 4m0 5c0 2.21-3.582 4-8 4s-8-1.79-8-4" /></svg>
|
|
124
|
+
Relational Repository (SQL)
|
|
125
|
+
</h4>
|
|
126
|
+
<div id="pg_grid" class="grid grid-cols-2 gap-6 transition-all duration-500">
|
|
127
|
+
<input type="text" id="db_host" placeholder="Silo Hostname" value="localhost" class="bg-white border-2 border-slate-100 rounded-xl px-5 py-4 text-xs font-bold text-slate-900 focus:outline-none focus:border-indigo-500/20" />
|
|
128
|
+
<input type="number" id="db_port" placeholder="Industrial Port" value="5432" class="bg-white border-2 border-slate-100 rounded-xl px-5 py-4 text-xs font-bold text-slate-900" />
|
|
129
|
+
<input type="text" id="db_user" placeholder="Postgres Authority" value="postgres" class="bg-white border-2 border-slate-100 rounded-xl px-5 py-4 text-xs font-bold text-slate-900" />
|
|
130
|
+
<input type="text" id="db_name" placeholder="Target Database" value="go_duck_db" class="bg-white border-2 border-slate-100 rounded-xl px-5 py-4 text-xs font-bold text-slate-900" />
|
|
131
|
+
</div>
|
|
132
|
+
</div>
|
|
133
|
+
|
|
134
|
+
<div id="mongo_card" class="p-10 bg-slate-50 border-2 border-transparent hover:border-emerald-500/20 rounded-[3rem] transition-all relative group shadow-sm">
|
|
135
|
+
<div class="absolute top-10 right-10 flex items-center space-x-3">
|
|
136
|
+
<span class="text-[9px] font-black uppercase tracking-widest text-emerald-600 opacity-60">Mongo Connector</span>
|
|
137
|
+
<input type="checkbox" id="mongo_enabled" onchange="updateUI()" class="w-5 h-5 text-emerald-600 border-slate-200 rounded-lg bg-white">
|
|
138
|
+
</div>
|
|
139
|
+
<h4 class="text-[10px] font-black text-slate-400 uppercase mb-8 flex items-center">
|
|
140
|
+
<svg class="w-4 h-4 mr-2 text-emerald-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" /></svg>
|
|
141
|
+
Document Registry (NoSQL)
|
|
142
|
+
</h4>
|
|
143
|
+
<div id="mongo_grid" class="space-y-6 opacity-20 pointer-events-none transition-all duration-500">
|
|
144
|
+
<input type="text" id="mongo_uri" placeholder="Cluster Connection URI" value="mongodb://localhost:27017" class="w-full bg-white border-2 border-slate-100 rounded-xl px-5 py-4 text-xs font-bold text-slate-900" />
|
|
145
|
+
<input type="text" id="mongo_db" placeholder="Cluster Instance" value="go_duck_mongo" class="w-full bg-white border-2 border-slate-100 rounded-xl px-5 py-4 text-xs font-bold text-slate-900" />
|
|
146
|
+
</div>
|
|
147
|
+
</div>
|
|
148
|
+
</div>
|
|
149
|
+
</div>
|
|
150
|
+
</section>
|
|
151
|
+
|
|
152
|
+
<!-- SECTION: SECURITY -->
|
|
153
|
+
<section id="tab-security" class="tab-content hidden space-y-8">
|
|
154
|
+
<div class="p-12 bg-white rounded-[3rem] border border-slate-200 shadow-xl shadow-slate-200/40">
|
|
155
|
+
<h2 class="text-3xl font-black text-slate-900 italic m-0 mb-12 tracking-tight leading-none decoration-rose-200 underline underline-offset-[12px] uppercase">Security Dashboard</h2>
|
|
156
|
+
|
|
157
|
+
<div class="space-y-8">
|
|
158
|
+
<div class="p-10 bg-slate-50 rounded-[3rem] border border-slate-100 shadow-inner">
|
|
159
|
+
<h4 class="text-[10px] font-black text-rose-500 uppercase tracking-[0.3em] mb-10 italic">OIDC Keycloak Integration</h4>
|
|
160
|
+
<div class="grid grid-cols-2 gap-x-8 gap-y-6">
|
|
161
|
+
<div class="space-y-3">
|
|
162
|
+
<label class="text-[9px] font-bold text-slate-400 uppercase ml-2">Auth Provider Host</label>
|
|
163
|
+
<input type="text" id="keycloak_host" value="http://localhost:8080" class="w-full bg-white border border-slate-200 rounded-2xl px-6 py-4 text-xs font-bold text-slate-900" />
|
|
164
|
+
</div>
|
|
165
|
+
<div class="space-y-3">
|
|
166
|
+
<label class="text-[9px] font-bold text-slate-400 uppercase ml-2">Master Realm</label>
|
|
167
|
+
<input type="text" id="keycloak_realm" value="go-duck-realm" class="w-full bg-white border border-slate-200 rounded-2xl px-6 py-4 text-xs font-bold text-slate-900" />
|
|
168
|
+
</div>
|
|
169
|
+
<div class="col-span-2 grid grid-cols-2 gap-8 mt-4 pt-6 border-t border-slate-200">
|
|
170
|
+
<div class="space-y-3">
|
|
171
|
+
<label class="text-[9px] font-bold text-slate-400 uppercase ml-2 tracking-widest flex items-center">
|
|
172
|
+
<svg class="w-2.5 h-2.5 mr-2 text-indigo-500" fill="currentColor" viewBox="0 0 20 20"><path d="M13 6a3 3 0 11-6 0 3 3 0 016 0zM18 8a2 2 0 11-4 0 2 2 0 014 0zM14 15a4 4 0 00-8 0v3h8v-3zM6 8a2 2 0 11-4 0 2 2 0 014 0zM16 18v-3a5.972 5.972 0 00-.75-2.906A3.005 3.005 0 0119 15v3h-3zM4.75 12.094A5.973 5.973 0 004 15v3H1v-3a3 3 0 013.75-2.906z" /></svg>
|
|
173
|
+
App Client ID
|
|
174
|
+
</label>
|
|
175
|
+
<input type="text" id="keycloak_app_id" value="go-duck-app" class="w-full bg-white border border-slate-200 rounded-2xl px-6 py-4 text-xs font-bold text-slate-900" />
|
|
176
|
+
</div>
|
|
177
|
+
<div class="space-y-3">
|
|
178
|
+
<label class="text-[9px] font-bold text-slate-400 uppercase ml-2 tracking-widest flex items-center">
|
|
179
|
+
<svg class="w-2.5 h-2.5 mr-2 text-indigo-500" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M18 8a6 6 0 01-7.743 5.743L10 14l-1 1-1 1H6v2H2v-4l4.257-4.257A6 6 0 1118 8zm-6-4a1 1 0 100 2 2 2 0 012 2 1 1 0 102 0 4 4 0 00-4-4z" clip-rule="evenodd" /></svg>
|
|
180
|
+
App Client Secret
|
|
181
|
+
</label>
|
|
182
|
+
<input type="password" id="keycloak_app_secret" value="app-secret-123" class="w-full bg-slate-50 border border-slate-200 rounded-2xl px-6 py-4 text-[10px] font-mono text-indigo-600 font-bold" />
|
|
183
|
+
</div>
|
|
184
|
+
</div>
|
|
185
|
+
<div class="col-span-2 grid grid-cols-2 gap-8 mt-4 pt-6 border-t border-slate-200">
|
|
186
|
+
<div class="space-y-3">
|
|
187
|
+
<label class="text-[9px] font-bold text-slate-400 uppercase ml-2 tracking-widest flex items-center text-amber-600">
|
|
188
|
+
<svg class="w-2.5 h-2.5 mr-2" fill="currentColor" viewBox="0 0 20 20"><path d="M2 11a1 1 0 011-1h2a1 1 0 011 1v5a1 1 0 01-1 1H3a1 1 0 01-1-1v-5zM8 7a1 1 0 011-1h2a1 1 0 011 1v9a1 1 0 01-1 1H9a1 1 0 01-1-1V7zM14 4a1 1 0 011-1h2a1 1 0 011 1v12a1 1 0 01-1 1h-2a1 1 0 01-1-1V4z" /></svg>
|
|
189
|
+
Service Client ID
|
|
190
|
+
</label>
|
|
191
|
+
<input type="text" id="keycloak_service_id" value="go-duck-service" class="w-full bg-white border border-slate-200 rounded-2xl px-6 py-4 text-xs font-bold text-slate-900" />
|
|
192
|
+
</div>
|
|
193
|
+
<div class="space-y-3">
|
|
194
|
+
<label class="text-[9px] font-bold text-slate-400 uppercase ml-2 tracking-widest flex items-center text-amber-600">
|
|
195
|
+
<svg class="w-2.5 h-2.5 mr-2" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M11.49 3.17c-.38-1.56-2.6-1.56-2.98 0a1.532 1.532 0 01-2.286.948c-1.372-.836-2.942.734-2.106 2.106.54.886.061 2.042-.947 2.287-1.561.379-1.561 2.6 0 2.978a1.532 1.532 0 01.947 2.287c-.836 1.372.734 2.942 2.106 2.106a1.532 1.532 0 012.287.947c.379 1.561 2.6 1.561 2.978 0a1.533 1.533 0 012.287-.947c1.372.836 2.942-.734 2.106-2.106a1.533 1.533 0 01.947-2.287c1.561-.379 1.561-2.6 0-2.978a1.532 1.532 0 01-.947-2.287c.836-1.372-.734-2.942-2.106-2.106a1.532 1.532 0 01-2.287-.947zM10 13a3 3 0 100-6 3 3 0 000 6z" clip-rule="evenodd" /></svg>
|
|
196
|
+
Service Secret
|
|
197
|
+
</label>
|
|
198
|
+
<input type="password" id="keycloak_service_secret" value="service-secret-123" class="w-full bg-slate-50 border border-slate-200 rounded-2xl px-6 py-4 text-[10px] font-mono text-amber-700 font-bold" />
|
|
199
|
+
</div>
|
|
200
|
+
</div>
|
|
201
|
+
<div class="col-span-2 grid grid-cols-2 gap-8 mt-4 pt-6 border-t border-slate-200 bg-slate-100/50 -mx-10 px-10 py-8 rounded-b-[2rem]">
|
|
202
|
+
<div class="space-y-3">
|
|
203
|
+
<label class="text-[9px] font-bold text-indigo-500 uppercase ml-2 tracking-widest flex items-center">
|
|
204
|
+
<svg class="w-2.5 h-2.5 mr-2" fill="currentColor" viewBox="0 0 20 20"><path d="M10 2a5 5 0 00-5 5v2a2 2 0 00-2 2v5a2 2 0 002 2h10a2 2 0 002-2v-5a2 2 0 00-2-2V7a5 5 0 00-5-5zM7 7a3 3 0 016 0v2H7V7z" /></svg>
|
|
205
|
+
Keycloak Admin ID
|
|
206
|
+
</label>
|
|
207
|
+
<input type="text" id="keycloak_admin_id" value="admin-cli" class="w-full bg-white border border-slate-200 rounded-2xl px-6 py-4 text-xs font-bold text-slate-900" />
|
|
208
|
+
</div>
|
|
209
|
+
<div class="space-y-3">
|
|
210
|
+
<label class="text-[9px] font-bold text-indigo-500 uppercase ml-2 tracking-widest flex items-center">
|
|
211
|
+
<svg class="w-2.5 h-2.5 mr-2" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M2.166 4.9L9.03 1.103a1.11 1.11 0 011.088 0l6.864 3.797c.394.218.636.63.636 1.076v9a1.11 1.11 0 01-.636 1.077l-6.864 3.796a1.11 1.11 0 01-1.088 0l-6.864-3.796A1.11 1.11 0 011.53 15.077v-9c0-.447.242-.858.636-1.076zM7.003 8.24a1 1 0 00-1 1.732l3 1.732a1 1 0 001-1.732l-3-1.732z" clip-rule="evenodd" /></svg>
|
|
212
|
+
Admin Secret
|
|
213
|
+
</label>
|
|
214
|
+
<input type="password" id="keycloak_admin_secret" value="admin-secret-xyz" class="w-full bg-white border border-slate-200 rounded-2xl px-6 py-4 text-[10px] font-mono text-indigo-600 font-bold" />
|
|
215
|
+
</div>
|
|
216
|
+
</div>
|
|
217
|
+
</div>
|
|
218
|
+
</div>
|
|
219
|
+
|
|
220
|
+
<div class="p-10 bg-white rounded-[3rem] border border-slate-200 shadow-sm">
|
|
221
|
+
<h4 class="text-[10px] font-black text-slate-400 uppercase tracking-[0.3em] mb-8">Executive CORS Policy</h4>
|
|
222
|
+
<div class="space-y-6">
|
|
223
|
+
<div class="space-y-2">
|
|
224
|
+
<label class="text-[9px] font-bold text-slate-300 uppercase ml-3">Permitted Domains</label>
|
|
225
|
+
<input type="text" id="cors_origins" value="*" class="w-full bg-slate-50 border border-slate-100 rounded-2xl px-6 py-4 text-xs font-bold text-slate-900" />
|
|
226
|
+
</div>
|
|
227
|
+
<div class="grid grid-cols-2 gap-8">
|
|
228
|
+
<div class="space-y-2 text-xs font-bold">
|
|
229
|
+
<label class="text-[9px] font-bold text-slate-300 uppercase ml-3">Whitelist Methods</label>
|
|
230
|
+
<input type="text" id="cors_methods" value="GET, POST, PUT, DELETE, OPTIONS" class="w-full bg-indigo-50/50 border border-indigo-100 rounded-2xl px-6 py-4 text-[10px] text-indigo-700 font-mono" />
|
|
231
|
+
</div>
|
|
232
|
+
<div class="space-y-2 text-xs font-bold">
|
|
233
|
+
<label class="text-[9px] font-bold text-slate-300 uppercase ml-3">Security Headers</label>
|
|
234
|
+
<input type="text" id="cors_headers" value="Origin, Content-Type, Accept, Authorization, X-Tenant-ID" class="w-full bg-indigo-50/50 border border-indigo-100 rounded-2xl px-6 py-4 text-[9px] text-indigo-700 font-mono" />
|
|
235
|
+
</div>
|
|
236
|
+
</div>
|
|
237
|
+
</div>
|
|
238
|
+
</div>
|
|
239
|
+
|
|
240
|
+
<div class="grid grid-cols-2 gap-6">
|
|
241
|
+
<div class="p-8 bg-slate-900 rounded-[2.5rem] flex items-center justify-between shadow-2xl">
|
|
242
|
+
<div class="space-y-1">
|
|
243
|
+
<span class="text-[10px] font-black text-white uppercase tracking-tighter block">Confidential Boundary</span>
|
|
244
|
+
<span class="text-[9px] text-slate-500 font-bold italic">Shields management silos</span>
|
|
245
|
+
</div>
|
|
246
|
+
<input type="checkbox" id="confidential_mode" checked class="w-6 h-6 text-indigo-500 rounded-lg">
|
|
247
|
+
</div>
|
|
248
|
+
<div class="p-8 bg-indigo-50 border border-indigo-100 rounded-[2.5rem] flex items-center justify-between">
|
|
249
|
+
<span class="text-[11px] font-black text-indigo-900 uppercase">Rate Limit (RPS)</span>
|
|
250
|
+
<input type="number" id="rate_limit_rps" value="100" class="w-16 bg-transparent border-none text-right font-black text-indigo-600 focus:ring-0 text-xl">
|
|
251
|
+
</div>
|
|
252
|
+
</div>
|
|
253
|
+
</div>
|
|
254
|
+
</div>
|
|
255
|
+
</section>
|
|
256
|
+
|
|
257
|
+
<!-- SECTION: MESSAGING -->
|
|
258
|
+
<section id="tab-messaging" class="tab-content hidden space-y-8">
|
|
259
|
+
<div class="p-12 bg-white rounded-[3rem] border border-slate-200 shadow-xl shadow-slate-200/40">
|
|
260
|
+
<h2 class="text-3xl font-black text-slate-900 italic m-0 mb-12 tracking-tight leading-none decoration-amber-200 underline underline-offset-[12px] uppercase">Messaging Pipeline</h2>
|
|
261
|
+
|
|
262
|
+
<div class="grid grid-cols-2 gap-8">
|
|
263
|
+
<div class="p-10 bg-slate-50 rounded-[3rem] border border-slate-100 space-y-6 group">
|
|
264
|
+
<div class="flex items-center space-x-3 mb-6">
|
|
265
|
+
<div class="w-3 h-3 bg-amber-500 rounded-full shadow-[0_0_8px_#f59e0b]"></div>
|
|
266
|
+
<h4 class="text-[10px] font-black text-slate-900 uppercase tracking-widest m-0 leading-none">MQTT Real-time Hub</h4>
|
|
267
|
+
</div>
|
|
268
|
+
<input type="text" id="mqtt_broker" value="tcp://localhost:1883" class="w-full bg-white border border-slate-200 rounded-2xl px-6 py-5 text-xs font-bold text-slate-900" />
|
|
269
|
+
<div class="p-4 bg-amber-500/5 rounded-2xl border border-amber-500/10 flex items-center justify-between">
|
|
270
|
+
<span class="text-[9px] font-black text-slate-400 uppercase tracking-tighter">Event Sink Prefix</span>
|
|
271
|
+
<span class="text-[10px] text-amber-700 font-bold italic font-mono uppercase tracking-widest opacity-60">go-duck/events</span>
|
|
272
|
+
</div>
|
|
273
|
+
</div>
|
|
274
|
+
<div class="p-10 bg-slate-50 rounded-[3rem] border border-slate-100 space-y-6">
|
|
275
|
+
<div class="flex items-center space-x-3 mb-6">
|
|
276
|
+
<div class="w-3 h-3 bg-amber-500 rounded-full"></div>
|
|
277
|
+
<h4 class="text-[10px] font-black text-slate-900 uppercase tracking-widest m-0 leading-none">NATS High-Perf Streaming</h4>
|
|
278
|
+
</div>
|
|
279
|
+
<input type="text" id="nats_url" value="nats://localhost:4222" class="w-full bg-white border border-slate-200 rounded-2xl px-6 py-5 text-xs font-bold text-slate-900" />
|
|
280
|
+
<div class="p-4 bg-emerald-500/5 rounded-2xl border border-emerald-500/10 flex items-center justify-between">
|
|
281
|
+
<span class="text-[9px] font-black text-slate-400 uppercase tracking-tighter">Cluster Peering</span>
|
|
282
|
+
<span class="text-[10px] text-emerald-700 font-bold uppercase tracking-widest opacity-60">Automatic</span>
|
|
283
|
+
</div>
|
|
284
|
+
</div>
|
|
285
|
+
</div>
|
|
286
|
+
|
|
287
|
+
<div class="mt-8 p-12 bg-white border-2 border-indigo-600 rounded-[4rem] shadow-2xl shadow-indigo-100 relative group overflow-hidden">
|
|
288
|
+
<div class="absolute -bottom-24 -right-24 w-64 h-64 bg-indigo-50 rounded-full blur-[60px] opacity-0 group-hover:opacity-100 transition-opacity duration-700"></div>
|
|
289
|
+
<div class="flex items-center justify-between mb-10">
|
|
290
|
+
<div class="space-y-1">
|
|
291
|
+
<h4 class="text-indigo-900 font-black text-2xl tracking-tight m-0 leading-none uppercase italic">Distributed Redis Stack</h4>
|
|
292
|
+
<p class="text-slate-400 text-[9px] font-black uppercase tracking-[0.2em] mt-3">Silo Lifecycle Management & Identity Caching</p>
|
|
293
|
+
</div>
|
|
294
|
+
<div class="flex items-center space-x-4">
|
|
295
|
+
<span class="text-[9px] font-black text-slate-300 uppercase tracking-widest opacity-60">Power Status</span>
|
|
296
|
+
<label class="relative inline-flex items-center cursor-pointer scale-110">
|
|
297
|
+
<input type="checkbox" id="redis_enabled" checked onchange="updateUI()" class="sr-only peer">
|
|
298
|
+
<div class="w-14 h-7 bg-slate-100 rounded-full peer peer-checked:after:translate-x-full after:content-[''] after:absolute after:top-[4px] after:left-[4px] after:bg-white after:rounded-full after:h-6 after:w-6 after:transition-all peer-checked:bg-indigo-600 shadow-inner border border-slate-200"></div>
|
|
299
|
+
</label>
|
|
300
|
+
</div>
|
|
301
|
+
</div>
|
|
302
|
+
<div id="redis_grid" class="grid grid-cols-2 gap-10 transition-all duration-700 items-end">
|
|
303
|
+
<div class="space-y-3">
|
|
304
|
+
<label class="text-[9px] font-black text-indigo-500 uppercase tracking-widest ml-3">Primary Node Host</label>
|
|
305
|
+
<input type="text" id="redis_host" value="localhost:6379" class="w-full bg-slate-50 border-2 border-slate-100 rounded-2xl px-6 py-5 text-sm font-bold text-slate-900 focus:outline-none" />
|
|
306
|
+
</div>
|
|
307
|
+
<div class="space-y-3">
|
|
308
|
+
<label class="text-[9px] font-black text-indigo-500 uppercase tracking-widest ml-3">TTL Persistence Window</label>
|
|
309
|
+
<input type="text" id="redis_ttl" value="10m" class="w-full bg-slate-50 border-2 border-slate-100 rounded-2xl px-6 py-5 text-sm font-bold text-slate-900 focus:outline-none text-center italic tracking-widest" />
|
|
310
|
+
</div>
|
|
311
|
+
</div>
|
|
312
|
+
</div>
|
|
313
|
+
</div>
|
|
314
|
+
</section>
|
|
315
|
+
|
|
316
|
+
<!-- SECTION: INFRASTRUCTURE -->
|
|
317
|
+
<section id="tab-infrastructure" class="tab-content hidden space-y-8">
|
|
318
|
+
<div class="p-12 bg-white rounded-[3rem] border border-slate-200 shadow-xl shadow-slate-200/40">
|
|
319
|
+
<h2 class="text-3xl font-black text-slate-900 italic m-0 mb-12 tracking-tight leading-none decoration-blue-200 underline underline-offset-[12px] uppercase">Universal Components</h2>
|
|
320
|
+
|
|
321
|
+
<div class="space-y-10">
|
|
322
|
+
<div class="p-10 bg-slate-50 rounded-[3rem] border border-slate-100">
|
|
323
|
+
<h4 class="text-[10px] font-black text-blue-600 uppercase tracking-[0.3em] mb-10 italic">Industrial Storage Bridge</h4>
|
|
324
|
+
<div class="flex items-center space-x-3 mb-10 overflow-x-auto pb-6 custom-scrollbar px-2">
|
|
325
|
+
<button onclick="setStorage('none')" id="store-none" class="store-btn px-8 py-4 bg-white border border-slate-200 rounded-2xl text-[10px] font-black uppercase text-slate-400 transition-all hover:border-indigo-500 active">None</button>
|
|
326
|
+
<button onclick="setStorage('s3')" id="store-s3" class="store-btn px-8 py-4 bg-white border border-slate-200 rounded-2xl text-[10px] font-black uppercase text-slate-400 transition-all hover:border-indigo-500">AWS S3</button>
|
|
327
|
+
<button onclick="setStorage('gcs')" id="store-gcs" class="store-btn px-8 py-4 bg-white border border-slate-200 rounded-2xl text-[10px] font-black uppercase text-slate-400 transition-all hover:border-indigo-500">GCP Cloud</button>
|
|
328
|
+
<button onclick="setStorage('minio')" id="store-minio" class="store-btn px-8 py-4 bg-white border border-slate-200 rounded-2xl text-[10px] font-black uppercase text-slate-400 transition-all hover:border-indigo-500">MinIO</button>
|
|
329
|
+
<button onclick="setStorage('github')" id="store-github" class="store-btn px-8 py-4 bg-white border border-slate-200 rounded-2xl text-[10px] font-black uppercase text-slate-400 transition-all hover:border-indigo-500">Git Bridge</button>
|
|
330
|
+
</div>
|
|
331
|
+
|
|
332
|
+
<div id="storage_details" class="hidden p-10 bg-white border-2 border-indigo-100 border-dashed rounded-[3.5rem] animate-pulse-slow">
|
|
333
|
+
<div id="fields_s3" class="storage-sub hidden grid grid-cols-2 gap-8">
|
|
334
|
+
<div class="space-y-3">
|
|
335
|
+
<label class="text-[9px] font-black text-blue-500 uppercase ml-2 tracking-widest">Environment Bucket</label>
|
|
336
|
+
<input type="text" id="s3_bucket" placeholder="e.g. production-blobs" class="w-full bg-slate-50 border border-slate-100 rounded-2xl px-6 py-4 text-xs font-bold text-slate-900" />
|
|
337
|
+
</div>
|
|
338
|
+
<div class="space-y-3">
|
|
339
|
+
<label class="text-[9px] font-black text-blue-500 uppercase ml-2 tracking-widest">Target Region</label>
|
|
340
|
+
<input type="text" id="s3_region" value="us-east-1" class="w-full bg-slate-50 border border-slate-100 rounded-2xl px-6 py-4 text-xs font-bold text-slate-900 text-center uppercase tracking-widest" />
|
|
341
|
+
</div>
|
|
342
|
+
</div>
|
|
343
|
+
<div id="fields_github" class="storage-sub hidden space-y-8 text-center py-6">
|
|
344
|
+
<p class="text-[11px] text-blue-600 font-black uppercase tracking-widest italic leading-relaxed">Federated Bootstrapping Protocol Active:<br><span class="text-slate-300 opacity-60 not-italic font-mono">Synchronizing SSH/Identity Secrets from Repository</span></p>
|
|
345
|
+
<input type="text" id="github_repo" placeholder="organization/infrastructure-secrets" class="w-full bg-slate-50 border border-slate-100 rounded-2xl px-6 py-5 text-sm font-bold text-slate-900 text-center" />
|
|
346
|
+
</div>
|
|
347
|
+
</div>
|
|
348
|
+
</div>
|
|
349
|
+
|
|
350
|
+
<div class="p-12 bg-indigo-900 rounded-[4rem] text-white shadow-2xl relative overflow-hidden group">
|
|
351
|
+
<div class="absolute inset-0 bg-gradient-to-br from-indigo-500/20 to-transparent"></div>
|
|
352
|
+
<h4 class="text-[10px] font-black text-indigo-400 uppercase tracking-[0.5em] mb-12 italic relative z-10 text-center">Global Resilience Policies</h4>
|
|
353
|
+
<div class="grid grid-cols-2 gap-10 relative z-10">
|
|
354
|
+
<div class="p-8 bg-white/10 backdrop-blur-md border border-white/10 rounded-[2.5rem] flex items-center justify-between hover:bg-white/15 transition-all">
|
|
355
|
+
<div class="space-y-1">
|
|
356
|
+
<span class="text-[10px] font-black text-indigo-200 uppercase tracking-widest">Circuit Breaker</span>
|
|
357
|
+
<span class="text-xl font-black text-white block mt-1 tracking-tighter italic">Industrial Mode</span>
|
|
358
|
+
</div>
|
|
359
|
+
<div class="w-3 h-3 bg-indigo-300 rounded-full shadow-[0_0_15px_rgba(255,255,255,0.5)]"></div>
|
|
360
|
+
</div>
|
|
361
|
+
<div class="p-8 bg-white/10 backdrop-blur-md border border-white/10 rounded-[2.5rem] flex items-center justify-between hover:bg-white/15 transition-all">
|
|
362
|
+
<div class="space-y-1">
|
|
363
|
+
<span class="text-[10px] font-black text-indigo-200 uppercase tracking-widest">Outbox Worker</span>
|
|
364
|
+
<span class="text-xl font-black text-white block mt-1 tracking-tighter italic">Broadcast-Sync</span>
|
|
365
|
+
</div>
|
|
366
|
+
<input type="checkbox" checked class="w-6 h-6 text-white bg-transparent border-2 border-white/20 rounded-lg">
|
|
367
|
+
</div>
|
|
368
|
+
</div>
|
|
369
|
+
</div>
|
|
370
|
+
</div>
|
|
371
|
+
</div>
|
|
372
|
+
</section>
|
|
373
|
+
|
|
374
|
+
<!-- SECTION: OBSERVABILITY -->
|
|
375
|
+
<section id="tab-observability" class="tab-content hidden space-y-8">
|
|
376
|
+
<div class="p-12 bg-white rounded-[3rem] border border-slate-200 shadow-xl shadow-slate-200/40">
|
|
377
|
+
<h2 class="text-3xl font-black text-slate-900 italic m-0 mb-12 tracking-tight leading-none decoration-purple-200 underline underline-offset-[12px] uppercase">Observability engine</h2>
|
|
378
|
+
|
|
379
|
+
<div class="space-y-10">
|
|
380
|
+
<div class="p-12 bg-[#fafbff] rounded-[4rem] border-2 border-purple-100 shadow-sm transition-all focus-within:border-purple-600/30">
|
|
381
|
+
<div class="flex items-center justify-between mb-12">
|
|
382
|
+
<div class="flex items-center space-x-4">
|
|
383
|
+
<div class="w-14 h-14 bg-purple-100 rounded-3xl flex items-center justify-center text-purple-600 shadow-inner">
|
|
384
|
+
<svg class="w-7 h-7" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" /></svg>
|
|
385
|
+
</div>
|
|
386
|
+
<div>
|
|
387
|
+
<h4 class="text-purple-900 font-black text-lg tracking-tight m-0 uppercase leading-none italic">Elasticsearch Sync</h4>
|
|
388
|
+
<p class="text-[10px] font-black text-purple-400 uppercase tracking-widest mt-2">Spring-Style Federated Searching Engine</p>
|
|
389
|
+
</div>
|
|
390
|
+
</div>
|
|
391
|
+
<label class="relative inline-flex items-center cursor-pointer">
|
|
392
|
+
<input type="checkbox" id="es_enabled" checked onchange="updateUI()" class="sr-only peer">
|
|
393
|
+
<div class="w-14 h-7 bg-purple-200/50 rounded-full peer peer-checked:after:translate-x-full after:content-[''] after:absolute after:top-[4px] after:left-[4px] after:bg-white after:rounded-full after:h-6 after:w-6 after:transition-all peer-checked:bg-purple-600 shadow-inner border border-purple-100"></div>
|
|
394
|
+
</label>
|
|
395
|
+
</div>
|
|
396
|
+
<div id="es_form" class="grid grid-cols-2 gap-10">
|
|
397
|
+
<div class="space-y-3">
|
|
398
|
+
<label class="text-[9px] font-black text-purple-500 uppercase tracking-widest ml-3">Internal Node URL</label>
|
|
399
|
+
<input type="text" id="es_addr" value="http://localhost:9200" class="w-full bg-white border border-purple-100 rounded-2xl px-6 py-5 text-xs font-mono text-slate-900 font-bold" />
|
|
400
|
+
</div>
|
|
401
|
+
<div class="space-y-3">
|
|
402
|
+
<label class="text-[9px] font-black text-purple-500 uppercase tracking-widest ml-3">Industrial Index Prefix</label>
|
|
403
|
+
<input type="text" value="go_duck_production" class="w-full bg-white border border-purple-100 rounded-2xl px-6 py-5 text-xs font-mono text-purple-300 font-bold opacity-40 italic cursor-not-allowed" disabled />
|
|
404
|
+
</div>
|
|
405
|
+
</div>
|
|
406
|
+
</div>
|
|
407
|
+
|
|
408
|
+
<div class="grid grid-cols-2 gap-10">
|
|
409
|
+
<div class="p-10 bg-white border border-slate-200 rounded-[3.5rem] shadow-sm group hover:border-purple-200 transition-all">
|
|
410
|
+
<div class="flex items-center justify-between mb-10">
|
|
411
|
+
<h4 class="text-[10px] font-black text-slate-400 uppercase tracking-widest">Datadog APM Log Stream</h4>
|
|
412
|
+
<input type="checkbox" id="datadog_enabled" onchange="updateUI()" class="w-5 h-5 text-purple-600 border-slate-200 rounded-lg">
|
|
413
|
+
</div>
|
|
414
|
+
<div id="datadog_form" class="space-y-6 opacity-10 pointer-events-none transition-all duration-700">
|
|
415
|
+
<input type="password" id="datadog_key" placeholder="Industrial API Token" class="w-full bg-slate-50 border border-slate-100 rounded-2xl px-6 py-5 text-xs font-mono text-slate-900" />
|
|
416
|
+
<div class="flex items-center justify-between px-3">
|
|
417
|
+
<span class="text-[9px] font-black text-slate-300 uppercase tracking-tighter">Global Site Node</span>
|
|
418
|
+
<span class="text-[10px] text-purple-600 font-black italic tracking-widest uppercase">datadoghq.com</span>
|
|
419
|
+
</div>
|
|
420
|
+
</div>
|
|
421
|
+
</div>
|
|
422
|
+
<div class="p-10 bg-white border border-slate-200 rounded-[3.5rem] shadow-sm group hover:border-indigo-200 transition-all">
|
|
423
|
+
<div class="flex items-center justify-between mb-10">
|
|
424
|
+
<h4 class="text-[10px] font-black text-slate-400 uppercase tracking-widest">OpenTelemetry Tracing</h4>
|
|
425
|
+
<input type="checkbox" id="otel_enabled" checked onchange="updateUI()" class="w-5 h-5 text-indigo-600 border-slate-200 rounded-lg">
|
|
426
|
+
</div>
|
|
427
|
+
<div id="otel_form" class="space-y-6 transition-all duration-700">
|
|
428
|
+
<input type="text" id="otel_endpoint" value="localhost:4317" class="w-full bg-slate-50 border border-slate-100 rounded-2xl px-6 py-5 text-xs font-mono text-slate-900" />
|
|
429
|
+
<div class="flex items-center justify-between px-3">
|
|
430
|
+
<span class="text-[9px] font-black text-slate-300 uppercase tracking-tighter">Distributed Trace Ratio</span>
|
|
431
|
+
<span class="text-[10px] text-indigo-600 font-black italic tracking-widest uppercase">1.0 (Audit Precision)</span>
|
|
432
|
+
</div>
|
|
433
|
+
</div>
|
|
434
|
+
</div>
|
|
435
|
+
</div>
|
|
436
|
+
</div>
|
|
437
|
+
</div>
|
|
438
|
+
</section>
|
|
439
|
+
</div>
|
|
440
|
+
</main>
|
|
441
|
+
|
|
442
|
+
<!-- Blueprint Inspector (Right Side Terminal) -->
|
|
443
|
+
<aside class="w-[660px] bg-white border-l border-slate-200 p-12 flex flex-col relative overflow-hidden shrink-0">
|
|
444
|
+
<div class="absolute top-0 right-0 w-96 h-96 bg-indigo-50/50 rounded-full blur-[100px] pointer-events-none"></div>
|
|
445
|
+
<div class="relative z-10 flex flex-col h-full">
|
|
446
|
+
<div class="flex items-center justify-between mb-8 border-b border-slate-100 pb-8">
|
|
447
|
+
<div class="flex items-center space-x-4">
|
|
448
|
+
<div class="w-10 h-10 bg-indigo-50 rounded-xl flex items-center justify-center text-indigo-600 shadow-sm">
|
|
449
|
+
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4" /></svg>
|
|
450
|
+
</div>
|
|
451
|
+
<div>
|
|
452
|
+
<h4 class="text-slate-900 font-black text-[12px] tracking-[0.2em] uppercase m-0 leading-none">Industrial blueprint</h4>
|
|
453
|
+
<p class="text-slate-400 text-[9px] font-bold mt-2 leading-none uppercase tracking-widest italic opacity-60">config.yaml • Executive Standard</p>
|
|
454
|
+
</div>
|
|
455
|
+
</div>
|
|
456
|
+
<button onclick="copyToClipboard()" class="p-4 bg-slate-50 border border-slate-200 rounded-2xl hover:bg-slate-100 transition-all group active:scale-95">
|
|
457
|
+
<svg class="w-5 h-5 text-slate-500 group-hover:text-indigo-600 transition-colors" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M8 5H6a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2v-1M8 5a2 2 0 002 2h2a2 2 0 002-2M8 5a2 2 0 012-2h2a2 2 0 012 2m0 0h2a2 2 0 012 2v3m2 4H10m0 0l3-3m-3 3l3 3" /></svg>
|
|
458
|
+
</button>
|
|
459
|
+
</div>
|
|
460
|
+
|
|
461
|
+
<div class="flex-grow overflow-hidden relative bg-[#0a0a0a] rounded-[3rem] border border-slate-800 shadow-2xl p-1 group">
|
|
462
|
+
<pre id="yaml-preview" class="text-[#00ff41] font-mono text-[13.5px] font-medium leading-[1.8] m-0 selection:bg-[#00ff41]/20 selection:text-white h-full overflow-y-auto custom-scrollbar p-12 pb-80">
|
|
463
|
+
</pre>
|
|
464
|
+
<div class="absolute inset-x-0 bottom-0 h-40 bg-gradient-to-t from-[#0a0a0a] via-[#0a0a0a]/90 to-transparent pointer-events-none"></div>
|
|
465
|
+
<div class="absolute top-8 right-8 opacity-0 group-hover:opacity-100 transition-opacity">
|
|
466
|
+
<span class="text-[10px] font-black text-[#00ff41] bg-[#00ff41]/10 px-3 py-1 rounded-full border border-[#00ff41]/20 animate-pulse">ELITE LIVE FEED</span>
|
|
467
|
+
</div>
|
|
468
|
+
</div>
|
|
469
|
+
|
|
470
|
+
<div class="mt-8 p-8 bg-emerald-50/10 border border-emerald-500/20 rounded-[3rem] shadow-sm backdrop-blur-sm">
|
|
471
|
+
<div class="flex items-center space-x-3">
|
|
472
|
+
<div class="w-2 h-2 bg-emerald-500 rounded-full animate-pulse shadow-[0_0_15px_#10b981]"></div>
|
|
473
|
+
<span class="text-[9px] font-black text-emerald-500 uppercase tracking-[0.3em] leading-none mt-0.5 italic">Industrial Pulse Protocol ACTIVE</span>
|
|
474
|
+
</div>
|
|
475
|
+
</div>
|
|
476
|
+
</div>
|
|
477
|
+
</aside>
|
|
478
|
+
</div>
|
|
479
|
+
</div>
|
|
480
|
+
|
|
481
|
+
<style>
|
|
482
|
+
.custom-scrollbar::-webkit-scrollbar { width: 4px; height: 4px; }
|
|
483
|
+
.custom-scrollbar::-webkit-scrollbar-track { background: rgba(0,0,0,0.01); }
|
|
484
|
+
.custom-scrollbar::-webkit-scrollbar-thumb { background: rgba(99, 102, 241, 0.3); border-radius: 10px; }
|
|
485
|
+
.custom-scrollbar::-webkit-scrollbar-thumb:hover { background: rgba(99, 102, 241, 0.5); }
|
|
486
|
+
|
|
487
|
+
.tab-btn.active { background: rgba(99, 102, 241, 0.05); border-color: rgba(99, 102, 241, 0.1); }
|
|
488
|
+
.tab-btn.active span { color: #4338ca; }
|
|
489
|
+
|
|
490
|
+
.animate-pulse-slow { animation: pulse 6s cubic-bezier(0.4, 0, 0.6, 1) infinite; }
|
|
491
|
+
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.8; } }
|
|
492
|
+
|
|
493
|
+
.store-btn.active { background: #4f46e5; border-color: transparent; color: white; shadow: 0 10px 15px -3px rgba(79, 70, 229, 0.3); }
|
|
494
|
+
|
|
495
|
+
input[type="checkbox"] { background: #f1f5f9; border: 2px solid #e2e8f0; cursor: pointer; transition: all 0.3s ease; }
|
|
496
|
+
input[type="checkbox"]:checked { background-color: #4f46e5; border-color: transparent; }
|
|
497
|
+
</style>
|
|
498
|
+
|
|
499
|
+
<!-- CLIENT LOGIC ENGINE -->
|
|
500
|
+
<script>
|
|
501
|
+
const d = (id) => { const el = document.getElementById(id); return el ? el.value : ""; };
|
|
502
|
+
const b = (id) => { const el = document.getElementById(id); return el ? el.checked : false; };
|
|
503
|
+
|
|
504
|
+
const switchTab = (tab) => {
|
|
505
|
+
document.querySelectorAll('.tab-btn').forEach(btn => btn.classList.remove('active'));
|
|
506
|
+
document.querySelectorAll('.tab-content').forEach(content => content.classList.add('hidden'));
|
|
507
|
+
|
|
508
|
+
event.currentTarget.classList.add('active');
|
|
509
|
+
document.getElementById(`tab-${tab}`).classList.remove('hidden');
|
|
510
|
+
};
|
|
511
|
+
|
|
512
|
+
const updateUI = () => {
|
|
513
|
+
const pg = b('pg_enabled');
|
|
514
|
+
const mongo = b('mongo_enabled');
|
|
515
|
+
const redis = b('redis_enabled');
|
|
516
|
+
const es = b('es_enabled');
|
|
517
|
+
const dd = b('datadog_enabled');
|
|
518
|
+
const otel = b('otel_enabled');
|
|
519
|
+
|
|
520
|
+
document.getElementById('pg_grid').style.opacity = pg ? '1' : '0.1';
|
|
521
|
+
document.getElementById('mongo_grid').style.opacity = mongo ? '1' : '0.1';
|
|
522
|
+
document.getElementById('redis_grid').style.opacity = redis ? '1' : '0.1';
|
|
523
|
+
document.getElementById('es_form').style.opacity = es ? '1' : '0.1';
|
|
524
|
+
document.getElementById('datadog_form').style.opacity = dd ? '1' : '0.1';
|
|
525
|
+
document.getElementById('otel_form').style.opacity = otel ? '1' : '0.1';
|
|
526
|
+
|
|
527
|
+
updatePreview();
|
|
528
|
+
};
|
|
529
|
+
|
|
530
|
+
let activeStorage = 'none';
|
|
531
|
+
const setStorage = (prov) => {
|
|
532
|
+
activeStorage = prov;
|
|
533
|
+
document.querySelectorAll('.store-btn').forEach(b => b.classList.remove('active'));
|
|
534
|
+
document.getElementById(`store-${prov}`).classList.add('active');
|
|
535
|
+
|
|
536
|
+
const panel = document.getElementById('storage_details');
|
|
537
|
+
document.querySelectorAll('.storage-sub').forEach(s => s.classList.add('hidden'));
|
|
538
|
+
|
|
539
|
+
if(prov !== 'none') {
|
|
540
|
+
panel.classList.remove('hidden');
|
|
541
|
+
const sub = document.getElementById(`fields_${prov}`);
|
|
542
|
+
if(sub) sub.classList.remove('hidden');
|
|
543
|
+
} else {
|
|
544
|
+
panel.classList.add('hidden');
|
|
545
|
+
}
|
|
546
|
+
updatePreview();
|
|
547
|
+
};
|
|
548
|
+
|
|
549
|
+
const generateYAML = () => {
|
|
550
|
+
const config = {
|
|
551
|
+
'go-duck': {
|
|
552
|
+
name: d('app_name'),
|
|
553
|
+
version: d('app_version'),
|
|
554
|
+
server: {
|
|
555
|
+
port: parseInt(d('server_port')) || 8080,
|
|
556
|
+
grpc: { addr: d('grpc_addr'), network: d('grpc_network'), timeout: "1s" },
|
|
557
|
+
cors: {
|
|
558
|
+
'allow-origins': d('cors_origins').split(',').map(s => s.trim()),
|
|
559
|
+
'allow-methods': d('cors_methods').split(',').map(s => s.trim()),
|
|
560
|
+
'allow-headers': d('cors_headers').split(',').map(s => s.trim())
|
|
561
|
+
}
|
|
562
|
+
},
|
|
563
|
+
datasource: {},
|
|
564
|
+
security: {
|
|
565
|
+
'keycloak-host': d('keycloak_host'),
|
|
566
|
+
'keycloak-realm': d('keycloak_realm'),
|
|
567
|
+
'keycloak-app-client-id': d('keycloak_app_id'),
|
|
568
|
+
'keycloak-app-client-secret': d('keycloak_app_secret'),
|
|
569
|
+
'keycloak-service-client-id': d('keycloak_service_id'),
|
|
570
|
+
'keycloak-service-secret': d('keycloak_service_secret'),
|
|
571
|
+
'keycloak-admin-client-id': d('keycloak_admin_id'),
|
|
572
|
+
'keycloak-admin-secret': d('keycloak_admin_secret'),
|
|
573
|
+
'confidential-mode': b('confidential_mode'),
|
|
574
|
+
'rate-limit': { rps: parseInt(d('rate_limit_rps')), burst: 200 }
|
|
575
|
+
},
|
|
576
|
+
messaging: {
|
|
577
|
+
mqtt: { enabled: true, broker: d('mqtt_broker') },
|
|
578
|
+
nats: { enabled: true, url: d('nats_url') }
|
|
579
|
+
},
|
|
580
|
+
cache: {
|
|
581
|
+
redis: { enabled: b('redis_enabled'), host: d('redis_host'), ttl: d('redis_ttl') }
|
|
582
|
+
},
|
|
583
|
+
resilience: {
|
|
584
|
+
'circuit-breaker': { enabled: true, 'failure-threshold': 5 }
|
|
585
|
+
},
|
|
586
|
+
telemetry: {
|
|
587
|
+
otel: { enabled: b('otel_enabled'), endpoint: d('otel_endpoint'), 'sampler-ratio': 1.0 }
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
};
|
|
591
|
+
|
|
592
|
+
if(b('pg_enabled')) {
|
|
593
|
+
config['go-duck'].datasource.host = d('db_host') || "localhost";
|
|
594
|
+
config['go-duck'].datasource.port = parseInt(d('db_port')) || 5432;
|
|
595
|
+
config['go-duck'].datasource.username = d('db_user') || "postgres";
|
|
596
|
+
config['go-duck'].datasource.database = d('db_name') || "go_duck_db";
|
|
597
|
+
config['go-duck'].datasource['ssl-mode'] = "disable";
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
if(b('mongo_enabled')) {
|
|
601
|
+
config['go-duck'].datasource.mongodb = {
|
|
602
|
+
enabled: true,
|
|
603
|
+
uri: d('mongo_uri') || "mongodb://localhost:27017",
|
|
604
|
+
database: d('mongo_db') || "go_duck_mongo"
|
|
605
|
+
};
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
if(b('datadog_enabled')) {
|
|
609
|
+
config['go-duck'].logging = {
|
|
610
|
+
datadog: { enabled: true, 'api-key': d('datadog_key') || "YOUR_KEY", site: "datadoghq.com" }
|
|
611
|
+
};
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
if(activeStorage !== 'none') {
|
|
615
|
+
config['go-duck'].storage = {};
|
|
616
|
+
config['go-duck'].storage[activeStorage] = { enabled: true };
|
|
617
|
+
if(activeStorage === 's3') {
|
|
618
|
+
config['go-duck'].storage.s3.bucket = d('s3_bucket');
|
|
619
|
+
config['go-duck'].storage.s3.region = d('s3_region');
|
|
620
|
+
}
|
|
621
|
+
if(activeStorage === 'github') {
|
|
622
|
+
config['go-duck'].storage.github = {
|
|
623
|
+
owner: d('github_repo').split('/')[0] || "YOUR_ORG",
|
|
624
|
+
repo: d('github_repo').split('/')[1] || "YOUR_REPO"
|
|
625
|
+
};
|
|
626
|
+
config['go-duck'].storage.bootstrap = { enabled: true, files: ["id_rsa"] };
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
if(b('es_enabled')) {
|
|
631
|
+
config['go-duck'].elasticsearch = { enabled: true, addresses: [d('es_addr')] };
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
config.environment = { active_profile: "dev" };
|
|
635
|
+
|
|
636
|
+
const toYAML = (obj, indent = 0) => {
|
|
637
|
+
let yaml = '';
|
|
638
|
+
const spaces = ' '.repeat(indent);
|
|
639
|
+
for (const key in obj) {
|
|
640
|
+
const val = obj[key];
|
|
641
|
+
if (typeof val === 'object' && !Array.isArray(val) && val !== null) {
|
|
642
|
+
const keys = Object.keys(val);
|
|
643
|
+
if(keys.length > 0) yaml += `${spaces}${key}:\n${toYAML(val, indent + 1)}`;
|
|
644
|
+
} else if (Array.isArray(val)) {
|
|
645
|
+
yaml += `${spaces}${key}: [${val.map(v => v === '*' ? '"*"' : `"${v}"`).join(', ')}]\n`;
|
|
646
|
+
} else {
|
|
647
|
+
const formattedVal = (typeof val === 'string' && val !== '*' && !val.includes(':') && !val.includes('/')) ? `"${val}"` : val;
|
|
648
|
+
yaml += `${spaces}${key}: ${formattedVal}\n`;
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
return yaml;
|
|
652
|
+
};
|
|
653
|
+
|
|
654
|
+
return toYAML(config);
|
|
655
|
+
};
|
|
656
|
+
|
|
657
|
+
const updatePreview = () => {
|
|
658
|
+
document.getElementById('yaml-preview').textContent = generateYAML();
|
|
659
|
+
};
|
|
660
|
+
|
|
661
|
+
const copyToClipboard = () => {
|
|
662
|
+
const text = document.getElementById('yaml-preview').textContent;
|
|
663
|
+
navigator.clipboard.writeText(text);
|
|
664
|
+
const btn = event.currentTarget;
|
|
665
|
+
const original = btn.innerHTML;
|
|
666
|
+
btn.innerHTML = '<svg class="w-5 h-5 text-emerald-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M5 13l4 4L19 7" /></svg>';
|
|
667
|
+
setTimeout(() => btn.innerHTML = original, 2000);
|
|
668
|
+
};
|
|
669
|
+
|
|
670
|
+
const bind = (id) => { const el = document.getElementById(id); if(el) el.addEventListener('input', updatePreview); if(el && el.type === 'checkbox') el.addEventListener('change', updatePreview); };
|
|
671
|
+
|
|
672
|
+
['app_name', 'app_version', 'server_port', 'grpc_addr', 'grpc_network', 'keycloak_host', 'keycloak_realm', 'keycloak_app_id', 'keycloak_app_secret', 'keycloak_service_id', 'keycloak_service_secret', 'keycloak_admin_id', 'keycloak_admin_secret', 'cors_origins', 'cors_methods', 'cors_headers', 'confidential_mode', 'rate_limit_rps', 'db_host', 'db_port', 'db_user', 'db_name', 'mongo_uri', 'mongo_db', 'mqtt_broker', 'nats_url', 'redis_enabled', 'redis_host', 'redis_ttl', 's3_bucket', 's3_region', 'github_repo', 'es_enabled', 'es_addr', 'datadog_enabled', 'datadog_key', 'otel_enabled', 'otel_endpoint']
|
|
673
|
+
.forEach(bind);
|
|
674
|
+
|
|
675
|
+
document.getElementById('main-download-btn').addEventListener('click', () => {
|
|
676
|
+
const yaml = generateYAML();
|
|
677
|
+
const blob = new Blob([yaml], { type: 'text/yaml' });
|
|
678
|
+
const url = URL.createObjectURL(blob);
|
|
679
|
+
const a = document.createElement('a'); a.href = url; a.download = 'config.yaml'; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url);
|
|
680
|
+
});
|
|
681
|
+
|
|
682
|
+
updatePreview();
|
|
683
|
+
</script>
|