From 830e98625d0e921d087d63701e03e28fdbb7082c Mon Sep 17 00:00:00 2001 From: Consultoria AS Date: Thu, 22 Jan 2026 01:48:57 +0000 Subject: [PATCH] feat: add shared package with types and constants Co-Authored-By: Claude Opus 4.5 --- packages/shared/package.json | 14 +++++++++ packages/shared/src/constants/plans.ts | 36 +++++++++++++++++++++ packages/shared/src/constants/roles.ts | 20 ++++++++++++ packages/shared/src/index.ts | 8 +++++ packages/shared/src/types/auth.ts | 43 ++++++++++++++++++++++++++ packages/shared/src/types/tenant.ts | 22 +++++++++++++ packages/shared/src/types/user.ts | 25 +++++++++++++++ packages/shared/tsconfig.json | 17 ++++++++++ 8 files changed, 185 insertions(+) create mode 100644 packages/shared/package.json create mode 100644 packages/shared/src/constants/plans.ts create mode 100644 packages/shared/src/constants/roles.ts create mode 100644 packages/shared/src/index.ts create mode 100644 packages/shared/src/types/auth.ts create mode 100644 packages/shared/src/types/tenant.ts create mode 100644 packages/shared/src/types/user.ts create mode 100644 packages/shared/tsconfig.json diff --git a/packages/shared/package.json b/packages/shared/package.json new file mode 100644 index 0000000..5442bb4 --- /dev/null +++ b/packages/shared/package.json @@ -0,0 +1,14 @@ +{ + "name": "@horux/shared", + "version": "0.0.1", + "private": true, + "main": "./src/index.ts", + "types": "./src/index.ts", + "scripts": { + "lint": "eslint src/", + "typecheck": "tsc --noEmit" + }, + "devDependencies": { + "typescript": "^5.3.0" + } +} diff --git a/packages/shared/src/constants/plans.ts b/packages/shared/src/constants/plans.ts new file mode 100644 index 0000000..9fab6e7 --- /dev/null +++ b/packages/shared/src/constants/plans.ts @@ -0,0 +1,36 @@ +export const PLANS = { + starter: { + name: 'Starter', + cfdiLimit: 100, + usersLimit: 1, + features: ['dashboard', 'cfdi_basic', 'iva_isr'], + }, + business: { + name: 'Business', + cfdiLimit: 500, + usersLimit: 3, + features: ['dashboard', 'cfdi_basic', 'iva_isr', 'reportes', 'alertas', 'calendario'], + }, + professional: { + name: 'Professional', + cfdiLimit: 2000, + usersLimit: 10, + features: ['dashboard', 'cfdi_basic', 'iva_isr', 'reportes', 'alertas', 'calendario', 'conciliacion', 'forecasting', 'xml_sat'], + }, + enterprise: { + name: 'Enterprise', + cfdiLimit: -1, + usersLimit: -1, + features: ['dashboard', 'cfdi_basic', 'iva_isr', 'reportes', 'alertas', 'calendario', 'conciliacion', 'forecasting', 'xml_sat', 'api', 'multi_empresa'], + }, +} as const; + +export type Plan = keyof typeof PLANS; + +export function getPlanLimits(plan: Plan) { + return PLANS[plan]; +} + +export function hasFeature(plan: Plan, feature: string): boolean { + return PLANS[plan].features.includes(feature); +} diff --git a/packages/shared/src/constants/roles.ts b/packages/shared/src/constants/roles.ts new file mode 100644 index 0000000..5b502d9 --- /dev/null +++ b/packages/shared/src/constants/roles.ts @@ -0,0 +1,20 @@ +export const ROLES = { + admin: { + name: 'Administrador', + permissions: ['read', 'write', 'delete', 'manage_users', 'manage_settings'], + }, + contador: { + name: 'Contador', + permissions: ['read', 'write'], + }, + visor: { + name: 'Visor', + permissions: ['read'], + }, +} as const; + +export type Role = keyof typeof ROLES; + +export function hasPermission(role: Role, permission: string): boolean { + return ROLES[role].permissions.includes(permission as any); +} diff --git a/packages/shared/src/index.ts b/packages/shared/src/index.ts new file mode 100644 index 0000000..30ed3f8 --- /dev/null +++ b/packages/shared/src/index.ts @@ -0,0 +1,8 @@ +// Types +export * from './types/auth'; +export * from './types/tenant'; +export * from './types/user'; + +// Constants +export * from './constants/plans'; +export * from './constants/roles'; diff --git a/packages/shared/src/types/auth.ts b/packages/shared/src/types/auth.ts new file mode 100644 index 0000000..fc071a1 --- /dev/null +++ b/packages/shared/src/types/auth.ts @@ -0,0 +1,43 @@ +export interface LoginRequest { + email: string; + password: string; +} + +export interface LoginResponse { + accessToken: string; + refreshToken: string; + user: UserInfo; +} + +export interface RegisterRequest { + empresa: { + nombre: string; + rfc: string; + }; + usuario: { + nombre: string; + email: string; + password: string; + }; +} + +export interface UserInfo { + id: string; + email: string; + nombre: string; + role: Role; + tenantId: string; + tenantName: string; +} + +export interface JWTPayload { + userId: string; + email: string; + role: Role; + tenantId: string; + schemaName: string; + iat?: number; + exp?: number; +} + +export type Role = 'admin' | 'contador' | 'visor'; diff --git a/packages/shared/src/types/tenant.ts b/packages/shared/src/types/tenant.ts new file mode 100644 index 0000000..79758e3 --- /dev/null +++ b/packages/shared/src/types/tenant.ts @@ -0,0 +1,22 @@ +import type { Plan } from '../constants/plans'; + +export interface Tenant { + id: string; + nombre: string; + rfc: string; + plan: Plan; + schemaName: string; + cfdiLimit: number; + usersLimit: number; + active: boolean; + createdAt: Date; + expiresAt: Date | null; +} + +export interface TenantUsage { + cfdiCount: number; + cfdiLimit: number; + usersCount: number; + usersLimit: number; + plan: Plan; +} diff --git a/packages/shared/src/types/user.ts b/packages/shared/src/types/user.ts new file mode 100644 index 0000000..c9f77a2 --- /dev/null +++ b/packages/shared/src/types/user.ts @@ -0,0 +1,25 @@ +import type { Role } from './auth'; + +export interface User { + id: string; + tenantId: string; + email: string; + nombre: string; + role: Role; + active: boolean; + lastLogin: Date | null; + createdAt: Date; +} + +export interface CreateUserRequest { + email: string; + nombre: string; + role: Role; + password: string; +} + +export interface UpdateUserRequest { + nombre?: string; + role?: Role; + active?: boolean; +} diff --git a/packages/shared/tsconfig.json b/packages/shared/tsconfig.json new file mode 100644 index 0000000..7c97b15 --- /dev/null +++ b/packages/shared/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "ES2022", + "lib": ["ES2022"], + "module": "ESNext", + "moduleResolution": "bundler", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "declaration": true, + "declarationMap": true, + "outDir": "./dist" + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] +}