──────
Build and Push Docker Images / detect-changes (push) Successful in 11s
Build and Push Docker Images / build-auth-api (push) Successful in 1m0s
Build and Push Docker Images / build-employee-api (push) Successful in 1m2s
Build and Push Docker Images / build-transit-api (push) Successful in 1m1s
Build and Push Docker Images / build-error-log-api (push) Successful in 1m5s
Build and Push Docker Images / build-admin-ui (push) Successful in 1m13s
Build and Push Docker Images / build-monitoring-ui (push) Successful in 1m15s
Build and Push Docker Images / deploy-test-node (push) Successful in 3s
Build and Push Docker Images / detect-changes (push) Successful in 11s
Build and Push Docker Images / build-auth-api (push) Successful in 1m0s
Build and Push Docker Images / build-employee-api (push) Successful in 1m2s
Build and Push Docker Images / build-transit-api (push) Successful in 1m1s
Build and Push Docker Images / build-error-log-api (push) Successful in 1m5s
Build and Push Docker Images / build-admin-ui (push) Successful in 1m13s
Build and Push Docker Images / build-monitoring-ui (push) Successful in 1m15s
Build and Push Docker Images / deploy-test-node (push) Successful in 3s
### Summary of Changes
1. Documentation Consolidation:
• Relocated the docs/ folder and all repository .md files (README.md, DEPLOYMENT.md, DOCKER_README.md,
DOMAINS_README.md, GETTING_STARTED.md, CI_CD_PORTAINER_GUIDE.md, ADMIN_DEPLOYMENT_SUMMARY.md,
SECURITY_PRIVATE_FILES.md, handoff.md, azure-project-plan.md, plus service-specific READMEs) into .
• Updated document links in README.md.
2. AI Agent Project Map:
• Created PROJECT_MAP.md in the project root containing complete architecture diagrams, service specs, ports, DB
schemas, environment variables, and developer workflows.
• Added PROJECT_MAP.md to .gitignore.
3. Monitoring UI & Infrastructure Integration:
• Added monitoring_ui service to docker-compose.yml (port 5175).
• Configured Gitea workflow docker-build.yml for monitoring_ui builds.
• Added CORS middleware headers in index.js.
• Added nginx.conf copy step in Dockerfile.
──────
### Recommended Commit Message
docs: consolidate project documentation into monitoring_ui and add agent project map
- Move all markdown documentation files and docs/ folder into monitoring_ui/docs/
- Update documentation hub index (monitoring_ui/docs/README.md) with relative paths
- Generate comprehensive AI agent reference map (PROJECT_MAP.md) in repository root
- Add PROJECT_MAP.md and monitoring_ui build output/env overrides to .gitignore
- Integrate monitoring_ui service into docker-compose.yml and Gitea CI workflow
- Configure CORS handling in employee_api for monitoring dashboard access
──────
### Alternative Short Commit Message
refactor(docs): move docs to monitoring_ui and create AI agent PROJECT_MAP.md
This commit is contained in:
@@ -0,0 +1,670 @@
|
||||
@import url("https://fonts.googleapis.com/css2?family=DM+Mono:wght@400;500&family=Manrope:wght@400;500;600;700;800&display=swap");
|
||||
:root {
|
||||
font-family: Manrope, sans-serif;
|
||||
color: #e7eeee;
|
||||
background: #101517;
|
||||
font-synthesis: none;
|
||||
--bg: #101517;
|
||||
--panel: #172022;
|
||||
--line: #2b393a;
|
||||
--muted: #91a2a1;
|
||||
--mint: #8ae8c2;
|
||||
--amber: #f2bd70;
|
||||
--blue: #7eb7f5;
|
||||
--coral: #f58d7d;
|
||||
--violet: #c1a5fa;
|
||||
}
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
min-width: 320px;
|
||||
background:
|
||||
radial-gradient(circle at 82% -10%, #24403b 0, transparent 32%),
|
||||
linear-gradient(135deg, #101517 0%, #111b1d 54%, #182020 100%);
|
||||
min-height: 100vh;
|
||||
}
|
||||
.app-shell {
|
||||
max-width: 1440px;
|
||||
margin: auto;
|
||||
padding: 0 42px 70px;
|
||||
}
|
||||
.topbar {
|
||||
height: 82px;
|
||||
border-bottom: 1px solid var(--line);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.brand {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
.brand-mark {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
border: 1px solid var(--mint);
|
||||
color: var(--mint);
|
||||
font-weight: 800;
|
||||
font-size: 20px;
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
.brand-mark::first-letter {
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
.brand strong,
|
||||
.brand span {
|
||||
display: block;
|
||||
}
|
||||
.brand strong {
|
||||
font:
|
||||
600 12px "DM Mono",
|
||||
monospace;
|
||||
letter-spacing: 0.12em;
|
||||
}
|
||||
.brand div span {
|
||||
color: var(--muted);
|
||||
font-size: 11px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
.top-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
color: var(--muted);
|
||||
font:
|
||||
500 12px "DM Mono",
|
||||
monospace;
|
||||
}
|
||||
.live-dot {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
border-radius: 50%;
|
||||
background: var(--mint);
|
||||
box-shadow: 0 0 14px var(--mint);
|
||||
}
|
||||
select,
|
||||
input,
|
||||
textarea {
|
||||
font: inherit;
|
||||
color: inherit;
|
||||
background: #111a1c;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 4px;
|
||||
padding: 10px 12px;
|
||||
outline: none;
|
||||
}
|
||||
select:focus,
|
||||
input:focus,
|
||||
textarea:focus {
|
||||
border-color: var(--mint);
|
||||
}
|
||||
.top-actions select {
|
||||
padding: 7px 9px;
|
||||
font-size: 11px;
|
||||
}
|
||||
.ghost-button {
|
||||
border: 1px solid var(--line);
|
||||
background: transparent;
|
||||
color: #d3dddd;
|
||||
padding: 9px 12px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.ghost-button:hover {
|
||||
border-color: var(--mint);
|
||||
color: var(--mint);
|
||||
}
|
||||
.hero-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: end;
|
||||
padding: 68px 0 38px;
|
||||
}
|
||||
.eyebrow {
|
||||
font:
|
||||
500 10px "DM Mono",
|
||||
monospace;
|
||||
color: var(--mint);
|
||||
letter-spacing: 0.16em;
|
||||
margin: 0 0 13px;
|
||||
}
|
||||
.hero-row h1 {
|
||||
font-size: clamp(38px, 6vw, 76px);
|
||||
line-height: 0.98;
|
||||
letter-spacing: -0.04em;
|
||||
margin: 0;
|
||||
max-width: 680px;
|
||||
}
|
||||
.hero-copy {
|
||||
color: var(--muted);
|
||||
font-size: 16px;
|
||||
margin: 20px 0 0;
|
||||
}
|
||||
.pulse-stat {
|
||||
border-left: 1px solid var(--line);
|
||||
padding-left: 25px;
|
||||
min-width: 180px;
|
||||
}
|
||||
.pulse-stat span,
|
||||
.pulse-stat em {
|
||||
display: block;
|
||||
color: var(--muted);
|
||||
font:
|
||||
11px "DM Mono",
|
||||
monospace;
|
||||
}
|
||||
.pulse-stat strong {
|
||||
display: block;
|
||||
font-size: 52px;
|
||||
line-height: 1.1;
|
||||
margin: 7px 0;
|
||||
color: var(--mint);
|
||||
}
|
||||
.pulse-stat small {
|
||||
font-size: 20px;
|
||||
color: var(--muted);
|
||||
font-weight: 500;
|
||||
}
|
||||
.pulse-stat em {
|
||||
font-style: normal;
|
||||
}
|
||||
.tabs {
|
||||
display: flex;
|
||||
gap: 24px;
|
||||
border-bottom: 1px solid var(--line);
|
||||
margin-bottom: 28px;
|
||||
overflow: auto;
|
||||
}
|
||||
.tabs button {
|
||||
white-space: nowrap;
|
||||
background: none;
|
||||
border: 0;
|
||||
border-bottom: 2px solid transparent;
|
||||
color: var(--muted);
|
||||
padding: 13px 0;
|
||||
cursor: pointer;
|
||||
font-weight: 700;
|
||||
font-size: 12px;
|
||||
}
|
||||
.tabs button.active,
|
||||
.tabs button:hover {
|
||||
color: #fff;
|
||||
border-color: var(--mint);
|
||||
}
|
||||
.tabs b {
|
||||
color: var(--coral);
|
||||
margin-left: 5px;
|
||||
}
|
||||
.service-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(5, 1fr);
|
||||
gap: 12px;
|
||||
}
|
||||
.service-card,
|
||||
.panel {
|
||||
background: rgba(23, 32, 34, 0.88);
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 6px;
|
||||
}
|
||||
.service-card {
|
||||
padding: 19px;
|
||||
min-height: 250px;
|
||||
border-top: 2px solid var(--card-color);
|
||||
}
|
||||
.service-card.amber {
|
||||
--card-color: var(--amber);
|
||||
}
|
||||
.service-card.teal {
|
||||
--card-color: var(--mint);
|
||||
}
|
||||
.service-card.blue {
|
||||
--card-color: var(--blue);
|
||||
}
|
||||
.service-card.coral {
|
||||
--card-color: var(--coral);
|
||||
}
|
||||
.service-card.violet {
|
||||
--card-color: var(--violet);
|
||||
}
|
||||
.card-top {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
}
|
||||
.service-icon {
|
||||
display: inline-grid;
|
||||
place-items: center;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
border-radius: 3px;
|
||||
font:
|
||||
500 10px "DM Mono",
|
||||
monospace;
|
||||
background: #293332;
|
||||
color: var(--card-color);
|
||||
}
|
||||
.card-top h3 {
|
||||
font-size: 14px;
|
||||
margin: 13px 0 3px;
|
||||
}
|
||||
.card-top p {
|
||||
color: var(--muted);
|
||||
font-size: 11px;
|
||||
margin: 0;
|
||||
}
|
||||
.status-pill {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
height: 22px;
|
||||
border-radius: 20px;
|
||||
padding: 0 8px;
|
||||
font:
|
||||
500 10px "DM Mono",
|
||||
monospace;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.status-pill i {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
background: currentColor;
|
||||
}
|
||||
.status-pill.healthy {
|
||||
color: var(--mint);
|
||||
background: #17372f;
|
||||
}
|
||||
.status-pill.degraded {
|
||||
color: var(--coral);
|
||||
background: #3b2523;
|
||||
}
|
||||
.status-pill.offline {
|
||||
color: #f17c76;
|
||||
background: #3b2523;
|
||||
}
|
||||
.status-pill.checking {
|
||||
color: var(--amber);
|
||||
background: #3c3020;
|
||||
}
|
||||
.metric-line {
|
||||
border-top: 1px solid var(--line);
|
||||
margin-top: 25px;
|
||||
padding-top: 13px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
color: var(--muted);
|
||||
font:
|
||||
10px "DM Mono",
|
||||
monospace;
|
||||
}
|
||||
.metric-line strong {
|
||||
color: #e8eeee;
|
||||
font-weight: 500;
|
||||
}
|
||||
.sparkline {
|
||||
height: 45px;
|
||||
display: flex;
|
||||
align-items: end;
|
||||
gap: 3px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
.sparkline span {
|
||||
display: block;
|
||||
flex: 1;
|
||||
min-width: 3px;
|
||||
background: var(--card-color);
|
||||
opacity: 0.75;
|
||||
border-radius: 1px;
|
||||
}
|
||||
.sparkline em {
|
||||
font:
|
||||
10px "DM Mono",
|
||||
monospace;
|
||||
color: #607170;
|
||||
}
|
||||
.service-card details {
|
||||
margin-top: 12px;
|
||||
color: var(--muted);
|
||||
font-size: 10px;
|
||||
}
|
||||
.service-card summary {
|
||||
cursor: pointer;
|
||||
}
|
||||
.service-card pre {
|
||||
max-height: 100px;
|
||||
overflow: auto;
|
||||
color: #c6d5d3;
|
||||
font:
|
||||
10px "DM Mono",
|
||||
monospace;
|
||||
}
|
||||
.lower-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1.5fr 1fr;
|
||||
gap: 12px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
.panel {
|
||||
padding: 25px;
|
||||
}
|
||||
.panel-heading {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: start;
|
||||
gap: 20px;
|
||||
margin-bottom: 21px;
|
||||
}
|
||||
.panel h2 {
|
||||
font-size: 19px;
|
||||
margin: 0;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
.panel-count {
|
||||
font:
|
||||
10px "DM Mono",
|
||||
monospace;
|
||||
color: var(--muted);
|
||||
border: 1px solid var(--line);
|
||||
padding: 6px 8px;
|
||||
border-radius: 3px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.data-list {
|
||||
border-top: 1px solid var(--line);
|
||||
}
|
||||
.data-row {
|
||||
display: grid;
|
||||
grid-template-columns: 10px 150px 1fr;
|
||||
gap: 11px;
|
||||
align-items: center;
|
||||
padding: 14px 0;
|
||||
border-bottom: 1px solid var(--line);
|
||||
font-size: 12px;
|
||||
}
|
||||
.data-row > span:last-child {
|
||||
color: var(--muted);
|
||||
font-size: 11px;
|
||||
}
|
||||
.service-dot {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
}
|
||||
.service-dot.amber {
|
||||
background: var(--amber);
|
||||
}
|
||||
.service-dot.teal {
|
||||
background: var(--mint);
|
||||
}
|
||||
.service-dot.blue {
|
||||
background: var(--blue);
|
||||
}
|
||||
.service-dot.coral {
|
||||
background: var(--coral);
|
||||
}
|
||||
.service-dot.violet {
|
||||
background: var(--violet);
|
||||
}
|
||||
.suggestion-panel ul {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.suggestion-panel li {
|
||||
padding: 13px 0;
|
||||
border-top: 1px solid var(--line);
|
||||
}
|
||||
.suggestion-panel li strong,
|
||||
.suggestion-panel li span {
|
||||
display: block;
|
||||
}
|
||||
.suggestion-panel li strong {
|
||||
font-size: 12px;
|
||||
}
|
||||
.suggestion-panel li span {
|
||||
color: var(--muted);
|
||||
font-size: 11px;
|
||||
line-height: 1.5;
|
||||
margin-top: 5px;
|
||||
}
|
||||
.catalog-panel,
|
||||
.incidents-panel,
|
||||
.settings-panel {
|
||||
min-height: 500px;
|
||||
}
|
||||
.catalog-block {
|
||||
display: grid;
|
||||
grid-template-columns: 270px 1fr;
|
||||
gap: 20px;
|
||||
padding: 20px 0;
|
||||
border-top: 1px solid var(--line);
|
||||
}
|
||||
.catalog-block > div:first-child {
|
||||
display: flex;
|
||||
gap: 9px;
|
||||
align-items: start;
|
||||
}
|
||||
.catalog-block p {
|
||||
color: var(--muted);
|
||||
font-size: 11px;
|
||||
margin: 7px 0 0 16px;
|
||||
}
|
||||
.route-chips {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.route-chips code {
|
||||
font:
|
||||
11px "DM Mono",
|
||||
monospace;
|
||||
color: #c8d8d5;
|
||||
border: 1px solid var(--line);
|
||||
background: #111a1c;
|
||||
border-radius: 3px;
|
||||
padding: 8px;
|
||||
}
|
||||
.table-head,
|
||||
.table-row {
|
||||
display: grid;
|
||||
grid-template-columns: 170px 220px 1fr;
|
||||
gap: 20px;
|
||||
padding: 13px 0;
|
||||
}
|
||||
.table-head {
|
||||
color: var(--muted);
|
||||
font:
|
||||
10px "DM Mono",
|
||||
monospace;
|
||||
border-bottom: 1px solid var(--line);
|
||||
}
|
||||
.table-row {
|
||||
font-size: 12px;
|
||||
border-bottom: 1px solid #243131;
|
||||
}
|
||||
.table-row time,
|
||||
.table-row > span {
|
||||
color: var(--muted);
|
||||
font-size: 11px;
|
||||
}
|
||||
.table-row strong small {
|
||||
display: block;
|
||||
color: var(--muted);
|
||||
font:
|
||||
10px "DM Mono",
|
||||
monospace;
|
||||
font-weight: 400;
|
||||
margin-top: 5px;
|
||||
}
|
||||
.empty,
|
||||
.result-placeholder {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
text-align: center;
|
||||
min-height: 250px;
|
||||
color: var(--muted);
|
||||
font-size: 12px;
|
||||
gap: 8px;
|
||||
}
|
||||
.empty strong {
|
||||
color: #e8eeee;
|
||||
}
|
||||
.lab-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1.25fr;
|
||||
gap: 12px;
|
||||
}
|
||||
.request-panel label,
|
||||
.settings-panel label {
|
||||
display: grid;
|
||||
gap: 7px;
|
||||
margin: 17px 0;
|
||||
color: var(--muted);
|
||||
font:
|
||||
10px "DM Mono",
|
||||
monospace;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.request-panel select,
|
||||
.request-panel textarea,
|
||||
.settings-panel input {
|
||||
width: 100%;
|
||||
}
|
||||
.request-panel textarea {
|
||||
height: 130px;
|
||||
resize: vertical;
|
||||
}
|
||||
.run-button {
|
||||
width: 100%;
|
||||
padding: 12px;
|
||||
background: var(--mint);
|
||||
color: #10201c;
|
||||
border: 0;
|
||||
border-radius: 4px;
|
||||
font-weight: 800;
|
||||
cursor: pointer;
|
||||
}
|
||||
.run-button:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: wait;
|
||||
}
|
||||
.helper,
|
||||
.settings-intro {
|
||||
font-size: 11px;
|
||||
line-height: 1.5;
|
||||
color: var(--muted);
|
||||
}
|
||||
.response-code {
|
||||
background: #0d1415;
|
||||
border: 1px solid var(--line);
|
||||
padding: 18px;
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
min-height: 320px;
|
||||
max-height: 520px;
|
||||
overflow: auto;
|
||||
color: #b8e9d6;
|
||||
font:
|
||||
11px "DM Mono",
|
||||
monospace;
|
||||
}
|
||||
.connection-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 0 18px;
|
||||
}
|
||||
.save-button {
|
||||
max-width: 180px;
|
||||
}
|
||||
.incidents-panel .panel-heading {
|
||||
align-items: center;
|
||||
}
|
||||
@media (max-width: 1100px) {
|
||||
.service-grid {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
.service-card:last-child {
|
||||
grid-column: auto;
|
||||
}
|
||||
.hero-row {
|
||||
align-items: start;
|
||||
gap: 30px;
|
||||
}
|
||||
.lower-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
.pulse-stat {
|
||||
min-width: 150px;
|
||||
}
|
||||
}
|
||||
@media (max-width: 700px) {
|
||||
.app-shell {
|
||||
padding: 0 18px 40px;
|
||||
}
|
||||
.topbar {
|
||||
height: auto;
|
||||
padding: 18px 0;
|
||||
align-items: start;
|
||||
gap: 14px;
|
||||
flex-direction: column;
|
||||
}
|
||||
.top-actions {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.hero-row {
|
||||
padding: 43px 0 28px;
|
||||
display: block;
|
||||
}
|
||||
.pulse-stat {
|
||||
border-left: 0;
|
||||
border-top: 1px solid var(--line);
|
||||
padding: 15px 0 0;
|
||||
margin-top: 28px;
|
||||
}
|
||||
.pulse-stat strong {
|
||||
font-size: 42px;
|
||||
}
|
||||
.service-grid {
|
||||
grid-template-columns: 1fr 1fr;
|
||||
}
|
||||
.service-card {
|
||||
min-height: 230px;
|
||||
padding: 14px;
|
||||
}
|
||||
.card-top {
|
||||
display: block;
|
||||
}
|
||||
.status-pill {
|
||||
margin-top: 12px;
|
||||
}
|
||||
.catalog-block,
|
||||
.lab-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
.table-head,
|
||||
.table-row {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 5px;
|
||||
}
|
||||
.table-head {
|
||||
display: none;
|
||||
}
|
||||
.table-row {
|
||||
padding: 15px 0;
|
||||
}
|
||||
.connection-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
.tabs {
|
||||
gap: 18px;
|
||||
}
|
||||
.panel {
|
||||
padding: 18px;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user