UNPKG

business-as-code

Version:

Primitives for expressing business logic and processes as code

585 lines 15.3 kB
/** * Organization Structure - Flows to FGA/RBAC * * Defines the complete organizational hierarchy: * * Organization * └── Department * └── Team * └── Position (Role + Worker) * └── Permissions (FGA/RBAC) * * This structure enables: * - Hierarchical permission inheritance * - Role-based task assignment * - Approval chains based on org structure * - Resource access control based on department/team * * @packageDocumentation */ import type { BusinessRole, TaskRoutingRule, WorkflowRole } from './roles.js'; /** * Organization - top-level business entity * * @example * ```ts * const acme: Organization = { * id: 'org_acme', * name: 'Acme Corp', * domain: 'acme.com', * industry: 'technology', * * // Hierarchy * departments: [engineering, sales, support], * * // Global settings * settings: { * defaultCurrency: 'USD', * timezone: 'America/Los_Angeles', * workWeek: ['monday', 'tuesday', 'wednesday', 'thursday', 'friday'], * }, * * // Resource hierarchy for FGA * resourceHierarchy: { * organization: { children: ['department', 'project', 'repository'] }, * department: { parent: 'organization', children: ['team'] }, * team: { parent: 'department', children: ['position'] }, * }, * } * ``` */ export interface Organization { /** Unique identifier */ id: string; /** Organization name */ name: string; /** Primary domain */ domain?: string; /** Legal name (if different) */ legalName?: string; /** Industry/sector */ industry?: string; /** Mission statement */ mission?: string; /** Core values */ values?: string[]; /** Founded date */ foundedAt?: Date; /** Headquarters location */ headquarters?: Address; /** Organization settings */ settings?: OrganizationSettings; /** Departments */ departments?: Department[]; /** Standalone teams (not in departments) */ teams?: Team[]; /** Organization-wide roles */ roles?: BusinessRole[]; /** Resource hierarchy for FGA */ resourceHierarchy?: ResourceHierarchy; /** Global approval chains */ approvalChains?: ApprovalChain[]; /** Task routing rules */ routingRules?: TaskRoutingRule[]; /** Metadata */ metadata?: Record<string, unknown>; } /** * Organization settings */ export interface OrganizationSettings { /** Default currency */ defaultCurrency?: string; /** Default timezone */ timezone?: string; /** Work week days */ workWeek?: string[]; /** Business hours */ businessHours?: { start: string; end: string; timezone?: string; }; /** Fiscal year start month (1-12) */ fiscalYearStart?: number; /** Default language */ language?: string; /** Date format */ dateFormat?: string; } /** * Address */ export interface Address { street?: string; city?: string; state?: string; postalCode?: string; country?: string; } /** * Department - major organizational division * * @example * ```ts * const engineering: Department = { * id: 'dept_eng', * name: 'Engineering', * code: 'ENG', * * // Leadership * head: { roleId: 'role_cto', positionId: 'pos_cto_jane' }, * * // Teams * teams: [platformTeam, productTeam, infraTeam], * * // Budget * budget: { * annual: 5000000, * currency: 'USD', * categories: { * salaries: 3500000, * tools: 200000, * infrastructure: 800000, * training: 100000, * }, * }, * * // FGA: Department-level permissions * defaultPermissions: { * repository: ['read'], * project: ['read'], * }, * } * ``` */ export interface Department { /** Unique identifier */ id: string; /** Department name */ name: string; /** Short code (e.g., 'ENG', 'SALES') */ code?: string; /** Description */ description?: string; /** Department head position */ head?: PositionRef; /** Parent department (for sub-departments) */ parentId?: string; /** Teams within department */ teams?: Team[]; /** Department budget */ budget?: Budget; /** Cost center code */ costCenter?: string; /** Department goals */ goals?: string[]; /** Default permissions for department members */ defaultPermissions?: Record<string, string[]>; /** Department-specific roles */ roles?: BusinessRole[]; /** Department-specific routing rules */ routingRules?: TaskRoutingRule[]; /** Metadata */ metadata?: Record<string, unknown>; } /** * Team - working group within a department * * @example * ```ts * const platformTeam: Team = { * id: 'team_platform', * name: 'Platform Team', * departmentId: 'dept_eng', * * // Leadership * lead: { roleId: 'role_lead', positionId: 'pos_lead_bob' }, * * // Members * positions: [ * { id: 'pos_1', roleId: 'role_engineer', workerId: 'worker_alice' }, * { id: 'pos_2', roleId: 'role_engineer', workerId: 'worker_charlie' }, * { id: 'pos_3', roleId: 'role_engineer', workerId: null }, // Open position * ], * * // Team resources (for FGA scoping) * resources: { * repositories: ['platform-core', 'platform-api'], * projects: ['platform-v2'], * }, * * // Team-level permissions (inherited by members) * defaultPermissions: { * repository: ['read', 'edit', 'act:merge'], * project: ['read', 'edit'], * }, * } * ``` */ export interface Team { /** Unique identifier */ id: string; /** Team name */ name: string; /** Parent department */ departmentId?: string; /** Description */ description?: string; /** Team lead position */ lead?: PositionRef; /** Team positions */ positions?: Position[]; /** Team objectives */ objectives?: string[]; /** Team resources (for FGA scoping) */ resources?: TeamResources; /** Team budget (if separate from department) */ budget?: Budget; /** Default permissions for team members */ defaultPermissions?: Record<string, string[]>; /** Workflow roles for this team */ workflowRoles?: WorkflowRole[]; /** Communication channels */ channels?: TeamChannels; /** Metadata */ metadata?: Record<string, unknown>; } /** * Team resources - scopes FGA permissions */ export interface TeamResources { /** Owned repositories */ repositories?: string[]; /** Owned projects */ projects?: string[]; /** Owned products */ products?: string[]; /** Custom resource types */ [resourceType: string]: string[] | undefined; } /** * Team communication channels */ export interface TeamChannels { slack?: string; teams?: string; email?: string; discord?: string; } /** * Position - a role filled by a worker * * The position is the link between: * - Business Role (responsibilities, permissions) * - Worker (human or AI agent) * - Location in org hierarchy (team → department → org) * * @example * ```ts * const seniorEngineerPosition: Position = { * id: 'pos_se_123', * title: 'Senior Software Engineer', * * // Role defines what this position can do * roleId: 'role_senior_engineer', * * // Worker currently filling this position * workerId: 'worker_alice', * workerType: 'human', * * // Hierarchy * teamId: 'team_platform', * reportsTo: 'pos_lead_bob', * * // Position-specific permissions (added to role permissions) * additionalPermissions: { * 'repository:platform-core': ['manage'], * }, * * // Employment details * startDate: new Date('2023-01-15'), * status: 'active', * } * ``` */ export interface Position { /** Unique identifier */ id: string; /** Position title */ title: string; /** Business role this position requires */ roleId: string; /** Worker filling this position (null = open position) */ workerId?: string | null; /** Type of worker (human, agent, or either) */ workerType?: 'human' | 'agent' | 'any'; /** Team this position belongs to */ teamId?: string; /** Position this reports to */ reportsTo?: string; /** Direct reports (position IDs) */ directReports?: string[]; /** Position-specific additional permissions */ additionalPermissions?: Record<string, string[]>; /** Start date */ startDate?: Date; /** End date (for contractors/temporary) */ endDate?: Date; /** Position status */ status?: 'active' | 'open' | 'on-leave' | 'terminated'; /** Full-time equivalent (1.0 = full-time) */ fte?: number; /** Location */ location?: string; /** Remote/hybrid/onsite */ workModel?: 'remote' | 'hybrid' | 'onsite'; /** Compensation */ compensation?: Compensation; /** Metadata */ metadata?: Record<string, unknown>; } /** * Position reference */ export interface PositionRef { positionId?: string; roleId?: string; workerId?: string; } /** * Compensation details */ export interface Compensation { /** Base salary */ baseSalary?: number; /** Currency */ currency?: string; /** Pay frequency */ frequency?: 'hourly' | 'weekly' | 'biweekly' | 'monthly' | 'annual'; /** Bonus target percentage */ bonusTarget?: number; /** Equity grants */ equity?: { type: 'options' | 'rsu' | 'shares'; amount: number; vestingSchedule?: string; }; /** Band/level */ band?: string; } /** * Budget allocation */ export interface Budget { /** Total annual budget */ annual?: number; /** Currency */ currency?: string; /** Budget period */ period?: string; /** Budget categories */ categories?: Record<string, number>; /** Spent to date */ spent?: number; /** Remaining */ remaining?: number; } /** * Resource hierarchy definition for FGA * * Defines how resources relate to each other for permission inheritance. * * @example * ```ts * const hierarchy: ResourceHierarchy = { * // Organization is root * organization: { * children: ['department', 'project', 'repository'], * }, * * // Department inherits from org * department: { * parent: 'organization', * children: ['team'], * }, * * // Team inherits from department * team: { * parent: 'department', * children: ['position'], * }, * * // Project can be org-level or team-level * project: { * parent: 'organization', * alternateParents: ['team'], * children: ['document', 'task'], * }, * * // Repository can be org-level or team-level * repository: { * parent: 'organization', * alternateParents: ['team'], * }, * } * ``` */ export interface ResourceHierarchy { [resourceType: string]: ResourceHierarchyNode; } /** * Node in resource hierarchy */ export interface ResourceHierarchyNode { /** Primary parent resource type */ parent?: string; /** Alternative parent types */ alternateParents?: string[]; /** Child resource types */ children?: string[]; /** Whether permissions cascade down */ inheritPermissions?: boolean; /** Maximum depth (for nested resources) */ maxDepth?: number; } /** * Approval chain - defines who approves what * * @example * ```ts * const expenseApprovalChain: ApprovalChain = { * id: 'chain_expense', * name: 'Expense Approval', * type: 'expense', * * levels: [ * { * threshold: 1000, * approvers: [{ type: 'direct-manager' }], * }, * { * threshold: 5000, * approvers: [ * { type: 'direct-manager' }, * { type: 'role', roleId: 'director' }, * ], * }, * { * threshold: 25000, * approvers: [ * { type: 'direct-manager' }, * { type: 'role', roleId: 'vp' }, * { type: 'role', roleId: 'cfo' }, * ], * }, * ], * * // Escalation settings * escalation: { * afterHours: 24, * escalateTo: 'skip-level-manager', * }, * } * ``` */ export interface ApprovalChain { /** Chain identifier */ id: string; /** Chain name */ name: string; /** What type of requests this chain handles */ type: string; /** Approval levels */ levels: ApprovalLevel[]; /** Escalation rules */ escalation?: EscalationRule; /** Active/inactive */ active?: boolean; /** Metadata */ metadata?: Record<string, unknown>; } /** * Approval level within a chain */ export interface ApprovalLevel { /** Threshold amount (requests above this need this level) */ threshold?: number; /** Approvers at this level */ approvers: ApproverSpec[]; /** How many approvers needed */ requiredApprovals?: number; /** Whether approvals at this level are sequential or parallel */ approvalMode?: 'sequential' | 'parallel' | 'any'; /** SLA for this level (hours) */ slaHours?: number; } /** * Approver specification */ export interface ApproverSpec { /** Approver type */ type: 'direct-manager' | 'skip-level-manager' | 'role' | 'position' | 'worker' | 'team'; /** Role ID (if type is 'role') */ roleId?: string; /** Position ID (if type is 'position') */ positionId?: string; /** Worker ID (if type is 'worker') */ workerId?: string; /** Team ID (if type is 'team') */ teamId?: string; } /** * Escalation rule */ export interface EscalationRule { /** Hours before escalation */ afterHours: number; /** Who to escalate to */ escalateTo: 'skip-level-manager' | 'department-head' | 'role' | 'position'; /** Role ID if escalating to role */ roleId?: string; /** Position ID if escalating to position */ positionId?: string; /** Maximum escalations */ maxEscalations?: number; } /** * Resolved permissions for a worker * * Combines: * - Organization-level defaults * - Department-level permissions * - Team-level permissions * - Role permissions * - Position-specific permissions */ export interface ResolvedPermissions { /** Worker ID */ workerId: string; /** Position ID */ positionId: string; /** Effective permissions by resource type */ permissions: Record<string, string[]>; /** Resource-specific permissions */ resourcePermissions: Record<string, Record<string, string[]>>; /** Approval capabilities */ canApprove: string[]; /** Task handling capabilities */ canHandle: string[]; /** Inheritance chain (for debugging) */ inheritanceChain: string[]; } /** * Resolve permissions for a position in the org hierarchy */ export declare function resolvePermissions(org: Organization, positionId: string): ResolvedPermissions | null; /** * Get approval chain for a request */ export declare function getApprovalChainForRequest(org: Organization, requestType: string, amount?: number): ApproverSpec[]; /** * Find manager for a position (follows reportsTo chain) */ export declare function findManager(org: Organization, positionId: string): Position | null; //# sourceMappingURL=organization.d.ts.map