BOC v1.0: RS256 auth, Ledger integration, Prometheus metrics, CI/CD, backup

This commit is contained in:
Bernt
2026-07-28 23:08:32 +00:00
parent 0b4f160af1
commit af874040ca
11541 changed files with 1654104 additions and 1103 deletions
@@ -0,0 +1,10 @@
// Automation module
export async function render(container) {
container.innerHTML = `
<header class="module-header">
<h1>Automation</h1>
<p class="subtitle">Workflows och schemalagda jobb</p>
</header>
<p>Modulen laddas...</p>
`;
}
+41
View File
@@ -0,0 +1,41 @@
// CRM module
export async function render(container) {
container.innerHTML = `
<header class="module-header">
<h1>CRM</h1>
<p class="subtitle">Kunder och leads</p>
</header>
<div class="toolbar">
<button class="btn-primary" id="btn-new-customer">+ Ny kund</button>
</div>
<div class="table-container">
<table class="data-table" id="customers-table">
<thead>
<tr><th>Namn</th><th>Företag</th><th>Status</th><th>Email</th></tr>
</thead>
<tbody></tbody>
</table>
</div>
`;
try {
const res = await apiRequest('/crm/customers');
const data = await res.json();
const tbody = container.querySelector('#customers-table tbody');
if (data.customers?.length) {
tbody.innerHTML = data.customers.map(c => `
<tr>
<td>${c.name}</td>
<td>${c.company || '-'}</td>
<td><span class="badge badge-${c.status}">${c.status}</span></td>
<td>${c.email || '-'}</td>
</tr>
`).join('');
} else {
tbody.innerHTML = '<tr><td colspan="4">Inga kunder hittades</td></tr>';
}
} catch (err) {
container.innerHTML += `<div class="alert alert-error">Kunde inte ladda kunder: ${err.message}</div>`;
}
}
+50
View File
@@ -0,0 +1,50 @@
// Dashboard module — rendered dynamically into #app
export async function render(container) {
container.innerHTML = `
<header class="module-header">
<h1>Dashboard</h1>
<p class="subtitle">Överblick över hela verksamheten</p>
</header>
<div class="kpi-grid">
<div class="kpi-card">
<div class="kpi-value" id="kpi-revenue">—</div>
<div class="kpi-label">Månadsintäkt</div>
</div>
<div class="kpi-card">
<div class="kpi-value" id="kpi-deals">—</div>
<div class="kpi-label">Aktiva deals</div>
</div>
<div class="kpi-card">
<div class="kpi-value" id="kpi-customers">—</div>
<div class="kpi-label">Kunder</div>
</div>
<div class="kpi-card">
<div class="kpi-value" id="kpi-tickets">—</div>
<div class="kpi-label">Öppna ärenden</div>
</div>
</div>
<div class="section">
<h2>Snabbåtgärder</h2>
<div class="quick-actions">
<button onclick="location.hash='/crm'">+ Ny kund</button>
<button onclick="location.hash='/sales'">+ Ny offert</button>
<button onclick="location.hash='/finance'">+ Ny faktura</button>
</div>
</div>
`;
// Load real data
try {
const [deals, customers, tickets] = await Promise.all([
apiRequest('/sales/deals').then(r => r.ok ? r.json() : {deals: []}),
apiRequest('/crm/customers').then(r => r.ok ? r.json() : {customers: []}),
apiRequest('/support/tickets').then(r => r.ok ? r.json() : {tickets: []}),
]);
document.getElementById('kpi-deals').textContent = deals.deals?.length || 0;
document.getElementById('kpi-customers').textContent = customers.customers?.length || 0;
document.getElementById('kpi-tickets').textContent = tickets.tickets?.length || 0;
} catch (err) {
console.error('Dashboard load error:', err);
}
}
+13
View File
@@ -0,0 +1,13 @@
// Finance module
export async function render(container) {
container.innerHTML = `
<header class="module-header">
<h1>Finance</h1>
<p class="subtitle">Fakturor och ekonomi</p>
</header>
<div class="toolbar">
<button class="btn-primary">+ Ny faktura</button>
</div>
<p>Modulen laddas...</p>
`;
}
+10
View File
@@ -0,0 +1,10 @@
// HR module
export async function render(container) {
container.innerHTML = `
<header class="module-header">
<h1>HR</h1>
<p class="subtitle">Anställda och tidrapporter</p>
</header>
<p>Modulen laddas...</p>
`;
}
+10
View File
@@ -0,0 +1,10 @@
// Legal module
export async function render(container) {
container.innerHTML = `
<header class="module-header">
<h1>Legal</h1>
<p class="subtitle">Kontrakt och påminnelser</p>
</header>
<p>Modulen laddas...</p>
`;
}
+10
View File
@@ -0,0 +1,10 @@
// Marketing module
export async function render(container) {
container.innerHTML = `
<header class="module-header">
<h1>Marketing</h1>
<p class="subtitle">Kampanjer och innehåll</p>
</header>
<p>Modulen laddas...</p>
`;
}
+14
View File
@@ -0,0 +1,14 @@
// Sales module
export async function render(container) {
container.innerHTML = `
<header class="module-header">
<h1>Sales</h1>
<p class="subtitle">Deals och offert</p>
</header>
<div class="toolbar">
<button class="btn-primary">+ Ny deal</button>
<button class="btn-secondary">+ Ny offert</button>
</div>
<p>Modulen laddas...</p>
`;
}
+10
View File
@@ -0,0 +1,10 @@
// Support module
export async function render(container) {
container.innerHTML = `
<header class="module-header">
<h1>Support</h1>
<p class="subtitle">Ärenden och kundtjänst</p>
</header>
<p>Modulen laddas...</p>
`;
}