Ctrl K
ComunidadGuías…

README.md

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
<!--
  ~ Shields.io Config
  ~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  ~ Default params:
  ~   style=for-the-badge
  ~   labelColor=404C5C
  ~   cacheSeconds=maxAge
  ~
  ~ Brand palette:
  ~   Success 4CAF50 · Error E53935 · Warning FFAB40
  ~   Purple 9C27B0 · Blue-grey 404C5C · Light-blue 039BE5 · Pink E040FB
  -->

<p align="center">
  <a href="https://aglyn.com" title="Go to aglyn.com">
    <img src="docs/assets/readme/cover.png" alt="Aglyn — one platform, zero black boxes" width="100%" />
  </a>
</p>

<h3 align="center">The clickable screen to create online.</h3>

<p align="center">
  <i>Aglyn™ is a multi-tenant website-builder platform that turns a live, clickable canvas<br>
  into a real business website — no code, no ceremony, no expensive rebuilds.</i>
</p>

<p align="center">
  <a href="https://aglyn.com"><strong>aglyn.com</strong></a> &nbsp;·&nbsp;
  <a href="https://app.aglyn.com">Console</a> &nbsp;·&nbsp;
  <a href="https://docs.aglyn.com">Docs</a> &nbsp;·&nbsp;
  <a href="CONTRIBUTING.md">Contributing</a> &nbsp;·&nbsp;
  <a href="https://app.aglyn.com/manage/report-issue">Report a bug</a>
</p>

<p align="center">
  <img src="https://img.shields.io/badge/Aglyn-Secure_Website-9C27B0?style=for-the-badge&labelColor=404C5C&color=9C27B0&logoHeight=40&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCI+PGRlZnM+PGNsaXBQYXRoIGlkPSJiIj48cmVjdCB3aWR0aD0iMjQiIGhlaWdodD0iMjQiLz48L2NsaXBQYXRoPjwvZGVmcz48ZyBpZD0iYSIgY2xpcC1wYXRoPSJ1cmwoI2IpIj48cmVjdCB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIGZpbGw9IiM0MDRjNWMiLz48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzLjEyOCAyLjYyOSkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAgMC43KSI+PHBhdGggZD0iTTE3LjQyMiwxOC41ODNIMTUuMjY5bC0yLjY3My01LjhINS40NTNMMi44LDE4LjU4M0guNTU3bDguMTg0LTE4aC42MTVabS01Ljc0OC03Ljg1M0w5LjA0OCw0Ljg4OCw2LjQsMTAuNzMxWiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTAuNTU3IC0wLjU4MykiIGZpbGw9IiMwMzliZTUiLz48L2c+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMSAwLjM0NikiPjxwYXRoIGQ9Ik0xNy40MjIsMTguNTgzSDE1LjI2OWwtMi42NzMtNS44SDUuNDUzTDIuOCwxOC41ODNILjU1N2w4LjE4NC0xOGguNjE1Wm0tNS43NDgtNy44NTNMOS4wNDgsNC44ODgsNi40LDEwLjczMVoiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0wLjU1NyAtMC41ODMpIiBmaWxsPSIjOWMyN2IwIi8+PC9nPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDIpIj48cGF0aCBkPSJNMTcuNDIyLDE4LjU4M0gxNS4yNjlsLTIuNjczLTUuOEg1LjQ1M0wyLjgsMTguNTgzSC41NTdsOC4xODQtMThoLjYxNVptLTUuNzQ4LTcuODUzTDkuMDQ4LDQuODg4LDYuNCwxMC43MzFaIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMC41NTcgLTAuNTgzKSIgZmlsbD0iI2ZmZiIvPjwvZz48L2c+PC9nPjwvc3ZnPg==" alt="Aglyn secure website"/>
  <img src="https://img.shields.io/github/license/aglyn/aglyn?style=for-the-badge&labelColor=404C5C&color=4CAF50" alt="License" />
  <img src="https://img.shields.io/github/package-json/v/aglyn/aglyn?style=for-the-badge&labelColor=404C5C&color=039BE5&label=version" alt="Version" />
</p>

<p align="center">
  <img src="https://img.shields.io/badge/Next.js-16-000000?style=for-the-badge&labelColor=404C5C&logo=nextdotjs" alt="Next.js" />
  <img src="https://img.shields.io/badge/React-19-087EA4?style=for-the-badge&labelColor=404C5C&logo=react" alt="React" />
  <img src="https://img.shields.io/badge/TypeScript-6/7-3178C6?style=for-the-badge&labelColor=404C5C&logo=typescript&logoColor=white" alt="TypeScript" />
  <img src="https://img.shields.io/badge/Firebase-12-FFCA28?style=for-the-badge&labelColor=404C5C&logo=firebase&logoColor=white" alt="Firebase" />
  <img src="https://img.shields.io/badge/MUI-9-007FFF?style=for-the-badge&labelColor=404C5C&logo=mui&logoColor=white" alt="MUI" />
  <img src="https://img.shields.io/badge/MobX-6-FF9955?style=for-the-badge&labelColor=404C5C&logo=mobx&logoColor=white" alt="MobX" />
  <img src="https://img.shields.io/badge/Nx-23-143055?style=for-the-badge&labelColor=404C5C&logo=nx&logoColor=white" alt="Nx" />
  <img src="https://img.shields.io/badge/Node-%E2%89%A524-5FA04E?style=for-the-badge&labelColor=404C5C&logo=nodedotjs&logoColor=white" alt="Node 24+" />
</p>

<hr/>

## ✨ What is Aglyn?

Aglyn takes the pain out of getting a professional website off the ground. Instead of hiring
engineers or wrestling with templates, you build on a **live, clickable canvas** — the _Besigner™_ —
where what you click is what you ship. Every element, page, and interaction is editable in place, and
publishing is instant across a globally-served, multi-tenant runtime.

It's a full platform, not just an editor: organizations, billing, a plugin marketplace, a digital
asset manager, e-commerce, bookings, email, workflows, and a documented REST API all live under one
roof.

> **Three surfaces, one platform**
> · [`aglyn.com`](https://aglyn.com) — the marketing site
> · [`app.aglyn.com`](https://app.aglyn.com) — where you build, manage orgs & billing
> · `aglyn.app` + your own custom domain — where your published site is served to the world

## 📸 Take a look

<p align="center">
  <img src="docs/assets/readme/besigner-editor.png" alt="The Aglyn Besigner — a clickable, in-place editing canvas" width="100%" />
</p>

<p align="center"><i><b>The Besigner™</b> — a clickable, in-place canvas where design and content live on the same surface. What you click is what you ship.</i></p>

<table>
  <tr>
    <td width="50%" align="center" valign="top">
      <img src="docs/assets/readme/console-dashboard.png" alt="Aglyn console dashboard" width="100%" />
      <br /><sub><b>Console dashboard</b> — traffic, users, campaigns & activity at a glance</sub>
    </td>
    <td width="50%" align="center" valign="top">
      <img src="docs/assets/readme/console-commerce.png" alt="Aglyn commerce products hub" width="100%" />
      <br /><sub><b>Built-in commerce</b> — products, pricing, orders & POS</sub>
    </td>
  </tr>
</table>

## 🚀 Highlights

| | |
|---|---|
| 🖱️ **Besigner canvas** | A clickable, in-place visual editor — design and content on the same surface. |
| 🌐 **True multi-tenancy** | One runtime serves every customer site, on `aglyn.app` or a custom domain, with ISR. |
| 🧩 **Plugin platform** | Commerce, Bookings, Contacts, Email, Events, Workflows, Redirects & more — installable per org, with a review-queued marketplace. |
| 🎨 **Theme & layout builder** | Design tokens, themes, and layout templates that stay consistent across every page. |
| 🖼️ **Digital Asset Manager** | Drag-and-drop media, folders, custom metadata, and stable CDN URLs that survive replace & move. |
| 🛒 **Built-in commerce** | Products, pricing, POS, and digital goods powered by Stripe. |
| 🔐 **Security first** | Firebase Auth with email-verify gates, durable rate limiting, CSRF protection, and rules-tested Firestore. |
| ⚡ **Modern stack** | Next.js App Router, React 19, server components, and an Nx-orchestrated monorepo. |
| 🔌 **Customer REST API** | Scoped `aglyn_sk_` API keys for programmatic access on Business plans. |
| 📚 **Docs that ship with the code** | Four Docusaurus instances (docs, api, learn, help) kept in sync with features. |

## 🏗️ Inside the monorepo

An [Nx](https://nx.dev) workspace organized into deployable **apps** and shareable **libs**.

```
aglyn/
├─ apps/
│  ├─ 🛠️ console     → dashboard, editor, billing    (app.aglyn.com)
│  ├─ 🚀 tenant      → runtime for published sites   (aglyn.app + custom domains)
│  └─ 📖 docs        → Docusaurus documentation
│
├─ libs/
│  ├─ aglyn                 → core platform library
│  ├─ aglyn-node-renderer   → server-side page renderer
│  ├─ besigner/             → the clickable visual editor (core + designer)
│  ├─ tenant/runtime        → shared tenant runtime (host events + composition)
│  ├─ plugins/              → bookings · commerce · contacts · data · email
│  │                          events-calendar · inbox · logic · marketing
│  │                          marketplace · mui · redirects · workflows
│  └─ shared/               → data · ui · util building blocks
│       ├─ data/  → enums · forms · mdi · regex · types
│       ├─ ui/    → jsx · jsx-forms · theme · color-picker · json-editor · next · …
│       └─ util/  → dom · email · errors · fbserver · http · logger · …
│
└─ cloud/          → Firebase (functions, Firestore/Storage rules, Remote Config)
```

**Library conventions** — each lib is one of four types, so dependencies stay predictable:

- **Feature** — smart UI with data access, for a specific business use case.
- **UI** — presentational ("dumb") components only.
- **Data-access** — back-end interaction and state management.
- **Utility** — low-level helpers shared broadly.

## 🧰 Tech stack

| Area | Tools |
|---|---|
| **Framework** | Next.js 16 (App Router, RSC) · React 19 |
| **Language** | TypeScript (dual `typescript@6` bridge + `@typescript/native@7` for `tsc`) |
| **UI** | MUI 9 · MobX 6 · Data-Driven Forms 4 |
| **Backend** | Firebase (Auth, Firestore, Storage, Remote Config) · Cloud Functions · `firebase-admin` 14 |
| **Payments & email** | Stripe · Resend |
| **Monorepo** | Nx 23 |
| **Testing** | Jest 30 (unit) · Playwright + Firebase emulators (e2e) |
| **Runtime** | Node ≥ 24 |

## ⚡ Quick start

> **Prerequisites:** Node ≥ 24, npm, and the [Firebase CLI](https://firebase.google.com/docs/cli)
> for local emulation.

```bash
# 1. Install dependencies
npm install

# 2. Copy the example environment and fill in the blanks
cp .env.example .env

# 3. Serve an app (console, tenant, or docs)
npx nx serve console
```

The dev server hot-reloads on http://localhost:4200. Use `--prod` for a production build.

### Run against the Firebase emulators

```bash
# Start the emulators (imports/exports local data)
firebase emulators:start --import=./.firebase --export-on-exit

# Serve the console wired to the emulators
npm run serve:console:emulated
```

Default emulator hosts: Firestore `localhost:8082`, Auth `localhost:9099`. See
[`docs/E2E_LOCAL.md`](docs/E2E_LOCAL.md) for the full local end-to-end recipe.

## 🐳 Self-hosting

Run the whole platform on your own infrastructure with Docker — any cloud, a
VPS, or bare metal — pointed at **your own Firebase project** and your own
Stripe/Resend keys:

```bash
cp .env.selfhost.example .env.selfhost   # fill it in
docker compose up --build
```

Console on `:4200`, published sites on `:4500`, your reverse proxy in front.
The full runbook — Firebase project setup, security-rules deploy, DNS, and the
honest limits (Firebase is required; the in-console custom-domain flow is
Vercel-only) — lives in [`docs/SELF_HOSTING.md`](docs/SELF_HOSTING.md).

## 🛠️ Common commands

| Task | Command |
|---|---|
| Serve an app | `nx serve <app>` (`--prod` for production) |
| Build an app | `nx build <app>` → output in `dist/` |
| Unit tests | `nx test <app>` · affected only: `nx affected:test` |
| E2E tests | `nx e2e <app-e2e>` · affected only: `nx affected:e2e` |
| Lint | `nx lint` · workspace: `npm run lint` |
| Type-check | `npm run typecheck` |
| Format | `npm run format` |
| Dependency graph | `nx graph` |
| Check/reclaim dev-cache disk | `npm run clean:next` · delete: `npm run clean:next:prune` |

> **Tools suddenly failing with `ENOSPC`, hanging, or killing your shell?** Check the disk before
> anything else — `apps/*/.next/dev/cache/turbopack` grows across a long dev session and has twice
> filled a 460 GB volume. Nothing in the error will mention the disk. See
> [Build performance](docs/BUILD_PERFORMANCE.md#if-your-tools-start-failing-for-no-reason-check-the-disk-first-agl-1425).

Scaffolding new projects:

```bash
nx g @nx/next:app <app-name>     # new Next.js app
nx g @nx/react:lib <lib-name>    # new React library
nx g @nx/react:component <name> --project=<app>
```

Libraries are shareable and imported as `@aglyn/<name>` (e.g. `@aglyn/shared-ui-jsx`).

## 📖 Documentation

📚 **Full product & developer docs live at [docs.aglyn.com](https://docs.aglyn.com).**

Repo-local deep-dives live in [`docs/`](docs), including:

- [Self-hosting](docs/SELF_HOSTING.md) · [Multi-tenant Firestore](docs/MULTI_TENANT_FIRESTORE.md) · [Platform provisioning](docs/PLATFORM_PROVISIONING.md)
- [Plugin loading](docs/PLUGIN_LOADING.md) · [Plugin platform gaps](docs/PLUGIN_PLATFORM_GAPS.md)
- [Rate limiting](docs/RATE_LIMITING.md) · [Security content review](docs/SECURITY_CONTENT_REVIEW.md) · [Analytics event taxonomy](docs/ANALYTICS.md)
- [Email setup](docs/EMAIL_SETUP.md) · [Stripe go-live](docs/STRIPE_GO_LIVE.md) · [Commerce token signing](docs/COMMERCE_TOKEN_SIGNING.md)
- [Vercel deployments](docs/VERCEL_DEPLOYMENTS.md) · [Build performance](docs/BUILD_PERFORMANCE.md) · [TypeScript 7](docs/TYPESCRIPT7.md)
- [Backfills, migrations and seeds](docs/BACKFILLS_AND_SEEDS.md) · [Commerce backfills](docs/COMMERCE_BACKFILLS.md) · [CRM lifecycle backfill](docs/CRM_LIFECYCLE_BACKFILL.md)

## 🤝 Contributing

We follow [Conventional Commits](https://www.conventionalcommits.org) — commit messages are linted.

```
<type>[(optional-scope)]: <description>

[optional body]

[optional footer(s)]
```

Common types: `feat` (new feature → minor), `fix` (bug patch → patch), plus `build`, `chore`, `ci`,
`docs`, `style`, `refactor`, `perf`, `test`, and `revert`. A `!` after the type/scope or a
`BREAKING CHANGE:` footer signals a major change.

See [CONTRIBUTING.md](CONTRIBUTING.md), the [Code of Conduct](CODE_OF_CONDUCT.md), and
[SECURITY.md](SECURITY.md) before opening a PR.

## 🌍 Terminology

- **Organization** — the entity that owns sites, members, and billing.
- **Workspace** — the UX word for an organization's working area.
- **Tenant** — a site at runtime (the served, published surface only).
- **Besigner** — Aglyn's clickable visual editor.
- **Plugin / Add-on** — pluggable, first- or third-party modules that extend an org or app while
  respecting its architecture.
- **Extension** — deeper, non-standard integrations that modify default behavior; typically
  third-party authored.

<hr/>

<h3 align="center">Connect with us</h3>

<p align="center">
  <a href="https://www.linkedin.com/company/aglyn" title="LinkedIn">
    <img src="https://img.shields.io/badge/LinkedIn-Follow-0A66C2?logo=linkedin&style=for-the-badge&labelColor=F1F1F1&logoColor=0A66C2&color=0A66C2" alt="LinkedIn" />
  </a>&nbsp;
  <a href="https://x.com/AglynSoftware" title="X">
    <img src="https://img.shields.io/badge/@AglynSoftware-Follow-000000?logo=x&style=for-the-badge&labelColor=F1F1F1&logoColor=000000&color=000000" alt="X" />
  </a>&nbsp;
  <a href="https://www.facebook.com/AglynSoftware/" title="Facebook">
    <img src="https://img.shields.io/badge/Facebook-Follow-1877F2?logo=facebook&style=for-the-badge&labelColor=F1F1F1&logoColor=1877F2&color=1877F2" alt="Facebook" />
  </a>&nbsp;
  <a href="https://www.instagram.com/aglyn_software/" title="Instagram">
    <img src="https://img.shields.io/badge/Instagram-Follow-E4405F?logo=instagram&style=for-the-badge&labelColor=F1F1F1&logoColor=E4405F&color=E4405F" alt="Instagram" />
  </a>
</p>

<p align="center">
  <a href="https://www.tiktok.com/@aglyn_software" title="TikTok">
    <img src="https://img.shields.io/badge/TikTok-Follow-000000?logo=tiktok&style=for-the-badge&labelColor=F1F1F1&logoColor=000000&color=000000" alt="TikTok" />
  </a>&nbsp;
  <a href="https://www.youtube.com/Aglyn" title="YouTube">
    <img src="https://img.shields.io/badge/YouTube-Subscribe-FF0000?logo=youtube&style=for-the-badge&labelColor=F1F1F1&logoColor=FF0000&color=FF0000" alt="YouTube" />
  </a>&nbsp;
  <a href="https://www.crunchbase.com/organization/aglyn" title="Crunchbase">
    <img src="https://img.shields.io/badge/Crunchbase-Aglyn-0288D1?logo=crunchbase&style=for-the-badge&labelColor=F1F1F1&logoColor=0288D1&color=0288D1" alt="Crunchbase" />
  </a>&nbsp;
  <a href="https://github.com/aglyn" title="GitHub org">
    <img src="https://img.shields.io/badge/GitHub-aglyn-181717?logo=github&style=for-the-badge&labelColor=F1F1F1&logoColor=181717&color=404C5C" alt="GitHub" />
  </a>
</p>

<h2 align="center">About Aglyn</h2>

<p align="center">
  Aglyn LLC is a distributed technology company building the clickable way to create online.
  We're improving the no-code web-development market by shrinking the distance between an idea and a
  live, professional website — easing maintenance and minimizing the expensive engineering work a
  business site usually demands.
</p>

<hr/>

<p align="center">
  <a href="LICENSE"><strong>Apache License 2.0</strong></a> · © Aglyn LLC
</p>