Added auth functionality, initial work with views and field types
This commit is contained in:
23
backend/src/models/account.model.ts
Normal file
23
backend/src/models/account.model.ts
Normal 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',
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
25
backend/src/models/app-page.model.ts
Normal file
25
backend/src/models/app-page.model.ts
Normal 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',
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
23
backend/src/models/app.model.ts
Normal file
23
backend/src/models/app.model.ts
Normal 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',
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
18
backend/src/models/base.model.ts
Normal file
18
backend/src/models/base.model.ts
Normal 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();
|
||||
}
|
||||
}
|
||||
78
backend/src/models/field-definition.model.ts
Normal file
78
backend/src/models/field-definition.model.ts
Normal 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',
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
46
backend/src/models/object-definition.model.ts
Normal file
46
backend/src/models/object-definition.model.ts
Normal 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',
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
25
backend/src/models/permission.model.ts
Normal file
25
backend/src/models/permission.model.ts
Normal 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',
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
28
backend/src/models/role-permission.model.ts
Normal file
28
backend/src/models/role-permission.model.ts
Normal 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',
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
66
backend/src/models/role.model.ts
Normal file
66
backend/src/models/role.model.ts
Normal 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',
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
28
backend/src/models/user-role.model.ts
Normal file
28
backend/src/models/user-role.model.ts
Normal 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',
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
57
backend/src/models/user.model.ts
Normal file
57
backend/src/models/user.model.ts
Normal 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',
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user