Added auth functionality, initial work with views and field types

This commit is contained in:
Francisco Gaona
2025-12-22 03:31:55 +01:00
parent 859dca6c84
commit 0fe56c0e03
170 changed files with 11599 additions and 435 deletions

View File

@@ -0,0 +1,23 @@
import { BaseModel } from './base.model';
export class Account extends BaseModel {
static tableName = 'accounts';
id!: string;
name!: string;
website?: string;
phone?: string;
industry?: string;
ownerId?: string;
static relationMappings = {
owner: {
relation: BaseModel.BelongsToOneRelation,
modelClass: 'user.model',
join: {
from: 'accounts.ownerId',
to: 'users.id',
},
},
};
}

View File

@@ -0,0 +1,25 @@
import { BaseModel } from './base.model';
import { App } from './app.model';
export class AppPage extends BaseModel {
static tableName = 'app_pages';
id!: string;
appId!: string;
slug!: string;
label!: string;
type!: string;
objectApiName?: string;
displayOrder!: number;
static relationMappings = {
app: {
relation: BaseModel.BelongsToOneRelation,
modelClass: App,
join: {
from: 'app_pages.appId',
to: 'apps.id',
},
},
};
}

View File

@@ -0,0 +1,23 @@
import { BaseModel } from './base.model';
import { AppPage } from './app-page.model';
export class App extends BaseModel {
static tableName = 'apps';
id!: string;
slug!: string;
label!: string;
description?: string;
displayOrder!: number;
static relationMappings = {
pages: {
relation: BaseModel.HasManyRelation,
modelClass: AppPage,
join: {
from: 'apps.id',
to: 'app_pages.appId',
},
},
};
}

View File

@@ -0,0 +1,18 @@
import { Model, ModelOptions, QueryContext, snakeCaseMappers } from 'objection';
export class BaseModel extends Model {
static columnNameMappers = snakeCaseMappers();
id: string;
createdAt: Date;
updatedAt: Date;
$beforeInsert(queryContext: QueryContext) {
this.createdAt = new Date();
this.updatedAt = new Date();
}
$beforeUpdate(opt: ModelOptions, queryContext: QueryContext) {
this.updatedAt = new Date();
}
}

View File

@@ -0,0 +1,78 @@
import { BaseModel } from './base.model';
export interface FieldOption {
label: string;
value: string | number | boolean;
}
export interface ValidationRule {
type: 'required' | 'min' | 'max' | 'email' | 'url' | 'pattern' | 'custom';
value?: any;
message?: string;
}
export interface UIMetadata {
// Display properties
placeholder?: string;
helpText?: string;
// View visibility
showOnList?: boolean;
showOnDetail?: boolean;
showOnEdit?: boolean;
sortable?: boolean;
// Field type specific options
options?: FieldOption[]; // For select, multi-select
rows?: number; // For textarea
min?: number; // For number, date
max?: number; // For number, date
step?: number; // For number
accept?: string; // For file/image
relationDisplayField?: string; // Which field to display for relations
// Formatting
format?: string; // Date format, number format, etc.
prefix?: string; // Currency symbol, etc.
suffix?: string;
// Validation
validationRules?: ValidationRule[];
// Advanced
dependsOn?: string[]; // Field dependencies
computedValue?: string; // Formula for computed fields
}
export class FieldDefinition extends BaseModel {
static tableName = 'field_definitions';
id!: string;
objectDefinitionId!: string;
apiName!: string;
label!: string;
type!: string;
length?: number;
precision?: number;
scale?: number;
referenceObject?: string;
defaultValue?: string;
description?: string;
isRequired!: boolean;
isUnique!: boolean;
isSystem!: boolean;
isCustom!: boolean;
displayOrder!: number;
uiMetadata?: UIMetadata;
static relationMappings = {
objectDefinition: {
relation: BaseModel.BelongsToOneRelation,
modelClass: 'object-definition.model',
join: {
from: 'field_definitions.objectDefinitionId',
to: 'object_definitions.id',
},
},
};
}

View File

@@ -0,0 +1,46 @@
import { BaseModel } from './base.model';
export class ObjectDefinition extends BaseModel {
static tableName = 'object_definitions';
id: string;
apiName: string;
label: string;
pluralLabel?: string;
description?: string;
isSystem: boolean;
isCustom: boolean;
createdAt: Date;
updatedAt: Date;
static get jsonSchema() {
return {
type: 'object',
required: ['apiName', 'label'],
properties: {
id: { type: 'string' },
apiName: { type: 'string' },
label: { type: 'string' },
pluralLabel: { type: 'string' },
description: { type: 'string' },
isSystem: { type: 'boolean' },
isCustom: { type: 'boolean' },
},
};
}
static get relationMappings() {
const { FieldDefinition } = require('./field-definition.model');
return {
fields: {
relation: BaseModel.HasManyRelation,
modelClass: FieldDefinition,
join: {
from: 'object_definitions.id',
to: 'field_definitions.objectDefinitionId',
},
},
};
}
}

View File

@@ -0,0 +1,25 @@
import { BaseModel } from './base.model';
export class Permission extends BaseModel {
static tableName = 'permissions';
id!: string;
name!: string;
guardName!: string;
description?: string;
static relationMappings = {
roles: {
relation: BaseModel.ManyToManyRelation,
modelClass: 'role.model',
join: {
from: 'permissions.id',
through: {
from: 'role_permissions.permissionId',
to: 'role_permissions.roleId',
},
to: 'roles.id',
},
},
};
}

View File

@@ -0,0 +1,28 @@
import { BaseModel } from './base.model';
export class RolePermission extends BaseModel {
static tableName = 'role_permissions';
id!: string;
roleId!: string;
permissionId!: string;
static relationMappings = {
role: {
relation: BaseModel.BelongsToOneRelation,
modelClass: 'role.model',
join: {
from: 'role_permissions.roleId',
to: 'roles.id',
},
},
permission: {
relation: BaseModel.BelongsToOneRelation,
modelClass: 'permission.model',
join: {
from: 'role_permissions.permissionId',
to: 'permissions.id',
},
},
};
}

View File

@@ -0,0 +1,66 @@
import { BaseModel } from './base.model';
export class Role extends BaseModel {
static tableName = 'roles';
id: string;
name: string;
guardName: string;
description?: string;
createdAt: Date;
updatedAt: Date;
static get jsonSchema() {
return {
type: 'object',
required: ['name'],
properties: {
id: { type: 'string' },
name: { type: 'string' },
guardName: { type: 'string' },
description: { type: 'string' },
},
};
}
static get relationMappings() {
const { RolePermission } = require('./role-permission.model');
const { Permission } = require('./permission.model');
const { User } = require('./user.model');
return {
rolePermissions: {
relation: BaseModel.HasManyRelation,
modelClass: RolePermission,
join: {
from: 'roles.id',
to: 'role_permissions.roleId',
},
},
permissions: {
relation: BaseModel.ManyToManyRelation,
modelClass: Permission,
join: {
from: 'roles.id',
through: {
from: 'role_permissions.roleId',
to: 'role_permissions.permissionId',
},
to: 'permissions.id',
},
},
users: {
relation: BaseModel.ManyToManyRelation,
modelClass: User,
join: {
from: 'roles.id',
through: {
from: 'user_roles.roleId',
to: 'user_roles.userId',
},
to: 'users.id',
},
},
};
}
}

View File

@@ -0,0 +1,28 @@
import { BaseModel } from './base.model';
export class UserRole extends BaseModel {
static tableName = 'user_roles';
id!: string;
userId!: string;
roleId!: string;
static relationMappings = {
user: {
relation: BaseModel.BelongsToOneRelation,
modelClass: 'user.model',
join: {
from: 'user_roles.userId',
to: 'users.id',
},
},
role: {
relation: BaseModel.BelongsToOneRelation,
modelClass: 'role.model',
join: {
from: 'user_roles.roleId',
to: 'roles.id',
},
},
};
}

View File

@@ -0,0 +1,57 @@
import { BaseModel } from './base.model';
export class User extends BaseModel {
static tableName = 'users';
id: string;
email: string;
password: string;
firstName?: string;
lastName?: string;
isActive: boolean;
createdAt: Date;
updatedAt: Date;
static get jsonSchema() {
return {
type: 'object',
required: ['email', 'password'],
properties: {
id: { type: 'string' },
email: { type: 'string', format: 'email' },
password: { type: 'string' },
firstName: { type: 'string' },
lastName: { type: 'string' },
isActive: { type: 'boolean' },
},
};
}
static get relationMappings() {
const { UserRole } = require('./user-role.model');
const { Role } = require('./role.model');
return {
userRoles: {
relation: BaseModel.HasManyRelation,
modelClass: UserRole,
join: {
from: 'users.id',
to: 'user_roles.userId',
},
},
roles: {
relation: BaseModel.ManyToManyRelation,
modelClass: Role,
join: {
from: 'users.id',
through: {
from: 'user_roles.userId',
to: 'user_roles.roleId',
},
to: 'roles.id',
},
},
};
}
}