Initial Switch to V2. Completely Overhauled Backend, Frontend and General Structure.

This commit is contained in:
2026-04-17 14:37:36 +03:00
parent eb773c5531
commit 0a8a42d69b
447 changed files with 70696 additions and 492 deletions

View File

@@ -0,0 +1,127 @@
<style>
#erd svg { width: 100%; height: auto; }
#erd svg.erDiagram .divider path { stroke-opacity: 0.4; }
#erd svg.erDiagram .row-rect-odd path,
#erd svg.erDiagram .row-rect-odd rect,
#erd svg.erDiagram .row-rect-even path,
#erd svg.erDiagram .row-rect-even rect { stroke: none !important; }
</style>
<div id="erd" style="padding: 1rem 0;"></div>
<script type="module">
import mermaid from 'https://esm.sh/mermaid@11/dist/mermaid.esm.min.mjs';
const dark = matchMedia('(prefers-color-scheme: dark)').matches;
await document.fonts.ready;
mermaid.initialize({
startOnLoad: false,
theme: 'base',
fontFamily: '"Anthropic Sans", sans-serif',
themeVariables: {
darkMode: dark,
fontSize: '13px',
fontFamily: '"Anthropic Sans", sans-serif',
lineColor: dark ? '#9c9a92' : '#73726c',
textColor: dark ? '#c2c0b6' : '#3d3d3a',
primaryColor: dark ? '#3C3489' : '#EEEDFE',
primaryTextColor: dark ? '#CECBF6' : '#3C3489',
primaryBorderColor: dark ? '#7F77DD' : '#534AB7',
secondaryColor: dark ? '#085041' : '#E1F5EE',
tertiaryColor: dark ? '#712B13' : '#FAECE7',
},
});
const diagram = `erDiagram
staff_users {
uuid id PK
string name
string email
string role
}
devices {
uuid id PK
string serial_number
string firmware_version
string firestore_doc_id
}
app_users {
uuid id PK
string email
string display_name
string firestore_uid
}
customers {
uuid id PK
string full_name
string email
string phone
timestamp created_at
}
entries {
uuid id PK
uuid author_id FK
varchar type
varchar status
varchar severity
string title
text body
timestamp created_at
timestamp updated_at
}
entry_links {
uuid id PK
uuid entry_id FK
varchar entity_type
uuid entity_id
}
support_tickets {
uuid id PK
uuid customer_id FK
uuid device_id FK
uuid linked_entry_id FK
varchar status
varchar priority
varchar opened_via
timestamp created_at
timestamp updated_at
}
ticket_messages {
uuid id PK
uuid ticket_id FK
uuid sender_id
varchar sender_type
text body
timestamp created_at
}
staff_users ||--o{ entries : "authors"
entries ||--o{ entry_links : "has links"
support_tickets ||--o{ ticket_messages : "has messages"
customers ||--o{ support_tickets : "opens"
devices ||--o{ support_tickets : "subject of"
entries ||--o| support_tickets : "escalated to"
`;
const { svg } = await mermaid.render('erd-svg', diagram);
document.getElementById('erd').innerHTML = svg;
document.querySelectorAll('#erd svg.erDiagram .node').forEach(node => {
const firstPath = node.querySelector('path[d]');
if (!firstPath) return;
const d = firstPath.getAttribute('d');
const nums = d.match(/-?[\d.]+/g)?.map(Number);
if (!nums || nums.length < 8) return;
const xs = [nums[0], nums[2], nums[4], nums[6]];
const ys = [nums[1], nums[3], nums[5], nums[7]];
const x = Math.min(...xs), y = Math.min(...ys);
const w = Math.max(...xs) - x, h = Math.max(...ys) - y;
const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
rect.setAttribute('x', x); rect.setAttribute('y', y);
rect.setAttribute('width', w); rect.setAttribute('height', h);
rect.setAttribute('rx', '8');
for (const a of ['fill', 'stroke', 'stroke-width', 'class', 'style']) {
if (firstPath.hasAttribute(a)) rect.setAttribute(a, firstPath.getAttribute(a));
}
firstPath.replaceWith(rect);
});
document.querySelectorAll('#erd svg.erDiagram .row-rect-odd path, #erd svg.erDiagram .row-rect-even path').forEach(p => {
p.setAttribute('stroke', 'none');
});
</script>