Homepage Repos Backend Plugin
The Homepage Repos Backend provides repository persistence for the homepage Git Repositories section, allowing users to save and organize their frequently used repositories.
Overview
| Property | Value |
|---|---|
| Package | @internal/plugin-homepage-repos-backend |
| Type | Backend |
| Plugin ID | homepage-repos |
| Database | PostgreSQL via Knex |
Architecture
API Endpoints
| Method | Endpoint | Description |
|---|---|---|
| GET | /repos | Get user's repos |
| GET | /repos/by-group/:groupRef | Get repos for group |
| POST | /repos | Add new repository |
| DELETE | /repos/:id | Delete entire repo |
| DELETE | /repos/:id/groups/:groupRef | Remove repo from group |
| GET | /autocomplete | Search existing repos |
| GET | /user-groups | Get user's groups |
Database Schema
homepage_repos
| Column | Type | Description |
|---|---|---|
| id | UUID | Primary key |
| url | VARCHAR | GitHub repository URL |
| name | VARCHAR | Repository name |
| owner | VARCHAR | Repository owner |
| description | TEXT | Optional description |
| group_refs | JSONB | Array of group refs |
| created_by | VARCHAR | Creator user reference |
| created_at | TIMESTAMP | Creation time |
| updated_at | TIMESTAMP | Last update time |
Request/Response Schemas
Create Repository
// POST /repos
interface CreateRepoRequest {
url: string; // GitHub URL
description?: string; // Optional description
groupRefs: string[]; // Groups to share with
}
// Zod schema
const createRepoSchema = z.object({
url: z.string().regex(/^https:\/\/github\.com\/[\w-]+\/[\w.-]+$/),
description: z.string().max(500).optional(),
groupRefs: z.array(z.string()).min(1),
});
Repository Response
interface Repository {
id: string;
url: string;
name: string;
owner: string;
description?: string;
groupRefs: string[];
createdBy: string;
createdAt: string;
updatedAt: string;
}
RepoStore Service
interface RepoStore {
// Repository operations
getRepos(groupRefs: string[]): Promise<Repository[]>;
getReposByGroup(groupRef: string): Promise<Repository[]>;
createRepo(input: CreateRepoInput, createdBy: string): Promise<Repository>;
deleteRepo(id: string): Promise<void>;
removeRepoFromGroup(id: string, groupRef: string): Promise<void>;
autocomplete(query: string): Promise<Repository[]>;
}
URL Validation
Repository URLs are validated and parsed:
class RepoUrlValidator {
validate(url: string): ParsedRepo {
const match = url.match(/^https:\/\/github\.com\/([\w-]+)\/([\w.-]+)$/);
if (!match) {
throw new InputError("Invalid GitHub repository URL");
}
return {
url,
owner: match[1],
name: match[2],
};
}
}
Accepted URL formats:
https://github.com/owner/repohttps://github.com/owner/repo.git(normalized)
Group-Based Access
Repositories are shared by group:
Usage Examples
Add Repository
curl -X POST http://localhost:7007/api/homepage-repos/repos \
-H "Content-Type: application/json" \
-d '{
"url": "https://github.com/badal-io/devex-backstage",
"description": "DevEx Backstage Platform",
"groupRefs": ["group:default/platform-team"]
}'
Get User's Repositories
curl http://localhost:7007/api/homepage-repos/repos
Response:
[
{
"id": "xxx",
"url": "https://github.com/badal-io/devex-backstage",
"name": "devex-backstage",
"owner": "badal-io",
"description": "DevEx Backstage Platform",
"groupRefs": ["group:default/platform-team"],
"createdBy": "user:default/john.doe",
"createdAt": "2024-01-15T10:00:00Z",
"updatedAt": "2024-01-15T10:00:00Z"
}
]
Search Repositories
curl "http://localhost:7007/api/homepage-repos/autocomplete?q=backstage"
Remove from Group
curl -X DELETE "http://localhost:7007/api/homepage-repos/repos/xxx/groups/group:default/platform-team"
Frontend Integration
The frontend combines saved repos with auto-detected ones:
Related Documentation
- Homepage Links Frontend - Frontend plugin
- Homepage Links Backend - Links management
- Homepage GCP Projects Backend - GCP projects
- Plugins Overview