Skip to main content

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​

PropertyValue
Package@internal/plugin-homepage-repos-backend
TypeBackend
Plugin IDhomepage-repos
DatabasePostgreSQL via Knex

Architecture​

API Endpoints​

MethodEndpointDescription
GET/reposGet user's repos
GET/repos/by-group/:groupRefGet repos for group
POST/reposAdd new repository
DELETE/repos/:idDelete entire repo
DELETE/repos/:id/groups/:groupRefRemove repo from group
GET/autocompleteSearch existing repos
GET/user-groupsGet user's groups

Database Schema​

homepage_repos​

ColumnTypeDescription
idUUIDPrimary key
urlVARCHARGitHub repository URL
nameVARCHARRepository name
ownerVARCHARRepository owner
descriptionTEXTOptional description
group_refsJSONBArray of group refs
created_byVARCHARCreator user reference
created_atTIMESTAMPCreation time
updated_atTIMESTAMPLast 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/repo
  • https://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: