feat: add shared package with types and constants
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
14
packages/shared/package.json
Normal file
14
packages/shared/package.json
Normal file
@@ -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"
|
||||
}
|
||||
}
|
||||
36
packages/shared/src/constants/plans.ts
Normal file
36
packages/shared/src/constants/plans.ts
Normal file
@@ -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);
|
||||
}
|
||||
20
packages/shared/src/constants/roles.ts
Normal file
20
packages/shared/src/constants/roles.ts
Normal file
@@ -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);
|
||||
}
|
||||
8
packages/shared/src/index.ts
Normal file
8
packages/shared/src/index.ts
Normal file
@@ -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';
|
||||
43
packages/shared/src/types/auth.ts
Normal file
43
packages/shared/src/types/auth.ts
Normal file
@@ -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';
|
||||
22
packages/shared/src/types/tenant.ts
Normal file
22
packages/shared/src/types/tenant.ts
Normal file
@@ -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;
|
||||
}
|
||||
25
packages/shared/src/types/user.ts
Normal file
25
packages/shared/src/types/user.ts
Normal file
@@ -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;
|
||||
}
|
||||
17
packages/shared/tsconfig.json
Normal file
17
packages/shared/tsconfig.json
Normal file
@@ -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"]
|
||||
}
|
||||
Reference in New Issue
Block a user