# fmorar/easyrent architecture

> Architecture diagram of the GitHub repository fmorar/easyrent, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-05-12). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/fmorar/easyrent
- Repository: https://github.com/fmorar/easyrent

## Overview

1. This is a Next.js App Router application that acts as a real-estate operations platform, not just a marketing site. The UI is split into route groups for authenticated workspace, public-facing pages, auth flows, and an “unbranded” share surface.

2. The highest-level boundary is between server-rendered pages/components and client-side interactive forms. Most domain screens live under `src/app/[locale]/(dashboard)` and `src/app/[locale]/(public)`, with many client components in `src/components/*` handling editing, dialogs, tables, maps, and uploaders.

3. Supabase is the core backend. `src/lib/supabase/{server,client,admin}.ts` provides the three main access modes, while `supabase/migrations/*` defines the data model, RLS, RPCs, storage policies, and feature-specific tables. The app relies on Supabase for auth, Postgres, storage, and public token-based report access.

4. The domain is centered on properties, projects, agents, leads, contracts, market analysis, and performance reporting. Each domain has its own action layer in `src/lib/actions/*`, UI in `src/components/<domain>/*`, and pages/API routes under `src/app/...`. This keeps CRUD flows, analytics flows, and public sharing flows separated.

5. Server actions appear to be the primary mutation path for standard workspace operations. Forms such as property/project/contract/report editors likely submit through these actions, which then persist to Supabase and may trigger enrichment, media handling, or document generation.

6. Heavy or long-running operations are exposed as API routes under `src/app/api/*`. These include contract generation/export/finalization, market-report and performance-report runs/PDFs, property voice intake, photo zip exports, and public report fetches by token. This is the boundary for work that is not simple form submission.

7. AI and document automation are first-class subsystems. `src/lib/contracts/*`, `src/lib/market-analysis/openai-report-service.ts`, `src/lib/property-performance/openai-owner-summary-service.ts`, and `src/lib/ai/*` indicate OpenAI-backed generation/rewrite/extraction flows for contracts, market reports, property-performance insights, and text cleanup.

8. Market analysis has its own pipeline: crawler adapters in `src/lib/market-analysis/crawler/adapters/*`, fetch/normalize logic, comparables scoring, pricing, FX conversion, and PDF rendering. The outputs feed both internal dashboards and public report pages, with tokenized public RPCs in the database.

9. Property-performance reporting is another pipeline with its own extraction, scoring, recommendation, analytics, and PDF services. It likely combines listing metadata, engagement analytics, and AI-generated summaries to produce owner-facing reports and dashboards.

10. Sharing and public visibility are explicit architectural concerns. Projects, properties, and reports can be published through tokenized links, branded/unbranded pages, and share dialogs/buttons. The app distinguishes internal workspace views from public report and marketplace views.

11. Internationalization is built into the route structure. There are localized routes under `src/app/[locale]`, message catalogs in `messages/en.json` and `messages/es.json`, and navigation/request helpers in `src/i18n/*`. That means locale resolution affects routing, layout, and content rendering across the app.

12. External integrations matter to the architecture: Google Places/geocoding for address and location workflows, likely PostHog for analytics (`src/components/analytics/*`, `src/lib/analytics/*`), and Supabase storage for uploads such as avatars, covers, property photos, videos, and generated documents.

13. The supporting UI layer is a reusable component library in `src/components/ui` plus domain-specific shells, sidebars, headers, and public-site sections. This keeps presentation concerns separate from the domain services and data-access layers.

14. Overall, the architecture is a three-part system: a localized Next.js frontend, a Supabase/Postgres-backed domain and auth layer, and a set of specialized generation/analysis pipelines for contracts, market reports, and performance reports. The key diagram boundaries should show workspace CRUD, public share/report access, and asynchronous AI/report-generation flows.

Main entry points: [`src/app/[locale]/(dashboard)/layout.tsx`](https://github.com/fmorar/easyrent/blob/main/src/app/[locale]/(dashboard)/layout.tsx) (Workspace), [`src/lib/actions`](https://github.com/fmorar/easyrent/tree/main/src/lib/actions) (Server actions), [`src/app/[locale]/layout.tsx`](https://github.com/fmorar/easyrent/blob/main/src/app/[locale]/layout.tsx) (Locale shell), [`src/app/api`](https://github.com/fmorar/easyrent/tree/main/src/app/api) (API routes)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_app["App routes"]
  node_locale_shell["Locale shell<br/>nextjs layout<br/>[layout.tsx]"]
  node_workspace_shell["Workspace<br/>dashboard layout<br/>[layout.tsx]"]
  node_public_shell["Public site<br/>public layout<br/>[layout.tsx]"]
  node_auth_shell["Auth flow<br/>auth layout<br/>[layout.tsx]"]
  node_api_routes["API routes<br/>server endpoints"]
end

subgraph group_components["UI layer"]
  node_ui_kit["UI kit<br/>shared components"]
  node_layout_components["Shell UI<br/>layout components"]
  node_property_components["Property UI<br/>domain components"]
  node_project_components["Project UI<br/>domain components"]
  node_contract_components["Contract UI<br/>domain components"]
  node_report_components["Report UI<br/>report components"]
  node_share_components["Sharing UI<br/>sharing components"]
end

subgraph group_services["Domain services"]
  node_actions["Server actions<br/>mutation layer"]
  node_contract_pipeline["Contract engine<br/>generation service"]
  node_market_pipeline["Market analysis<br/>analysis pipeline"]
  node_performance_pipeline["Performance reports<br/>analysis pipeline"]
  node_i18n["i18n<br/>routing helpers<br/>[request.ts]"]
end

subgraph group_data["Data platform"]
  node_supabase_server[("Supabase server<br/>db access<br/>[server.ts]")]
  node_supabase_client[("Supabase client<br/>db access<br/>[client.ts]")]
  node_supabase_admin[("Supabase admin<br/>db access<br/>[admin.ts]")]
  node_schema[("Schema<br/>migrations")]
end

node_locale_shell -->|"routes"| node_workspace_shell
node_locale_shell -->|"routes"| node_public_shell
node_locale_shell -->|"routes"| node_auth_shell
node_locale_shell -->|"resolves locale"| node_i18n
node_workspace_shell -->|"uses"| node_layout_components
node_public_shell -->|"uses"| node_layout_components
node_workspace_shell -->|"renders"| node_property_components
node_workspace_shell -->|"renders"| node_project_components
node_workspace_shell -->|"renders"| node_contract_components
node_workspace_shell -->|"shares"| node_share_components
node_public_shell -->|"renders"| node_report_components
node_public_shell -->|"publishes"| node_share_components
node_property_components -->|"builds on"| node_ui_kit
node_project_components -->|"builds on"| node_ui_kit
node_contract_components -->|"builds on"| node_ui_kit
node_actions -->|"reads/writes"| node_supabase_server
node_actions -->|"hydrates"| node_supabase_client
node_actions -->|"privileged ops"| node_supabase_admin
node_actions -->|"persists"| node_schema
node_contract_pipeline -->|"loads data"| node_supabase_server
node_contract_pipeline -->|"exports"| node_supabase_admin
node_market_pipeline -->|"stores results"| node_supabase_server
node_market_pipeline -->|"public token RPC"| node_supabase_admin
node_performance_pipeline -->|"stores results"| node_supabase_server
node_performance_pipeline -->|"public token RPC"| node_supabase_admin
node_api_routes -->|"executes"| node_contract_pipeline
node_api_routes -->|"executes"| node_market_pipeline
node_api_routes -->|"executes"| node_performance_pipeline
node_api_routes -->|"delegates"| node_actions
node_schema -->|"defines data"| node_actions

click node_locale_shell "https://github.com/fmorar/easyrent/blob/main/src/app/[locale]/layout.tsx"
click node_workspace_shell "https://github.com/fmorar/easyrent/blob/main/src/app/[locale]/(dashboard)/layout.tsx"
click node_public_shell "https://github.com/fmorar/easyrent/blob/main/src/app/[locale]/(public)/layout.tsx"
click node_auth_shell "https://github.com/fmorar/easyrent/blob/main/src/app/[locale]/(auth)/layout.tsx"
click node_api_routes "https://github.com/fmorar/easyrent/tree/main/src/app/api"
click node_ui_kit "https://github.com/fmorar/easyrent/tree/main/src/components/ui"
click node_layout_components "https://github.com/fmorar/easyrent/tree/main/src/components/layout"
click node_property_components "https://github.com/fmorar/easyrent/tree/main/src/components/property"
click node_project_components "https://github.com/fmorar/easyrent/tree/main/src/components/project"
click node_contract_components "https://github.com/fmorar/easyrent/tree/main/src/components/contracts"
click node_report_components "https://github.com/fmorar/easyrent/tree/main/src/components/public-report"
click node_share_components "https://github.com/fmorar/easyrent/tree/main/src/components/sharing"
click node_actions "https://github.com/fmorar/easyrent/tree/main/src/lib/actions"
click node_contract_pipeline "https://github.com/fmorar/easyrent/blob/main/src/lib/contracts/contract-generation-service.ts"
click node_market_pipeline "https://github.com/fmorar/easyrent/blob/main/src/lib/market-analysis/openai-report-service.ts"
click node_performance_pipeline "https://github.com/fmorar/easyrent/blob/main/src/lib/property-performance/openai-owner-summary-service.ts"
click node_supabase_server "https://github.com/fmorar/easyrent/blob/main/src/lib/supabase/server.ts"
click node_supabase_client "https://github.com/fmorar/easyrent/blob/main/src/lib/supabase/client.ts"
click node_supabase_admin "https://github.com/fmorar/easyrent/blob/main/src/lib/supabase/admin.ts"
click node_schema "https://github.com/fmorar/easyrent/tree/main/supabase/migrations"
click node_i18n "https://github.com/fmorar/easyrent/blob/main/src/i18n/request.ts"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_locale_shell,node_workspace_shell,node_public_shell,node_auth_shell,node_api_routes toneBlue
class node_ui_kit,node_layout_components,node_property_components,node_project_components,node_contract_components,node_report_components,node_share_components toneAmber
class node_actions,node_contract_pipeline,node_market_pipeline,node_performance_pipeline,node_i18n toneMint
class node_supabase_server,node_supabase_client,node_supabase_admin,node_schema toneRose
```

## Components

### App routes

Localized route groups, page shells, and API boundaries.

- [Locale shell](https://github.com/fmorar/easyrent/blob/main/src/app/[locale]/layout.tsx): nextjs layout · Locale-aware root that coordinates routing and content across the app. · `src/app/[locale]/layout.tsx`
- [Workspace](https://github.com/fmorar/easyrent/blob/main/src/app/[locale]/(dashboard)/layout.tsx): dashboard layout · Authenticated workspace area for CRUD screens and operational workflows. · `src/app/[locale]/(dashboard)/layout.tsx`
- [Public site](https://github.com/fmorar/easyrent/blob/main/src/app/[locale]/(public)/layout.tsx): public layout · Public-facing pages, marketplace, projects, agents, and report views. · `src/app/[locale]/(public)/layout.tsx`
- [Auth flow](https://github.com/fmorar/easyrent/blob/main/src/app/[locale]/(auth)/layout.tsx): auth layout · Login, invite acceptance, and password reset flows. · `src/app/[locale]/(auth)/layout.tsx`
- [API routes](https://github.com/fmorar/easyrent/tree/main/src/app/api): server endpoints · Heavy or asynchronous operations such as generation, export, run, and token fetch flows. · `src/app/api`

### UI layer

Reusable shells, domain editors, and presentation components.

- [UI kit](https://github.com/fmorar/easyrent/tree/main/src/components/ui): shared components · Reusable low-level controls used across forms, dialogs, tables, and sheets. · `src/components/ui`
- [Shell UI](https://github.com/fmorar/easyrent/tree/main/src/components/layout): layout components · Headers, sidebars, footers, locale switcher, and other global chrome. · `src/components/layout`
- [Property UI](https://github.com/fmorar/easyrent/tree/main/src/components/property): domain components · Property forms, galleries, maps, uploaders, and ownership/contact controls. · `src/components/property`
- [Project UI](https://github.com/fmorar/easyrent/tree/main/src/components/project): domain components · Project editors, previews, FAQ, amenities, property links, and sharing controls. · `src/components/project`
- [Contract UI](https://github.com/fmorar/easyrent/tree/main/src/components/contracts): domain components · Contract editor, data form, export actions, validation banners, and status views. · `src/components/contracts`
- [Report UI](https://github.com/fmorar/easyrent/tree/main/src/components/public-report): report components · Public market and property-performance report renderers and supporting charts. · `src/components/public-report`
- [Sharing UI](https://github.com/fmorar/easyrent/tree/main/src/components/sharing): sharing components · Share dialogs, public links, and publication prompts for projects and properties. · `src/components/sharing`

### Domain services

Server actions, AI pipelines, and report generation logic.

- [Server actions](https://github.com/fmorar/easyrent/tree/main/src/lib/actions): mutation layer · Primary mutation boundary for workspace CRUD, enrichment, and sharing flows. · `src/lib/actions`
- [Contract engine](https://github.com/fmorar/easyrent/blob/main/src/lib/contracts/contract-generation-service.ts): generation service · Prefill, template health, generation, description cleanup, and export services for contracts. · `src/lib/contracts/contract-generation-service.ts`
- [Market analysis](https://github.com/fmorar/easyrent/blob/main/src/lib/market-analysis/openai-report-service.ts): analysis pipeline · Crawler, normalization, pricing, comparables, FX, PDF, and OpenAI report generation. · `src/lib/market-analysis/openai-report-service.ts`
- [Performance reports](https://github.com/fmorar/easyrent/blob/main/src/lib/property-performance/openai-owner-summary-service.ts): analysis pipeline · Extraction, scoring, recommendations, owner summaries, and PDF generation for performance reports. · `src/lib/property-performance/openai-owner-summary-service.ts`
- [i18n](https://github.com/fmorar/easyrent/blob/main/src/i18n/request.ts): routing helpers · Locale routing and request helpers used by localized pages and navigation. · `src/i18n/request.ts`

### Data platform

Supabase access modes and schema/migrations.

- [Supabase server](https://github.com/fmorar/easyrent/blob/main/src/lib/supabase/server.ts): db access · Server-side authenticated database and storage access. · `src/lib/supabase/server.ts`
- [Supabase client](https://github.com/fmorar/easyrent/blob/main/src/lib/supabase/client.ts): db access · Browser-side Supabase access for interactive client components. · `src/lib/supabase/client.ts`
- [Supabase admin](https://github.com/fmorar/easyrent/blob/main/src/lib/supabase/admin.ts): db access · Privileged service access used for backend-only operations and tokenized public reads. · `src/lib/supabase/admin.ts`
- [Schema](https://github.com/fmorar/easyrent/tree/main/supabase/migrations): migrations · Postgres schema, RLS, RPCs, storage policies, and feature tables. · `supabase/migrations`

## Connections

- Locale shell → Workspace: routes · Locale-aware routes branch into authenticated workspace pages.
- Locale shell → Public site: routes · Locale-aware routes branch into public-facing pages and reports.
- Locale shell → Auth flow: routes · Locale-aware routes branch into login, invite, and reset flows.
- Locale shell → i18n: resolves locale · Locale resolution and navigation helpers drive routing and content selection.
- Workspace → Shell UI: uses · Workspace pages compose shared headers, sidebars, and topbars.
- Public site → Shell UI: uses · Public pages compose global headers, footers, and mobile navigation.
- Workspace → Property UI: renders · Property workspace screens use property editors, maps, uploads, and preview components.
- Workspace → Project UI: renders · Project workspace screens use project editors, previews, and share controls.
- Workspace → Contract UI: renders · Contract workspace screens use contract editors and export UI.
- Workspace → Sharing UI: shares · Workspace views expose publication dialogs, links, and share prompts.
- Public site → Report UI: renders · Public report pages render market-analysis and property-performance reports.
- Public site → Sharing UI: publishes · Public-facing entities expose share links and publication entry points.
- Property UI → UI kit: builds on · Property UI is composed from shared inputs, tables, dialogs, and tabs.
- Project UI → UI kit: builds on · Project UI is composed from shared inputs, dialogs, and tables.
- Contract UI → UI kit: builds on · Contract UI is composed from shared inputs, editors, and status primitives.
- Server actions → Supabase server: reads/writes · Server actions use authenticated Supabase access for workspace mutations.
- Server actions → Supabase client: hydrates · Client forms and interactive screens pair with browser Supabase access.
- Server actions → Supabase admin: privileged ops · Some actions rely on admin access for backend-only operations.
- Server actions → Schema: persists · Actions operate over the Supabase/Postgres schema and policies.
- Contract engine → Supabase server: loads data · Contract generation and export services read workspace data from Supabase.
- Contract engine → Supabase admin: exports · Export/finalization flows use privileged access when needed.
- Market analysis → Supabase server: stores results · Market analysis persists report state and compares data through Supabase.
- Market analysis → Supabase admin: public token RPC · Public market report access is backed by privileged token-based database calls.
- Performance reports → Supabase server: stores results · Performance report runs and summaries persist through Supabase.
- Performance reports → Supabase admin: public token RPC · Public performance report access uses token-based database reads.
- API routes → Contract engine: executes · Contract API routes trigger generation, export, and finalize workflows.
- API routes → Market analysis: executes · Market-report API routes run analysis and render PDFs.
- API routes → Performance reports: executes · Performance-report API routes run analysis and render PDFs.
- API routes → Server actions: delegates · Some endpoints reuse the standard server-action mutation layer.
- Schema → Server actions: defines data · Schema migrations define the tables and RPCs consumed by workspace actions.
