Impulse AI Docs
Intern dokumentasjon
skipLink.label

Console Admin API

Komplett referanse for Console web-appen (console.impulseai.app) — autentisering, arkitektur og admin-API.

Autentiseringsarkitektur

heading.anchorLabel

Console har fire sikkerhetslag:

LagMekanismeHva sjekkesHvor
1Email + passordBrukerens identitetSupabase Auth
2is_console_admin metadataAt brukeren har admin-rolleConsole middleware
3CONSOLE_ALLOWED_EMAILSAt e-posten er i allowlistenConsole middleware
4CONSOLE_ADMIN_TOKEN bearerConsole som tjeneste mot APIAPI bearer auth

Lag 1-3 beskytter innlogging. Lag 4 beskytter data-henting fra API.

Opprette admin-bruker

heading.anchorLabel

I Supabase Dashboard → Authentication → Users → Add User:

  1. Sett email og passord
  2. Klikk brukeren → Edit User → User Metadata:
    { "is_console_admin": true }

Alternativt via SQL Editor:

UPDATE auth.users
SET raw_user_meta_data = raw_user_meta_data || '{"is_console_admin": true}'::jsonb
WHERE email = 'din-admin@impulseai.app';

Admin-brukere per miljoe

heading.anchorLabel
MiljoeEmailSupabase-prosjekt
STGconsole-admin-stg@impulseai.appconxpuqktkeiphnnpfiv
PRDconsole-admin@impulseai.appjksqfeutntcvukrisrno

Klient-autorisasjonsmatrise

heading.anchorLabel
KlientKlient-authBruker-authScope
iOS/AndroidX-API-Key headerSupabase JWTEgne data (RLS)
ConsoleBearer CONSOLE_ADMIN_TOKENSupabase session cookieAlle data (admin)
WebhooksPlattform-signaturIngenSkrive (events)
Health checkSecret URL-pathIngenKun status

API middleware-kjede

heading.anchorLabel
Request inn
|-- /health/{secret} → Bypass alt (Railway health check)
|-- /webhooks/* → Bypass API key (egen signaturverifisering)
|-- /admin/* → Bypass API key (egen Bearer token-auth)
'-- /api/v1/* → Krev X-API-Key + JWT

API-autentisering

heading.anchorLabel

Alle /admin/monitoring-endepunkter krever Bearer token:

Authorization: Bearer <CONSOLE_ADMIN_TOKEN>
  • Timing-safe token-sammenligning
  • Fritatt fra X-API-Key-krav og global rate limiting
  • Returnerer 401 ved manglende eller ugyldig token

Environment-variabler

heading.anchorLabel

Paakrevd (Console frontend)

heading.anchorLabel
VariabelBeskrivelse
NEXT_PUBLIC_SUPABASE_URLSupabase project URL
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEYSupabase anon key
SUPABASE_SECRET_KEYSupabase service role key (server-only)
NEXT_PUBLIC_CONSOLE_API_URLAPI server URL (f.eks. https://api.impulseai.app)
CONSOLE_ADMIN_TOKENBearer token for admin-endepunkter
CONSOLE_ALLOWED_EMAILSKommaseparert allowlist for innlogging (Doppler)

Valgfrie (API-server, aktiverer ekstra features)

heading.anchorLabel
VariabelAktiverer
CONSOLE_SENTRY_API_TOKEN + CONSOLE_SENTRY_ORG + CONSOLE_SENTRY_PROJECTSentry error tracking i /errors
CONSOLE_RAILWAY_API_TOKEN + CONSOLE_RAILWAY_PROJECT_IDRailway deployments i /deployments
CONSOLE_VERCEL_API_TOKEN (+ CONSOLE_VERCEL_TEAM_ID)Web analytics i /web-analytics
CONSOLE_API_PRODUCTION_URLProd API health check i /external-status
CONSOLE_API_STAGING_URLStaging API health check i /external-status

Alle endepunkter er under /admin/monitoring.


Dashboard & KPI-er

heading.anchorLabel

GET /overview

heading.anchorLabel

Hoeynivaa-metrikker for dashboardet.

Response:

{
"users": { "total": 150, "active_subscriptions": 42 },
"activity": {
"impulses_7d": 230,
"sessions_7d": 85,
"check_ins_7d": 120,
"ai_requests_24h": 340
},
"spend": { "current_month": 18.50, "total_requests": 2400 },
"feedback_unread": 3,
"timestamp": "2026-03-29T12:00:00Z"
}

Revenue & oekonomi

heading.anchorLabel

GET /revenue?period={7d|30d|90d}

heading.anchorLabel

Detaljert revenue- og loennsomhetsanalyse.

ParamDefaultVerdier
period30d7d, 30d, 90d

Response:

{
"mrr": 504.00,
"arr": 6048.00,
"ai_cost": {
"total": 45.20,
"per_user": 1.08,
"by_workload": {
"classification": { "requests": 200, "cost": 5.00, "tokens": 50000, "avg_cost": 0.025 },
"guidance": { "requests": 150, "cost": 25.00, "tokens": 300000, "avg_cost": 0.167 }
},
"by_day": { "2026-03-28": 1.50, "2026-03-29": 1.20 }
},
"gross_margin": 91.0,
"subscribers": {
"total": 42,
"by_tier": { "foundation": { "count": 30, "mrr": 180 }, "mastery": { "count": 12, "mrr": 144 } },
"margin_by_tier": { "foundation": { "mrr": 180, "ai_cost": 20, "margin": 88.9, "count": 30 } }
},
"churn": { "count": 2, "rate": 4.8 },
"app_store": {
"has_data": true,
"gross_revenue": 504.00,
"refunds": 0,
"net_revenue": 428.40,
"transactions": 42,
"by_day": { "2026-03-28": 12.00 },
"by_platform": { "ios": { "gross": 504.00, "transactions": 42 } }
},
"period": "30d",
"timestamp": "2026-03-29T12:00:00Z"
}

Prediksjoner & runway

heading.anchorLabel

GET /predictions

heading.anchorLabel

Brukervaekst, churn, revenue-prognoser og cash runway.

Response:

{
"current": {
"total_users": 150,
"paying_users": 42,
"avg_daily_signups": 2.1,
"avg_daily_spend": 1.50,
"conversion_rate": 28.0,
"churn_rate": 4.8
},
"cash_runway": {
"balance": 450.00,
"daily_burn": 1.50,
"runway_days": 300,
"runway_date": "2027-01-23",
"next_payout": { "date": "2026-05-15", "estimated_amount": 428.40 }
},
"forecasts": {
"conservative": { "30d": { "users": 160, "paying_users": 44, "mrr": 530, "ai_spend": 48, "margin": 90.9 } },
"realistic": { "30d": { "users": 175, "paying_users": 50, "mrr": 600, "ai_spend": 52, "margin": 91.3 } },
"optimistic": { "30d": { "users": 210, "paying_users": 60, "mrr": 720, "ai_spend": 58, "margin": 91.9 } }
},
"rate_limit_headroom": {
"current_daily_requests": 340,
"tier4_rpm_limit": 4000,
"estimated_max_concurrent_users": 1333
},
"trends": {
"signups_by_day": { "2026-03-28": 3, "2026-03-29": 2 },
"spend_by_day": { "2026-03-28": 1.50, "2026-03-29": 1.20 }
},
"timestamp": "2026-03-29T12:00:00Z"
}

System-monitorering

heading.anchorLabel

GET /ai-health

heading.anchorLabel

AI-tjenestens helse: rate limits, forbruk og Anthropic-saldo.

Response:

{
"rate_limits": [
{
"model_class": "claude-sonnet-4-20250514",
"rpm_limit": 4000, "rpm_remaining": 3990, "rpm_reset_at": "2026-03-29T12:01:00Z",
"itpm_limit": 400000, "itpm_remaining": 395000, "itpm_reset_at": "2026-03-29T12:01:00Z",
"otpm_limit": 80000, "otpm_remaining": 78000, "otpm_reset_at": "2026-03-29T12:01:00Z"
}
],
"spend": {
"current_month": 45.20,
"total_requests": 2400,
"total_tokens": 4800000,
"by_workload": { "classification": { "requests": 200, "cost": 5.00, "tokens": 50000 } }
},
"balance": { "amount_usd": 450.00, "last_updated": "2026-03-29T11:00:00Z" },
"timestamp": "2026-03-29T12:00:00Z"
}

GET /queue-health

heading.anchorLabel

Status for alle BullMQ-koeeer.

Koeeer: impulse-classification, unified-guidance, session-summary, insights-regeneration, check-in-assessment

Response:

{
"status": "healthy",
"queues": [
{
"name": "impulse-classification",
"waiting": 0, "active": 1, "completed": 500, "failed": 2, "delayed": 0,
"status": "healthy"
}
],
"timestamp": "2026-03-29T12:00:00Z"
}

En koee er degraded hvis failed > 10.

GET /external-status

heading.anchorLabel

Helsesjekk av avhengige tjenester.

Response:

{
"claude": {
"status": "operational",
"description": "All Systems Operational",
"components": [{ "name": "API", "status": "operational" }],
"incidents": []
},
"api": { "status": "ok", "redis": true, "timestamp": "2026-03-29T12:00:00Z" },
"api_staging": { "status": "ok", "redis": true, "timestamp": "2026-03-29T12:00:00Z" },
"timestamp": "2026-03-29T12:00:00Z"
}

Siste feil fra Sentry (krever Sentry-variabler).

Response:

{
"configured": true,
"issues": [
{
"id": "12345",
"title": "TypeError: Cannot read property 'id' of undefined",
"culprit": "src/routes/impulses.ts",
"level": "error",
"count": 3,
"first_seen": "2026-03-28T10:00:00Z",
"last_seen": "2026-03-29T11:00:00Z",
"permalink": "https://sentry.io/issues/12345/"
}
],
"timestamp": "2026-03-29T12:00:00Z"
}

GET /deployments

heading.anchorLabel

Siste Railway-deployments (krever Railway-variabler).

Response:

{
"configured": true,
"deployments": [
{
"id": "deploy-123",
"status": "SUCCESS",
"created_at": "2026-03-29T10:00:00Z",
"environment": "production",
"service": "im-api",
"commit_message": "fix: resolve session timeout",
"commit_hash": "abc1234"
}
],
"timestamp": "2026-03-29T12:00:00Z"
}

GET /web-analytics

heading.anchorLabel

Vercel web analytics (krever Vercel-variabler).

Response:

{
"configured": true,
"data": {},
"timestamp": "2026-03-29T12:00:00Z"
}

Brukeradministrasjon

heading.anchorLabel

GET /users?tier=&status=&search=&limit=50&offset=0

heading.anchorLabel

Paginert brukerliste med soek og filtrering.

ParamDefaultBeskrivelse
tieralltrial, foundation, mastery, free, all
statusallactive, cancelled, all
searchSoek i email/display_name (maks 100 tegn)
limit50Maks 200
offset0Paginering

Response:

{
"users": [
{
"id": "uuid",
"email": "user@example.com",
"display_name": "User Name",
"subscription_tier": "foundation",
"subscription_status": "active",
"billing_period": "monthly",
"trial_started_at": null,
"trial_ends_at": null,
"trial_converted": false,
"is_partner": false,
"created_at": "2026-03-01T10:00:00Z",
"updated_at": "2026-03-29T12:00:00Z"
}
],
"total": 150,
"by_tier": { "trial": 50, "foundation": 80, "mastery": 20 },
"timestamp": "2026-03-29T12:00:00Z"
}

GET /users/:id

heading.anchorLabel

Komplett brukerprofil med aktivitet, AI-bruk og admin-notater.

Response:

{
"profile": {
"id": "uuid",
"email": "user@example.com",
"display_name": "User Name",
"subscription_tier": "foundation",
"subscription_status": "active",
"billing_period": "monthly",
"trial_started_at": null,
"trial_ends_at": null,
"trial_converted": false,
"is_partner": false,
"partner_source": null,
"preferred_language": "no",
"gender": null,
"birth_year": null,
"ai_personalization_enabled": true,
"created_at": "2026-03-01T10:00:00Z",
"updated_at": "2026-03-29T12:00:00Z"
},
"auth": {
"last_sign_in_at": "2026-03-29T08:00:00Z",
"banned_until": null,
"email_confirmed_at": "2026-03-01T10:05:00Z"
},
"usage": {
"total_requests": 120,
"total_tokens": 240000,
"total_cost": 3.50,
"by_workload_type": {
"classification": { "requests": 40, "tokens": 20000, "cost": 0.50 },
"guidance": { "requests": 50, "tokens": 150000, "cost": 2.50 }
}
},
"feedback": [],
"activity": [
{ "type": "impulse", "id": "uuid", "created_at": "2026-03-29T10:00:00Z", "summary": "Expansion impulse" },
{ "type": "session", "id": "uuid", "created_at": "2026-03-29T10:30:00Z", "summary": "Realization session completed" }
],
"admin_notes": [],
"subscriptions": [
{ "platform": "ios", "tier": "foundation", "status": "active", "purchase_date": "2026-03-15", "expires_date": "2026-04-15" }
],
"timestamp": "2026-03-29T12:00:00Z"
}

PATCH /users/:id

heading.anchorLabel

Oppdater brukerprofil. Kun hvitelistede felt.

Body (alle valgfrie):

{
"display_name": "New Name",
"subscription_tier": "mastery",
"subscription_status": "active",
"billing_period": "annual",
"is_partner": true
}

Oppretter automatisk admin_notes-oppfoering.

POST /users/:id/reset-password

heading.anchorLabel

Send passord-reset-lenke.

Response:

{ "success": true, "message": "Password reset link generated", "link": "https://..." }

POST /users/:id/suspend

heading.anchorLabel

Suspender eller reaktiver bruker.

Body:

{ "action": "suspend", "ban_duration": "876000h" }

Response:

{ "success": true, "banned_until": "2126-03-29T12:00:00Z" }

POST /users/:id/force-signout

heading.anchorLabel

Ugyldigjoer alle aktive sesjoner paa tvers av enheter.

Response:

{ "success": true }

POST /users/:id/notes

heading.anchorLabel

Legg til admin-notat paa bruker.

Body:

{ "note": "User reported login issues", "category": "support" }

Kategorier: general, support, tier_change, suspension, password_reset

Response:

{ "note": { "id": "uuid", "note": "...", "category": "support", "created_by": "admin", "created_at": "2026-03-29T12:00:00Z" } }

DELETE /users/:id

heading.anchorLabel

Soft-delete bruker via Supabase auth.

Body (paakrevd):

{ "confirm": true }

GET /feedback?limit=50

heading.anchorLabel

Brukertilbakemeldinger, sortert nyeste foerst.

ParamDefaultMaks
limit50200

Response:

{
"items": [
{ "id": "uuid", "created_at": "2026-03-29T10:00:00Z", "content": "Great app!", "admin_notes": null, "user_id": "uuid" }
],
"total": 25,
"unread": 3,
"last_7d": 5,
"timestamp": "2026-03-29T12:00:00Z"
}

Innstillinger

heading.anchorLabel

GET /settings/:key

heading.anchorLabel

Les admin-innstilling.

PUT /settings/:key

heading.anchorLabel

Oppdater admin-innstilling.

Tillatte noekkler: anthropic_balance, alert_thresholds, slack_webhook_url

Body:

{ "value": 500.00 }

Bull Board (koee-dashboard)

heading.anchorLabel

URL: /admin/queues/

Interaktivt web-dashboard for BullMQ-koeeer. Beskyttet med samme Bearer token.

Funksjoner:

  • Se alle koeeer med jobb-telling
  • Inspiser individuelle jobber
  • Manuell retry/slett av feilede jobber
  • Visuell status (waiting, active, completed, failed, delayed)