BREAKING CHANGE
API and persisted records use PowerOnModel system fields: - sysCreatedAt, sysCreatedBy, sysModifiedAt, sysModifiedBy Removed legacy JSON/DB field names: - _createdAt, _createdBy, _modifiedAt, _modifiedBy Frontend (frontend_nyla) and gateway call sites were updated accordingly. Database: - Bootstrap runs idempotent backfill (_migrateSystemFieldColumns) from old underscore columns and selected business duplicates into sys* where sys* IS NULL. - Re-run app bootstrap against each PostgreSQL database after deploy. - Optional: DROP INDEX IF EXISTS "idx_invitation_createdby" if an old index remains; new index: idx_invitation_syscreatedby on Invitation(sysCreatedBy). Tests: - RBAC integration tests aligned with current GROUP mandate filter and UserMandate-based UserConnection GROUP clause; buildRbacWhereClause(..., mandateId=...) must be passed explicitly (same as production request context).
This commit is contained in:
parent
f5f6cad542
commit
77e7eba711
34 changed files with 89 additions and 89 deletions
|
|
@ -258,7 +258,7 @@ export interface Automation2Task {
|
|||
result?: Record<string, unknown>;
|
||||
/** Workflow label (enriched by API) */
|
||||
workflowLabel?: string;
|
||||
/** Unix timestamp ms (from _createdAt) */
|
||||
/** Unix timestamp ms (from sysCreatedAt) */
|
||||
createdAt?: number;
|
||||
/** Optional due date - configurable in future */
|
||||
dueAt?: number;
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@ export interface Automation {
|
|||
nextExecution?: number;
|
||||
executionLogs?: AutomationLog[];
|
||||
allowedProviders?: string[];
|
||||
_createdAt?: number;
|
||||
sysCreatedAt?: number;
|
||||
_updatedAt?: number;
|
||||
_createdByUserName?: string;
|
||||
sysCreatedByUserName?: string;
|
||||
mandateName?: string;
|
||||
featureInstanceName?: string;
|
||||
[key: string]: any;
|
||||
|
|
@ -48,9 +48,9 @@ export interface AutomationTemplate {
|
|||
label: TextMultilingual;
|
||||
overview?: TextMultilingual;
|
||||
template: string; // JSON string with {{KEY:...}} placeholders
|
||||
_createdAt?: number;
|
||||
_createdBy?: string;
|
||||
_createdByUserName?: string;
|
||||
sysCreatedAt?: number;
|
||||
sysCreatedBy?: string;
|
||||
sysCreatedByUserName?: string;
|
||||
}
|
||||
|
||||
// Workflow action definition from backend
|
||||
|
|
@ -301,7 +301,7 @@ export async function fetchAutomationTemplateById(
|
|||
*/
|
||||
export async function createAutomationTemplateApi(
|
||||
request: ApiRequestFunction,
|
||||
templateData: Omit<AutomationTemplate, 'id' | '_createdAt' | '_createdBy'>
|
||||
templateData: Omit<AutomationTemplate, 'id' | 'sysCreatedAt' | 'sysCreatedBy'>
|
||||
): Promise<AutomationTemplate> {
|
||||
return await request({
|
||||
url: '/api/automation-templates',
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ export interface Prompt {
|
|||
mandateId: string;
|
||||
content: string;
|
||||
name: string;
|
||||
_createdBy?: string;
|
||||
sysCreatedBy?: string;
|
||||
_hideDelete?: boolean;
|
||||
[key: string]: any; // Allow additional properties
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ export interface RealEstateProject {
|
|||
featureInstanceId?: string;
|
||||
perimeter?: any;
|
||||
parzellen?: RealEstateParcel[];
|
||||
_createdAt?: number;
|
||||
_modifiedAt?: number;
|
||||
sysCreatedAt?: number;
|
||||
sysModifiedAt?: number;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
|
|
@ -38,8 +38,8 @@ export interface RealEstateParcel {
|
|||
plz?: string;
|
||||
perimeter?: any;
|
||||
bauzone?: string;
|
||||
_createdAt?: number;
|
||||
_modifiedAt?: number;
|
||||
sysCreatedAt?: number;
|
||||
sysModifiedAt?: number;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,10 +18,10 @@ export interface TrusteeOrganisation {
|
|||
label: string;
|
||||
enabled: boolean;
|
||||
mandateId?: string;
|
||||
_createdAt?: number;
|
||||
_modifiedAt?: number;
|
||||
_createdBy?: string;
|
||||
_modifiedBy?: string;
|
||||
sysCreatedAt?: number;
|
||||
sysModifiedAt?: number;
|
||||
sysCreatedBy?: string;
|
||||
sysModifiedBy?: string;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
|
|
@ -29,10 +29,10 @@ export interface TrusteeRole {
|
|||
id: string;
|
||||
desc: string;
|
||||
mandateId?: string;
|
||||
_createdAt?: number;
|
||||
_modifiedAt?: number;
|
||||
_createdBy?: string;
|
||||
_modifiedBy?: string;
|
||||
sysCreatedAt?: number;
|
||||
sysModifiedAt?: number;
|
||||
sysCreatedBy?: string;
|
||||
sysModifiedBy?: string;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
|
|
@ -43,10 +43,10 @@ export interface TrusteeAccess {
|
|||
userId: string;
|
||||
contractId?: string | null;
|
||||
mandateId?: string;
|
||||
_createdAt?: number;
|
||||
_modifiedAt?: number;
|
||||
_createdBy?: string;
|
||||
_modifiedBy?: string;
|
||||
sysCreatedAt?: number;
|
||||
sysModifiedAt?: number;
|
||||
sysCreatedBy?: string;
|
||||
sysModifiedBy?: string;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
|
|
@ -56,10 +56,10 @@ export interface TrusteeContract {
|
|||
label: string;
|
||||
enabled: boolean;
|
||||
mandateId?: string;
|
||||
_createdAt?: number;
|
||||
_modifiedAt?: number;
|
||||
_createdBy?: string;
|
||||
_modifiedBy?: string;
|
||||
sysCreatedAt?: number;
|
||||
sysModifiedAt?: number;
|
||||
sysCreatedBy?: string;
|
||||
sysModifiedBy?: string;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
|
|
@ -71,10 +71,10 @@ export interface TrusteeDocument {
|
|||
documentMimeType: string;
|
||||
documentData?: any;
|
||||
mandateId?: string;
|
||||
_createdAt?: number;
|
||||
_modifiedAt?: number;
|
||||
_createdBy?: string;
|
||||
_modifiedBy?: string;
|
||||
sysCreatedAt?: number;
|
||||
sysModifiedAt?: number;
|
||||
sysCreatedBy?: string;
|
||||
sysModifiedBy?: string;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
|
|
@ -98,10 +98,10 @@ export interface TrusteePosition {
|
|||
costCenter?: string;
|
||||
bookingReference?: string;
|
||||
mandateId?: string;
|
||||
_createdAt?: number;
|
||||
_modifiedAt?: number;
|
||||
_createdBy?: string;
|
||||
_modifiedBy?: string;
|
||||
sysCreatedAt?: number;
|
||||
sysModifiedAt?: number;
|
||||
sysCreatedBy?: string;
|
||||
sysModifiedBy?: string;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
|
|
@ -696,8 +696,8 @@ export interface TrusteePositionDocument {
|
|||
documentId: string;
|
||||
mandateId?: string;
|
||||
featureInstanceId?: string;
|
||||
_createdAt?: number;
|
||||
_modifiedAt?: number;
|
||||
sysCreatedAt?: number;
|
||||
sysModifiedAt?: number;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@ export function useMandates() {
|
|||
return false; // Don't show readonly fields in edit form
|
||||
}
|
||||
// Also filter out common non-editable fields
|
||||
const nonEditableFields = ['id', 'mandateId', '_createdBy', '_hideDelete'];
|
||||
const nonEditableFields = ['id', 'mandateId', 'sysCreatedBy', '_hideDelete'];
|
||||
return !nonEditableFields.includes(attr.name);
|
||||
})
|
||||
.map(attr => {
|
||||
|
|
@ -305,7 +305,7 @@ export function useMandates() {
|
|||
return false;
|
||||
}
|
||||
// Filter out ID fields and other auto-generated fields
|
||||
const nonEditableFields = ['id', 'mandateId', '_createdBy', '_hideDelete'];
|
||||
const nonEditableFields = ['id', 'mandateId', 'sysCreatedBy', '_hideDelete'];
|
||||
return !nonEditableFields.includes(attr.name);
|
||||
})
|
||||
.map(attr => {
|
||||
|
|
|
|||
|
|
@ -206,7 +206,7 @@ export function useRbacRoles() {
|
|||
return false; // Don't show readonly fields in edit form
|
||||
}
|
||||
// Also filter out common non-editable fields
|
||||
const nonEditableFields = ['id', 'roleId', '_createdBy', '_hideDelete'];
|
||||
const nonEditableFields = ['id', 'roleId', 'sysCreatedBy', '_hideDelete'];
|
||||
return !nonEditableFields.includes(attr.name);
|
||||
})
|
||||
.map(attr => {
|
||||
|
|
@ -346,7 +346,7 @@ export function useRbacRoles() {
|
|||
return false;
|
||||
}
|
||||
// Filter out ID fields and other auto-generated fields
|
||||
const nonEditableFields = ['id', 'roleId', '_createdBy', '_hideDelete'];
|
||||
const nonEditableFields = ['id', 'roleId', 'sysCreatedBy', '_hideDelete'];
|
||||
return !nonEditableFields.includes(attr.name);
|
||||
})
|
||||
.map(attr => {
|
||||
|
|
|
|||
|
|
@ -182,7 +182,7 @@ export function useRbacRules() {
|
|||
return false; // Don't show readonly fields in edit form
|
||||
}
|
||||
// Also filter out common non-editable fields
|
||||
const nonEditableFields = ['id', 'ruleId', '_createdBy', '_hideDelete'];
|
||||
const nonEditableFields = ['id', 'ruleId', 'sysCreatedBy', '_hideDelete'];
|
||||
return !nonEditableFields.includes(attr.name);
|
||||
})
|
||||
.map(attr => {
|
||||
|
|
@ -322,7 +322,7 @@ export function useRbacRules() {
|
|||
return false;
|
||||
}
|
||||
// Filter out ID fields and other auto-generated fields
|
||||
const nonEditableFields = ['id', 'ruleId', '_createdBy', '_hideDelete'];
|
||||
const nonEditableFields = ['id', 'ruleId', 'sysCreatedBy', '_hideDelete'];
|
||||
return !nonEditableFields.includes(attr.name);
|
||||
})
|
||||
.map(attr => {
|
||||
|
|
|
|||
|
|
@ -536,7 +536,7 @@ export function useAutomationTemplates() {
|
|||
return await fetchAutomationTemplateById(request, templateId);
|
||||
}, [request]);
|
||||
|
||||
const createTemplate = useCallback(async (data: Omit<AutomationTemplate, 'id' | '_createdAt' | '_createdBy'>) => {
|
||||
const createTemplate = useCallback(async (data: Omit<AutomationTemplate, 'id' | 'sysCreatedAt' | 'sysCreatedBy'>) => {
|
||||
return await createAutomationTemplateApi(request, data);
|
||||
}, [request]);
|
||||
|
||||
|
|
|
|||
|
|
@ -83,11 +83,11 @@ export function useTablePermission(tableName: string) {
|
|||
canDelete: hasAccess(permission.delete),
|
||||
|
||||
// Record-basierte Prüfungen
|
||||
canReadRecord: (record: { _createdBy?: string }) =>
|
||||
canReadRecord: (record: { sysCreatedBy?: string }) =>
|
||||
canAccessRecord(permission.read, record, userId),
|
||||
canUpdateRecord: (record: { _createdBy?: string }) =>
|
||||
canUpdateRecord: (record: { sysCreatedBy?: string }) =>
|
||||
canAccessRecord(permission.update, record, userId),
|
||||
canDeleteRecord: (record: { _createdBy?: string }) =>
|
||||
canDeleteRecord: (record: { sysCreatedBy?: string }) =>
|
||||
canAccessRecord(permission.delete, record, userId),
|
||||
};
|
||||
}
|
||||
|
|
@ -296,7 +296,7 @@ export function useInstancePermissions(): InstancePermissions | undefined {
|
|||
*/
|
||||
export function useCanEditRecord(
|
||||
tableName: string,
|
||||
record: { _createdBy?: string } | undefined,
|
||||
record: { sysCreatedBy?: string } | undefined,
|
||||
userId: string
|
||||
): boolean {
|
||||
const { update } = useTablePermission(tableName);
|
||||
|
|
@ -311,7 +311,7 @@ export function useCanEditRecord(
|
|||
*/
|
||||
export function useCanDeleteRecord(
|
||||
tableName: string,
|
||||
record: { _createdBy?: string } | undefined,
|
||||
record: { sysCreatedBy?: string } | undefined,
|
||||
userId: string
|
||||
): boolean {
|
||||
const { delete: deleteLevel } = useTablePermission(tableName);
|
||||
|
|
@ -329,7 +329,7 @@ interface PermissionGateProps {
|
|||
table?: string;
|
||||
view?: string;
|
||||
action?: 'view' | 'read' | 'create' | 'update' | 'delete';
|
||||
record?: { _createdBy?: string };
|
||||
record?: { sysCreatedBy?: string };
|
||||
children: React.ReactNode;
|
||||
fallback?: React.ReactNode;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ export function usePrompts() {
|
|||
return false; // Don't show readonly fields in edit form
|
||||
}
|
||||
// Also filter out common non-editable fields
|
||||
const nonEditableFields = ['id', 'mandateId', '_createdBy', '_hideDelete'];
|
||||
const nonEditableFields = ['id', 'mandateId', 'sysCreatedBy', '_hideDelete'];
|
||||
return !nonEditableFields.includes(attr.name);
|
||||
})
|
||||
.map(attr => {
|
||||
|
|
@ -367,7 +367,7 @@ export function usePrompts() {
|
|||
return false;
|
||||
}
|
||||
// Filter out ID fields and other auto-generated fields
|
||||
const nonEditableFields = ['id', 'mandateId', '_createdBy', '_hideDelete'];
|
||||
const nonEditableFields = ['id', 'mandateId', 'sysCreatedBy', '_hideDelete'];
|
||||
return !nonEditableFields.includes(attr.name);
|
||||
})
|
||||
.map(attr => {
|
||||
|
|
@ -530,7 +530,7 @@ export function usePromptOperations() {
|
|||
|
||||
try {
|
||||
// Pass all provided fields (supports partial inline updates like isSystem toggle)
|
||||
const { id, mandateId, _createdBy, _createdAt, _modifiedAt, _permissions, ...requestBody } = updateData;
|
||||
const { id, mandateId, sysCreatedBy, sysCreatedAt, sysModifiedAt, _permissions, ...requestBody } = updateData;
|
||||
|
||||
const updatedPrompt = await updatePromptApi(request, promptId, requestBody as UpdatePromptData);
|
||||
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@ function _createRealEstateEntityHook<T extends { id: string }>(config: RealEstat
|
|||
.filter(attr => {
|
||||
if (attr.readonly === true || attr.editable === false) return false;
|
||||
if (attr.name === 'id') return false;
|
||||
const nonEditable = ['_createdBy', '_createdAt', '_modifiedBy', '_modifiedAt'];
|
||||
const nonEditable = ['sysCreatedBy', 'sysCreatedAt', 'sysModifiedBy', 'sysModifiedAt'];
|
||||
return !nonEditable.includes(attr.name);
|
||||
})
|
||||
.map(attr => {
|
||||
|
|
@ -210,7 +210,7 @@ function _createRealEstateEntityHook<T extends { id: string }>(config: RealEstat
|
|||
const generateCreateFieldsFromAttributes = useCallback(() => {
|
||||
if (!attributes || attributes.length === 0) return [];
|
||||
return attributes
|
||||
.filter(attr => !['_createdBy', '_createdAt', '_modifiedBy', '_modifiedAt', 'mandateId', 'featureInstanceId'].includes(attr.name))
|
||||
.filter(attr => !['sysCreatedBy', 'sysCreatedAt', 'sysModifiedBy', 'sysModifiedAt', 'mandateId', 'featureInstanceId'].includes(attr.name))
|
||||
.map(attr => {
|
||||
let fieldType: 'string' | 'boolean' | 'email' | 'textarea' | 'date' | 'enum' | 'multiselect' | 'readonly' | 'number' = 'string';
|
||||
let options: Array<{ value: string | number; label: string }> | undefined;
|
||||
|
|
|
|||
|
|
@ -218,7 +218,7 @@ function _createTrusteeEntityHook<T extends { id: string }>(config: TrusteeEntit
|
|||
if (attr.name === 'id') {
|
||||
return false;
|
||||
}
|
||||
const nonEditableFields = ['_createdBy', '_createdAt', '_modifiedBy', '_modifiedAt'];
|
||||
const nonEditableFields = ['sysCreatedBy', 'sysCreatedAt', 'sysModifiedBy', 'sysModifiedAt'];
|
||||
return !nonEditableFields.includes(attr.name);
|
||||
})
|
||||
.map(attr => {
|
||||
|
|
@ -284,7 +284,7 @@ function _createTrusteeEntityHook<T extends { id: string }>(config: TrusteeEntit
|
|||
|
||||
return attributes
|
||||
.filter(attr => {
|
||||
const systemFields = ['_createdBy', '_createdAt', '_modifiedBy', '_modifiedAt', 'mandateId'];
|
||||
const systemFields = ['sysCreatedBy', 'sysCreatedAt', 'sysModifiedBy', 'sysModifiedAt', 'mandateId'];
|
||||
return !systemFields.includes(attr.name);
|
||||
})
|
||||
.map(attr => {
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ export function useTrusteeAccess() {
|
|||
if (attr.readonly === true || attr.editable === false) {
|
||||
return false;
|
||||
}
|
||||
const nonEditableFields = ['id', 'mandate', '_createdBy', '_modifiedBy', '_createdAt', '_modifiedAt'];
|
||||
const nonEditableFields = ['id', 'mandate', 'sysCreatedBy', 'sysModifiedBy', 'sysCreatedAt', 'sysModifiedAt'];
|
||||
return !nonEditableFields.includes(attr.name);
|
||||
})
|
||||
.map(attr => {
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ export function useTrusteeContracts() {
|
|||
if (attr.readonly === true || attr.editable === false) {
|
||||
return false;
|
||||
}
|
||||
const nonEditableFields = ['id', 'mandate', '_createdBy', '_modifiedBy', '_createdAt', '_modifiedAt'];
|
||||
const nonEditableFields = ['id', 'mandate', 'sysCreatedBy', 'sysModifiedBy', 'sysCreatedAt', 'sysModifiedAt'];
|
||||
return !nonEditableFields.includes(attr.name);
|
||||
})
|
||||
.map(attr => {
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ export function useTrusteeDocuments() {
|
|||
return false;
|
||||
}
|
||||
// documentData is handled separately (binary upload)
|
||||
const nonEditableFields = ['id', 'documentData', 'mandate', '_createdBy', '_modifiedBy', '_createdAt', '_modifiedAt'];
|
||||
const nonEditableFields = ['id', 'documentData', 'mandate', 'sysCreatedBy', 'sysModifiedBy', 'sysCreatedAt', 'sysModifiedAt'];
|
||||
return !nonEditableFields.includes(attr.name);
|
||||
})
|
||||
.map(attr => {
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ export function useTrusteeOrganisations() {
|
|||
if (attr.readonly === true || attr.editable === false) {
|
||||
return false;
|
||||
}
|
||||
const nonEditableFields = ['mandate', '_createdBy', '_modifiedBy', '_createdAt', '_modifiedAt'];
|
||||
const nonEditableFields = ['mandate', 'sysCreatedBy', 'sysModifiedBy', 'sysCreatedAt', 'sysModifiedAt'];
|
||||
return !nonEditableFields.includes(attr.name);
|
||||
})
|
||||
.map(attr => {
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ export function useTrusteePositionDocuments() {
|
|||
if (attr.readonly === true || attr.editable === false) {
|
||||
return false;
|
||||
}
|
||||
const nonEditableFields = ['id', 'mandate', '_createdBy', '_modifiedBy', '_createdAt', '_modifiedAt'];
|
||||
const nonEditableFields = ['id', 'mandate', 'sysCreatedBy', 'sysModifiedBy', 'sysCreatedAt', 'sysModifiedAt'];
|
||||
return !nonEditableFields.includes(attr.name);
|
||||
})
|
||||
.map(attr => {
|
||||
|
|
|
|||
|
|
@ -178,7 +178,7 @@ export function useTrusteePositions() {
|
|||
if (attr.readonly === true || attr.editable === false) {
|
||||
return false;
|
||||
}
|
||||
const nonEditableFields = ['id', 'mandate', '_createdBy', '_modifiedBy', '_createdAt', '_modifiedAt'];
|
||||
const nonEditableFields = ['id', 'mandate', 'sysCreatedBy', 'sysModifiedBy', 'sysCreatedAt', 'sysModifiedAt'];
|
||||
return !nonEditableFields.includes(attr.name);
|
||||
})
|
||||
.map(attr => {
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ export function useTrusteeRoles() {
|
|||
if (attr.readonly === true || attr.editable === false) {
|
||||
return false;
|
||||
}
|
||||
const nonEditableFields = ['mandate', '_createdBy', '_modifiedBy', '_createdAt', '_modifiedAt'];
|
||||
const nonEditableFields = ['mandate', 'sysCreatedBy', 'sysModifiedBy', 'sysCreatedAt', 'sysModifiedAt'];
|
||||
return !nonEditableFields.includes(attr.name);
|
||||
})
|
||||
.map(attr => {
|
||||
|
|
|
|||
|
|
@ -412,7 +412,7 @@ export function useOrgUsers() {
|
|||
return false; // Don't show readonly fields in edit form
|
||||
}
|
||||
// Also filter out common non-editable fields
|
||||
const nonEditableFields = ['id', 'mandateId', '_createdBy', '_hideDelete'];
|
||||
const nonEditableFields = ['id', 'mandateId', 'sysCreatedBy', '_hideDelete'];
|
||||
return !nonEditableFields.includes(attr.name);
|
||||
})
|
||||
.map(attr => {
|
||||
|
|
@ -560,7 +560,7 @@ export function useOrgUsers() {
|
|||
return false;
|
||||
}
|
||||
// Filter out ID fields and other auto-generated fields
|
||||
const nonEditableFields = ['id', 'mandateId', '_createdBy', '_hideDelete', 'authenticationAuthority'];
|
||||
const nonEditableFields = ['id', 'mandateId', 'sysCreatedBy', '_hideDelete', 'authenticationAuthority'];
|
||||
return !nonEditableFields.includes(attr.name);
|
||||
})
|
||||
.map(attr => {
|
||||
|
|
|
|||
|
|
@ -224,7 +224,7 @@ export function useUserWorkflows(options?: { instanceId?: string; featureCode?:
|
|||
return false; // Don't show readonly fields in edit form
|
||||
}
|
||||
// Also filter out common non-editable fields
|
||||
const nonEditableFields = ['id', 'mandateId', '_createdBy', '_hideDelete'];
|
||||
const nonEditableFields = ['id', 'mandateId', 'sysCreatedBy', '_hideDelete'];
|
||||
return !nonEditableFields.includes(attr.name);
|
||||
})
|
||||
.map(attr => {
|
||||
|
|
|
|||
|
|
@ -204,7 +204,7 @@ export const ConnectionsPage: React.FC = () => {
|
|||
|
||||
// Form attributes for edit modal
|
||||
const formAttributes = useMemo(() => {
|
||||
const excludedFields = ['id', 'mandateId', 'userId', '_createdBy', '_createdAt', '_modifiedAt', 'connectedAt', 'lastChecked'];
|
||||
const excludedFields = ['id', 'mandateId', 'userId', 'sysCreatedBy', 'sysCreatedAt', 'sysModifiedAt', 'connectedAt', 'lastChecked'];
|
||||
return (attributes || [])
|
||||
.filter(attr => !excludedFields.includes(attr.name));
|
||||
}, [attributes]);
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ export const FilesPage: React.FC = () => {
|
|||
}));
|
||||
|
||||
cols.push({
|
||||
key: '_createdBy',
|
||||
key: 'sysCreatedBy',
|
||||
label: 'Created By',
|
||||
type: 'text' as any,
|
||||
sortable: true,
|
||||
|
|
@ -289,7 +289,7 @@ export const FilesPage: React.FC = () => {
|
|||
}, [selectedFolderId, _tableRefetch]);
|
||||
|
||||
const formAttributes = useMemo(() => {
|
||||
const excludedFields = ['id', 'mandateId', 'fileHash', '_createdBy', '_createdAt', '_modifiedAt', 'creationDate', 'source'];
|
||||
const excludedFields = ['id', 'mandateId', 'fileHash', 'sysCreatedBy', 'sysCreatedAt', 'sysModifiedAt', 'creationDate', 'source'];
|
||||
return (attributes || []).filter(attr => !excludedFields.includes(attr.name));
|
||||
}, [attributes]);
|
||||
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ export const PromptsPage: React.FC = () => {
|
|||
// Generate columns from attributes - exclude ID fields from display
|
||||
const columns = useMemo(() => {
|
||||
// Fields to hide in table view
|
||||
const hiddenColumns = ['id', 'mandateId', '_createdAt', '_modifiedAt', '_hideDelete', '_permissions'];
|
||||
const hiddenColumns = ['id', 'mandateId', 'sysCreatedAt', 'sysModifiedAt', '_hideDelete', '_permissions'];
|
||||
|
||||
const cols = (attributes || [])
|
||||
.filter(attr => !hiddenColumns.includes(attr.name))
|
||||
|
|
@ -71,9 +71,9 @@ export const PromptsPage: React.FC = () => {
|
|||
fkDisplayField: (attr as any).fkDisplayField,
|
||||
}));
|
||||
|
||||
// Add _createdBy column with FK resolution to show username
|
||||
// Add sysCreatedBy column with FK resolution to show username
|
||||
cols.push({
|
||||
key: '_createdBy',
|
||||
key: 'sysCreatedBy',
|
||||
label: 'Created By',
|
||||
type: 'text' as any,
|
||||
sortable: true,
|
||||
|
|
@ -148,7 +148,7 @@ export const PromptsPage: React.FC = () => {
|
|||
|
||||
// Form attributes for create/edit modal
|
||||
const formAttributes = useMemo(() => {
|
||||
const excludedFields = ['id', 'mandateId', 'isSystem', '_createdBy', '_createdAt', '_modifiedAt', '_hideDelete', '_permissions'];
|
||||
const excludedFields = ['id', 'mandateId', 'isSystem', 'sysCreatedBy', 'sysCreatedAt', 'sysModifiedAt', '_hideDelete', '_permissions'];
|
||||
return (attributes || [])
|
||||
.filter(attr => !excludedFields.includes(attr.name));
|
||||
}, [attributes]);
|
||||
|
|
|
|||
|
|
@ -110,9 +110,9 @@ export const AutomationDefinitionsView: React.FC = () => {
|
|||
|
||||
const columns = useMemo(() => {
|
||||
const hiddenColumns = [
|
||||
'id', 'mandateId', 'featureInstanceId', '_createdBy', '_createdAt', '_modifiedAt',
|
||||
'id', 'mandateId', 'featureInstanceId', 'sysCreatedBy', 'sysCreatedAt', 'sysModifiedAt',
|
||||
'template', 'executionLogs', 'placeholders',
|
||||
'_createdByUserName', 'mandateName', 'featureInstanceName',
|
||||
'sysCreatedByUserName', 'mandateName', 'featureInstanceName',
|
||||
];
|
||||
const attrColumns = (attributes || [])
|
||||
.filter(attr => !hiddenColumns.includes(attr.name))
|
||||
|
|
@ -130,7 +130,7 @@ export const AutomationDefinitionsView: React.FC = () => {
|
|||
const enrichedColumns = [
|
||||
{ key: 'mandateName', label: 'Mandant', type: 'text' as any, sortable: true, filterable: true, searchable: true, width: 150, minWidth: 100, maxWidth: 250 },
|
||||
{ key: 'featureInstanceName', label: 'Feature-Instanz', type: 'text' as any, sortable: true, filterable: true, searchable: true, width: 160, minWidth: 100, maxWidth: 250 },
|
||||
{ key: '_createdByUserName', label: 'Erstellt von', type: 'text' as any, sortable: true, filterable: true, searchable: true, width: 150, minWidth: 100, maxWidth: 250 },
|
||||
{ key: 'sysCreatedByUserName', label: 'Erstellt von', type: 'text' as any, sortable: true, filterable: true, searchable: true, width: 150, minWidth: 100, maxWidth: 250 },
|
||||
];
|
||||
return [...attrColumns, ...enrichedColumns];
|
||||
}, [attributes]);
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ export const AutomationTemplatesView: React.FC = () => {
|
|||
value ? <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4, fontSize: '0.75rem', padding: '0.125rem 0.5rem', borderRadius: 10, background: 'var(--info-color, #3182ce)', color: '#fff' }}><FaLock style={{ fontSize: '0.625rem' }} /> System</span>
|
||||
: <span style={{ fontSize: '0.75rem', padding: '0.125rem 0.5rem', borderRadius: 10, background: 'var(--success-color, #38a169)', color: '#fff' }}>Instanz</span>
|
||||
},
|
||||
{ key: '_createdByUserName', label: 'Erstellt von', type: 'string' as const, width: 150 },
|
||||
{ key: 'sysCreatedByUserName', label: 'Erstellt von', type: 'string' as const, width: 150 },
|
||||
], []);
|
||||
|
||||
const handleEditClick = async (template: AutomationTemplate) => {
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ export const RealEstateParcelsView: React.FC = () => {
|
|||
};
|
||||
|
||||
const formAttributes = useMemo(() => {
|
||||
const excluded = ['id', 'mandateId', 'instanceId', '_createdBy', '_createdAt', '_modifiedAt', '_modifiedBy'];
|
||||
const excluded = ['id', 'mandateId', 'instanceId', 'sysCreatedBy', 'sysCreatedAt', 'sysModifiedAt', 'sysModifiedBy'];
|
||||
return (attributes || []).filter(attr => !excluded.includes(attr.name));
|
||||
}, [attributes]);
|
||||
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ export const RealEstateProjectsView: React.FC = () => {
|
|||
};
|
||||
|
||||
const formAttributes = useMemo(() => {
|
||||
const excluded = ['id', 'mandateId', 'instanceId', '_createdBy', '_createdAt', '_modifiedAt', '_modifiedBy'];
|
||||
const excluded = ['id', 'mandateId', 'instanceId', 'sysCreatedBy', 'sysCreatedAt', 'sysModifiedAt', 'sysModifiedBy'];
|
||||
return (attributes || []).filter(attr => !excluded.includes(attr.name));
|
||||
}, [attributes]);
|
||||
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ export const TrusteeDocumentsView: React.FC = () => {
|
|||
|
||||
// Form attributes (exclude system fields)
|
||||
const formAttributes = useMemo(() => {
|
||||
const excludedFields = ['id', 'mandateId', 'instanceId', '_createdBy', '_createdAt', '_modifiedAt', '_modifiedBy'];
|
||||
const excludedFields = ['id', 'mandateId', 'instanceId', 'sysCreatedBy', 'sysCreatedAt', 'sysModifiedAt', 'sysModifiedBy'];
|
||||
return (attributes || []).filter(attr => !excludedFields.includes(attr.name));
|
||||
}, [attributes]);
|
||||
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ export const TrusteePositionDocumentsView: React.FC = () => {
|
|||
if (!attributes || attributes.length === 0) return [];
|
||||
|
||||
// Exclude system fields from table columns
|
||||
const excludedFields = ['id', 'mandateId', 'featureInstanceId', '_createdBy', '_createdAt', '_modifiedAt', '_modifiedBy'];
|
||||
const excludedFields = ['id', 'mandateId', 'featureInstanceId', 'sysCreatedBy', 'sysCreatedAt', 'sysModifiedAt', 'sysModifiedBy'];
|
||||
|
||||
return attributes
|
||||
.filter((attr: any) => !excludedFields.includes(attr.name))
|
||||
|
|
@ -127,7 +127,7 @@ export const TrusteePositionDocumentsView: React.FC = () => {
|
|||
|
||||
// Form attributes (exclude system fields)
|
||||
const formAttributes = useMemo(() => {
|
||||
const excludedFields = ['id', 'mandateId', 'featureInstanceId', '_createdBy', '_createdAt', '_modifiedAt', '_modifiedBy'];
|
||||
const excludedFields = ['id', 'mandateId', 'featureInstanceId', 'sysCreatedBy', 'sysCreatedAt', 'sysModifiedAt', 'sysModifiedBy'];
|
||||
return (attributes || []).filter((attr: any) => !excludedFields.includes(attr.name));
|
||||
}, [attributes]);
|
||||
|
||||
|
|
|
|||
|
|
@ -257,7 +257,7 @@ export const TrusteePositionsView: React.FC = () => {
|
|||
const positionColumnOrder = [
|
||||
'_documentRefs', // Belege (download icons)
|
||||
'_syncStatus', // Sync-Status
|
||||
'_createdAt', // Erstellt am
|
||||
'sysCreatedAt', // Erstellt am
|
||||
'valuta', // Valuta date
|
||||
'tags',
|
||||
'company',
|
||||
|
|
@ -372,7 +372,7 @@ export const TrusteePositionsView: React.FC = () => {
|
|||
|
||||
// Form attributes (exclude system fields)
|
||||
const formAttributes = useMemo(() => {
|
||||
const excludedFields = ['id', 'mandateId', 'instanceId', '_createdBy', '_createdAt', '_modifiedAt', '_modifiedBy'];
|
||||
const excludedFields = ['id', 'mandateId', 'instanceId', 'sysCreatedBy', 'sysCreatedAt', 'sysModifiedAt', 'sysModifiedBy'];
|
||||
return (attributes || []).filter(attr => !excludedFields.includes(attr.name));
|
||||
}, [attributes]);
|
||||
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ const NeutralizationPanel: React.FC<NeutralizationPanelProps> = ({ instanceId })
|
|||
patternType: m.patternType || 'unknown',
|
||||
fileId: m.fileId,
|
||||
fileName: m.fileName,
|
||||
createdAt: m.createdAt || m._createdAt,
|
||||
createdAt: m.createdAt || m.sysCreatedAt,
|
||||
})));
|
||||
} catch (err) {
|
||||
console.error('Failed to load mappings:', err);
|
||||
|
|
|
|||
|
|
@ -322,14 +322,14 @@ export function hasAccess(level: AccessLevel): boolean {
|
|||
*/
|
||||
export function canAccessRecord(
|
||||
level: AccessLevel,
|
||||
record: { _createdBy?: string },
|
||||
record: { sysCreatedBy?: string },
|
||||
userId: string
|
||||
): boolean {
|
||||
switch (level) {
|
||||
case 'n':
|
||||
return false;
|
||||
case 'm':
|
||||
return record._createdBy === userId;
|
||||
return record.sysCreatedBy === userId;
|
||||
case 'g':
|
||||
case 'a':
|
||||
return true;
|
||||
|
|
|
|||
Loading…
Reference in a new issue