@ -1,375 +1,23 @@
@@ -1,375 +1,23 @@
<!DOCTYPE html>
< html lang = "en" >
< head >
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" >
< title > System Design Game< / title >
< link rel = "stylesheet" type = "text/css" href = "/static/style.css" / >
< / head >
< body >
< div id = "page-container" >
< div id = "sd-header" >
< h1 class = "header-text" > System Design Game< / h1 >
{{ if and .Username .Avatar }}
< div class = "userbox" >
< img src = "{{ .Avatar }}" class = "avatar" / >
< span class = "username" > {{ .Username }}< / span >
< / div >
{{ else }}
< a href = "/login" id = "github-login-btn" >
< img src = "https://cdn.jsdelivr.net/gh/devicons/devicon/icons/github/github-original.svg" alt = "GitHub Logo" >
Login with GitHub
< / a >
{{ end }}
< / div >
< div id = "main-content" >
< div id = "challenge-container" >
< h2 class = "sidebar-title" > Challenges< / h2 >
< ul class = "challenge-list" >
{{range .Levels}}
< li class = "challenge-item {{if and (eq .Name $.Level.Name) (eq .Difficulty $.Level.Difficulty)}}active{{end}}" >
< div class = "challenge-name" > {{.Name}}< / div >
< div class = "challenge-difficulty {{.Difficulty}}" > {{.Difficulty}}< / div >
< / li >
{{end}}
< / ul >
< / div >
< div id = "canvas-wrapper" >
< input type = "radio" id = "tab1" name = "tab" checked >
< input type = "radio" id = "tab2" name = "tab" >
< input type = "radio" id = "tab3" name = "tab" >
< head >
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" >
< title > System Design Game< / title >
< link rel = "stylesheet" type = "text/css" href = "/static/style.css" / >
< / head >
< div class = "tabs" >
< div class = "tab-labels" >
< label for = "tab1" > Requirements< / label >
< label for = "tab2" > Design< / label >
< label for = "tab3" > Metrics< / label >
< / div >
< body >
< div id = "page-container" >
{{ template "header" . }}
< div id = "main-content" >
{{ template "challenges" . }}
<!-- Requirements -->
< div id = "content1" class = "tab-content" >
{{ if .Level.InterviewerRequirements }}
< div class = "requirements-section" >
< h3 > Interviewer Requirements< / h3 >
< ul class = "requirements-list" >
{{ range .Level.InterviewerRequirements }}
< li class = "requirement-item" > {{ . }}< / li >
{{ end }}
< / ul >
< / div >
{{ end }}
{{ template "canvas" . }}
{{ if .Level.FunctionalRequirements }}
< div class = "requirements-section" >
< h3 > Functional Requirements< / h3 >
< ul class = "requirements-list" >
{{ range .Level.FunctionalRequirements }}
< li class = "requirement-item" > {{ . }}< / li >
{{ end }}
< / ul >
< / div >
{{ end }}
{{ template "chat" . }}
< script type = "module" src = "/static/index.js" > < / script >
< / body >
{{ if .Level.NonFunctionalRequirements }}
< div class = "requirements-section" >
< h3 > Non-Functional Requirements< / h3 >
< ul class = "requirements-list" >
{{ range .Level.NonFunctionalRequirements }}
< li class = "requirement-item" > {{ . }}< / li >
{{ end }}
< / ul >
< / div >
{{ end }}
< / div >
<!-- Design -->
< div id = "content2" class = "tab-content" >
< div id = "sidebar" >
< div class = "component-icon" draggable = "true" data-type = "user" >
user
< / div >
< div class = "component-icon" draggable = "true" data-type = "loadBalancer" >
load balancer
< / div >
< div class = "component-icon" draggable = "true" data-type = "webserver" >
webserver
< / div >
< div class = "component-icon" draggable = "true" data-type = "database" >
database
< / div >
< div class = "component-icon" draggable = "true" data-type = "cache" >
cache
< / div >
< div class = "component-icon" draggable = "true" data-type = "messageQueue" >
message queue
< / div >
< div class = "component-icon" draggable = "true" data-type = "cdn" >
CDN
< / div >
< div class = "component-icon" draggable = "true" data-type = "microservice" >
microservice node
< / div >
< div class = "component-icon" draggable = "true" data-type = "data pipeline" >
data pipeline
< / div >
< div class = "component-icon" draggable = "true" data-type = "monitoring/alerting" >
monitoring/alerting
< / div >
< div class = "component-icon" draggable = "true" data-type = "third party service" >
third-party service
< / div >
< / div >
< div id = "canvas-container" >
< div id = "connection-modal" style = "display: none;" class = "modal" >
< div class = "modal-content" >
< h3 > Create Connection< / h3 >
< label >
Label:
< input type = "text" id = "connection-label" value = "Read traffic" >
< / label >
< label >
Protocol:
< select id = "connection-protocol" >
< option > HTTP< / option >
< option > HTTPS< / option >
< option > gRPC< / option >
< option > WebSocket< / option >
< option > GraphQL< / option >
< option > Kafka< / option >
< option > AMQP< / option >
< option > MQTT< / option >
< option > SQL< / option >
< option > NoSQL< / option >
< option > Redis< / option >
< option > TLS< / option >
< / select >
< / label >
< label style = "margin-top: 10px;" >
< input type = "checkbox" id = "connection-tls" >
Enable TLS (encryption)
< / label >
< label for = "connection-capacity" > Capacity Limit (RPS):< / label >
< input type = "number" id = "connection-capacity" value = "1000" min = "1" / >
< div class = "modal-actions" >
< button id = "connection-save" > Save< / button >
< button id = "connection-cancel" > Cancel< / button >
< / div >
< / div >
< / div >
< div id = "canvas-toolbar" >
< button id = "arrow-tool-btn" class = "toolbar-btn" > Arrow Tool< / button >
< / div >
< div id = "info-panel" >
< div id = "constraints-panel" >
< div class = "panel-title" > level constraints< / div >
< div class = "panel-metric" > < span class = "label" > 🎯 target rps:< / span > < span id = "constraint-rps" > {{.Level.TargetRPS}}< / span > < / div >
< div class = "panel-metric" > < span class = "label" > ⏱️ max p95 latency:< / span > < span id = "constraint-latency" > {{.Level.MaxP95LatencyMs}}ms< / span > < / div >
< div class = "panel-metric" > < span class = "label" > 💸 max cost:< / span > < span id = "constraint-cost" > ${{.Level.MaxMonthlyUSD}}< / span > < / div >
< div class = "panel-metric" > < span class = "label" > 🔒 availability:< / span > < span id = "constraint-availability" > {{printf "%.2f" .Level.RequiredAvailabilityPct}}%< / span > < / div >
< / div >
< / div >
< svg id = "canvas" >
< defs >
< marker id = "arrowhead-start" markerWidth = "10" markerHeight = "7" refX = "0" refY = "3.5"
orient="auto" markerUnits="strokeWidth">
< path d = "M10 0 L0 3.5 L10 7" fill = "#ccc" / >
< / marker >
< marker id = "arrowhead-end" markerWidth = "10" markerHeight = "7" refX = "10" refY = "3.5"
orient="auto" markerUnits="strokeWidth">
< path d = "M0 0 L10 3.5 L0 7" fill = "#ccc" / >
< / marker >
< / defs >
< / svg >
< div id = "node-props-panel" >
< h3 > node properties< / h3 >
< div id = "label-group" data-group = "label-group" >
< label > label:< / label >
< input type = "text" name = "label" / >
< / div >
< div id = "db-group" class = "prop-group" data-group = "db-group" >
< label > replication factor:< input type = "number" name = "replication" min = "1" step = "1" / > < / label >
< / div >
< div id = "cache-group" class = "prop-group" data-group = "cache-group" >
< label > cache ttl (secs):< input type = "number" name = "cacheTTL" min = "0" step = "60" / > < / label >
< label > Max Entries: < input name = "maxEntries" type = "number" / > < / label >
< label > Eviction Policy:
< select name = "evictionPolicy" >
< option value = "LRU" > LRU< / option >
< option value = "LFU" > LFU< / option >
< option value = "Random" > Random< / option >
< / select >
< / label >
< / div >
< div id = "compute-group" data-group = "compute-group" class = "prop-group" >
< label > CPU Cores:< / label >
< input type = "number" name = "cpu" min = "1" / >
< label > RAM (GB):< / label >
< input type = "number" name = "ramGb" min = "1" / >
< label > RPS Capacity:< / label >
< input type = "number" name = "rpsCapacity" min = "1" / >
< label > Monthly Cost (USD):< / label >
< input type = "number" name = "monthlyCostUsd" min = "0" / >
< / div >
< div id = "lb-group" data-group = "lb-group" class = "prop-group" >
< label > Algorithm< / label >
< select name = "algorithm" >
< option value = "round-robin" > Round Robin< / option >
< option value = "least-connections" > Least Connections< / option >
< / select >
< / div >
< div id = "mq-group" data-group = "mq-group" class = "prop-group" >
< label > Queue Capacity (,ax Messages that can be held in que)< / label >
< input type = "number" name = "queueCapacity" min = "1" / >
< label > Retention Time (seconds)< / label >
< input type = "number" name = "retentionSeconds" min = "1" / >
< / div >
< div id = "cdn-group" data-group = "cdn-group" class = "prop-group" >
< label > TTL (seconds)< / label >
< input type = "number" name = "ttl" min = "1" / >
< label > Geo Replication< / label >
< select name = "geoReplication" >
< option value = "global" > Global< / option >
< option value = "regional" > Regional< / option >
< option value = "custom" > Custom< / option >
< / select >
< label > Caching Strategy< / label >
< select name = "cachingStrategy" >
< option value = "cache-first" > Cache First< / option >
< option value = "network-first" > Network First< / option >
< option value = "stale-while-revalidate" > Stale While Revalidate< / option >
< / select >
< label > Compression< / label >
< select name = "compression" >
< option value = "brotli" > Brotli< / option >
< option value = "gzip" > Gzip< / option >
< option value = "none" > None< / option >
< / select >
< label > HTTP/2 Support< / label >
< select name = "http2" >
< option value = "enabled" > Enabled< / option >
< option value = "disabled" > Disabled< / option >
< / select >
< / div >
< div id = "microservice-group" data-group = "microservice-group" class = "prop-group" >
< label >
Instance Count:
< input type = "number" name = "instanceCount" value = "3" min = "1" / >
< / label >
< label >
CPU (vCPUs):
< input type = "number" name = "cpu" value = "2" min = "1" / >
< / label >
< label >
RAM (GB):
< input type = "number" name = "ramGb" value = "4" min = "1" / >
< / label >
< label >
RPS Capacity:
< input type = "number" name = "rpsCapacity" value = "150" min = "1" / >
< / label >
< label >
Monthly Cost (USD):
< input type = "number" name = "monthlyUsd" value = "18" min = "0" step = "1" / >
< / label >
< label >
Scaling Strategy:
< select name = "scalingStrategy" >
< option value = "auto" selected > Auto< / option >
< option value = "manual" > Manual< / option >
< / select >
< / label >
< label >
API Version:
< input type = "text" name = "apiVersion" value = "v1" / >
< / label >
< / div >
< div id = "datapipeline-group" data-group = "pipeline-group" class = "prop-group" >
< label > Batch Size< / label >
< input type = "number" name = "batchSize" min = "1" / >
< label > Schedule< / label >
< select name = "schedule" >
< option value = "realtime" > Real-time< / option >
< option value = "hourly" > Hourly< / option >
< option value = "daily" > Daily< / option >
< option value = "weekly" > Weekly< / option >
< / select >
< label > Transformations< / label >
< select name = "transformations" >
< option value = "normalize" > Normalize< / option >
< option value = "dedupe" > Dedupe< / option >
< option value = "filter" > Filter< / option >
< option value = "enrich" > Enrich< / option >
< option value = "aggregate" > Aggregate< / option >
< / select >
< label > Destination< / label >
< input type = "text" name = "destination" placeholder = "e.g. data warehouse" / >
< / div >
< div id = "monitor-group" data-group = "monitor-group" class = "prop-group" >
< label > Monitoring Tool< / label >
< select name = "tool" >
< option value = "Prometheus" > Prometheus< / option >
< option value = "Datadog" > Datadog< / option >
< option value = "New Relic" > New Relic< / option >
< option value = "Grafana Cloud" > Grafana Cloud< / option >
< / select >
< label > Alert Threshold (%)< / label >
< input type = "number" name = "alertThreshold" min = "0" max = "100" / >
< / div >
< div id = "third-party-group" data-group = "third-party-group" class = "prop-group" >
< label > Provider< / label >
< input type = "text" name = "provider" / >
< label > Latency (ms)< / label >
< input type = "number" name = "latency" min = "0" / >
< / div >
<!-- PUT NEW COMPONENTS BEFORE THIS BUTTON -->
< button id = "node-props-save" disabled > save< / button >
< / div >
< div id = "bottom-panel" >
< button id = "run-button" disabled > Test Design< / button >
< / div >
< / div >
< / div >
<!-- Metrics -->
< div id = "content3" class = "tab-content" > This is Tab 3 content.< / div >
< / div >
< / div >
< / div >
< / div >
< script type = "module" src = "/static/index.js" > < / script >
< / body >
< / html >