Passa al contenuto principale

ADR-0001: Stack tecnologico Akira — Python/FastAPI + Next.js

Status

Accepted — congelato il 7 maggio 2026 (cfr. STARTUP_PROGETTO.md §13). ADR retro-attivo che formalizza la decisione.

Context

Akira è la piattaforma VoIP/SIP wholesale che sostituisce Stealth. Lo stack deve coprire:

  • Backend API per moduli MVP (Companies, Originators, Terminators, Devices, Tariffs, Balance, Routing, Reports, Traffic Tools).
  • Frontend operatore con UX ricca (mockup akira-mockup.html 22 route, hash-routed).
  • Signaling layer (Kamailio + RTPengine + FreeSWITCH) con tooling Python.
  • AgentCore esterno (repo agent-core di A.Sheep) come motore conversazionale Telegram.
  • Pipeline batch notturna (rating, settlement, report) e job UI (PDF, IMAP, Pattern Analyzer).
  • Team di sviluppo principalmente Python (A.Sheep), familiarità con framework asincroni.

Vincoli:

  • TimescaleDB come unico data warehouse (no Mongo, no Elastic).
  • Redis disponibile per caching/queue.
  • Deployment su VM Hetzner Cloud, orchestrazione Ansible (akira-infra).
  • Convenzioni A.Sheep già consolidate in agent-core e toolbox (Python 3.12, uv).

Decision

Frontend

  • Next.js 15 con App Router.
  • TypeScript 5.x strict mode.
  • Tailwind CSS + shadcn/ui per componenti.
  • pnpm come package manager (lockfile committed).
  • Build statico ove possibile (admin SPA), SSR solo dove serve.

Backend

  • Python 3.12 runtime.
  • FastAPI per API HTTP + WebSocket.
  • SQLAlchemy 2.x async con asyncpg driver per TimescaleDB.
  • Alembic per migrazioni schema.
  • Pydantic v2 per validation + serialization (model_validate / model_dump).
  • structlog per logging JSON strutturato.
  • uv come package manager + virtualenv (pyproject.toml).

Job queue

  • arq su Redis per job UI/admin: PDF generation, Future Tariff applier, IMAP poller, Pattern Analyzer scheduled, Telegram outbound queue.
  • NOTA: per la pipeline CDR ad alta volumetria si è scelto NATS JetStream — vedi ADR-0007.

Clarification (ADR-0015, 2026-05-20): arq + Redis resta canonical per pattern "submit job from API -> return result polled" (UI/admin use case: export PDF, tariff applier scheduled, agent fee bulk recompute). Per pattern "consume stream eventi continuous" (kam-cdr-bridge, fs-esl-gateway, notification-dispatcher) e' stato adottato NATSWorker (vedi ADR-0015). I due pattern sono complementari: ADR-0001 NON e' superseded da ADR-0015.

Decision tree:

  • Subscriber stream eventi -> NATSWorker / NATSJetStream*Worker (ADR-0015)
  • Submit + result return -> arq + Redis (ADR-0001)
  • Cron schedule fisso -> systemd timer

AgentCore

  • Esterno, repo separato agent-core (paradigma A.Sheep: ChatLoop + Memory + MCP).
  • Akira espone tool MCP via HTTP server FastAPI dedicato (apps/agentcore-bridge).
  • Comunicazione bidirezionale: AgentCore → Akira tool calls; Akira → AgentCore notifiche outbound.

SIPp orchestrator

  • Microservizio Python FastAPI dedicato (apps/sipp-orchestrator).
  • Esegue scenari SIPp via subprocess, espone REST API per Quality Verifier (NOC TT).
  • Stateless, scala orizzontalmente.

Container & deploy

  • Docker + Docker Compose per dev/staging.
  • Produzione: Compose su VM (Fase 2 Opzione A), Kubernetes valutato post-MVP.
  • Immagini multi-stage, base python:3.12-slim e node:22-alpine.

CI/CD

  • GitHub Actions per lint, test, build, push registry.
  • Workflow: lint → test → build → push image → ansible deploy (manual approval su prod).

Repo layout (monorepo)

akira/
apps/
api/ # FastAPI backend
web/ # Next.js frontend
agentcore-bridge/ # MCP server
sipp-orchestrator/
cdr-worker/ # NATS consumer → TimescaleDB
packages/
shared-types/ # TS types generati da Pydantic
sip-utils/ # helper SIP comuni
infra/
ansible/ # ex akira-infra
docker/
docs/
adr/
conventions/
tests/
integration/
e2e/

Consequences

Positive

  • Linguaggio coerente con il resto dell'ecosistema A.Sheep (riuso agent-core, toolbox).
  • FastAPI + Pydantic v2 = type safety end-to-end (OpenAPI generato → TS types con openapi-typescript).
  • async/await uniforme dal HTTP handler al DB (asyncpg) al broker (nats-py).
  • Next.js 15 maturo, ecosistema componenti ricco.
  • uv velocissimo per install/lock (10-100× pip).

Negative

  • 2 toolchain (Python + Node) → CI più complessa.
  • Python async cognitive load (event loop, libraries non-async ancora frequenti).
  • SQLAlchemy 2.x async è ancora meno documentato della versione sync.

Neutral

  • Monorepo richiede disciplina su versioning interni (pnpm workspaces + uv workspaces).
  • Pydantic v2 breaking changes da v1 — qualsiasi codice esterno copiato va verificato.

Implementation hints

  • pyproject.toml root con [tool.uv.workspace] members = ["apps/*"].
  • pnpm-workspace.yaml per frontend + packages condivisi.
  • Generare TypeScript types da OpenAPI schema: pnpm run gen:types invoca openapi-typescript http://localhost:8000/openapi.json.
  • Versione Python pin via .python-version (3.12.x).
  • Node pin via .nvmrc (22.x LTS).

Alternatives considered

  • Django + DRF: scartato — meno idiomatico async, ORM più verboso, no superset di FastAPI per il nostro caso.
  • Go backend: scartato — team Python-first, riuso AgentCore/Toolbox impossibile.
  • Remix / SvelteKit: scartato — Next.js ha l'ecosistema più maturo e mockup già pensato per React.
  • Celery invece di arq: scartato — arq è async-native, più leggero, sufficiente per volumi UI/admin.
  • Poetry invece di uv: scartato — uv è 10-100× più veloce, supportato attivamente da Astral.