Technical roadmap · Firebase → own backend

Migration Plan — Sign CRM

From a static SPA wired directly to Firebase to an architecture with its own backend, a relational database, and real per-company data isolation.

Updated 07/07/2026 Scope Frontend + Backend + Data Rollout Incremental, module by module
Context

The current system works and is in production, but security relies only on checks done in the browser. Any authenticated user can, in theory, read and write another company's data. This plan exists to fix that by moving authorization logic and data behind a backend the client never accesses directly.

The 5 changes

01 — Structure

Split frontend and backend

  • Two applications in the same repository: /frontend and /backend
  • Communication only through HTTP endpoints (REST API) — never a direct import of code from one side into the other
  • That rule alone leaves the system ready to become multiple services (e.g. a mobile app) later, without rewriting anything

02 — Backend

Node.js + TypeScript

  • Reuses the logic that already exists today: estimate calculation, job status flow, PDF generation
  • Node.js by itself is just the runtime, not a framework — NestJS is what exposes the endpoints, running on top of Express (swappable for Fastify) and already organizing modules and dependency injection

03 — Data

PostgreSQL instead of Firestore

  • Every company isolated by workspace_id, checked on every query in the backend
  • Authorization (who is admin, who is pending or blocked) validated on the server — no longer just in the browser
  • ORM: Prisma — the most widely used in the market today, type-safe. Kept behind a repository interface in the domain layer, so business rules never depend on the ORM directly

04 — Frontend

React

  • Rewrites the current interface as components
  • Talks only to the backend API — never touches the database directly
  • Frontend validation is UX-only (required fields, format) — never business rules; everything is re-validated on the backend

05 — Internal architecture

Clean Architecture + Hexagonal in the backend

  • Separate layers: domain (business rules) → application (use cases) → infrastructure (database, HTTP)
  • Business rules testable without a database running
  • Swap pieces later — database, framework, adding a mobile app — without touching business rules
Rule

Validation happens on both sides, but with different roles: the backend owns business rules (domain layer) and re-validates everything, always. The frontend only handles UX — required fields, formatting, immediate feedback — it never decides a business rule, and no frontend validation is trusted on its own.

Language

All code is written in English (variables, functions, tables, endpoints, commits), no exceptions. The backend always responds in English — error messages and translation keys, never fixed translated text. The frontend decides the display language — defaulting to the client's browser, with the option to choose manually — reusing the i18n module that already exists.

06 — Execution order

1

Model the Postgres tables

Based on the data that already exists today in Firestore.

2

Build the backend skeleton

Clean Architecture layers + first working endpoint: authentication.

3

Migrate module by module

Clients → Jobs → Expenses → Inventory → the rest. Never all at once.

4

Keep the current system live

Until each new module is validated — so the client never feels the transition.

5

Fix security directly in the new architecture

Per-company isolation, server-side validation, and the public approval page depending on a real token stored in the database — not on URL parameters.