Template del servicio de SIM
This commit is contained in:
9
.env
Normal file
9
.env
Normal file
@@ -0,0 +1,9 @@
|
||||
POSTGRES_PASSWORD='1234'
|
||||
POSTGRES_USER=postgres
|
||||
POSTGRES_DB=postgres
|
||||
POSTGRES_PORT='5432'
|
||||
DEV_POSTGRES_PORT='5432'
|
||||
|
||||
PORT=3000
|
||||
RABBITMQ_USER='guest'
|
||||
RABBITMQ_PASSWORD='guest'
|
||||
5
.yarnrc.yml
Normal file
5
.yarnrc.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
compressionLevel: mixed
|
||||
|
||||
enableGlobalCache: false
|
||||
|
||||
nodeLinker: node-modules
|
||||
2
build.local.sh
Executable file
2
build.local.sh
Executable file
@@ -0,0 +1,2 @@
|
||||
#/bin/bash
|
||||
docker compose -f deployment/local/docker/docker-compose.yaml --project-directory ./ build
|
||||
19
deployment/Dockerfile.dev
Normal file
19
deployment/Dockerfile.dev
Normal file
@@ -0,0 +1,19 @@
|
||||
# stage base para coordinar las fases de build y ejecucion
|
||||
FROM node:22-alpine AS base
|
||||
WORKDIR /usr/local/app
|
||||
COPY ./package.json ./yarn.lock ./
|
||||
RUN corepack enable && \
|
||||
corepack prepare yarn@4.12.0 --activate
|
||||
|
||||
# compilacion del ts -> js
|
||||
FROM base AS backend
|
||||
WORKDIR /usr/local/app
|
||||
EXPOSE ${PORT}
|
||||
COPY package*.json ./
|
||||
# copia el codigo en general
|
||||
COPY .tsconfig*.json ./
|
||||
COPY ./packages ./packages
|
||||
RUN yarn && cat package.json
|
||||
CMD ["yarn", "run", "dev"]
|
||||
|
||||
|
||||
31
deployment/database/test.sql
Normal file
31
deployment/database/test.sql
Normal file
@@ -0,0 +1,31 @@
|
||||
CREATE TABLE sim_job_queue (
|
||||
id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
job_type TEXT NOT NULL,
|
||||
sim_id INT, -- NOT NULL???
|
||||
payload JSONB NOT NULL,
|
||||
status TEXT NOT NULL DEFAULT "pending", -- pasar a enum
|
||||
priority SMALLINT NOT NULL DEFAULT 100, -- trabajamos entre 200 y 0 para 0 la maxima prioridad
|
||||
retry_count INT NOT NULL DEFAULT 0,
|
||||
max_retries INT NOT NULL DEFAULT 3, -- lo definiria en runtime
|
||||
scheduled_for TIMESTAMP NOT NULL DEFAULT now(),
|
||||
created_at TIMESTAMP NOT NULL DEFAULT now(),
|
||||
started_at TIMESTAMP,
|
||||
completed_at TIMESTAMP,
|
||||
error_msg TEXT,
|
||||
|
||||
-- En teoria el check es mas flexible que el enum
|
||||
CONSTRAINT valid_status CHECK (
|
||||
status IN ('pending', 'processing', 'completed', 'failed', 'dead')
|
||||
)
|
||||
|
||||
-- Revisar si interesa asociar cada trabajo a un id o permitir que sean independientes
|
||||
CONSTRAINT fk_sim_id
|
||||
FOREIGN KEY(sim_id) REFERENCES tableName(tarjetas_sim)
|
||||
)
|
||||
|
||||
-- Indice de pendientes de consumir
|
||||
CREATE INDEX idx_job_fetch ON sim_job_queue (status, scheduled_for, priority DESC, created_at)
|
||||
WHERE status = 'pending';
|
||||
|
||||
-- Indice del resto de procesos
|
||||
CREATE INDEX idx_job_monitor ON sim_job_queue (job_type, status, created_at);
|
||||
65
deployment/local/docker/docker-compose.yaml
Normal file
65
deployment/local/docker/docker-compose.yaml
Normal file
@@ -0,0 +1,65 @@
|
||||
name: sim-eventos
|
||||
networks:
|
||||
default:
|
||||
name: network-test # Tiene que coincidir con el compose objetivo
|
||||
services:
|
||||
rabbitmq:
|
||||
container_name: rabbitmq-broker
|
||||
image: "rabbitmq:4.2.2-management"
|
||||
ports:
|
||||
- "5672:5672"
|
||||
- "15672:15672"
|
||||
env_file:
|
||||
- .env
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD", "rabbitmq-diagnostics", "check_port_connectivity"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 5
|
||||
environment:
|
||||
RABBITMQ_DEFAULT_USER: ${RABBITMQ_USER}
|
||||
RABBITMQ_DEFAULT_PASS: ${RABBITMQ_PASSWORD}
|
||||
volumes:
|
||||
- ./rabbitmq_plugins/enabled_plugins:/etc/rabbitmq/enabled_plugins:ro
|
||||
- ./deployment/rabbit/rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf:ro
|
||||
- ./deployment/rabbit/definitions.json:/etc/rabbitmq/definitions.json:ro
|
||||
|
||||
sim-gateway:
|
||||
container_name: sim-gateway
|
||||
volumes:
|
||||
- ./:/usr/local/app
|
||||
- ./node_modules:/usr/local/node_modules
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: deployment/Dockerfile.dev
|
||||
args:
|
||||
PORT: "${PORT:-3000}"
|
||||
develop:
|
||||
watch:
|
||||
- path: ./src
|
||||
action: sync
|
||||
target: /usr/local/app/src
|
||||
- path: ./package.json
|
||||
action: rebuild
|
||||
ports:
|
||||
- ${PORT}:${PORT}
|
||||
env_file:
|
||||
- .env
|
||||
restart: unless-stopped
|
||||
|
||||
postgresql-sim:
|
||||
image: postgres:16.1
|
||||
env_file:
|
||||
- .env
|
||||
ports:
|
||||
- "5432:${DEV_POSTGRES_PORT}"
|
||||
volumes:
|
||||
- ./sql-data/:/var/lib/postgres/data
|
||||
- ./deployment/database/test.sql:/docker-entrypoint-initdb.d/init.sql
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
|
||||
interval: 10s
|
||||
retries: 5
|
||||
start_period: 30s
|
||||
timeout: 10s
|
||||
9
deployment/local/docker/rebuild.sh
Normal file
9
deployment/local/docker/rebuild.sh
Normal file
@@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
cd /mnt/docker-storage/containers/savefamily/sf-shopify-orders
|
||||
|
||||
docker stop sf-shopify-orders-api || true
|
||||
docker rm sf-shopify-orders-api || true
|
||||
docker rmi sf-shopify-orders-api || true
|
||||
|
||||
docker compose -f docker-compose.yaml up --build -d
|
||||
71
deployment/rabbit/definitions.json
Normal file
71
deployment/rabbit/definitions.json
Normal file
@@ -0,0 +1,71 @@
|
||||
{
|
||||
"rabbit_version": "4.2.2",
|
||||
"rabbitmq_version": "4.2.2",
|
||||
"product_name": "RabbitMQ",
|
||||
"product_version": "4.2.2",
|
||||
"users": [
|
||||
{
|
||||
"name": "guest",
|
||||
"password": "guest",
|
||||
"hashing_algorithm": "rabbit_password_hashing_sha256",
|
||||
"tags": "administrator"
|
||||
}
|
||||
],
|
||||
"vhosts": [
|
||||
{
|
||||
"name": "sim-vhost"
|
||||
}
|
||||
],
|
||||
"permissions": [
|
||||
{
|
||||
"user": "guest",
|
||||
"vhost": "sim-vhost",
|
||||
"configure": ".*",
|
||||
"write": ".*",
|
||||
"read": ".*"
|
||||
}
|
||||
],
|
||||
"topic_permissions": [],
|
||||
"parameters": [],
|
||||
"global_parameters": [
|
||||
{
|
||||
"name": "cluster_name",
|
||||
"value": "rabbit@a8d5c6e08439"
|
||||
},
|
||||
{
|
||||
"name": "internal_cluster_id",
|
||||
"value": "rabbitmq-cluster-id-gXeBLbsUC2W2tU0Bx_QY_w"
|
||||
}
|
||||
],
|
||||
"policies": [],
|
||||
"exchanges": [
|
||||
{
|
||||
"name": "sim.exchange",
|
||||
"vhost": "sim-vhost",
|
||||
"type": "direct",
|
||||
"durable": true,
|
||||
"auto_delete": false,
|
||||
"internal": false,
|
||||
"argurments": {}
|
||||
}
|
||||
],
|
||||
"queues": [
|
||||
{
|
||||
"name": "sim.queue",
|
||||
"vhost": "sim-vhost",
|
||||
"durable": true,
|
||||
"auto_delete": false,
|
||||
"arguments": {}
|
||||
}
|
||||
],
|
||||
"bindings": [
|
||||
{
|
||||
"source": "sim.exchange",
|
||||
"vhost": "sim-vhost",
|
||||
"destination": "sim.queue",
|
||||
"destination_type": "queue",
|
||||
"routing_key": "sim.*",
|
||||
"arguments": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
11
deployment/rabbit/rabbitmq.conf
Normal file
11
deployment/rabbit/rabbitmq.conf
Normal file
@@ -0,0 +1,11 @@
|
||||
default_user = guest
|
||||
default_pass = guest
|
||||
|
||||
listeners.tcp.default = 5672
|
||||
management.tcp.port = 15672
|
||||
|
||||
management.load_definitions = /etc/rabbitmq/definitions.json
|
||||
|
||||
default_queue_type = quorum
|
||||
|
||||
|
||||
1843
package-lock.json
generated
Normal file
1843
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
36
package.json
36
package.json
@@ -1,4 +1,38 @@
|
||||
{
|
||||
"name": "sim-cola-eventos",
|
||||
"packageManager": "yarn@4.12.0"
|
||||
"packageManager": "yarn@4.12.0",
|
||||
"workspaces": [
|
||||
"packages/*"
|
||||
],
|
||||
"scripts": {
|
||||
"test": "vitest watch",
|
||||
"build": "npx tsc",
|
||||
"start": "node dist/index.js",
|
||||
"typecheck": "npx tsc --noEmit",
|
||||
"dev": "yarn workspaces foreach -A run dev",
|
||||
"lint": "eslint .",
|
||||
"lint:fix": "eslint --fix .",
|
||||
"format": "prettier --write .",
|
||||
"format:check": "prettier --check ."
|
||||
},
|
||||
"dependencies": {
|
||||
"@tsconfig/node22": "^22.0.5",
|
||||
"cors": "^2.8.5",
|
||||
"dotenv": "^17.2.3",
|
||||
"express": "^5.2.1",
|
||||
"typescript": "^5.9.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/cors": "^2.8.19",
|
||||
"@types/express": "^5.0.6",
|
||||
"@types/node": "^25.0.3",
|
||||
"@types/supertest": "^6.0.3",
|
||||
"prettier": "^3.7.4",
|
||||
"supertest": "^7.1.4",
|
||||
"tsx": "^4.21.0",
|
||||
"vitest": "^4.0.16"
|
||||
},
|
||||
"imports": {
|
||||
"#*": "./src/*"
|
||||
}
|
||||
}
|
||||
|
||||
7
packages/shared/config/env/env-validators.ts
vendored
Normal file
7
packages/shared/config/env/env-validators.ts
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
import { makeValidator } from 'envalid';
|
||||
|
||||
import { isValidEnvString, isValidEnvStringArray } from '#shared/domain/utils/env-validators';
|
||||
|
||||
export const ensureEnvStringArray = makeValidator((value: unknown) => isValidEnvStringArray(value));
|
||||
|
||||
export const ensureEnvString = makeValidator((value: unknown) => isValidEnvString(value));
|
||||
45
packages/shared/config/env/index.ts
vendored
Normal file
45
packages/shared/config/env/index.ts
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
import { bool, cleanEnv, num, port, str } from 'envalid';
|
||||
|
||||
import { USER_ROLES } from '#shared/domain/models/authorizer-user.entity';
|
||||
|
||||
import { ensureEnvString } from './env-validators';
|
||||
|
||||
export const env = cleanEnv(process.env, {
|
||||
ENVIRONMENT: str({
|
||||
choices: ['local', 'development', 'production']
|
||||
}),
|
||||
USE_IN_MEMORY_REPOSITORIES: bool(),
|
||||
ALERTS_API_PORT: port(),
|
||||
COMPANIES_COMMAND_URL: ensureEnvString(),
|
||||
DEVICES_COMMAND_URL: ensureEnvString(),
|
||||
USERS_COMMAND_URL: ensureEnvString(),
|
||||
REDIS_PASSWORD: ensureEnvString(),
|
||||
REDIS_PORT: port(),
|
||||
REDIS_HOST: ensureEnvString(),
|
||||
POSTGRES_USER: ensureEnvString(),
|
||||
POSTGRES_PASSWORD: ensureEnvString(),
|
||||
POSTGRES_PORT: port(),
|
||||
POSTGRES_HOST: ensureEnvString(),
|
||||
POSTGRES_DATABASE: ensureEnvString(),
|
||||
RABBITMQ_HOST: ensureEnvString(),
|
||||
RABBITMQ_USER: ensureEnvString(),
|
||||
RABBITMQ_PASSWORD: ensureEnvString(),
|
||||
RABBITMQ_EXCHANGE: ensureEnvString(),
|
||||
RABBITMQ_PORT: port(),
|
||||
RABBITMQ_MODULENAME: ensureEnvString(),
|
||||
RABBITMQ_TTL: port(),
|
||||
RABBITMQ_SECURE: bool(),
|
||||
RABBITMQ_RETRY_INTERVAL: num(),
|
||||
SYSTEM_USER_ID: ensureEnvString(),
|
||||
SYSTEM_USER_EMAIL: ensureEnvString(),
|
||||
SYSTEM_USER_ROLE: str({
|
||||
choices: [
|
||||
USER_ROLES.ADMIN,
|
||||
USER_ROLES.CLIENT,
|
||||
USER_ROLES.DELEGATION_MANAGER,
|
||||
USER_ROLES.OPERATOR,
|
||||
USER_ROLES.ROOM_STAFF
|
||||
],
|
||||
default: USER_ROLES.ADMIN
|
||||
})
|
||||
});
|
||||
12
packages/shared/config/event-bus/index.ts
Normal file
12
packages/shared/config/event-bus/index.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { env } from '#api/config/env';
|
||||
|
||||
export const eventBusConfig = {
|
||||
host: env.RABBITMQ_HOST,
|
||||
user: env.RABBITMQ_USER,
|
||||
password: env.RABBITMQ_PASSWORD,
|
||||
exchange: env.RABBITMQ_EXCHANGE,
|
||||
port: env.RABBITMQ_PORT,
|
||||
modulename: env.RABBITMQ_MODULENAME,
|
||||
ttl: env.RABBITMQ_TTL,
|
||||
secure: env.RABBITMQ_SECURE
|
||||
};
|
||||
2
packages/shared/index.ts
Normal file
2
packages/shared/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
console.log("shared")
|
||||
export default {}
|
||||
31
packages/shared/package.json
Normal file
31
packages/shared/package.json
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"name": "sim-shared",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "src/app.ts",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"dev": "tsx index.ts"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"private": true,
|
||||
"packageManager": "yarn@4.12.0",
|
||||
"dependencies": {
|
||||
"@tsconfig/node22": "*",
|
||||
"cors": "*",
|
||||
"dotenv": "*",
|
||||
"express": "*",
|
||||
"typescript": "*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/cors": "*",
|
||||
"@types/express": "*",
|
||||
"@types/node": "*",
|
||||
"@types/supertest": "*",
|
||||
"prettier": "*",
|
||||
"supertest": "*",
|
||||
"tsx": "*",
|
||||
"vitest": "*"
|
||||
}
|
||||
}
|
||||
34
packages/shared/tsconfig.json
Normal file
34
packages/shared/tsconfig.json
Normal file
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../dist/shared",
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"#adapters/*": [
|
||||
"src/adapters/*"
|
||||
],
|
||||
"#domain/*": [
|
||||
"src/domain/*"
|
||||
],
|
||||
"#ports/*": [
|
||||
"src/ports/*"
|
||||
],
|
||||
"#tests/*": [
|
||||
"__tests__/*"
|
||||
],
|
||||
"#shared/*": [
|
||||
"./*"
|
||||
]
|
||||
}
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
],
|
||||
"include": [
|
||||
"**/*.ts",
|
||||
"src/**/*.d.ts"
|
||||
],
|
||||
"files": [
|
||||
"index.ts"
|
||||
]
|
||||
}
|
||||
13
packages/sim-gestor-eventos/.env
Normal file
13
packages/sim-gestor-eventos/.env
Normal file
@@ -0,0 +1,13 @@
|
||||
ENVIORMENT=development
|
||||
|
||||
RABBITMQ_HOST=rabittmq-broker
|
||||
RABBITMQ_PORT=5672
|
||||
RABBITMQ_USER=guest
|
||||
RABBITMQ_PASSWORD=guest
|
||||
RABBITMQ_SECURE=false
|
||||
|
||||
POSTGRES_DATABASE=postres
|
||||
POSTGRES_HOST=postgresql-sim-1
|
||||
POSTGRES_PORT=5432
|
||||
POSTGRES_USER=postgres
|
||||
POSTGRES_PASSWORD=postgres
|
||||
7
packages/sim-gestor-eventos/config/env/env-validators.ts
vendored
Normal file
7
packages/sim-gestor-eventos/config/env/env-validators.ts
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
import { makeValidator } from 'envalid';
|
||||
|
||||
import { isValidEnvString, isValidEnvStringArray } from '#shared/domain/utils/env-validators';
|
||||
|
||||
export const ensureEnvStringArray = makeValidator((value: unknown) => isValidEnvStringArray(value));
|
||||
|
||||
export const ensureEnvString = makeValidator((value: unknown) => isValidEnvString(value));
|
||||
17
packages/sim-gestor-eventos/config/env/index.ts
vendored
Normal file
17
packages/sim-gestor-eventos/config/env/index.ts
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
export const env = {
|
||||
ENVIRONMENT: process.env.ENVIORMENT,
|
||||
POSTGRES_USER: process.env.POSTGRES_USER,
|
||||
POSTGRES_PASSWORD: process.env.POSTGRES_PASSWORD,
|
||||
POSTGRES_PORT: process.env.POSTGRES_PORT,
|
||||
POSTGRES_HOST: process.env.POSTGRES_HOST,
|
||||
POSTGRES_DATABASE: process.env.POSTGRES_DATABASE,
|
||||
RABBITMQ_HOST: process.env.RABBITMQ_HOST,
|
||||
RABBITMQ_USER: process.env.RABBITMQ_USER,
|
||||
RABBITMQ_PASSWORD: process.env.RABBITMQ_PASSWORD,
|
||||
RABBITMQ_EXCHANGE: process.env.RABBITMQ_EXCHANGE,
|
||||
RABBITMQ_PORT: process.env.RABBITMQ_PORT,
|
||||
RABBITMQ_MODULENAME: process.env.MODULENAME,
|
||||
RABBITMQ_TTL: process.env.RABBITMQ_TTL,
|
||||
RABBITMQ_SECURE: process.env.RABBITMQ_SECURE,
|
||||
RABBITMQ_RETRY_INTERVAL: process.env.RABBITMQ_INTERVAL,
|
||||
};
|
||||
12
packages/sim-gestor-eventos/config/event-bus/index.ts
Normal file
12
packages/sim-gestor-eventos/config/event-bus/index.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { env } from '#api/config/env';
|
||||
|
||||
export const eventBusConfig = {
|
||||
host: env.RABBITMQ_HOST,
|
||||
user: env.RABBITMQ_USER,
|
||||
password: env.RABBITMQ_PASSWORD,
|
||||
exchange: env.RABBITMQ_EXCHANGE,
|
||||
port: env.RABBITMQ_PORT,
|
||||
modulename: env.RABBITMQ_MODULENAME,
|
||||
ttl: env.RABBITMQ_TTL,
|
||||
secure: env.RABBITMQ_SECURE
|
||||
};
|
||||
43
packages/sim-gestor-eventos/index.ts
Normal file
43
packages/sim-gestor-eventos/index.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import client, { ChannelModel, connect, Connection } from "amqplib"
|
||||
import { env } from "config/env"
|
||||
import { Channel } from "node:diagnostics_channel"
|
||||
|
||||
const rmqUser = env.RABBITMQ_USER
|
||||
const rmqPass = env.RABBITMQ_PASSWORD
|
||||
const rmqHost = env.RABBITMQ_HOST
|
||||
const rmqPort = Number(env.RABBITMQ_PORT)
|
||||
const rmqSecure = env.RABBITMQ_SECURE
|
||||
|
||||
class RabbitConnection {
|
||||
connection?: Connection
|
||||
channel?: Channel
|
||||
connected: Boolean = false
|
||||
|
||||
|
||||
protected async createConnection(): Promise<ChannelModel> {
|
||||
const { hostname, port, secure } = { hostname: rmqHost, port: rmqPort, secure: rmqSecure }
|
||||
const { username, password } = { username: rmqUser, password: rmqPass };
|
||||
const protocol = secure ? 'amqps' : 'amqp';
|
||||
|
||||
const connection = await connect({
|
||||
protocol,
|
||||
hostname,
|
||||
port,
|
||||
username,
|
||||
password
|
||||
});
|
||||
|
||||
connection.on('error', (error: unknown) => {
|
||||
console.error(`[EVENT BUS] Rabbitmq connection error :: ${error}`);
|
||||
Promise.reject(error);
|
||||
});
|
||||
|
||||
return connection;
|
||||
}
|
||||
}
|
||||
|
||||
while (true) {
|
||||
console.log("test")
|
||||
}
|
||||
|
||||
export default {}
|
||||
32
packages/sim-gestor-eventos/package.json
Normal file
32
packages/sim-gestor-eventos/package.json
Normal file
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"name": "sim-gestor-eventos",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.ts",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"dev": "tsx index.ts"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"packageManager": "yarn@4.12.0",
|
||||
"dependencies": {
|
||||
"@tsconfig/node22": "*",
|
||||
"amqplib": "^0.10.9",
|
||||
"cors": "*",
|
||||
"dotenv": "*",
|
||||
"express": "*",
|
||||
"typescript": "*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/amqplib": "^0.10.8",
|
||||
"@types/cors": "*",
|
||||
"@types/express": "*",
|
||||
"@types/node": "*",
|
||||
"@types/supertest": "*",
|
||||
"prettier": "*",
|
||||
"supertest": "*",
|
||||
"tsx": "*",
|
||||
"vitest": "*"
|
||||
}
|
||||
}
|
||||
34
packages/sim-gestor-eventos/tsconfig.json
Normal file
34
packages/sim-gestor-eventos/tsconfig.json
Normal file
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../dist/sim-gestor-eventos",
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"#adapters/*": [
|
||||
"src/adapters/*"
|
||||
],
|
||||
"#domain/*": [
|
||||
"src/domain/*"
|
||||
],
|
||||
"#ports/*": [
|
||||
"src/ports/*"
|
||||
],
|
||||
"#tests/*": [
|
||||
"__tests__/*"
|
||||
],
|
||||
"#shared/*": [
|
||||
"../shared/*"
|
||||
],
|
||||
}
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
],
|
||||
"include": [
|
||||
"**/*.ts",
|
||||
"src/**/*.d.ts"
|
||||
],
|
||||
"files": [
|
||||
"index.ts"
|
||||
]
|
||||
}
|
||||
1
rabbitmq_plugins/enabled_plugins
Normal file
1
rabbitmq_plugins/enabled_plugins
Normal file
@@ -0,0 +1 @@
|
||||
[rabbitmq_management].
|
||||
2
run.local.sh
Executable file
2
run.local.sh
Executable file
@@ -0,0 +1,2 @@
|
||||
#/bin/bash
|
||||
docker compose -f deployment/local/docker/docker-compose.yaml --project-directory ./ up
|
||||
29
src/app.ts
Normal file
29
src/app.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import express from 'express';
|
||||
import cors from 'cors';
|
||||
import { config } from './config';
|
||||
|
||||
const PORT = config.port;
|
||||
|
||||
const server = express();
|
||||
|
||||
// Middleware
|
||||
server.use(cors());
|
||||
|
||||
// Webhooks often require raw body for signature verification if not handled by express.json()
|
||||
// using verify option in body-parser/express.json to get raw body if needed.
|
||||
server.use(express.json({
|
||||
verify: (req: any, res, buf) => {
|
||||
req.rawBody = buf;
|
||||
}
|
||||
}));
|
||||
server.use(express.urlencoded({ extended: true }));
|
||||
|
||||
// Health check
|
||||
server.get('/health', (req, res) => {
|
||||
res.status(200).send({ resp: 'OK' });
|
||||
});
|
||||
|
||||
server.listen(PORT, () => {
|
||||
console.log(`[Server] Server is running on port ${PORT} in ${config.env} mode`);
|
||||
console.log(`[Server] Webhook endpoint: http://localhost:${PORT}/api/webhooks`);
|
||||
});
|
||||
12
src/config/index.ts
Normal file
12
src/config/index.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import dotenv from 'dotenv';
|
||||
dotenv.config();
|
||||
|
||||
export const config = {
|
||||
port: process.env.PORT || 3000,
|
||||
env: process.env.NODE_ENV || 'development',
|
||||
};
|
||||
|
||||
export const rabbitConfing = {
|
||||
|
||||
}
|
||||
|
||||
70
src/config/initial_hosts.ts
Normal file
70
src/config/initial_hosts.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* Configuracion de los host iniciales y a que topics escuchan
|
||||
*/
|
||||
|
||||
import { ScheduledEvent, SetupSubscription, SubscriptionData } from "#controllers/subscriptions.types.js"
|
||||
import { webhooksConfig } from "."
|
||||
|
||||
|
||||
export function generateSubscriptions(initialHosts?: SetupSubscription[]) {
|
||||
const initialhs = initialHosts || INITIAL_HOSTS
|
||||
const topicSubscriberMap = new Map<string, SubscriptionData>()
|
||||
|
||||
for (const setup of initialhs) {
|
||||
const topic = setup.topic
|
||||
if (topicSubscriberMap.get(topic) == undefined) {
|
||||
topicSubscriberMap.set(topic, {
|
||||
topic: topic,
|
||||
subscriptors: []
|
||||
})
|
||||
}
|
||||
topicSubscriberMap.get(topic)!.subscriptors.push({
|
||||
...setup
|
||||
})
|
||||
}
|
||||
return topicSubscriberMap
|
||||
}
|
||||
|
||||
type InitialHost = {
|
||||
topic: string,
|
||||
host: string,
|
||||
port: string,
|
||||
endpoint: string,
|
||||
method: "POST" | "PUT" | "DELETE",
|
||||
secretkey: string,
|
||||
}
|
||||
|
||||
export const INITIAL_HOSTS: InitialHost[] = [
|
||||
{
|
||||
topic: "order/create",
|
||||
host: "localhost",
|
||||
port: "3500",
|
||||
endpoint: "/order/create",
|
||||
method: "POST",
|
||||
secretkey: webhooksConfig.apiSecret || "1234",
|
||||
},
|
||||
{
|
||||
topic: "order/create",
|
||||
host: "localhost",
|
||||
port: "3000",
|
||||
endpoint: '/webhooks/shopify/orders',
|
||||
method: "POST",
|
||||
secretkey: webhooksConfig.apiSecret || "1234",
|
||||
},
|
||||
{
|
||||
topic: "order/create",
|
||||
host: "sf-shopify-orders-api",
|
||||
port: "3000",
|
||||
endpoint: '/webhooks/shopify/orders',
|
||||
method: "POST",
|
||||
secretkey: webhooksConfig.apiSecret || "1234",
|
||||
}
|
||||
]
|
||||
|
||||
export const INITIAL_EVENTS: ScheduledEvent[] = [
|
||||
{
|
||||
topic: "order/create",
|
||||
numberOfMessages: -1,
|
||||
periodMs: 5000
|
||||
}
|
||||
]
|
||||
3
src/rabbit.ts
Normal file
3
src/rabbit.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import rabbit from "rabbitmq-stream-js-client"
|
||||
|
||||
const client = await rabbit.connect()
|
||||
2
stop.local.sh
Executable file
2
stop.local.sh
Executable file
@@ -0,0 +1,2 @@
|
||||
#/bin/bash
|
||||
docker compose -f deployment/local/docker/docker-compose.yaml --project-directory ./ down -v
|
||||
13
tsconfig.json
Normal file
13
tsconfig.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"extends": "@tsconfig/node22/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./"
|
||||
},
|
||||
"include": [
|
||||
"**/*.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"dist"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user