npm package: @flowaitec/corex-app
Description: **`create-org-app`** é um *framework modular e orientado a eventos* para construção de aplicações escaláveis, distribuídas e multi-driver.
Latest version: 0.0.1

# 🧩 create-org-app

**`create-org-app`** é um *framework modular e orientado a eventos* para construção de aplicações escaláveis, distribuídas e multi-driver.

Suporta **HTTP**, **WebSocket**, **NATS**, **Redis**, **BullMQ**, **gRPC** e muito mais — oferecendo um ecossistema completo para desenvolvimento de **microserviços**, **SaaS**, **sistemas reativos** e **plataformas de automação**.

---

## 🚀 Visão Geral

A biblioteca fornece uma estrutura unificada para organizar e executar:

* **Serviços** (`app/services`)
* **Eventos** (`app/events`)
* **Entidades e DTOs** (`core/entities`)
* **Bibliotecas internas** (`core/libs`)
* **Utilitários globais** (`core/utils`)
* **Infraestrutura (DB, Web, Workers, etc.)** (`infra/*`)
* **Fluxo de inicialização e encerramento controlado** (`index.js` e `start.js`)

---

## 📦 Instalação

```bash
npm install create-org-app
```

---

## 📁 Estrutura Geral

```
src/
├── app/
│   ├── services/
│   │   └── test/app.js
│   └── events/
│       └── test/app.js
│
├── core/
│   ├── entities/
│   │   └── user.js
│   ├── libs/
│   │   └── password.js
│   └── utils/
│       └── auth.js
│
├── infra/
│   ├── db/
│   │   └── index.js
│   ├── repositories/
│   │   └── test/app.js
│   ├── web/
│   │   ├── http.js
│   │   ├── routers/
│   │   │   └── test.js
│   │   └── ws/
│   │       └── test.js
│   └── workers/
│       └── worker.js
│
├── start.js
└── index.js
```

---

## ⚙️ Ciclo de Vida da Aplicação

### `index.js`

```js
export default {
  async bootstrap({ core }) {
    core.service("test.app").execute({});
    /* 
    core.driver("nats").command("test.app1", { name: "ssssss" }, {
      apiKey: "sssss"
    });
    */
  },

  async distroy(core) {
    console.log("close", e);
  }
};
```

| Método                | Momento  | Descrição                                                                              |
| --------------------- | -------- | -------------------------------------------------------------------------------------- |
| `bootstrap({ core })` | Startup  | Executado na inicialização. Ideal para pré-carregar serviços, listeners e integrações. |
| `distroy(core)`       | Shutdown | Executado no encerramento da aplicação, para limpar conexões e recursos.               |

---

## 🚀 start.js

```js
import { app } from "../esm/index.js";
// import { app } from "create-org-app";

await app.run({
  drivers: [
    /* { type: "nats", name: "nats", config: { servers: process.env.NATS_URL } }, */
  ],
  servers: [
    { type: "http", rootPath: "" },
    /* { type: "nats", driver: "nats", services: ["test.*"] } */
  ]
});
```

---

## 🧩 Estrutura Avançada — Exemplo Completo

A seguir, um exemplo de integração entre todos os módulos principais, com suporte a **eventos, serviços, entidades, DB, Web, WS e Workers**.

---

### 🧠 Eventos (`app/events/test/app.js`)

```js
// Evento interno (Node)
export default () => ({
  event: {
    method: "node"
  },
  execute: (data) => {
    console.log(data, "event");
  }
});
```

```js
// Evento WebSocket
export default () => ({
  event: {
    method: "ws",
    route: "/test",
    topic: "test.app"
  },
  execute: (data) => {
    console.log(data, "event");
  }
});
```

---

### ⚙️ Serviço (`app/services/test/app.js`)

```js
export default ({ entity, repository }) => ({
  driver: {
    node: true
  },
  async execute(data) {
    console.log(data);
    const app = await entity("user").entity(data);
    const res = await repository("test.app").execute(app.id || "ddddddddddd");
    return { data: res };
  }
});
```

---

### 🧱 Entidades (`core/entities/user.js`)

```js
import { z } from "zod";

export default () => ({
  entity(data) {
    const schema = z.object({
      id: z.string().optional(),
      name: z.string().min(2)
    });
    return schema.parse(data);
  },
  dto() {
    return { name: "sss" };
  }
});
```

---

### 🔐 Libs (`core/libs/password.js`)

```js
export default () => ({
  password(text) {
    return text;
  },
  compare(password, hash) {
    return password === hash;
  }
});
```

---

### 🧩 Utils (`core/utils/auth.js`)

```js
export default () => ({
  apiKey(headers) {
    console.log(headers);
    return false;
  }
});
```

---

### 🧭 DB (`infra/db/index.js`)

```js
export default () => ({
  app: {
    findUnique(id) {
      return id;
    }
  }
});
```

---

### 💾 Repositório (`infra/repositories/test/app.js`)

```js
export default ({ db }) => ({
  async execute(id) {
    return await db.app.findUnique(id);
  }
});
```

---

### 🌐 HTTP — Routers (`infra/web/routers/test.js`)

```js
export default ({ util }) => ([
  {
    url: "/api/test",
    method: "get",
    middlewares: [util("auth").apiKey([])],
    async handler(request, reply) {
      const { user } = request;
      try {
        reply.send({ data: user });
      } catch (error) {
        reply.status(500).send({ error: error.message });
      }
    }
  }
]);
```

---

### 🔌 WebSocket (`infra/web/ws/test.js`)

```js
import forawait from "../../../../esm/forawait.js";

export default ({ events }) => ({
  route: "/test",

  async auth(socket, next) {
    try {
      next();
    } catch (error) {
      next(error);
    }
  },

  async connection(socket) {
    console.info("Socket connected!", socket.id);
    socket.join("test");

    forawait.generate(events, (io) => {
      socket.on(io.event.topic, (input, cb) => {
        io.execute({ input, cb }, { socket, io: this });
      });
    });

    socket.on("disconnect", async () => {
      console.log("disconnect:" + socket.id);
    });
  }
});
```

---

### 🧰 Servidor HTTP Base (`infra/web/http.js`)

```js
export default ({ routers = [], ws = [] }) => ({
  io: null,

  async start() {
    console.log(routers, ws);
  },

  async stop() {}
});
```

---

### ⚙️ Worker (`infra/workers/worker.js`)

```js
export default ({ service }) => ({
  job: {
    name: "test.app",
    method: "node"
  },
  async execute({ data }) {
    await service("test.app").execute(data);
    return {};
  }
});
```

---

## 🧪 Testes Automatizados (`vitest`)

```js
import { expect, describe, beforeAll, afterEach, test } from "vitest";
import { testApp } from "../esm/index.js";

let core = {};

beforeAll(async () => {
  const { core: Core } = await testApp.run({
    db: {
      app: {
        async findUnique(id) {
          return { id, name: "dddd", desc: "ddddddd" };
        }
      }
    }
  });

  core = Core;

  Core.event("node").sub({ topic: "service::test.app" }, ({ data }) => {
    console.log(data);
    Core.event("node").pub({ topic: "test.app" }, { id: data.id });
  });
});

describe("core", () => {
  test("executa serviço principal", async () => {
    const res = await core.service("test.app").execute({ name: "ddd" }, "node");

    expect(res.data).toBeDefined();
    expect(res.error).toBeUndefined();
    expect(res.data.id).toBeDefined();
  });
});
```

---

## 🧩 Configuração Avançada — Multi-Drivers e Servidores

```js
await app.run({
  drivers: [
    {
      type: "nats",
      name: "nats",
      config: { servers: "nats://localhost:4222" }
    },
    {
      type: "redis",
      name: "redis",
      config: { url: "redis://localhost:6379" }
    },
    {
      type: "bull",
      name: "bull",
      config: { url: "redis://localhost:6379" }
    }
  ],
  servers: [
    {
      type: "http",
      rootPath: "/api"
    },
    {
      type: "ws",
      route: "/ws",
      driver: "nats"
    },
    {
      type: "nats",
      driver: "nats",
      services: [
        "test.app",
        { name: "test.app1", auth: "util:auth.apiKey" }
      ]
    }
  ]
});
```

---

## 🧠 Fluxo de Inicialização

```
start.js
  ↓
app.run(config)
  ↓
index.js → bootstrap({ core })
  ↓
core.service("test.app").execute({})
  ↓
Serviço → Entidade → Repositório → DB
  ↓
Eventos → Workers → Web → WS
```

---

## ✅ Conclusão

A integração de `create-org-app` com `index.js` e `start.js` fornece:

✔️ **Arquitetura limpa e modular**
✔️ **Ciclo de vida controlado (bootstrap/destroy)**
✔️ **Suporte nativo a múltiplos drivers e servidores**
✔️ **Eventos reativos, workers e WebSockets**
✔️ **Perfeita para microserviços e SaaS distribuídos**