Design Specification · 2026-07-22

Ratecenter — open-source billing for ISPs and telcos

Status: Approved design, pre-implementation ratecenter.app · built by Fibernetics MIT · Go · React · PostgreSQL

1What this is

A ground-up, open-source successor to Freeside — the Perl/Mason billing, CRM, and provisioning platform for ISPs, WISPs, VoIP providers, and hosting companies. Freeside 4.x is ~250k lines of core Perl, ~128k lines of Mason templates, 306+ database tables, and is effectively quiescent (last upstream commit July 2024).

Primary goal: a fully operational billing system that existing Freeside 4.x deployments can migrate to safely and fully accurately. Accuracy of migrated data and generated invoices is the project's non-negotiable bar and is enforced by CI, not by QA.

Audience: open-source community project from day one, with Fibernetics as the loudly-credited creator and flagship production user. The maintainer's own production Freeside deployment is the first migration and the source of the validation corpus, but scope and interfaces are designed for general adoption.

2Decisions of record

DecisionChoice
StackGo API + React/TypeScript UI + PostgreSQL
ArchitectureModular monolith, single binary, UI embedded
LicenseMIT
Migration contractClean new schema; one-way importer from 4.x (no schema compatibility, no sync bridge)
V1 scopeBilling core, CRM, payments, tax, CDR rating, provisioning exports, self-service portal, multi-company/agents, RT integration, 4.x importer
TicketingNot rebuilt — integrate with the operator's existing RT server
Network monitoringTorrus dropped — modern alternatives exist (Prometheus, LibreNMS)
UI principleModern feel, familiar structure — Freeside's menu tree and workflow layout preserved so operators need no retraining
Build approachVertical slices with golden-data validation
Dev environmentDedicated VM/server hosting the 4.2 reference instance, production snapshot, and golden CI runner
RepoMaintainer's GitHub org; goes public once Phase 0 lands (clean-room rule and scaffold in place)
Web presenceratecenter.app (primary; confirmed free 2026-07-22, register promptly) — .io/.systems/.dev also free, recommended as defensive registrations

3Legal ground rules (MIT next to AGPL)

Freeside 4.x is AGPLv3. Ratecenter is MIT. These coexist only under a strict clean-room discipline:

Naming note (resolved 2026-07-22): the project is Ratecenter (ratecenter.app) — named for the telco rate center, the geographic unit that determines call rating, chosen for instant insider recognition with the target audience. Fibernetics is the credited creator and flagship production user ("Ratecenter, the open-source billing system for ISPs and telcos — built by Fibernetics"); a neutral product name avoids competitor-brand friction for adopting telcos and the "Freeside" mark of Freeside Internet Services, Inc. entirely. A formal trademark search is advised before public launch.

4Architecture

4.1 Shape

One Go binary, internally decomposed into domain modules with enforced boundaries. A domain exposes a public Go interface; internals are package-private. Domains may only call each other's public interfaces (enforced by lint/arch tests). This preserves the option to split into services later without paying the microservices tax now — and single-binary distribution is a deliberate adoption feature for the self-hosting ISP audience.

ModuleResponsibility
catalogPackage definitions, pricing, price plans, tax classes
partyCustomers, contacts, service locations, agents (multi-company)
billingBilling runs, proration, invoice generation, credits/voids, event framework (conditions/actions)
paymentsGateway interface + drivers, payment application, refunds, dunning/collections
taxInternal tax tables v1; connector interface for Avalara/SureTax-class services later
provisioningExport framework (queue, retry, driver interface) + drivers (RADIUS, LDAP, DNS, SSH-command, …)
ratingCDR import framework + format parsers, usage rating, usage→invoice flow
portalCustomer self-service API surface (separate principal type)
ticketingREST client for the operator's existing RT server; customer↔ticket linkage
importerFreeside 4.x migration — grows with every phase, never a standalone phase

4.2 Technical choices

4.3 UI

Phase 0 captures the 4.x menu tree and top ~30 staff workflows as the information-architecture contract: same menu names, grouping, and customer-page mental model. What changes is responsiveness: instant type-ahead customer search, no full-page reloads, SSE-driven progress, dark mode, responsive layout.

Reports: every long-running report immediately returns a progress view and streams results (async job + pagination). Deep SQL optimization is deferred, but slowness becomes visible, cancelable, and non-blocking in v1 — no more frozen white pages.

5Migration & validation spine

Two rules hold across all phases:

  1. The importer is never a phase. Each vertical slice extends the importer for its own tables, so migration is continuously exercised from Phase 1 onward.
  2. Accuracy is a CI gate. From Phase 3 onward, CI imports the production snapshot, re-runs historical billing cycles, and line-diffs generated invoices against the real historical ones. A commit that changes an imported invoice by one cent fails the build.

Test corpus: a full copy of the maintainer's production Freeside database, resident on the dedicated VM only. Private data never enters the public repo or leaves the VM; the golden gate runs there as a self-hosted CI runner. Public GitHub Actions runs everything that doesn't need the corpus.

Testing layers:

  1. Unit tests (TDD) on all money/date/proration math.
  2. Per-domain integration tests against real PostgreSQL.
  3. Characterization tests: scripted scenarios executed against the 4.2 reference instance, captured outputs stored as fixtures the new engine must reproduce.
  4. Golden production gate (above).

6Phasing

Nine sub-projects in dependency order. Each gets its own spec → plan → implementation cycle and ends with working software.

PhaseNameDelivers
0Archaeology & harnessjcodemunch index of 4.x; inventory of actually used exports/CDR formats/price plans/gateways/events/reports from production config; dev VM with 4.2 reference instance + snapshot; invoice-diff harness proven against 4.x itself; repo scaffold, CI, graphify, MIT license, module skeleton; IA contract (menu tree + workflows)
1Catalog & partyNew schema for packages/pricing/tax classes; customers/contacts/locations/agents (multi-company native); importer v1 (customers + packages); customer search/view + package browser UI
2Package lifecycleOrder/suspend/cancel/change state machine; event framework skeleton; importer v2 (states + history)
3Billing engineBilling runs, proration, recurring/setup fees, invoice generation, internal tax tables, credits/voids; importer v3 (balances + historical invoices); golden CI gate on, permanently
4Payments & collectionsGateway interface; drivers for the operator's gateways (per Phase 0 inventory) + Stripe as OSS reference; dunning; payment application; refunds
5ProvisioningExport framework (queue/retry/driver interface); starter drivers: RADIUS, LDAP, DNS, SSH-command + inventoried needs; job/queue UI
6CDR & ratingCDR import framework + inventoried formats; rating engine; usage→invoice via Phase 3 engine
7Portal & RTSelf-service portal (view/pay invoices, update card); RT REST integration with customer↔ticket UI linkage
8Cutover kitPre-flight checks, dry-run reports, full reconciliation report, rollback plan, operator runbook — makes migration safe for shops other than the maintainer's

Explicitly deferred past v1: report SQL optimization (pattern in place, tuning later), tax-service connectors (interface in v1), additional gateway/export/CDR drivers beyond inventory (plugin interfaces are the product; drivers accrete by community), any Torrus replacement.

7Tooling & infrastructure

8Risks & mitigations

RiskMitigation
Silent billing inaccuracy (the failure mode of every billing rewrite)Golden production gate in CI from Phase 3; characterization tests; TDD on money math; integer money + decimal boundaries; float lint ban
Business-logic archaeology gaps (20 years of edge cases, no upstream behavioral tests)Phase 0 inventory narrows scope to what's actually used; 4.2 reference instance answers "what does it do?" empirically; jcodemunch for structural questions
Scope explosion (4.x is five products)RT integrated not rebuilt; Torrus dropped; drivers limited to inventory + reference implementations; plugin interfaces carry the long tail
AGPL contamination of MIT codebaseClean-room rule in CONTRIBUTING.md; legacy knowledge enters only as schema docs, behavioral notes, and test fixtures
Trademark exposure on the nameResolved: named Ratecenter (generic telco term, no Freeside mark); formal trademark search before public launch
Schema rework after billing reality hitsVertical slices put the billing engine on the new schema by Phase 3, early enough to correct Phase 1 decisions cheaply

9Success criteria

  1. The maintainer's production Freeside deployment migrates with a clean reconciliation report: every customer, package, balance, and historical invoice accounted for.
  2. Re-running historical billing cycles in Ratecenter reproduces production invoices line-for-line (documented, justified exceptions only).
  3. Staff use the new UI without retraining; the top ~30 workflows land in familiar locations.
  4. Reports never freeze the UI: progress + streaming results from v1.
  5. A stranger can git clone, run one binary against Postgres, and evaluate the product — and a Freeside 4.x shop can run the cutover kit's dry-run against their own data.