// src/components/MetricsPanel.tsx
'use client'
import { useEffect, useState } from 'react'
import { Card, CardHeader } from '@/components/ui/Card'
export function MetricsPanel({ projectId }: Props) {
const [data, setData] = useState<Metric[]>([])
useEffect(() => {
const ctrl = new AbortController()
fetch(`/api/projects/${projectId}/metrics`, { signal: ctrl.signal })
.then(r => r.json())
.then(setData)
.catch(() => {})
return () => ctrl.abort()
}, [projectId])
return (
<Card>
<CardHeader>Real-time metrics</CardHeader>
{data.map(m => <MetricRow key={m.id} metric={m} />)}
</Card>
)
}
# python/etl/transform.py
from typing import Iterable
import polars as pl
from prefect import flow, task
@task(retries=3, retry_delay_seconds=30)
def load_events(source: str) -> pl.DataFrame:
return pl.read_parquet(source)
@task
def aggregate(df: pl.DataFrame) -> pl.DataFrame:
return (
df.lazy()
.group_by(['tenant_id', 'event_type'])
.agg([
pl.col('amount').sum().alias('total'),
pl.col('id').count().alias('count'),
])
.collect()
)
@flow(name='hourly-rollup')
def rollup_pipeline(sources: Iterable[str]) -> None:
for src in sources:
df = load_events(src)
result = aggregate(df)
result.write_parquet(f'rollups/{src}.parquet')
// rust/src/auth.rs
use jsonwebtoken::{decode, DecodingKey, Validation, Algorithm};
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
pub struct Claims {
pub sub: String,
pub exp: usize,
pub roles: Vec<String>,
}
pub fn verify_token(token: &str, key: &[u8]) -> Result<Claims, AuthError> {
let mut validation = Validation::new(Algorithm::HS256);
validation.set_audience(&["api.kyaxcorp.com"]);
decode::<Claims>(token, &DecodingKey::from_secret(key), &validation)
.map(|data| data.claims)
.map_err(|_| AuthError::InvalidToken)
}
-- sql/migrations/0042_audit_log.sql
CREATE TABLE IF NOT EXISTS audit_log (
id BIGSERIAL PRIMARY KEY,
actor_id UUID NOT NULL,
tenant_id UUID NOT NULL,
action TEXT NOT NULL,
resource TEXT NOT NULL,
metadata JSONB DEFAULT '{}'::jsonb,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_audit_actor ON audit_log (actor_id, created_at DESC);
CREATE INDEX idx_audit_tenant ON audit_log (tenant_id, created_at DESC);
// src/components/MetricsPanel.tsx
'use client'
import { useEffect, useState } from 'react'
import { Card, CardHeader } from '@/components/ui/Card'
export function MetricsPanel({ projectId }: Props) {
const [data, setData] = useState<Metric[]>([])
useEffect(() => {
const ctrl = new AbortController()
fetch(`/api/projects/${projectId}/metrics`, { signal: ctrl.signal })
.then(r => r.json())
.then(setData)
.catch(() => {})
return () => ctrl.abort()
}, [projectId])
return (
<Card>
<CardHeader>Real-time metrics</CardHeader>
{data.map(m => <MetricRow key={m.id} metric={m} />)}
</Card>
)
}
# python/etl/transform.py
from typing import Iterable
import polars as pl
from prefect import flow, task
@task(retries=3, retry_delay_seconds=30)
def load_events(source: str) -> pl.DataFrame:
return pl.read_parquet(source)
@task
def aggregate(df: pl.DataFrame) -> pl.DataFrame:
return (
df.lazy()
.group_by(['tenant_id', 'event_type'])
.agg([
pl.col('amount').sum().alias('total'),
pl.col('id').count().alias('count'),
])
.collect()
)
@flow(name='hourly-rollup')
def rollup_pipeline(sources: Iterable[str]) -> None:
for src in sources:
df = load_events(src)
result = aggregate(df)
result.write_parquet(f'rollups/{src}.parquet')
// rust/src/auth.rs
use jsonwebtoken::{decode, DecodingKey, Validation, Algorithm};
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
pub struct Claims {
pub sub: String,
pub exp: usize,
pub roles: Vec<String>,
}
pub fn verify_token(token: &str, key: &[u8]) -> Result<Claims, AuthError> {
let mut validation = Validation::new(Algorithm::HS256);
validation.set_audience(&["api.kyaxcorp.com"]);
decode::<Claims>(token, &DecodingKey::from_secret(key), &validation)
.map(|data| data.claims)
.map_err(|_| AuthError::InvalidToken)
}
-- sql/migrations/0042_audit_log.sql
CREATE TABLE IF NOT EXISTS audit_log (
id BIGSERIAL PRIMARY KEY,
actor_id UUID NOT NULL,
tenant_id UUID NOT NULL,
action TEXT NOT NULL,
resource TEXT NOT NULL,
metadata JSONB DEFAULT '{}'::jsonb,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_audit_actor ON audit_log (actor_id, created_at DESC);
CREATE INDEX idx_audit_tenant ON audit_log (tenant_id, created_at DESC);