Skip to main content

SPEC 002 — Organization Management

FieldValue
StatusDRAFT
PriorityP0 — Launch-Critical
Backendequa-server/modules/organizations/
APIequa-server/modules/api/src/endpoints/organization-endpoints.ts
Frontendequa-web/src/modules/organization/, equa-web/src/modules/organization-dashboard/

1. Feature Purpose

Organizations are the top-level entity in Equa. Every cap table, agreement, document, and member belongs to an organization. This module handles creating and configuring organizations (company type, equity structure, operating agreement), managing members and their roles, tracking addresses with content-addressable hashing, and enforcing member limits per plan.

2. Current State (Verified)

2.1 Backend

ComponentPath
Module rootequa-server/modules/organizations/
API endpointsequa-server/modules/api/src/endpoints/organization-endpoints.ts

2.2 Frontend

ComponentPathDescription
Organization moduleequa-web/src/modules/organization/Org management, securities, legends, portfolio
Dashboard moduleequa-web/src/modules/organization-dashboard/Dashboard, recent actions, capital summary

2.3 Permission Model

RBAC enforced through three join tables:
TablePurpose
OrganizationsRolesMaps roles to organizations
MembersRolesMaps roles to members within an organization
PermissionsRolesMaps granular permissions to roles

3. Data Model

Organizations

ColumnTypeConstraints
iduuidPK
namevarcharNOT NULL
operatingAgreementhashContent-addressed reference
companyTypeintEnum (LLC, C-Corp, S-Corp, etc.)
equityStructureintEnum
ownershipTransferabilityintEnum
agentuuidFK → registered agent
logouuidFK → file storage
einvarchar
websitevarchar
creatoruuidFK → Users
phoneNumbervarchar
registrationNumbervarchar
startDatedate
legacyDataRoombooleanFlags orgs migrated from legacy system

OrganizationDetailsTable

ColumnTypeConstraints
namevarchar
companyTypeint
businessAddressvarchar
phoneNumbervarchar
registrationNumbervarchar
startDatedate

OrganizationTemplates

ColumnTypeConstraints
organizationuuidFK → Organizations
typevarcharTemplate category
contenthashContent-addressed template body

Members

ColumnTypeConstraints
iduuidPK
fullNamevarcharNOT NULL
emailcitext
organizationuuidFK → Organizations
useruuidFK → Users, nullable
isIndividualbooleanIndividual vs. entity member
titlevarchar

MemberLimits

ColumnTypeConstraints
organizationuuidFK → Organizations
memberLimitintMax members allowed by plan

Addresses

ColumnTypeConstraints
iduuidPK
owneruuidFK → Organizations or Members
street1varchar
street2varcharnullable
street3varcharnullable
countryvarchar
cityvarchar
postalCodevarchar
provincevarchar

HashedAddresses

Content-addressable address records. The hash is derived from the address fields, enabling deduplication and immutable references from agreements and other documents.

4. API Endpoints

MethodPathAuthDescription
POST/api/v1/organizationsYesCreate a new organization
GET/api/v1/organizationsYesList organizations for current user
GET/api/v1/organizations/:idYesGet organization details
PUT/api/v1/organizations/:idYesUpdate organization settings
DELETE/api/v1/organizations/:idYesDelete organization (owner only)
GET/api/v1/organizations/:id/membersYesList members
POST/api/v1/organizations/:id/membersYesAdd a member
PUT/api/v1/organizations/:id/members/:memberIdYesUpdate member details
DELETE/api/v1/organizations/:id/members/:memberIdYesRemove a member
GET/api/v1/organizations/:id/dashboardYesDashboard data (recent actions, capital summary)
PUT/api/v1/organizations/:id/templatesYesSet organization templates

5. Frontend Components

ComponentPathDescription
Organization moduleequa-web/src/modules/organization/Org settings, securities config, legends, portfolio view
Organization dashboardequa-web/src/modules/organization-dashboard/Summary dashboard with recent actions and capital overview
Securities managementequa-web/src/modules/organization/Security type configuration within org module
Legends managementequa-web/src/modules/organization/Share certificate legend templates
Portfolio viewequa-web/src/modules/organization/Member portfolio overview within org context

6. Business Rules

  1. Creator is default owner — The user who creates an organization is assigned the owner role automatically.
  2. Member limits — Each organization has a memberLimit (set by billing plan). Adding members beyond the limit is rejected.
  3. Members can be entitiesisIndividual = false allows companies, trusts, and other entities as members.
  4. Content-addressed documentsoperatingAgreement and template content are stored as hashes referencing immutable content, ensuring auditability.
  5. HashedAddresses — Addresses are content-addressed so that the same physical address used across agreements produces a single canonical reference.
  6. RBAC scoped to organization — OrganizationsRoles, MembersRoles, and PermissionsRoles control who can view, edit, or administer each organization.
  7. Legacy data room flag — Organizations migrated from the legacy system have legacyDataRoom = true to gate compatibility behavior.
  8. Unique email per org — Member email (citext) is unique within an organization context to prevent duplicate invitations.

7. Acceptance Criteria

  • User can create a new organization with name, company type, and equity structure
  • Organization settings (EIN, website, phone, registration number, start date) can be updated
  • Creator is automatically assigned the owner role
  • Members can be added up to the plan’s member limit
  • Attempting to exceed the member limit returns an error
  • Members can be individual persons or entities (isIndividual flag)
  • Addresses are stored and deduplicated via content-addressable hashing
  • Operating agreement and templates are stored as immutable content-addressed hashes
  • Organization dashboard displays recent actions and capital summary
  • RBAC prevents unauthorized users from viewing or modifying organization data
  • Organization can be deleted by the owner only

8. Risks

RiskImpactMitigation
Member limit bypass via race conditionExceeds paid plan capacityUse database-level constraint or serialized check
Orphaned members after org deletionData integrity issuesCascade delete or soft-delete with cleanup job
Content-addressed hash collisionWrong document servedUse SHA-256 or stronger; collision probability negligible
Legacy data room flag not checked consistentlyLegacy orgs see incorrect UICentralize flag check in middleware or service layer
RBAC misconfiguration allows cross-org accessUnauthorized data exposureIntegration tests for permission boundaries; audit logging
EIN / registration number stored in plaintextRegulatory exposureEvaluate encryption at rest for sensitive identifiers