15 KiB
COMP-004: Organization Components Repository
Overview
Enable teams to share a central component repository at the organization level. When a user belongs to a GitHub organization, they can access shared components from that org's component repository, creating a design system that's consistent across all team projects.
Context
Individual developers can export components to personal repos (COMP-003), but teams need:
- Shared component library accessible to all org members
- Consistent design system across projects
- Centralized component governance
- Version control for team components
This task adds organization-level component repositories to the prefab source system.
Organization Flow
User authenticates with GitHub (GIT-001)
↓
System detects user's organizations
↓
For each org, check for `noodl-components` repo
↓
Register as prefab source if found
↓
Components appear in NodePicker
Requirements
Functional Requirements
-
Organization Detection
- Detect user's GitHub organizations
- Check for component repository in each org
- Support custom repo names (configurable)
- Handle multiple organizations
-
Repository Discovery
- Auto-detect
{org}/noodl-componentsrepos - Validate repository structure
- Read repository manifest
- Cache organization components
- Auto-detect
-
Component Access
- List org components in NodePicker
- Show org badge on components
- Filter by organization
- Search across all org repos
-
Permission Handling
- Respect GitHub permissions
- Handle private repositories
- Clear error messages for access issues
- Re-auth prompt when needed
-
Organization Settings
- Enable/disable specific org repos
- Priority ordering between orgs
- Refresh/sync controls
- View org repo on GitHub
Non-Functional Requirements
- Org components load within 3 seconds
- Cached for offline use after first load
- Handles orgs with 100+ components
- Works with GitHub Enterprise (future)
Technical Approach
1. Organization Prefab Source
// packages/noodl-editor/src/editor/src/models/prefab/sources/OrganizationPrefabSource.ts
interface OrganizationConfig {
orgName: string;
repoName: string;
enabled: boolean;
priority: number;
}
class OrganizationPrefabSource implements PrefabSource {
config: PrefabSourceConfig;
constructor(private orgConfig: OrganizationConfig) {
this.config = {
id: `org:${orgConfig.orgName}`,
name: orgConfig.orgName,
priority: orgConfig.priority,
enabled: orgConfig.enabled
};
}
async initialize(): Promise<void> {
// Verify repo access
const hasAccess = await this.verifyRepoAccess();
if (!hasAccess) {
throw new PrefabSourceError('No access to organization repository');
}
// Load manifest
await this.loadManifest();
}
async listPrefabs(): Promise<PrefabMetadata[]> {
const manifest = await this.getManifest();
return manifest.components.map(c => ({
...c,
id: `org:${this.orgConfig.orgName}:${c.id}`,
source: 'organization',
organization: this.orgConfig.orgName
}));
}
async downloadPrefab(id: string): Promise<string> {
// Clone specific component from repo
const componentPath = this.getComponentPath(id);
return await this.downloadFromGitHub(componentPath);
}
}
2. Organization Discovery Service
// packages/noodl-editor/src/editor/src/services/OrganizationService.ts
interface Organization {
name: string;
displayName: string;
avatarUrl: string;
hasComponentRepo: boolean;
componentRepoUrl?: string;
memberCount?: number;
}
class OrganizationService {
private static instance: OrganizationService;
// Discovery
async discoverOrganizations(): Promise<Organization[]>;
async checkForComponentRepo(orgName: string): Promise<boolean>;
async validateComponentRepo(orgName: string, repoName: string): Promise<boolean>;
// Registration
async registerOrgSource(org: Organization): Promise<void>;
async unregisterOrgSource(orgName: string): Promise<void>;
// Settings
getOrgSettings(orgName: string): OrganizationConfig;
updateOrgSettings(orgName: string, settings: Partial<OrganizationConfig>): void;
// Refresh
async refreshOrgComponents(orgName: string): Promise<void>;
async refreshAllOrgs(): Promise<void>;
}
3. Auto-Registration on Login
// Integration with GitHub OAuth
async function onGitHubAuthenticated(token: string): Promise<void> {
const orgService = OrganizationService.instance;
const registry = PrefabRegistry.instance;
// Discover user's organizations
const orgs = await orgService.discoverOrganizations();
for (const org of orgs) {
// Check for component repo
const hasRepo = await orgService.checkForComponentRepo(org.name);
if (hasRepo) {
// Register as prefab source
const source = new OrganizationPrefabSource({
orgName: org.name,
repoName: 'noodl-components',
enabled: true,
priority: 80 // Below built-in, above docs
});
registry.registerSource(source);
}
}
}
4. Organization Settings UI
┌─────────────────────────────────────────────────────────────────────┐
│ Organization Components │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ Connected Organizations │
│ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ [🏢] Acme Corp │ │
│ │ noodl-components • 24 components • Last synced: 2h ago │ │
│ │ [☑ Enabled] [⚙️ Settings] [🔄 Sync] [↗️ View on GitHub] │ │
│ ├─────────────────────────────────────────────────────────────────┤ │
│ │ [🏢] StartupXYZ │ │
│ │ noodl-components • 8 components • Last synced: 1d ago │ │
│ │ [☑ Enabled] [⚙️ Settings] [🔄 Sync] [↗️ View on GitHub] │ │
│ ├─────────────────────────────────────────────────────────────────┤ │
│ │ [🏢] OpenSource Collective │ │
│ │ ⚠️ No component repository found │ │
│ │ [Create Repository] │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
│ [🔄 Refresh Organizations] │
│ │
└─────────────────────────────────────────────────────────────────────┘
5. NodePicker Integration
┌─────────────────────────────────────────────────────────────────────┐
│ Prefabs │
├─────────────────────────────────────────────────────────────────────┤
│ 🔍 Search prefabs... │
├─────────────────────────────────────────────────────────────────────┤
│ Source: [All Sources ▾] Category: [All ▾] │
│ • All Sources │
│ • Built-in │
│ • Acme Corp │
│ • StartupXYZ │
│ • Community │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ACME CORP │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ 🏢 AcmeButton v2.1.0 [Clone] │ │
│ │ Standard button following Acme design system │ │
│ ├────────────────────────────────────────────────────────────────┤ │
│ │ 🏢 AcmeCard v1.3.0 [Clone] │ │
│ │ Card component with Acme styling │ │
│ └────────────────────────────────────────────────────────────────┘ │
│ │
│ BUILT-IN │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ 📦 Form Input v1.0.0 [Clone] │ │
│ │ Standard form input with validation │ │
│ └────────────────────────────────────────────────────────────────┘ │
Files to Create
packages/noodl-editor/src/editor/src/models/prefab/sources/OrganizationPrefabSource.tspackages/noodl-editor/src/editor/src/services/OrganizationService.tspackages/noodl-core-ui/src/components/settings/OrganizationSettings/OrganizationSettings.tsxpackages/noodl-core-ui/src/components/settings/OrganizationSettings/OrgCard.tsxpackages/noodl-core-ui/src/preview/launcher/Launcher/views/OrganizationsView.tsx
Files to Modify
-
packages/noodl-editor/src/editor/src/services/GitHubOAuthService.ts- Trigger org discovery on auth
-
packages/noodl-editor/src/editor/src/models/prefab/PrefabRegistry.ts- Handle org sources dynamically
- Add source filtering
-
packages/noodl-editor/src/editor/src/views/NodePicker/tabs/NodePickerSearchView/NodePickerSearchView.tsx- Add source filter dropdown
- Show org badges
-
packages/noodl-editor/src/editor/src/views/NodePicker/components/ModuleCard/ModuleCard.tsx- Show organization name
- Different styling for org components
-
packages/noodl-core-ui/src/preview/launcher/Launcher/Launcher.tsx- Add Organizations section/page
Implementation Steps
Phase 1: Organization Discovery
- Create OrganizationService
- Implement GitHub org listing
- Check for component repos
- Store org data
Phase 2: Organization Source
- Create OrganizationPrefabSource
- Implement manifest loading
- Implement component downloading
- Add to PrefabRegistry
Phase 3: Auto-Registration
- Hook into OAuth flow
- Auto-register on login
- Handle permission changes
- Persist org settings
Phase 4: Settings UI
- Create OrganizationSettings component
- Create OrgCard component
- Add to Settings panel
- Implement enable/disable
Phase 5: NodePicker Integration
- Add source filter
- Show org grouping
- Add org badges
- Update search
Phase 6: Polish
- Sync/refresh functionality
- Error handling
- Offline support
- Performance optimization
Testing Checklist
- Organizations discovered on login
- Component repos detected
- Source registered for orgs with repos
- Components appear in NodePicker
- Source filter works
- Org badge displays
- Enable/disable works
- Sync refreshes components
- Private repos accessible
- Permission errors handled
- Works with multiple orgs
- Caching works offline
- Settings persist
Dependencies
- COMP-001 (Prefab System Refactoring)
- COMP-003 (Component Export) - for repository structure
- GIT-001 (GitHub OAuth) - for organization access
Blocked By
- COMP-001
- GIT-001
Blocks
- COMP-005 (depends on org repos existing)
- COMP-006 (depends on org repos existing)
Estimated Effort
- Organization discovery: 3-4 hours
- OrganizationPrefabSource: 4-5 hours
- Auto-registration: 2-3 hours
- Settings UI: 3-4 hours
- NodePicker integration: 3-4 hours
- Polish & testing: 3-4 hours
- Total: 18-24 hours
Success Criteria
- Orgs auto-detected on GitHub login
- Component repos discovered automatically
- Org components appear in NodePicker
- Can filter by organization
- Settings allow enable/disable
- Works with private repositories
- Clear error messages for access issues
Repository Setup Guide (For Users)
To create an organization component repository:
- Create repo named
noodl-componentsin your org - Add
index.jsonmanifest file:
{
"name": "Acme Components",
"version": "1.0.0",
"components": []
}
- Export components using COMP-003
- Noodl will auto-detect the repository
Future Enhancements
- GitHub Enterprise support
- Repository templates
- Permission levels (read/write per component)
- Component approval workflow
- Usage analytics per org
- Component deprecation notices
- Multi-repo per org support