mirror of
https://github.com/Since-3/since3-portal.git
synced 2026-10-12 20:51:17 +00:00
added dashboard
This commit is contained in:
parent
29ea53a03d
commit
64b2c85f81
14 changed files with 1496 additions and 11 deletions
37
lib/supabase/migrations/20260930100000_info_section.sql
Normal file
37
lib/supabase/migrations/20260930100000_info_section.sql
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
-- Info-Sektion: Produktstatus, laufende Vorgänge, interne Notizen
|
||||
|
||||
-- Hosting als eigene Kategorie (neben Webseite, E-Mail, SEO)
|
||||
alter type public.product_category add value if not exists 'hosting';
|
||||
|
||||
-- Freitext zum Status, z. B. "Erreichbar, keine Störungen" oder "Wartung geplant am 12.10."
|
||||
alter table public.client_products
|
||||
add column if not exists status_message text;
|
||||
|
||||
-- Vorgänge müssen nicht zwingend an ein Produkt gebunden sein
|
||||
alter table public.product_tasks
|
||||
alter column product_id drop not null;
|
||||
|
||||
-- "zuletzt bearbeitet von ..." für interne Notizen
|
||||
alter table public.internal_notes
|
||||
add column if not exists updated_by uuid references public.profiles(id) on delete set null default auth.uid(),
|
||||
add column if not exists updated_at timestamptz not null default now();
|
||||
|
||||
update public.internal_notes
|
||||
set updated_by = created_by, updated_at = created_at
|
||||
where updated_by is null;
|
||||
|
||||
create or replace function public.set_updated_by()
|
||||
returns trigger language plpgsql set search_path = '' as $$
|
||||
begin
|
||||
new.updated_by = auth.uid();
|
||||
return new;
|
||||
end $$;
|
||||
|
||||
create trigger set_updated_at before update on public.internal_notes
|
||||
for each row execute function public.set_updated_at();
|
||||
|
||||
create trigger set_updated_by before update on public.internal_notes
|
||||
for each row execute function public.set_updated_by();
|
||||
|
||||
create index if not exists internal_notes_client_updated_idx
|
||||
on public.internal_notes (client_id, updated_at desc);
|
||||
51
lib/supabase/migrations/20260930120000_product_checks.sql
Normal file
51
lib/supabase/migrations/20260930120000_product_checks.sql
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
-- Erreichbarkeitsprüfungen für Produkte (manuell per Button + beim Seitenaufruf)
|
||||
create table public.product_checks (
|
||||
id bigint generated always as identity primary key,
|
||||
product_id uuid not null references public.client_products(id) on delete cascade,
|
||||
client_id uuid not null references public.clients(id) on delete cascade,
|
||||
checked_at timestamptz not null default now(),
|
||||
ok boolean not null,
|
||||
status_code int,
|
||||
response_ms int,
|
||||
error text
|
||||
);
|
||||
|
||||
create index on public.product_checks (product_id, checked_at desc);
|
||||
|
||||
-- Lesen: Admin alles, Client nur eigene. Schreiben bewusst ohne Policy:
|
||||
-- Ergebnisse schreibt nur der Server (Service Role), damit Clients ihre Uptime nicht fälschen können.
|
||||
alter table public.product_checks enable row level security;
|
||||
|
||||
create policy admin_select on public.product_checks for select to authenticated
|
||||
using ((select public.is_admin()));
|
||||
|
||||
create policy client_select on public.product_checks for select to authenticated
|
||||
using (client_id = (select public.current_client_id()));
|
||||
|
||||
-- Letzte Prüfung + Uptime der letzten 30 Tage je Produkt
|
||||
create view public.product_check_summary with (security_invoker = true) as
|
||||
select
|
||||
p.id as product_id,
|
||||
last.checked_at,
|
||||
last.ok,
|
||||
last.status_code,
|
||||
last.response_ms,
|
||||
last.error,
|
||||
stats.checks_30d,
|
||||
stats.uptime_30d
|
||||
from public.client_products p
|
||||
left join lateral (
|
||||
select c.checked_at, c.ok, c.status_code, c.response_ms, c.error
|
||||
from public.product_checks c
|
||||
where c.product_id = p.id
|
||||
order by c.checked_at desc
|
||||
limit 1
|
||||
) last on true
|
||||
left join lateral (
|
||||
select
|
||||
count(*)::int as checks_30d,
|
||||
round(100.0 * count(*) filter (where c.ok) / nullif(count(*), 0), 2) as uptime_30d
|
||||
from public.product_checks c
|
||||
where c.product_id = p.id
|
||||
and c.checked_at > now() - interval '30 days'
|
||||
) stats on true;
|
||||
Loading…
Add table
Add a link
Reference in a new issue