-
Notifications
You must be signed in to change notification settings - Fork 0
Add interactive architecture diagrams #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,124 @@ | ||
|
|
||
| <!doctype html> | ||
| <html lang="en"> | ||
| <head> | ||
| <meta charset="utf-8"> | ||
| <title>HarryPanel – Architecture</title> | ||
| <style> | ||
| :root{ --paper:#050510; --paper-2:#0d0d1a; --ink:#eaeaea; --muted:#8a8a9e; | ||
| --rule:rgba(234,234,234,0.12); --accent:#00d4aa; --link:#6a95d8; } | ||
| *{ box-sizing:border-box; margin:0; padding:0; } | ||
| body{ background:var(--paper); color:var(--ink); | ||
| font-family:'Geist',system-ui,-apple-system,sans-serif; | ||
| padding:2rem; line-height:1.5; } | ||
| h1{ font-family:'Instrument Serif',serif; font-size:2rem; | ||
| letter-spacing:-0.02em; margin-bottom:.5rem; } | ||
| .meta{ font-family:'Geist Mono',monospace; font-size:11px; | ||
| color:var(--muted); margin-bottom:1rem; } | ||
| .grid{ display:grid; grid-template-columns:repeat(auto-fit,minmax(360px,1fr)); | ||
| gap:1.2rem; margin-top:1.5rem; } | ||
| .card{ background:var(--paper-2); border:1px solid var(--rule); | ||
| border-radius:4px; padding:1rem; } | ||
| .card h2{ font-size:1rem; margin-bottom:.75rem; color:var(--accent); | ||
| font-family:'Geist Mono',monospace; text-transform:uppercase; | ||
| letter-spacing:.1em; } | ||
| .card svg{ width:100%; height:auto; } | ||
| dialog{ background:var(--paper-2); color:var(--ink); | ||
| border:1px solid var(--accent); border-radius:6px; | ||
| padding:1.5rem; max-width:480px; } | ||
| dialog::backdrop{ background:rgba(0,0,0,0.7); } | ||
| dialog h3{ color:var(--accent); margin-bottom:.5rem; | ||
| font-family:'Geist Mono',monospace; } | ||
| dialog p{ font-size:14px; color:var(--muted); } | ||
| dialog button{ background:var(--accent); color:var(--paper); | ||
| border:0; padding:.5rem 1rem; border-radius:3px; | ||
| font-family:'Geist Mono',monospace; margin-top:1rem; cursor:pointer; } | ||
| a.back{ color:var(--muted); text-decoration:none; | ||
| font-family:'Geist Mono',monospace; font-size:11px; } | ||
| .node{ cursor:pointer; transition:filter .2s ease; } | ||
| .node:hover{ filter:drop-shadow(0 0 8px var(--accent)); } | ||
| .node text{ font-family:'Geist',sans-serif; fill:var(--ink); } | ||
| .node-label{ font-family:'Geist Mono',monospace; font-size:9px; | ||
| fill:var(--muted); } | ||
| </style> | ||
| </head> | ||
| <body> | ||
| <a class="back" href="../../README.md">← Back to README</a> | ||
| <h1>HarryPanel – Architecture</h1> | ||
| <div class="meta">★ 1 · Procfile, Python, HTML, Dockerfile · created 2026-07-02 · updated 2026-07-19</div> | ||
| <p>Web hosting control panel: server management, database admin, file manager, and deployment tools</p> | ||
| <div class="grid"> | ||
| <div class="card"><h2>Architecture</h2><svg viewBox="0 0 940 460" xmlns="http://www.w3.org/2000/svg"> | ||
| <title>Architecture</title> | ||
| <defs><marker id="arr" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse"><path d="M0 0 L10 5 L0 10 Z" fill="rgba(234,234,234,0.45)"/></marker></defs> | ||
| <rect width="940" height="460" fill="transparent"/> | ||
| <line x1="470" y1="90" x2="470" y2="130" stroke="rgba(234,234,234,0.25)" stroke-width="1" marker-end="url(#arr)"/> | ||
| <line x1="470" y1="90" x2="470" y2="240" stroke="rgba(234,234,234,0.25)" stroke-width="1" marker-end="url(#arr)"/> | ||
| <line x1="470" y1="200" x2="470" y2="240" stroke="rgba(234,234,234,0.25)" stroke-width="1" marker-end="url(#arr)"/> | ||
| <g class="node" data-node data-title="Input" data-desc="User / API Entry"><rect x="310" y="20" width="320" height="70" rx="4" ry="4" fill="rgba(0,212,170,0.06)" stroke="#00d4aa" stroke-width="1.2"/><text x="470" y="48" text-anchor="middle" font-size="13" font-weight="600" fill="#eaeaea">Input</text><text x="470" y="68" text-anchor="middle" font-size="10" fill="#8a8a9e" class="node-label">User / API Entry</text></g> | ||
| <g class="node" data-node data-title="Core Engine" data-desc="HarryPanel logic"><rect x="310" y="130" width="320" height="70" rx="4" ry="4" fill="rgba(0,212,170,0.06)" stroke="#6a95d8" stroke-width="1.2"/><text x="470" y="158" text-anchor="middle" font-size="13" font-weight="600" fill="#eaeaea">Core Engine</text><text x="470" y="178" text-anchor="middle" font-size="10" fill="#8a8a9e" class="node-label">HarryPanel logic</text></g> | ||
| <g class="node" data-node data-title="Output" data-desc="Reports / Artifacts"><rect x="310" y="240" width="320" height="70" rx="4" ry="4" fill="rgba(0,212,170,0.06)" stroke="#d3ad7a" stroke-width="1.2"/><text x="470" y="268" text-anchor="middle" font-size="13" font-weight="600" fill="#eaeaea">Output</text><text x="470" y="288" text-anchor="middle" font-size="10" fill="#8a8a9e" class="node-label">Reports / Artifacts</text></g> | ||
| </svg></div> | ||
| <div class="card"><h2>Components</h2><svg viewBox="0 0 940 460" xmlns="http://www.w3.org/2000/svg"> | ||
| <title>Components</title> | ||
| <defs><marker id="arr" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse"><path d="M0 0 L10 5 L0 10 Z" fill="rgba(234,234,234,0.45)"/></marker></defs> | ||
| <rect width="940" height="460" fill="transparent"/> | ||
| <line x1="300" y1="90" x2="300" y2="130" stroke="rgba(234,234,234,0.25)" stroke-width="1" marker-end="url(#arr)"/> | ||
| <line x1="300" y1="90" x2="300" y2="240" stroke="rgba(234,234,234,0.25)" stroke-width="1" marker-end="url(#arr)"/> | ||
| <line x1="640" y1="90" x2="640" y2="130" stroke="rgba(234,234,234,0.25)" stroke-width="1" marker-end="url(#arr)"/> | ||
| <line x1="640" y1="90" x2="640" y2="240" stroke="rgba(234,234,234,0.25)" stroke-width="1" marker-end="url(#arr)"/> | ||
| <line x1="300" y1="200" x2="300" y2="240" stroke="rgba(234,234,234,0.25)" stroke-width="1" marker-end="url(#arr)"/> | ||
| <line x1="640" y1="200" x2="640" y2="240" stroke="rgba(234,234,234,0.25)" stroke-width="1" marker-end="url(#arr)"/> | ||
| <g class="node" data-node data-title="CLI" data-desc="Entry"><rect x="140" y="20" width="320" height="70" rx="4" ry="4" fill="rgba(0,212,170,0.06)" stroke="#00d4aa" stroke-width="1.2"/><text x="300" y="48" text-anchor="middle" font-size="13" font-weight="600" fill="#eaeaea">CLI</text><text x="300" y="68" text-anchor="middle" font-size="10" fill="#8a8a9e" class="node-label">Entry</text></g> | ||
| <g class="node" data-node data-title="Config" data-desc="YAML/JSON"><rect x="480" y="20" width="320" height="70" rx="4" ry="4" fill="rgba(0,212,170,0.06)" stroke="#00d4aa" stroke-width="1.2"/><text x="640" y="48" text-anchor="middle" font-size="13" font-weight="600" fill="#eaeaea">Config</text><text x="640" y="68" text-anchor="middle" font-size="10" fill="#8a8a9e" class="node-label">YAML/JSON</text></g> | ||
| <g class="node" data-node data-title="Parser" data-desc="Load input"><rect x="140" y="130" width="320" height="70" rx="4" ry="4" fill="rgba(0,212,170,0.06)" stroke="#6a95d8" stroke-width="1.2"/><text x="300" y="158" text-anchor="middle" font-size="13" font-weight="600" fill="#eaeaea">Parser</text><text x="300" y="178" text-anchor="middle" font-size="10" fill="#8a8a9e" class="node-label">Load input</text></g> | ||
| <g class="node" data-node data-title="Logic" data-desc="Web hosting control panel"><rect x="480" y="130" width="320" height="70" rx="4" ry="4" fill="rgba(0,212,170,0.06)" stroke="#6a95d8" stroke-width="1.2"/><text x="640" y="158" text-anchor="middle" font-size="13" font-weight="600" fill="#eaeaea">Logic</text><text x="640" y="178" text-anchor="middle" font-size="10" fill="#8a8a9e" class="node-label">Web hosting control panel</text></g> | ||
| <g class="node" data-node data-title="Storage" data-desc="Cache/DB"><rect x="140" y="240" width="320" height="70" rx="4" ry="4" fill="rgba(0,212,170,0.06)" stroke="#d3ad7a" stroke-width="1.2"/><text x="300" y="268" text-anchor="middle" font-size="13" font-weight="600" fill="#eaeaea">Storage</text><text x="300" y="288" text-anchor="middle" font-size="10" fill="#8a8a9e" class="node-label">Cache/DB</text></g> | ||
| <g class="node" data-node data-title="Logger" data-desc="Audit trail"><rect x="480" y="240" width="320" height="70" rx="4" ry="4" fill="rgba(0,212,170,0.06)" stroke="#d3ad7a" stroke-width="1.2"/><text x="640" y="268" text-anchor="middle" font-size="13" font-weight="600" fill="#eaeaea">Logger</text><text x="640" y="288" text-anchor="middle" font-size="10" fill="#8a8a9e" class="node-label">Audit trail</text></g> | ||
| </svg></div> | ||
| <div class="card"><h2>Data Flow</h2><svg viewBox="0 0 940 460" xmlns="http://www.w3.org/2000/svg"> | ||
| <title>Data Flow</title> | ||
| <defs><marker id="arr" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse"><path d="M0 0 L10 5 L0 10 Z" fill="rgba(234,234,234,0.45)"/></marker></defs> | ||
| <rect width="940" height="460" fill="transparent"/> | ||
| <line x1="470" y1="90" x2="300" y2="130" stroke="rgba(234,234,234,0.25)" stroke-width="1" marker-end="url(#arr)"/> | ||
| <line x1="470" y1="90" x2="640" y2="130" stroke="rgba(234,234,234,0.25)" stroke-width="1" marker-end="url(#arr)"/> | ||
| <line x1="470" y1="90" x2="470" y2="240" stroke="rgba(234,234,234,0.25)" stroke-width="1" marker-end="url(#arr)"/> | ||
| <line x1="300" y1="200" x2="470" y2="240" stroke="rgba(234,234,234,0.25)" stroke-width="1" marker-end="url(#arr)"/> | ||
| <line x1="640" y1="200" x2="470" y2="240" stroke="rgba(234,234,234,0.25)" stroke-width="1" marker-end="url(#arr)"/> | ||
| <g class="node" data-node data-title="Start" data-desc="Init"><rect x="310" y="20" width="320" height="70" rx="4" ry="4" fill="rgba(0,212,170,0.06)" stroke="#00d4aa" stroke-width="1.2"/><text x="470" y="48" text-anchor="middle" font-size="13" font-weight="600" fill="#eaeaea">Start</text><text x="470" y="68" text-anchor="middle" font-size="10" fill="#8a8a9e" class="node-label">Init</text></g> | ||
| <g class="node" data-node data-title="Read" data-desc="Input"><rect x="140" y="130" width="320" height="70" rx="4" ry="4" fill="rgba(0,212,170,0.06)" stroke="#6a95d8" stroke-width="1.2"/><text x="300" y="158" text-anchor="middle" font-size="13" font-weight="600" fill="#eaeaea">Read</text><text x="300" y="178" text-anchor="middle" font-size="10" fill="#8a8a9e" class="node-label">Input</text></g> | ||
| <g class="node" data-node data-title="Process" data-desc="HarryPanel Procfile"><rect x="480" y="130" width="320" height="70" rx="4" ry="4" fill="rgba(0,212,170,0.06)" stroke="#d3ad7a" stroke-width="1.2"/><text x="640" y="158" text-anchor="middle" font-size="13" font-weight="600" fill="#eaeaea">Process</text><text x="640" y="178" text-anchor="middle" font-size="10" fill="#8a8a9e" class="node-label">HarryPanel Procfile</text></g> | ||
| <g class="node" data-node data-title="Emit" data-desc="Result"><rect x="310" y="240" width="320" height="70" rx="4" ry="4" fill="rgba(0,212,170,0.06)" stroke="#d3ad7a" stroke-width="1.2"/><text x="470" y="268" text-anchor="middle" font-size="13" font-weight="600" fill="#eaeaea">Emit</text><text x="470" y="288" text-anchor="middle" font-size="10" fill="#8a8a9e" class="node-label">Result</text></g> | ||
| </svg></div> | ||
| <div class="card"><h2>Hybrid</h2><svg viewBox="0 0 940 460" xmlns="http://www.w3.org/2000/svg"> | ||
| <title>Hybrid</title> | ||
| <defs><marker id="arr" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse"><path d="M0 0 L10 5 L0 10 Z" fill="rgba(234,234,234,0.45)"/></marker></defs> | ||
| <rect width="940" height="460" fill="transparent"/> | ||
| <line x1="470" y1="90" x2="470" y2="130" stroke="rgba(234,234,234,0.25)" stroke-width="1" marker-end="url(#arr)"/> | ||
| <line x1="470" y1="90" x2="300" y2="240" stroke="rgba(234,234,234,0.25)" stroke-width="1" marker-end="url(#arr)"/> | ||
| <line x1="470" y1="90" x2="640" y2="240" stroke="rgba(234,234,234,0.25)" stroke-width="1" marker-end="url(#arr)"/> | ||
| <line x1="130" y1="200" x2="300" y2="240" stroke="rgba(234,234,234,0.25)" stroke-width="1" marker-end="url(#arr)"/> | ||
| <line x1="470" y1="200" x2="300" y2="240" stroke="rgba(234,234,234,0.25)" stroke-width="1" marker-end="url(#arr)"/> | ||
| <line x1="470" y1="200" x2="640" y2="240" stroke="rgba(234,234,234,0.25)" stroke-width="1" marker-end="url(#arr)"/> | ||
| <line x1="810" y1="200" x2="640" y2="240" stroke="rgba(234,234,234,0.25)" stroke-width="1" marker-end="url(#arr)"/> | ||
| <g class="node" data-node data-title="User" data-desc="Operator"><rect x="310" y="20" width="320" height="70" rx="4" ry="4" fill="rgba(0,212,170,0.06)" stroke="#00d4aa" stroke-width="1.2"/><text x="470" y="48" text-anchor="middle" font-size="13" font-weight="600" fill="#eaeaea">User</text><text x="470" y="68" text-anchor="middle" font-size="10" fill="#8a8a9e" class="node-label">Operator</text></g> | ||
| <g class="node" data-node data-title="Auth" data-desc="Session"><rect x="-30" y="130" width="320" height="70" rx="4" ry="4" fill="rgba(0,212,170,0.06)" stroke="#00d4aa" stroke-width="1.2"/><text x="130" y="158" text-anchor="middle" font-size="13" font-weight="600" fill="#eaeaea">Auth</text><text x="130" y="178" text-anchor="middle" font-size="10" fill="#8a8a9e" class="node-label">Session</text></g> | ||
| <g class="node" data-node data-title="Logic" data-desc="Main"><rect x="310" y="130" width="320" height="70" rx="4" ry="4" fill="rgba(0,212,170,0.06)" stroke="#6a95d8" stroke-width="1.2"/><text x="470" y="158" text-anchor="middle" font-size="13" font-weight="600" fill="#eaeaea">Logic</text><text x="470" y="178" text-anchor="middle" font-size="10" fill="#8a8a9e" class="node-label">Main</text></g> | ||
| <g class="node" data-node data-title="DB" data-desc="State"><rect x="650" y="130" width="320" height="70" rx="4" ry="4" fill="rgba(0,212,170,0.06)" stroke="#6a95d8" stroke-width="1.2"/><text x="810" y="158" text-anchor="middle" font-size="13" font-weight="600" fill="#eaeaea">DB</text><text x="810" y="178" text-anchor="middle" font-size="10" fill="#8a8a9e" class="node-label">State</text></g> | ||
| <g class="node" data-node data-title="Report" data-desc="Output"><rect x="140" y="240" width="320" height="70" rx="4" ry="4" fill="rgba(0,212,170,0.06)" stroke="#d3ad7a" stroke-width="1.2"/><text x="300" y="268" text-anchor="middle" font-size="13" font-weight="600" fill="#eaeaea">Report</text><text x="300" y="288" text-anchor="middle" font-size="10" fill="#8a8a9e" class="node-label">Output</text></g> | ||
| <g class="node" data-node data-title="Audit" data-desc="Log"><rect x="480" y="240" width="320" height="70" rx="4" ry="4" fill="rgba(0,212,170,0.06)" stroke="#d3ad7a" stroke-width="1.2"/><text x="640" y="268" text-anchor="middle" font-size="13" font-weight="600" fill="#eaeaea">Audit</text><text x="640" y="288" text-anchor="middle" font-size="10" fill="#8a8a9e" class="node-label">Log</text></g> | ||
| </svg></div> | ||
| </div> | ||
| <dialog id="node-modal"><h3 id="modal-title"></h3><p id="modal-desc"></p><button onclick="document.getElementById('node-modal').close()">Close</button></dialog> | ||
| <script> | ||
| function showNode(title, desc){ | ||
| document.getElementById('modal-title').textContent = title; | ||
| document.getElementById('modal-desc').textContent = desc; | ||
| document.getElementById('node-modal').showModal(); | ||
| } | ||
| document.querySelectorAll('[data-node]').forEach(n=>{ | ||
| n.addEventListener('click', ()=>showNode(n.dataset.title, n.dataset.desc)); | ||
| }); | ||
| </script> | ||
| </body> | ||
| </html> | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When this page is opened from
docs/architecture.html,../../README.mdresolves two directories up, outside the repository path (or to the site root on GitHub Pages), so the “Back to README” link lands on a missing file instead of the project README. Since the README now directs users to this page, the backlink should only go up one level, e.g.../README.md.Useful? React with 👍 / 👎.