Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions taco/internal/api/org_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ func (h *OrgHandler) CreateOrganization(c echo.Context) error {
slog.Info("Creating organization",
"name", req.Name,
"displayName", req.DisplayName,
"externalOrgID", req.ExternalOrgID,
"createdBy", userIDStr,
)

Expand Down
6 changes: 3 additions & 3 deletions taco/internal/query/types/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,9 @@ func (rut *RuleUnitTag) BeforeCreate(tx *gorm.DB) error {

type Organization struct {
ID string `gorm:"type:varchar(36);primaryKey"`
Name string `gorm:"type:varchar(255);not null;uniqueIndex"` // Unique identifier (e.g., "acme") - used in CLI and paths
DisplayName string `gorm:"type:varchar(255);not null"` // Friendly name (e.g., "Acme Corp") - shown in UI
ExternalOrgID *string `gorm:"type:varchar(500);uniqueIndex"` // External org identifier (optional, nullable)
Name string `gorm:"type:varchar(255);not null;index"` // Non-unique - multiple orgs can have same name (e.g., "Personal")
DisplayName string `gorm:"type:varchar(255);not null"` // Friendly name (e.g., "Acme Corp") - shown in UI
ExternalOrgID *string `gorm:"type:varchar(500);uniqueIndex"` // External org identifier (optional, nullable) - THIS is unique
CreatedBy string `gorm:"type:varchar(255);not null"`
CreatedAt time.Time
UpdatedAt time.Time
Expand Down
13 changes: 3 additions & 10 deletions taco/internal/repositories/org_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,9 @@ func (r *orgRepository) Create(ctx context.Context, orgID, name, displayName, ex
return nil, err
}

// Check if org already exists by name (infrastructure logic)
var existing types.Organization
err := r.db.WithContext(ctx).Where(queryOrgByName, orgID).First(&existing).Error
if err == nil {
return nil, domain.ErrOrgExists
}
if !errors.Is(err, gorm.ErrRecordNotFound) {
return nil, fmt.Errorf("failed to check existing org: %w", err)
}

// Note: Name uniqueness is no longer enforced - multiple orgs can have the same name
// Only external_org_id must be unique (enforced by database constraint)

// Check if external org ID already exists (if provided)
if externalOrgID != "" {
var existingExternal types.Organization
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-- Modify "organizations" table
ALTER TABLE `organizations` DROP INDEX `idx_organizations_name`;
-- Modify "organizations" table
ALTER TABLE `organizations` ADD INDEX `idx_organizations_name` (`name`);
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-- Drop index "idx_organizations_name" from table: "organizations"
DROP INDEX "public"."idx_organizations_name";
-- Create index "idx_organizations_name" to table: "organizations"
CREATE INDEX "idx_organizations_name" ON "public"."organizations" ("name");
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
-- Disable the enforcement of foreign-keys constraints
PRAGMA foreign_keys = off;
-- Create "new_organizations" table
CREATE TABLE `new_organizations` (
`id` varchar NULL,
`name` varchar NOT NULL,
`display_name` varchar NOT NULL,
`external_org_id` varchar NULL,
`created_by` varchar NOT NULL,
`created_at` datetime NULL,
`updated_at` datetime NULL,
PRIMARY KEY (`id`)
);
-- Copy rows from old table "organizations" to new temporary table "new_organizations"
INSERT INTO `new_organizations` (`id`, `name`, `display_name`, `external_org_id`, `created_by`, `created_at`, `updated_at`) SELECT `id`, `name`, `display_name`, `external_org_id`, `created_by`, `created_at`, `updated_at` FROM `organizations`;
-- Drop "organizations" table after copying rows
DROP TABLE `organizations`;
-- Rename temporary table "new_organizations" to "organizations"
ALTER TABLE `new_organizations` RENAME TO `organizations`;
-- Create index "idx_organizations_external_org_id" to table: "organizations"
CREATE UNIQUE INDEX `idx_organizations_external_org_id` ON `organizations` (`external_org_id`);
-- Create index "idx_organizations_name" to table: "organizations"
CREATE INDEX `idx_organizations_name` ON `organizations` (`name`);
-- Enable back the enforcement of foreign-keys constraints
PRAGMA foreign_keys = on;
4 changes: 2 additions & 2 deletions ui/src/routes/api/auth/workos/webhooks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,9 @@ export const Route = createFileRoute('/api/auth/workos/webhooks')({
console.log(`Syncing organization ${orgName} to backend and statesman`);
try {
await syncOrgToBackend(invitation.organizationId!, orgName, null);
await syncOrgToStatesman(invitation.organizationId!, orgName, personalOrgDisplayName, invitation.userId!, invitation.userEmail!);
await syncOrgToStatesman(invitation.organizationId!, orgName, orgName, invitation.userId!, invitation.userEmail!);
} catch (error) {
console.error(`Error syncing user to backend:`, error);
console.error(`Error syncing organization to backend:`, error);
throw error;
}
}
Expand Down
Loading