@litusarchieve18/agricore-utils 1.0.20 → 1.0.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -46,6 +46,7 @@ import {
46
46
  RelationshipType,
47
47
  RowOrientation,
48
48
  SENTINEL_UUID,
49
+ SESSION_SCHEMA,
49
50
  SIGNATURE_MODES,
50
51
  SoilTexture,
51
52
  StockPolicyTier,
@@ -61,7 +62,7 @@ import {
61
62
  UserRole,
62
63
  VigorRating,
63
64
  WaterSource
64
- } from "./chunk-XD36URZU.mjs";
65
+ } from "./chunk-V2DL7OTH.mjs";
65
66
  export {
66
67
  ACCESS_RANK,
67
68
  ACT,
@@ -110,6 +111,7 @@ export {
110
111
  RelationshipType,
111
112
  RowOrientation,
112
113
  SENTINEL_UUID,
114
+ SESSION_SCHEMA,
113
115
  SIGNATURE_MODES,
114
116
  SoilTexture,
115
117
  StockPolicyTier,
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { d as AgriCoreSession, aF as UserRoleType, ah as ResourceRequirement, c as AccessLevelType, j as AvailableScope, U as InfrastructureFields, S as FormMeta, av as TabConfig, af as ResolvedError } from './constants-C_Pwif6Q.mjs';
2
- export { A as ACCESS_RANK, a as ACT, b as AccessLevel, e as ApprovalStatus, f as ApprovalType, g as AuditStatus, h as AuditType, i as AuthScopeFields, B as BarcodeNamespace, k as BarcodeNamespaceType, l as BarcodeType, m as BarcodeTypeType, n as Base44Id, C as CAR_SUPPORTED_EVIDENCE_MIME_TYPES, o as CAR_SUPPORTED_SIGNATURE_MIME_TYPES, p as CAT, q as CATEGORY_TABS, r as CORRECTIVE_ACTION_GENERATION_SOURCES, s as CORRECTIVE_ACTION_STATUSES, t as CanonicalId, u as CarSupportedEvidenceMimeType, v as CarSupportedSignatureMimeType, w as CarTemplateFileMetadata, x as CatalogSyncStatus, y as CatalogSyncStatusType, z as CompanyConfig, D as CorrectiveActionCompileTaskMetadata, E as CorrectiveActionGenerationSource, F as CorrectiveActionStatus, G as CropCycleStatus, H as DOCUMENT_DISPLAY_INFO, I as DOCUMENT_MENU_MAP, J as DocumentCategory, K as DocumentType, L as ERROR_DICTIONARY, M as EVERYONE, N as EmitterType, O as EnabledModule, P as FORM_REGISTRY, Q as FacilityType, R as FileUploadTaskType, T as HarvestMethod, V as LinkedStatus, W as MOD, X as MODULE_LABELS, Y as MicroclimateZone, Z as MimeType, _ as ModCode, $ as NettingType, a0 as NormalizedSignatureValue, a1 as NotificationMode, a2 as OrderStatus, a3 as PermissionLevel, a4 as PhysicalState, a5 as PlantingMethod, a6 as ProductType, a7 as ProductTypeType, a8 as ProductUnit, a9 as ProductUnitType, aa as RESOURCE_MODULE_MAP, ab as RESOURCE_PATHS, ac as RESOURCE_REQUIREMENTS, ad as ROLE_SECTIONS_BY_KEY, ae as RelationshipType, ag as ResourceOverrides, ai as RowOrientation, aj as SENTINEL_UUID, ak as SIGNATURE_MODES, al as ScopeType, am as SignatureInput, an as SignatureMode, ao as SoilTexture, ap as StockPolicyTier, aq as StockPolicyTierType, ar as StoragePhases, as as StorageType, at as TASK_TYPE_REGISTRY, au as TEMPLATE_SCOPE_LEVELS, aw as TargetEntityType, ax as TaskStatus, ay as TaskType, az as TaskTypeConfig, aA as TemplateScopeLevel, aB as TransactionType, aC as TrellisType, aD as UserPrivilege, aE as UserRole, aG as VigorRating, aH as WaterSource } from './constants-C_Pwif6Q.mjs';
1
+ import { d as AgriCoreSession, ao as ScopeType, aL as WireSession, aI as UserRoleType, ah as ResourceRequirement, c as AccessLevelType, j as AvailableScope, U as InfrastructureFields, S as FormMeta, ay as TabConfig, af as ResolvedError } from './constants-lhTP4wzB.mjs';
2
+ export { A as ACCESS_RANK, a as ACT, b as AccessLevel, e as ApprovalStatus, f as ApprovalType, g as AuditStatus, h as AuditType, i as AuthScopeFields, B as BarcodeNamespace, k as BarcodeNamespaceType, l as BarcodeType, m as BarcodeTypeType, n as Base44Id, C as CAR_SUPPORTED_EVIDENCE_MIME_TYPES, o as CAR_SUPPORTED_SIGNATURE_MIME_TYPES, p as CAT, q as CATEGORY_TABS, r as CORRECTIVE_ACTION_GENERATION_SOURCES, s as CORRECTIVE_ACTION_STATUSES, t as CanonicalId, u as CarSupportedEvidenceMimeType, v as CarSupportedSignatureMimeType, w as CarTemplateFileMetadata, x as CatalogSyncStatus, y as CatalogSyncStatusType, z as CompanyConfig, D as CorrectiveActionCompileTaskMetadata, E as CorrectiveActionGenerationSource, F as CorrectiveActionStatus, G as CropCycleStatus, H as DOCUMENT_DISPLAY_INFO, I as DOCUMENT_MENU_MAP, J as DocumentCategory, K as DocumentType, L as ERROR_DICTIONARY, M as EVERYONE, N as EmitterType, O as EnabledModule, P as FORM_REGISTRY, Q as FacilityType, R as FileUploadTaskType, T as HarvestMethod, V as LinkedStatus, W as MOD, X as MODULE_LABELS, Y as MicroclimateZone, Z as MimeType, _ as ModCode, $ as NettingType, a0 as NormalizedSignatureValue, a1 as NotificationMode, a2 as OrderStatus, a3 as PermissionLevel, a4 as PhysicalState, a5 as PlantingMethod, a6 as ProductType, a7 as ProductTypeType, a8 as ProductUnit, a9 as ProductUnitType, aa as RESOURCE_MODULE_MAP, ab as RESOURCE_PATHS, ac as RESOURCE_REQUIREMENTS, ad as ROLE_SECTIONS_BY_KEY, ae as RelationshipType, ag as ResourceOverrides, ai as RoleAssignment, aj as RowOrientation, ak as SENTINEL_UUID, al as SESSION_SCHEMA, am as SIGNATURE_MODES, an as SchemaField, ap as SignatureInput, aq as SignatureMode, ar as SoilTexture, as as StockPolicyTier, at as StockPolicyTierType, au as StoragePhases, av as StorageType, aw as TASK_TYPE_REGISTRY, ax as TEMPLATE_SCOPE_LEVELS, az as TargetEntityType, aA as TaskStatus, aB as TaskType, aC as TaskTypeConfig, aD as TemplateScopeLevel, aE as TransactionType, aF as TrellisType, aG as UserPrivilege, aH as UserRole, aJ as VigorRating, aK as WaterSource } from './constants-lhTP4wzB.mjs';
3
3
 
4
4
  declare const AgriLogger: {
5
5
  log(level: "INFO" | "WARN" | "ERROR", message: string, meta: any): void;
@@ -104,24 +104,26 @@ declare function generateCanonicalId(): string;
104
104
  * Standardizes the creation of new entities by walking up the scope tree.
105
105
  */
106
106
  declare function generateInfrastructureFields(activeScope: AvailableScope, availableScopes: AvailableScope[]): InfrastructureFields;
107
- declare function buildRlsFilter(session: AgriCoreSession, extra?: Record<string, any>): {
108
- authScopeId: {
109
- $in: string[];
110
- };
111
- };
112
- declare function canRead(session: AgriCoreSession, authScopeId: string): boolean;
113
- declare function canWrite(session: AgriCoreSession, authScopeId: string, resourcePath: string): boolean;
107
+ declare function encodeSession(session: AgriCoreSession): WireSession;
108
+ declare function decodeSession(short: WireSession): AgriCoreSession;
109
+ declare function hasRoleAnywhere(session: AgriCoreSession, role: string): boolean;
110
+ declare function hasPrivilegeAnywhere(session: AgriCoreSession, privilege: string): boolean;
114
111
  /**
115
- * Hard-throws if the user cannot write.
116
- * Use this on the backend (inside Deno functions) to enforce server-side.
112
+ * "Does this user hold this role/privilege AT this specific scope?"
113
+ * This is the default choice for any authorization gate evaluating
114
+ * "can the user perform this action on the resource/scope they're
115
+ * currently acting on." No inheritance — only an explicit assignment
116
+ * at exactly this authScopeId counts, matching the no-inherit-write rule.
117
117
  */
118
- declare function assertCanWrite(session: AgriCoreSession, authScopeId: string, resourcePath: string): void;
118
+ declare function getRoleAt(session: AgriCoreSession, scopeId: string | undefined | null): string | null;
119
+ declare function hasRoleAt(session: AgriCoreSession, scopeId: string | undefined | null, allowedRoles: Set<string> | string[]): boolean;
120
+ declare function getPrivilegesAt(session: AgriCoreSession, scopeId: string | undefined | null): string[];
121
+ declare function hasPrivilegeAt(session: AgriCoreSession, scopeId: string | undefined | null, requiredPrivileges: string[]): boolean;
119
122
  /**
120
123
  * Full resolution: DB override → static config fallback → public default.
121
124
  * Returns 'NONE' | 'READ' | 'WRITE'.
122
125
  */
123
126
  declare function resolveAccess(session: AgriCoreSession, activeScopeId: string, tabConfig: TabConfig): 'NONE' | 'READ' | 'WRITE';
124
- declare function resolveMenuVisibility(session: AgriCoreSession, authScopeId: string, resourcePath: string): 'hidden' | 'read_only' | 'active';
125
127
  declare function isTabVisible(session: AgriCoreSession, activeScopeId: string, tabConfig: TabConfig): boolean;
126
128
  declare function isTabWritable(session: AgriCoreSession, activeScopeId: string, tabConfig: TabConfig): boolean;
127
129
  declare function evaluateBaseAccess(resourcePath: string, session: {
@@ -138,7 +140,7 @@ declare function assertTenantBoundary(db: any, session: AgriCoreSession, // Pass
138
140
  targets: {
139
141
  targetUserId?: string;
140
142
  authScopeId?: string;
141
- expectedScopeType?: 'company' | 'legalEntity' | 'facility';
143
+ expectedScopeType?: ScopeType;
142
144
  }): Promise<boolean>;
143
145
  declare function verifyAndExtractSession(token: string, secret: string): Promise<AgriCoreSession>;
144
146
  declare function getFormMeta(componentId: string): FormMeta | null;
@@ -172,4 +174,4 @@ declare function calculateFileMetadataMatch(criteria: {
172
174
  contextMatch?: string[];
173
175
  }, fileMetadata: Record<string, any>, auditContext: Record<string, any>): number;
174
176
 
175
- export { AccessLevelType, AgriCoreSession, AgriLogger, AppError, AvailableScope, Converter, ErrorFactory, FormMeta, InfrastructureFields, ResolvedError, ResourceRequirement, TabConfig, UserRoleType, Validator, assertCanWrite, assertTenantBoundary, buildRlsFilter, calculateFileMetadataMatch, canRead, canWrite, evaluateBaseAccess, extractAppCode, findSpecificOverride, generateCanonicalId, generateDocumentPath, generateInfrastructureFields, getAcceptedMimeTypes, getApproveAction, getFormMeta, getFormsGroupedByModule, getTaskTypeOptions, handleAppErrorResponse, isTabVisible, isTabWritable, resolveAccess, resolveAppError, resolveEffectiveAccess, resolveError, resolveMenuVisibility, verifyAndExtractSession, withAgriLogging };
177
+ export { AccessLevelType, AgriCoreSession, AgriLogger, AppError, AvailableScope, Converter, ErrorFactory, FormMeta, InfrastructureFields, ResolvedError, ResourceRequirement, ScopeType, TabConfig, UserRoleType, Validator, WireSession, assertTenantBoundary, calculateFileMetadataMatch, decodeSession, encodeSession, evaluateBaseAccess, extractAppCode, findSpecificOverride, generateCanonicalId, generateDocumentPath, generateInfrastructureFields, getAcceptedMimeTypes, getApproveAction, getFormMeta, getFormsGroupedByModule, getPrivilegesAt, getRoleAt, getTaskTypeOptions, handleAppErrorResponse, hasPrivilegeAnywhere, hasPrivilegeAt, hasRoleAnywhere, hasRoleAt, isTabVisible, isTabWritable, resolveAccess, resolveAppError, resolveEffectiveAccess, resolveError, verifyAndExtractSession, withAgriLogging };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { d as AgriCoreSession, aF as UserRoleType, ah as ResourceRequirement, c as AccessLevelType, j as AvailableScope, U as InfrastructureFields, S as FormMeta, av as TabConfig, af as ResolvedError } from './constants-C_Pwif6Q.js';
2
- export { A as ACCESS_RANK, a as ACT, b as AccessLevel, e as ApprovalStatus, f as ApprovalType, g as AuditStatus, h as AuditType, i as AuthScopeFields, B as BarcodeNamespace, k as BarcodeNamespaceType, l as BarcodeType, m as BarcodeTypeType, n as Base44Id, C as CAR_SUPPORTED_EVIDENCE_MIME_TYPES, o as CAR_SUPPORTED_SIGNATURE_MIME_TYPES, p as CAT, q as CATEGORY_TABS, r as CORRECTIVE_ACTION_GENERATION_SOURCES, s as CORRECTIVE_ACTION_STATUSES, t as CanonicalId, u as CarSupportedEvidenceMimeType, v as CarSupportedSignatureMimeType, w as CarTemplateFileMetadata, x as CatalogSyncStatus, y as CatalogSyncStatusType, z as CompanyConfig, D as CorrectiveActionCompileTaskMetadata, E as CorrectiveActionGenerationSource, F as CorrectiveActionStatus, G as CropCycleStatus, H as DOCUMENT_DISPLAY_INFO, I as DOCUMENT_MENU_MAP, J as DocumentCategory, K as DocumentType, L as ERROR_DICTIONARY, M as EVERYONE, N as EmitterType, O as EnabledModule, P as FORM_REGISTRY, Q as FacilityType, R as FileUploadTaskType, T as HarvestMethod, V as LinkedStatus, W as MOD, X as MODULE_LABELS, Y as MicroclimateZone, Z as MimeType, _ as ModCode, $ as NettingType, a0 as NormalizedSignatureValue, a1 as NotificationMode, a2 as OrderStatus, a3 as PermissionLevel, a4 as PhysicalState, a5 as PlantingMethod, a6 as ProductType, a7 as ProductTypeType, a8 as ProductUnit, a9 as ProductUnitType, aa as RESOURCE_MODULE_MAP, ab as RESOURCE_PATHS, ac as RESOURCE_REQUIREMENTS, ad as ROLE_SECTIONS_BY_KEY, ae as RelationshipType, ag as ResourceOverrides, ai as RowOrientation, aj as SENTINEL_UUID, ak as SIGNATURE_MODES, al as ScopeType, am as SignatureInput, an as SignatureMode, ao as SoilTexture, ap as StockPolicyTier, aq as StockPolicyTierType, ar as StoragePhases, as as StorageType, at as TASK_TYPE_REGISTRY, au as TEMPLATE_SCOPE_LEVELS, aw as TargetEntityType, ax as TaskStatus, ay as TaskType, az as TaskTypeConfig, aA as TemplateScopeLevel, aB as TransactionType, aC as TrellisType, aD as UserPrivilege, aE as UserRole, aG as VigorRating, aH as WaterSource } from './constants-C_Pwif6Q.js';
1
+ import { d as AgriCoreSession, ao as ScopeType, aL as WireSession, aI as UserRoleType, ah as ResourceRequirement, c as AccessLevelType, j as AvailableScope, U as InfrastructureFields, S as FormMeta, ay as TabConfig, af as ResolvedError } from './constants-lhTP4wzB.js';
2
+ export { A as ACCESS_RANK, a as ACT, b as AccessLevel, e as ApprovalStatus, f as ApprovalType, g as AuditStatus, h as AuditType, i as AuthScopeFields, B as BarcodeNamespace, k as BarcodeNamespaceType, l as BarcodeType, m as BarcodeTypeType, n as Base44Id, C as CAR_SUPPORTED_EVIDENCE_MIME_TYPES, o as CAR_SUPPORTED_SIGNATURE_MIME_TYPES, p as CAT, q as CATEGORY_TABS, r as CORRECTIVE_ACTION_GENERATION_SOURCES, s as CORRECTIVE_ACTION_STATUSES, t as CanonicalId, u as CarSupportedEvidenceMimeType, v as CarSupportedSignatureMimeType, w as CarTemplateFileMetadata, x as CatalogSyncStatus, y as CatalogSyncStatusType, z as CompanyConfig, D as CorrectiveActionCompileTaskMetadata, E as CorrectiveActionGenerationSource, F as CorrectiveActionStatus, G as CropCycleStatus, H as DOCUMENT_DISPLAY_INFO, I as DOCUMENT_MENU_MAP, J as DocumentCategory, K as DocumentType, L as ERROR_DICTIONARY, M as EVERYONE, N as EmitterType, O as EnabledModule, P as FORM_REGISTRY, Q as FacilityType, R as FileUploadTaskType, T as HarvestMethod, V as LinkedStatus, W as MOD, X as MODULE_LABELS, Y as MicroclimateZone, Z as MimeType, _ as ModCode, $ as NettingType, a0 as NormalizedSignatureValue, a1 as NotificationMode, a2 as OrderStatus, a3 as PermissionLevel, a4 as PhysicalState, a5 as PlantingMethod, a6 as ProductType, a7 as ProductTypeType, a8 as ProductUnit, a9 as ProductUnitType, aa as RESOURCE_MODULE_MAP, ab as RESOURCE_PATHS, ac as RESOURCE_REQUIREMENTS, ad as ROLE_SECTIONS_BY_KEY, ae as RelationshipType, ag as ResourceOverrides, ai as RoleAssignment, aj as RowOrientation, ak as SENTINEL_UUID, al as SESSION_SCHEMA, am as SIGNATURE_MODES, an as SchemaField, ap as SignatureInput, aq as SignatureMode, ar as SoilTexture, as as StockPolicyTier, at as StockPolicyTierType, au as StoragePhases, av as StorageType, aw as TASK_TYPE_REGISTRY, ax as TEMPLATE_SCOPE_LEVELS, az as TargetEntityType, aA as TaskStatus, aB as TaskType, aC as TaskTypeConfig, aD as TemplateScopeLevel, aE as TransactionType, aF as TrellisType, aG as UserPrivilege, aH as UserRole, aJ as VigorRating, aK as WaterSource } from './constants-lhTP4wzB.js';
3
3
 
4
4
  declare const AgriLogger: {
5
5
  log(level: "INFO" | "WARN" | "ERROR", message: string, meta: any): void;
@@ -104,24 +104,26 @@ declare function generateCanonicalId(): string;
104
104
  * Standardizes the creation of new entities by walking up the scope tree.
105
105
  */
106
106
  declare function generateInfrastructureFields(activeScope: AvailableScope, availableScopes: AvailableScope[]): InfrastructureFields;
107
- declare function buildRlsFilter(session: AgriCoreSession, extra?: Record<string, any>): {
108
- authScopeId: {
109
- $in: string[];
110
- };
111
- };
112
- declare function canRead(session: AgriCoreSession, authScopeId: string): boolean;
113
- declare function canWrite(session: AgriCoreSession, authScopeId: string, resourcePath: string): boolean;
107
+ declare function encodeSession(session: AgriCoreSession): WireSession;
108
+ declare function decodeSession(short: WireSession): AgriCoreSession;
109
+ declare function hasRoleAnywhere(session: AgriCoreSession, role: string): boolean;
110
+ declare function hasPrivilegeAnywhere(session: AgriCoreSession, privilege: string): boolean;
114
111
  /**
115
- * Hard-throws if the user cannot write.
116
- * Use this on the backend (inside Deno functions) to enforce server-side.
112
+ * "Does this user hold this role/privilege AT this specific scope?"
113
+ * This is the default choice for any authorization gate evaluating
114
+ * "can the user perform this action on the resource/scope they're
115
+ * currently acting on." No inheritance — only an explicit assignment
116
+ * at exactly this authScopeId counts, matching the no-inherit-write rule.
117
117
  */
118
- declare function assertCanWrite(session: AgriCoreSession, authScopeId: string, resourcePath: string): void;
118
+ declare function getRoleAt(session: AgriCoreSession, scopeId: string | undefined | null): string | null;
119
+ declare function hasRoleAt(session: AgriCoreSession, scopeId: string | undefined | null, allowedRoles: Set<string> | string[]): boolean;
120
+ declare function getPrivilegesAt(session: AgriCoreSession, scopeId: string | undefined | null): string[];
121
+ declare function hasPrivilegeAt(session: AgriCoreSession, scopeId: string | undefined | null, requiredPrivileges: string[]): boolean;
119
122
  /**
120
123
  * Full resolution: DB override → static config fallback → public default.
121
124
  * Returns 'NONE' | 'READ' | 'WRITE'.
122
125
  */
123
126
  declare function resolveAccess(session: AgriCoreSession, activeScopeId: string, tabConfig: TabConfig): 'NONE' | 'READ' | 'WRITE';
124
- declare function resolveMenuVisibility(session: AgriCoreSession, authScopeId: string, resourcePath: string): 'hidden' | 'read_only' | 'active';
125
127
  declare function isTabVisible(session: AgriCoreSession, activeScopeId: string, tabConfig: TabConfig): boolean;
126
128
  declare function isTabWritable(session: AgriCoreSession, activeScopeId: string, tabConfig: TabConfig): boolean;
127
129
  declare function evaluateBaseAccess(resourcePath: string, session: {
@@ -138,7 +140,7 @@ declare function assertTenantBoundary(db: any, session: AgriCoreSession, // Pass
138
140
  targets: {
139
141
  targetUserId?: string;
140
142
  authScopeId?: string;
141
- expectedScopeType?: 'company' | 'legalEntity' | 'facility';
143
+ expectedScopeType?: ScopeType;
142
144
  }): Promise<boolean>;
143
145
  declare function verifyAndExtractSession(token: string, secret: string): Promise<AgriCoreSession>;
144
146
  declare function getFormMeta(componentId: string): FormMeta | null;
@@ -172,4 +174,4 @@ declare function calculateFileMetadataMatch(criteria: {
172
174
  contextMatch?: string[];
173
175
  }, fileMetadata: Record<string, any>, auditContext: Record<string, any>): number;
174
176
 
175
- export { AccessLevelType, AgriCoreSession, AgriLogger, AppError, AvailableScope, Converter, ErrorFactory, FormMeta, InfrastructureFields, ResolvedError, ResourceRequirement, TabConfig, UserRoleType, Validator, assertCanWrite, assertTenantBoundary, buildRlsFilter, calculateFileMetadataMatch, canRead, canWrite, evaluateBaseAccess, extractAppCode, findSpecificOverride, generateCanonicalId, generateDocumentPath, generateInfrastructureFields, getAcceptedMimeTypes, getApproveAction, getFormMeta, getFormsGroupedByModule, getTaskTypeOptions, handleAppErrorResponse, isTabVisible, isTabWritable, resolveAccess, resolveAppError, resolveEffectiveAccess, resolveError, resolveMenuVisibility, verifyAndExtractSession, withAgriLogging };
177
+ export { AccessLevelType, AgriCoreSession, AgriLogger, AppError, AvailableScope, Converter, ErrorFactory, FormMeta, InfrastructureFields, ResolvedError, ResourceRequirement, ScopeType, TabConfig, UserRoleType, Validator, WireSession, assertTenantBoundary, calculateFileMetadataMatch, decodeSession, encodeSession, evaluateBaseAccess, extractAppCode, findSpecificOverride, generateCanonicalId, generateDocumentPath, generateInfrastructureFields, getAcceptedMimeTypes, getApproveAction, getFormMeta, getFormsGroupedByModule, getPrivilegesAt, getRoleAt, getTaskTypeOptions, handleAppErrorResponse, hasPrivilegeAnywhere, hasPrivilegeAt, hasRoleAnywhere, hasRoleAt, isTabVisible, isTabWritable, resolveAccess, resolveAppError, resolveEffectiveAccess, resolveError, verifyAndExtractSession, withAgriLogging };
package/dist/index.js CHANGED
@@ -71,6 +71,7 @@ __export(index_exports, {
71
71
  RelationshipType: () => RelationshipType,
72
72
  RowOrientation: () => RowOrientation,
73
73
  SENTINEL_UUID: () => SENTINEL_UUID,
74
+ SESSION_SCHEMA: () => SESSION_SCHEMA,
74
75
  SIGNATURE_MODES: () => SIGNATURE_MODES,
75
76
  SoilTexture: () => SoilTexture,
76
77
  StockPolicyTier: () => StockPolicyTier,
@@ -87,12 +88,10 @@ __export(index_exports, {
87
88
  Validator: () => Validator,
88
89
  VigorRating: () => VigorRating,
89
90
  WaterSource: () => WaterSource,
90
- assertCanWrite: () => assertCanWrite,
91
91
  assertTenantBoundary: () => assertTenantBoundary,
92
- buildRlsFilter: () => buildRlsFilter,
93
92
  calculateFileMetadataMatch: () => calculateFileMetadataMatch,
94
- canRead: () => canRead,
95
- canWrite: () => canWrite,
93
+ decodeSession: () => decodeSession,
94
+ encodeSession: () => encodeSession,
96
95
  evaluateBaseAccess: () => evaluateBaseAccess,
97
96
  extractAppCode: () => extractAppCode,
98
97
  findSpecificOverride: () => findSpecificOverride,
@@ -103,15 +102,20 @@ __export(index_exports, {
103
102
  getApproveAction: () => getApproveAction,
104
103
  getFormMeta: () => getFormMeta,
105
104
  getFormsGroupedByModule: () => getFormsGroupedByModule,
105
+ getPrivilegesAt: () => getPrivilegesAt,
106
+ getRoleAt: () => getRoleAt,
106
107
  getTaskTypeOptions: () => getTaskTypeOptions,
107
108
  handleAppErrorResponse: () => handleAppErrorResponse,
109
+ hasPrivilegeAnywhere: () => hasPrivilegeAnywhere,
110
+ hasPrivilegeAt: () => hasPrivilegeAt,
111
+ hasRoleAnywhere: () => hasRoleAnywhere,
112
+ hasRoleAt: () => hasRoleAt,
108
113
  isTabVisible: () => isTabVisible,
109
114
  isTabWritable: () => isTabWritable,
110
115
  resolveAccess: () => resolveAccess,
111
116
  resolveAppError: () => resolveAppError,
112
117
  resolveEffectiveAccess: () => resolveEffectiveAccess,
113
118
  resolveError: () => resolveError,
114
- resolveMenuVisibility: () => resolveMenuVisibility,
115
119
  verifyAndExtractSession: () => verifyAndExtractSession,
116
120
  withAgriLogging: () => withAgriLogging
117
121
  });
@@ -390,6 +394,34 @@ var AccessLevel = {
390
394
  READ: "READ",
391
395
  WRITE: "WRITE"
392
396
  };
397
+ var SESSION_SCHEMA = [
398
+ { key: "u", path: "userId", type: "scalar" },
399
+ { key: "n", path: "userName", type: "scalar" },
400
+ { key: "e", path: "userEmail", type: "scalar" },
401
+ { key: "c", path: "companyId", type: "scalar" },
402
+ { key: "a", path: "activeScopeId", type: "scalar" },
403
+ {
404
+ key: "cc",
405
+ path: "companyConfig",
406
+ type: "object",
407
+ fields: [{ key: "me", path: "isMultiEntity", type: "scalar" }]
408
+ },
409
+ { key: "m", path: "enabledModules", type: "scalar" },
410
+ { key: "ra", path: "roleAssignments", type: "scalar" },
411
+ {
412
+ key: "as",
413
+ path: "availableScopes",
414
+ type: "recordArray",
415
+ fields: [
416
+ { key: "ai", path: "authScopeId", type: "scalar" },
417
+ { key: "bi", path: "base44Id", type: "scalar" },
418
+ { key: "t", path: "type", type: "scalar", enum: ["company", "legalEntity", "facility"] },
419
+ { key: "nm", path: "name", type: "scalar" },
420
+ { key: "pi", path: "parentId", type: "scalar" }
421
+ ]
422
+ },
423
+ { key: "ro", path: "resourceOverrides", type: "scalar" }
424
+ ];
393
425
  var EnabledModule = {
394
426
  FARM_MANAGEMENT: "farm_management",
395
427
  PACKHOUSE: "packhouse",
@@ -651,38 +683,47 @@ var RESOURCE_PATHS = {
651
683
  // ── Operations ────────────────────────────────────────────────────────────
652
684
  farmManagement: "operations.farmManagement",
653
685
  packhouse: "operations.packhouse",
686
+ accommodation: "operations.accommodation",
654
687
  // ── Inventory ────────────────────────────────────────────────────────────
655
688
  // === Consumables ===
689
+ inventory: "inventory",
690
+ inventoryConsumable: "inventory.consumable",
656
691
  inventoryConsumableProduct: "inventory.consumable.product",
657
692
  inventoryConsumableStock: "inventory.consumable.stock",
658
693
  inventoryConsumableStockEditThreshold: "inventory.consumable.stock.editThreshold",
659
694
  inventoryConsumableStockReconcile: "inventory.consumable.stock.reconcile",
660
695
  inventoryConsumableStockMovement: "inventory.consumable.stockMovement",
661
696
  inventoryConsumableStockMovementTransfer: "inventory.consumable.stockMovement.transfer",
662
- inventoryConsumableStockMovementPurchase: "inventory.consumable.stockMovement.purchase",
697
+ // inventoryConsumableStockMovementPurchase: "inventory.consumable.stockMovement.purchase",
663
698
  // === Chemicals ===
699
+ inventoryChemical: "inventory.chemical",
664
700
  inventoryChemicalProduct: "inventory.chemical.product",
665
701
  inventoryChemicalStock: "inventory.chemical.stock",
666
702
  inventoryChemicalStockEditThreshold: "inventory.chemical.stock.editThreshold",
667
703
  inventoryChemicalStockReconcile: "inventory.chemical.stock.reconcile",
668
704
  inventoryChemicalStockMovement: "inventory.chemical.stockMovement",
669
705
  inventoryChemicalStockMovementTransfer: "inventory.chemical.stockMovement.transfer",
670
- inventoryChemicalStockMovementPurchase: "inventory.chemical.stockMovement.purchase",
706
+ // inventoryChemicalStockMovementPurchase: "inventory.chemical.stockMovement.purchase",
671
707
  // === Maintenance Parts ===
708
+ inventoryMaintenancePart: "inventory.maintenancePart",
672
709
  inventoryMaintenancePartProduct: "inventory.maintenancePart.product",
673
710
  inventoryMaintenancePartStock: "inventory.maintenancePart.stock",
674
711
  inventoryMaintenancePartStockEditThreshold: "inventory.maintenancePart.stock.editThreshold",
675
712
  inventoryMaintenancePartStockReconcile: "inventory.maintenancePart.stock.reconcile",
676
713
  inventoryMaintenancePartStockMovement: "inventory.maintenancePart.stockMovement",
677
714
  inventoryMaintenancePartStockMovementTransfer: "inventory.maintenancePart.stockMovement.transfer",
678
- inventoryMaintenancePartStockMovementPurchase: "inventory.maintenancePart.stockMovement.purchase",
679
- accommodation: "operations.accommodation",
715
+ // inventoryMaintenancePartStockMovementPurchase: "inventory.maintenancePart.stockMovement.purchase",
680
716
  // ── Equipment & Fleet ──────────────────────────────────────────────────────
681
717
  equipPreStart: "equipment.preStart",
682
718
  equipMaintenance: "equipment.maintenance",
683
719
  equipFuelRegister: "equipment.fuelRegister",
684
720
  equipCalibration: "equipment.calibration",
685
721
  equipFleet: "equipment.fleetManagement",
722
+ finance: "finance",
723
+ financeProductRequisition: "finance.product.requistion",
724
+ financeDashboard: "finance.dashboard",
725
+ financeTransaction: "finance.transaction",
726
+ financeBudgetAllocation: "finance.budgetAllocation",
686
727
  // ── Safety, Quality & Compliance ──────────────────────────────────────────
687
728
  safetyAuditing: "safety.auditing",
688
729
  safetyFood: "safety.foodSafety",
@@ -708,14 +749,20 @@ var RESOURCE_MODULE_MAP = {
708
749
  [RESOURCE_PATHS.equipment]: ALL_OPERATIONS,
709
750
  [RESOURCE_PATHS.safety]: ALL_OPERATIONS,
710
751
  [RESOURCE_PATHS.team]: ALL_OPERATIONS,
752
+ [RESOURCE_PATHS.inventory]: ALL_OPERATIONS,
753
+ [RESOURCE_PATHS.finance]: ALL_OPERATIONS,
711
754
  [RESOURCE_PATHS.records]: ALL_OPERATIONS,
712
755
  [RESOURCE_PATHS.adminSettings]: ALL_OPERATIONS,
713
756
  // ── Inventory ──────────────────────────────────────────────────────
757
+ [RESOURCE_PATHS.inventoryConsumable]: ALL_OPERATIONS,
714
758
  [RESOURCE_PATHS.inventoryConsumableProduct]: ALL_OPERATIONS,
715
759
  [RESOURCE_PATHS.inventoryConsumableStock]: ALL_OPERATIONS,
716
760
  [RESOURCE_PATHS.inventoryConsumableStockMovement]: ALL_OPERATIONS,
761
+ [RESOURCE_PATHS.inventoryChemical]: ALL_OPERATIONS,
717
762
  [RESOURCE_PATHS.inventoryChemicalProduct]: ALL_OPERATIONS,
718
763
  [RESOURCE_PATHS.inventoryChemicalStock]: ALL_OPERATIONS,
764
+ [RESOURCE_PATHS.inventoryChemicalStockMovement]: ALL_OPERATIONS,
765
+ [RESOURCE_PATHS.inventoryMaintenancePart]: ALL_OPERATIONS,
719
766
  [RESOURCE_PATHS.inventoryMaintenancePartProduct]: ALL_OPERATIONS,
720
767
  [RESOURCE_PATHS.inventoryMaintenancePartStock]: ALL_OPERATIONS,
721
768
  [RESOURCE_PATHS.inventoryMaintenancePartStockMovement]: ALL_OPERATIONS,
@@ -804,9 +851,9 @@ var RESOURCE_REQUIREMENTS = {
804
851
  [RESOURCE_PATHS.inventoryConsumableStockMovementTransfer]: {
805
852
  allowedRoles: [UserRole.OWNER, UserRole.MANAGER, UserRole.SUPERVISOR]
806
853
  },
807
- [RESOURCE_PATHS.inventoryConsumableStockMovementPurchase]: {
808
- allowedRoles: [UserRole.OWNER, UserRole.MANAGER]
809
- },
854
+ // [RESOURCE_PATHS.inventoryConsumableStockMovementPurchase]: {
855
+ // allowedRoles: [UserRole.OWNER, UserRole.MANAGER]
856
+ // },
810
857
  // CHEMICALS PERMISSIONS
811
858
  [RESOURCE_PATHS.inventoryChemicalProduct]: {
812
859
  allowedRoles: [UserRole.OWNER, UserRole.MANAGER, UserRole.SUPERVISOR]
@@ -822,9 +869,9 @@ var RESOURCE_REQUIREMENTS = {
822
869
  [RESOURCE_PATHS.inventoryChemicalStockMovementTransfer]: {
823
870
  allowedRoles: [UserRole.OWNER, UserRole.MANAGER, UserRole.SUPERVISOR]
824
871
  },
825
- [RESOURCE_PATHS.inventoryChemicalStockMovementPurchase]: {
826
- allowedRoles: [UserRole.OWNER, UserRole.MANAGER]
827
- },
872
+ // [RESOURCE_PATHS.inventoryChemicalStockMovementPurchase]: {
873
+ // allowedRoles: [UserRole.OWNER, UserRole.MANAGER]
874
+ // },
828
875
  [RESOURCE_PATHS.inventoryMaintenancePartProduct]: {
829
876
  allowedRoles: [UserRole.OWNER, UserRole.MANAGER, UserRole.SUPERVISOR]
830
877
  },
@@ -836,11 +883,24 @@ var RESOURCE_REQUIREMENTS = {
836
883
  allowedRoles: [UserRole.OWNER, UserRole.MANAGER, UserRole.SUPERVISOR]
837
884
  },
838
885
  [RESOURCE_PATHS.inventoryMaintenancePartStockMovement]: { allowedRoles: EVERYONE },
839
- [RESOURCE_PATHS.inventoryMaintenancePartStockMovementPurchase]: {
886
+ // [RESOURCE_PATHS.inventoryMaintenancePartStockMovementPurchase]: {
887
+ // allowedRoles: [UserRole.OWNER, UserRole.MANAGER]
888
+ // },
889
+ // ── Finance ────────────────────────────────────────────────────────────────
890
+ [RESOURCE_PATHS.financeProductRequisition]: {
840
891
  allowedRoles: [UserRole.OWNER, UserRole.MANAGER]
841
892
  },
842
- [RESOURCE_PATHS.inventoryMaintenancePartStockMovementPurchase]: {
843
- allowedRoles: [UserRole.OWNER, UserRole.MANAGER]
893
+ [RESOURCE_PATHS.financeBudgetAllocation]: {
894
+ allowedRoles: [UserRole.OWNER],
895
+ requiredPrivileges: [UserPrivilege.FINANCE]
896
+ },
897
+ [RESOURCE_PATHS.financeDashboard]: {
898
+ allowedRoles: [UserRole.OWNER],
899
+ requiredPrivileges: [UserPrivilege.FINANCE]
900
+ },
901
+ [RESOURCE_PATHS.financeTransaction]: {
902
+ allowedRoles: [UserRole.OWNER],
903
+ requiredPrivileges: [UserPrivilege.FINANCE]
844
904
  },
845
905
  // ── Admin Settings ─────────────────────────────────────────────────────────
846
906
  [RESOURCE_PATHS.adminUserRoster]: {
@@ -1308,39 +1368,117 @@ function generateInfrastructureFields(activeScope, availableScopes) {
1308
1368
  authScopeId: activeScope.authScopeId
1309
1369
  };
1310
1370
  }
1311
- function buildRlsFilter(session, extra = {}) {
1312
- return { ...extra, authScopeId: { $in: session.readScopes || [] } };
1371
+ function encodeField(field, value) {
1372
+ if (value === void 0) return void 0;
1373
+ switch (field.type) {
1374
+ case "object": {
1375
+ const out = {};
1376
+ for (const sub of field.fields ?? []) {
1377
+ out[sub.key] = encodeField(sub, value[sub.path]);
1378
+ }
1379
+ return out;
1380
+ }
1381
+ case "recordArray": {
1382
+ return value.map(
1383
+ (record) => (field.fields ?? []).map((sub) => {
1384
+ const raw = record[sub.path];
1385
+ if (sub.enum) {
1386
+ const code = sub.enum.indexOf(raw);
1387
+ if (code === -1) {
1388
+ throw new Error(
1389
+ `sessionSchema: value "${raw}" for "${sub.path}" not in enum [${sub.enum.join(", ")}]. Add it to the enum in SESSION_SCHEMA before encoding.`
1390
+ );
1391
+ }
1392
+ return code;
1393
+ }
1394
+ return raw;
1395
+ })
1396
+ );
1397
+ }
1398
+ default:
1399
+ return value;
1400
+ }
1401
+ }
1402
+ function decodeField(field, value) {
1403
+ if (value === void 0) return void 0;
1404
+ switch (field.type) {
1405
+ case "object": {
1406
+ const out = {};
1407
+ for (const sub of field.fields ?? []) {
1408
+ out[sub.path] = decodeField(sub, value[sub.key]);
1409
+ }
1410
+ return out;
1411
+ }
1412
+ case "recordArray": {
1413
+ return value.map((tuple) => {
1414
+ const out = {};
1415
+ (field.fields ?? []).forEach((sub, i) => {
1416
+ const raw = tuple[i];
1417
+ out[sub.path] = sub.enum ? sub.enum[raw] : raw;
1418
+ });
1419
+ return out;
1420
+ });
1421
+ }
1422
+ default:
1423
+ return value;
1424
+ }
1313
1425
  }
1314
- function canRead(session, authScopeId) {
1315
- return session.readScopes?.includes(authScopeId) ?? false;
1426
+ function encodeSession(session) {
1427
+ const out = {};
1428
+ const sessionRecord = session;
1429
+ for (const field of SESSION_SCHEMA) {
1430
+ const encoded = encodeField(field, sessionRecord[field.path]);
1431
+ if (encoded !== void 0) out[field.key] = encoded;
1432
+ }
1433
+ return out;
1316
1434
  }
1317
- function canWrite(session, authScopeId, resourcePath) {
1318
- const override = session.resourceOverrides?.[authScopeId]?.[resourcePath];
1319
- if (override === "WRITE") return true;
1320
- if (override === "NONE" || override === "READ") return false;
1321
- return session.writeScopes?.includes(authScopeId) ?? false;
1435
+ function decodeSession(short) {
1436
+ const out = {};
1437
+ const shortRecord = short;
1438
+ for (const field of SESSION_SCHEMA) {
1439
+ const decoded = decodeField(field, shortRecord[field.key]);
1440
+ if (decoded !== void 0) out[field.path] = decoded;
1441
+ }
1442
+ return out;
1322
1443
  }
1323
- function assertCanWrite(session, authScopeId, resourcePath) {
1324
- const override = session.resourceOverrides?.[authScopeId]?.[resourcePath];
1325
- if (override === "WRITE") return;
1326
- if (override === "NONE" || override === "READ") {
1327
- throw new AppError(
1328
- 403,
1329
- MOD.SESSION,
1330
- CAT.PERMISSION,
1331
- ACT.GENERIC,
1332
- `You do not have write access to "${resourcePath}" in this scope.`
1333
- );
1444
+ (function validateSchema(fields = SESSION_SCHEMA, seen = /* @__PURE__ */ new Set(), pathPrefix = "") {
1445
+ for (const f of fields) {
1446
+ if (seen.has(f.key)) {
1447
+ throw new Error(
1448
+ `sessionSchema: duplicate short key "${f.key}" detected near "${pathPrefix}${f.path}". Every key must be unique within its object level.`
1449
+ );
1450
+ }
1451
+ seen.add(f.key);
1452
+ if (f.fields && f.type === "object") {
1453
+ validateSchema(f.fields, /* @__PURE__ */ new Set(), `${pathPrefix}${f.path}.`);
1454
+ }
1334
1455
  }
1335
- if (session.writeScopes?.includes(authScopeId)) return;
1336
- throw new AppError(
1337
- 403,
1338
- MOD.SESSION,
1339
- CAT.PERMISSION,
1340
- ACT.GENERIC,
1341
- "You do not have permission to modify records in this scope."
1456
+ })();
1457
+ function hasRoleAnywhere(session, role) {
1458
+ return Object.values(session.roleAssignments ?? {}).some((a) => a.role === role);
1459
+ }
1460
+ function hasPrivilegeAnywhere(session, privilege) {
1461
+ return Object.values(session.roleAssignments ?? {}).some(
1462
+ (a) => a.privileges?.includes(privilege)
1342
1463
  );
1343
1464
  }
1465
+ function getRoleAt(session, scopeId) {
1466
+ if (!scopeId) return null;
1467
+ return session.roleAssignments?.[scopeId]?.role ?? null;
1468
+ }
1469
+ function hasRoleAt(session, scopeId, allowedRoles) {
1470
+ const role = getRoleAt(session, scopeId);
1471
+ if (!role) return false;
1472
+ return allowedRoles instanceof Set ? allowedRoles.has(role) : allowedRoles.includes(role);
1473
+ }
1474
+ function getPrivilegesAt(session, scopeId) {
1475
+ if (!scopeId) return [];
1476
+ return session.roleAssignments?.[scopeId]?.privileges ?? [];
1477
+ }
1478
+ function hasPrivilegeAt(session, scopeId, requiredPrivileges) {
1479
+ const privileges = getPrivilegesAt(session, scopeId);
1480
+ return requiredPrivileges.some((p) => privileges.includes(p));
1481
+ }
1344
1482
  function resolveAccess(session, activeScopeId, tabConfig) {
1345
1483
  const resourcePath = tabConfig?.resourceId;
1346
1484
  const overrides = session.resourceOverrides?.[activeScopeId] ?? {};
@@ -1356,22 +1494,14 @@ function resolveAccess(session, activeScopeId, tabConfig) {
1356
1494
  const requiredPrivileges = tabConfig?.requiredPrivileges ?? [];
1357
1495
  const hasRestrictions = allowedRoles.length > 0 || requiredPrivileges.length > 0;
1358
1496
  if (hasRestrictions) {
1359
- const role = session?.role ?? "";
1360
- const privileges = session?.privileges ?? [];
1497
+ const assignment = session?.roleAssignments?.[activeScopeId];
1498
+ const role = assignment?.role ?? "";
1499
+ const privileges = assignment?.privileges ?? [];
1361
1500
  const passesRole = allowedRoles.length > 0 && allowedRoles.includes(role);
1362
1501
  const passesPrivilege = requiredPrivileges.length > 0 && requiredPrivileges.some((p) => privileges.includes(p));
1363
1502
  return passesRole || passesPrivilege ? "WRITE" : "NONE";
1364
1503
  }
1365
- return "READ";
1366
- }
1367
- function resolveMenuVisibility(session, authScopeId, resourcePath) {
1368
- const override = session.resourceOverrides?.[authScopeId]?.[resourcePath];
1369
- if (override === "NONE") return "hidden";
1370
- if (override === "READ") return "read_only";
1371
- if (override === "WRITE") return "active";
1372
- if (session.writeScopes?.includes(authScopeId)) return "active";
1373
- if (session.readScopes?.includes(authScopeId)) return "read_only";
1374
- return "hidden";
1504
+ return "NONE";
1375
1505
  }
1376
1506
  function isTabVisible(session, activeScopeId, tabConfig) {
1377
1507
  return resolveAccess(session, activeScopeId, tabConfig) !== "NONE";
@@ -1570,6 +1700,7 @@ function calculateFileMetadataMatch(criteria, fileMetadata, auditContext) {
1570
1700
  RelationshipType,
1571
1701
  RowOrientation,
1572
1702
  SENTINEL_UUID,
1703
+ SESSION_SCHEMA,
1573
1704
  SIGNATURE_MODES,
1574
1705
  SoilTexture,
1575
1706
  StockPolicyTier,
@@ -1586,12 +1717,10 @@ function calculateFileMetadataMatch(criteria, fileMetadata, auditContext) {
1586
1717
  Validator,
1587
1718
  VigorRating,
1588
1719
  WaterSource,
1589
- assertCanWrite,
1590
1720
  assertTenantBoundary,
1591
- buildRlsFilter,
1592
1721
  calculateFileMetadataMatch,
1593
- canRead,
1594
- canWrite,
1722
+ decodeSession,
1723
+ encodeSession,
1595
1724
  evaluateBaseAccess,
1596
1725
  extractAppCode,
1597
1726
  findSpecificOverride,
@@ -1602,15 +1731,20 @@ function calculateFileMetadataMatch(criteria, fileMetadata, auditContext) {
1602
1731
  getApproveAction,
1603
1732
  getFormMeta,
1604
1733
  getFormsGroupedByModule,
1734
+ getPrivilegesAt,
1735
+ getRoleAt,
1605
1736
  getTaskTypeOptions,
1606
1737
  handleAppErrorResponse,
1738
+ hasPrivilegeAnywhere,
1739
+ hasPrivilegeAt,
1740
+ hasRoleAnywhere,
1741
+ hasRoleAt,
1607
1742
  isTabVisible,
1608
1743
  isTabWritable,
1609
1744
  resolveAccess,
1610
1745
  resolveAppError,
1611
1746
  resolveEffectiveAccess,
1612
1747
  resolveError,
1613
- resolveMenuVisibility,
1614
1748
  verifyAndExtractSession,
1615
1749
  withAgriLogging
1616
1750
  });