Edit plans/PHASE_1_PLAN.md

This commit is contained in:
2026-06-08 14:47:22 -05:00
parent c32e08be38
commit fd81f443d6
+337 -337
View File
@@ -1,337 +1,337 @@
# Gitocean Phase 1 Plan: MVP # Gitocean Phase 1 Plan: MVP
Phase 1 focuses on building the minimum viable Git hosting platform: CLI + API only, MySQL metadata, repositories stored on disk, HTTP Smart Git transport, public/private repositories, search, forks, and pull requests. Phase 1 focuses on building the minimum viable Git hosting platform: CLI + API only, MySQL metadata, repositories stored on disk, HTTP Smart Git transport, public/private repositories, search, forks, and pull requests.
This phase intentionally avoids a web UI, SSH Git transport, organizations, teams, CI/CD, and enterprise features. The goal is a working personal Git hosting foundation. This phase intentionally avoids a web UI, SSH Git transport, organizations, teams, CI/CD, and enterprise features. The goal is a working personal Git hosting foundation.
## Goals ## Goals
- Build a Go-based Git repository hosting platform. - Build a Go-based Git repository hosting platform.
- Store bare repositories under `storage/repos/{owner}/{repo}.git`. - Store bare repositories under `storage/repos/{owner}/{repo}.git`.
- Use MySQL for metadata. - Use MySQL for metadata.
- Support HTTP Smart Git clone/fetch/push. - Support HTTP Smart Git clone/fetch/push.
- Provide CLI-based registration, login, repository management, search, forks, and pull requests. - Provide CLI-based registration, login, repository management, search, forks, and pull requests.
- Support public and private repositories. - Support public and private repositories.
- Use temporary 7-day API/Git auth tokens. - Use temporary 7-day API/Git auth tokens.
- Keep permissions simple: owner-only writes and private access in MVP. - Keep permissions simple: owner-only writes and private access in MVP.
--- ---
## 1. Product decisions ## 1. Product decisions
### Platform shape ### Platform shape
- Gitocean is a CLI + API Git hosting system. - Gitocean is a CLI + API Git hosting system.
- No Web UI in Phase 1. - No Web UI in Phase 1.
- No SSH Git transport in Phase 1. - No SSH Git transport in Phase 1.
- Repositories are stored as bare Git repositories on disk. - Repositories are stored as bare Git repositories on disk.
- Metadata is stored in MySQL. - Metadata is stored in MySQL.
### Registration and login ### Registration and login
- Registration is open. - Registration is open.
- Users register with: - Users register with:
- email - email
- username - username
- password - password
- Users can log in with either: - Users can log in with either:
- email + password - email + password
- username + password - username + password
- Login returns a temporary token that expires after 7 days. - Login returns a temporary token that expires after 7 days.
- The CLI stores the token locally for API calls. - The CLI stores the token locally for API calls.
- The CLI can approve the token into Git's credential helper for HTTP Git operations. - The CLI can approve the token into Git's credential helper for HTTP Git operations.
### Naming defaults ### Naming defaults
- CLI binary name: `gitocean`. - CLI binary name: `gitocean`.
- Default branch: `main`. - Default branch: `main`.
- Repository names allow lowercase letters, numbers, `.`, `_`, and `-`. - Repository names allow lowercase letters, numbers, `.`, `_`, and `-`.
- Usernames allow lowercase letters, numbers, `_`, and `-`. - Usernames allow lowercase letters, numbers, `_`, and `-`.
- Pull request numbers are scoped per target repository. - Pull request numbers are scoped per target repository.
--- ---
## 2. Permissions ## 2. Permissions
### Repository visibility ### Repository visibility
Public repositories: Public repositories:
- Anyone can clone/fetch. - Anyone can clone/fetch.
- Only the owner can push. - Only the owner can push.
- Only the owner can delete or manage settings. - Only the owner can delete or manage settings.
Private repositories: Private repositories:
- Only the owner can clone/fetch. - Only the owner can clone/fetch.
- Only the owner can push. - Only the owner can push.
- Only the owner can delete or manage settings. - Only the owner can delete or manage settings.
### Writes ### Writes
- Phase 1 uses owner-only writes. - Phase 1 uses owner-only writes.
- No collaborators, organizations, teams, or fine-grained permissions yet. - No collaborators, organizations, teams, or fine-grained permissions yet.
- Outside collaboration happens through pull requests against public repositories. - Outside collaboration happens through pull requests against public repositories.
--- ---
## 3. Storage layout ## 3. Storage layout
Repositories live under: Repositories live under:
```text ```text
storage/repos/{owner}/{repo}.git storage/repos/{owner}/{repo}.git
``` ```
Example: Example:
```text ```text
storage/ storage/
repos/ repos/
alice/ alice/
demo.git/ demo.git/
bob/ bob/
project.git/ project.git/
``` ```
Each repository directory is a bare Git repository created with `git init --bare`. Each repository directory is a bare Git repository created with `git init --bare`.
--- ---
## 4. MySQL schema ## 4. MySQL schema
Core tables: Core tables:
### `users` ### `users`
- `id` - `id`
- `email` - `email`
- `username` - `username`
- `password_hash` - `password_hash`
- `created_at` - `created_at`
### `auth_tokens` ### `auth_tokens`
- `id` - `id`
- `user_id` - `user_id`
- `token_hash` - `token_hash`
- `expires_at` - `expires_at`
- `revoked_at` - `revoked_at`
- `created_at` - `created_at`
### `repositories` ### `repositories`
- `id` - `id`
- `owner_user_id` - `owner_user_id`
- `name` - `name`
- `visibility`: `public` or `private` - `visibility`: `public` or `private`
- `forked_from_repository_id` nullable - `forked_from_repository_id` nullable
- `created_at` - `created_at`
- `updated_at` - `updated_at`
### `pull_requests` ### `pull_requests`
- `id` - `id`
- `target_repository_id` - `target_repository_id`
- `number` - `number`
- `author_user_id` - `author_user_id`
- `source_repository_id` - `source_repository_id`
- `source_branch` - `source_branch`
- `target_branch` - `target_branch`
- `title` - `title`
- `description` - `description`
- `status`: `open`, `closed`, or `merged` - `status`: `open`, `closed`, or `merged`
- `closed_at` nullable - `closed_at` nullable
- `merged_at` nullable - `merged_at` nullable
- `created_at` - `created_at`
- `updated_at` - `updated_at`
--- ---
## 5. API routes ## 5. API routes
### Auth ### Auth
```http ```http
POST /api/register POST /api/register
POST /api/login POST /api/login
POST /api/logout POST /api/logout
GET /api/me GET /api/me
``` ```
### Repositories ### Repositories
```http ```http
POST /api/repos POST /api/repos
GET /api/repos/search?q=demo&scope=all GET /api/repos/search?q=demo&scope=all
GET /api/repos/search?q=demo&scope=mine GET /api/repos/search?q=demo&scope=mine
GET /api/repos/{owner}/{repo} GET /api/repos/{owner}/{repo}
DELETE /api/repos/{owner}/{repo}?force=false DELETE /api/repos/{owner}/{repo}?force=false
POST /api/repos/{owner}/{repo}/fork POST /api/repos/{owner}/{repo}/fork
``` ```
### Pull requests ### Pull requests
```http ```http
POST /api/repos/{owner}/{repo}/pulls POST /api/repos/{owner}/{repo}/pulls
GET /api/repos/{owner}/{repo}/pulls GET /api/repos/{owner}/{repo}/pulls
GET /api/repos/{owner}/{repo}/pulls/{number} GET /api/repos/{owner}/{repo}/pulls/{number}
POST /api/repos/{owner}/{repo}/pulls/{number}/close POST /api/repos/{owner}/{repo}/pulls/{number}/close
POST /api/repos/{owner}/{repo}/pulls/{number}/merge POST /api/repos/{owner}/{repo}/pulls/{number}/merge
``` ```
### Git HTTP ### Git HTTP
```http ```http
/{owner}/{repo}.git/info/refs /{owner}/{repo}.git/info/refs
/{owner}/{repo}.git/git-upload-pack /{owner}/{repo}.git/git-upload-pack
/{owner}/{repo}.git/git-receive-pack /{owner}/{repo}.git/git-receive-pack
``` ```
--- ---
## 6. CLI commands ## 6. CLI commands
### Server ### Server
```bash ```bash
gitocean server --addr :8080 --dsn 'user:pass@tcp(127.0.0.1:3306)/gitocean?parseTime=true' --storage storage gitocean server --addr :8080 --dsn 'user:pass@tcp(127.0.0.1:3306)/gitocean?parseTime=true' --storage storage
``` ```
### Auth ### Auth
```bash ```bash
gitocean register gitocean register
gitocean login gitocean login
gitocean logout gitocean logout
gitocean whoami gitocean whoami
``` ```
### Repositories ### Repositories
```bash ```bash
gitocean repo create NAME --public gitocean repo create NAME --public
gitocean repo create NAME --private gitocean repo create NAME --private
gitocean repo delete OWNER/NAME [--force] gitocean repo delete OWNER/NAME [--force]
gitocean repo search QUERY --all gitocean repo search QUERY --all
gitocean repo search QUERY --mine gitocean repo search QUERY --mine
gitocean repo fork OWNER/NAME [--name NEW_NAME] gitocean repo fork OWNER/NAME [--name NEW_NAME]
``` ```
### Clone ### Clone
```bash ```bash
gitocean clone OWNER/NAME gitocean clone OWNER/NAME
``` ```
### Pull requests ### Pull requests
```bash ```bash
gitocean pr create --from OWNER/REPO:BRANCH --to OWNER/REPO:BRANCH --title TITLE --description DESC gitocean pr create --from OWNER/REPO:BRANCH --to OWNER/REPO:BRANCH --title TITLE --description DESC
gitocean pr create --repo OWNER/REPO --from BRANCH --to BRANCH --title TITLE --description DESC gitocean pr create --repo OWNER/REPO --from BRANCH --to BRANCH --title TITLE --description DESC
gitocean pr list OWNER/REPO gitocean pr list OWNER/REPO
gitocean pr view OWNER/REPO NUMBER gitocean pr view OWNER/REPO NUMBER
gitocean pr close OWNER/REPO NUMBER gitocean pr close OWNER/REPO NUMBER
gitocean pr merge OWNER/REPO NUMBER gitocean pr merge OWNER/REPO NUMBER
``` ```
--- ---
## 7. Git HTTP behavior ## 7. Git HTTP behavior
Use Git's built-in Smart HTTP backend: Use Git's built-in Smart HTTP backend:
```bash ```bash
git http-backend git http-backend
``` ```
Required behavior: Required behavior:
- Public clone/fetch works without auth. - Public clone/fetch works without auth.
- Private clone/fetch requires owner auth. - Private clone/fetch requires owner auth.
- Push always requires auth. - Push always requires auth.
- Push is owner-only. - Push is owner-only.
- Git username is the account username. - Git username is the account username.
- Git password is the 7-day token. - Git password is the 7-day token.
--- ---
## 8. Fork behavior ## 8. Fork behavior
- Logged-in users can fork public repositories. - Logged-in users can fork public repositories.
- Private repositories can only be forked by the owner in Phase 1. - Private repositories can only be forked by the owner in Phase 1.
- Forks are copied as bare repositories under the new owner's storage path. - Forks are copied as bare repositories under the new owner's storage path.
- Fork metadata stores `forked_from_repository_id`. - Fork metadata stores `forked_from_repository_id`.
--- ---
## 9. Pull request rules ## 9. Pull request rules
### Same-repository PRs ### Same-repository PRs
- Source and target repository are the same. - Source and target repository are the same.
- Only the repository owner can create same-repo PRs. - Only the repository owner can create same-repo PRs.
- Source and target branches must both exist. - Source and target branches must both exist.
### Cross-repository PRs ### Cross-repository PRs
- Source repository branch points to target repository branch. - Source repository branch points to target repository branch.
- Source repository must be owned by the PR author. - Source repository must be owned by the PR author.
- Target repository must be public, unless the author is also the target owner. - Target repository must be public, unless the author is also the target owner.
- Source and target branches must both exist. - Source and target branches must both exist.
- Only the target repository owner can close or merge the PR. - Only the target repository owner can close or merge the PR.
--- ---
## 10. Merge behavior ## 10. Merge behavior
Phase 1 merge mode is a normal merge commit: Phase 1 merge mode is a normal merge commit:
1. Clone the target repo into a temporary worktree. 1. Clone the target repo into a temporary worktree.
2. Checkout the target branch. 2. Checkout the target branch.
3. Add/fetch the source repo branch. 3. Add/fetch the source repo branch.
4. Run `git merge --no-ff FETCH_HEAD`. 4. Run `git merge --no-ff FETCH_HEAD`.
5. Push the result back to the target branch. 5. Push the result back to the target branch.
6. Mark the PR as merged. 6. Mark the PR as merged.
If conflicts occur: If conflicts occur:
- Return an error. - Return an error.
- Keep the PR open. - Keep the PR open.
- Do not modify PR status. - Do not modify PR status.
--- ---
## 11. Implementation milestones ## 11. Implementation milestones
1. Project scaffold and build setup. 1. Project scaffold and build setup.
2. MySQL migrations. 2. MySQL migrations.
3. User registration, login, logout, and token auth. 3. User registration, login, logout, and token auth.
4. Repository create, delete, detail, and search. 4. Repository create, delete, detail, and search.
5. HTTP Smart Git integration using `git http-backend`. 5. HTTP Smart Git integration using `git http-backend`.
6. CLI auth and repository commands. 6. CLI auth and repository commands.
7. Fork support. 7. Fork support.
8. Pull request create/list/view/close. 8. Pull request create/list/view/close.
9. Pull request merge. 9. Pull request merge.
10. Tests, hardening, and UX polish. 10. Tests, hardening, and UX polish.
--- ---
## Phase 1 completion criteria ## Phase 1 completion criteria
Phase 1 is complete when: Phase 1 is complete when:
- The server starts with MySQL metadata storage. - The server starts with MySQL metadata storage.
- Missing MySQL databases can be created automatically. - Missing MySQL databases can be created automatically.
- Users can register, login, logout, and run `whoami`. - Users can register, login, logout, and run `whoami`.
- Login tokens expire after 7 days. - Login tokens expire after 7 days.
- Users can create public/private repositories. - Users can create public/private repositories.
- Public repositories can be cloned/fetched without auth. - Public repositories can be cloned/fetched without auth.
- Private repositories require owner auth. - Private repositories require owner auth.
- Owners can push over HTTP. - Owners can push over HTTP.
- Non-owners cannot push. - Non-owners cannot push.
- Users can search visible repositories. - Users can search visible repositories.
- Users can fork allowed repositories. - Users can fork allowed repositories.
- Users can create, list, view, close, and merge pull requests. - Users can create, list, view, close, and merge pull requests.
- `go test ./...` passes. - `go test ./...` passes.
- `go vet ./...` passes. - `go vet ./...` passes.