# GiteaCustomApi Gitea repository metadata cache + query API for git.hangman-lab.top. ## Overview A lightweight Go service that: - Caches repository metadata (id, name, owner, visibility, url) from Gitea MySQL database - Refreshes every 5 hours via full sync - Listens for Gitea webhook events (repo create/delete) for real-time cache updates - Exposes a `/list?username=xxx` endpoint that queries cached repos + live collaborator permissions from MySQL ## Architecture ``` ┌─────────────────────────────────────────────────────────────┐ │ VPS.git │ │ ┌──────────────┐ ┌─────────────┐ ┌──────────────────┐ │ │ │ Gitea DB │ │ go-server │ │ Nginx │ │ │ │ (MySQL) │◄──│ (cache+api) │ │ /c-api -> :8080 │ │ │ └──────────────┘ └─────────────┘ └──────────────────┘ │ │ ▲ │ │ ┌────────┴────────┐ │ │ │ Gitea Webhook │ │ │ │ (create/delete)│ │ │ └─────────────────┘ │ └─────────────────────────────────────────────────────────────┘ ``` ## Tech Stack - **Language**: Go - **Database**: SQLite (local cache) - **Source DB**: Gitea MySQL (read-only, same docker network) - **HTTP**: Standard library `net/http` - **Deployment**: Docker + Docker Compose on vps.git ## API ### `GET /list?username={username}` Returns all repositories visible to the given Gitea user. **Response** (JSON): ```json [ { "name": "ClawSkills", "owner": "lyn", "url": "https://git.hangman-lab.top/lyn/ClawSkills.git", "is_private": false, "can_write": true } ] ``` `can_write` is determined at query time by checking: - User is the repo owner, OR - User has explicit access via `access` table, OR - User is a member of a team that has access to the repo ### `POST /webhook/gitea` Receives Gitea webhook events (requires `X-Gitea-Event` header). Supported events: - `repository.create` — insert new repo into cache - `repository.delete` — remove repo from cache ### `GET /health` Returns `{"status": "ok"}`. ## Data Model ### SQLite cache table: `repos` | Column | Type | Notes | |--------------|---------|------------------------------| | id | INTEGER | Gitea repo ID (primary key) | | name | TEXT | | | owner | TEXT | Gitea username of owner | | is_private | INTEGER | 0 or 1 | | url | TEXT | Full .git HTTPS URL | | updated_at | INTEGER | Unix timestamp of last sync | ## Configuration Environment variables: | Variable | Default | Description | |---------------|---------|------------------------------| | `DB_HOST` | `mysql` | MySQL container hostname | | `DB_USER` | `root` | MySQL username | | `DB_PASS` | — | MySQL password | | `DB_NAME` | `giteadb` | MySQL database name | | `SQLITE_PATH` | `cache.db` | SQLite file path | | `WEBHOOK_SECRET` | — | Gitea webhook secret token | | `PORT` | `8080` | HTTP listen port | ## Docker ### Dockerfile ```dockerfile FROM golang:1.22-alpine AS build WORKDIR /app COPY go.mod go.sum ./ RUN go mod download COPY *.go ./ RUN CGO_ENABLED=0 GOOS=linux go build -o server . CMD ["./server"] ``` ### docker-compose.yml (fragment to merge into vps.git compose) ```yaml services: gitea-custom-api: build: ./gitea-custom-api container_name: gitea-custom-api restart: unless-stopped environment: DB_HOST: mysql DB_USER: root DB_PASS: ${MYSQL_ROOT_PASSWORD} DB_NAME: giteadb SQLITE_PATH: /data/cache.db WEBHOOK_SECRET: ${GITEA_WEBHOOK_SECRET} PORT: 8080 volumes: - ./gitea-custom-api/data:/data networks: - git-network networks: git-network: external: true ``` ### Nginx location (merge into vps.git nginx config) ```nginx location /c-api/ { proxy_pass http://localhost:8080/; } ``` ## Gitea Webhook Setup In Gitea admin panel → Webhooks → Add webhook: - **URL**: `https://git.hangman-lab.top/c-api/webhook/gitea` - **HTTP Method**: POST - **Content Type**: `application/json` - **Secret**: set a strong token, pass via `WEBHOOK_SECRET` - **Events**: Repository: Create, Repository: Delete ## Refresh Strategy 1. **Startup**: full sync of all non-archived repos from `repository` table 2. **Every 5 hours**: full sync (upsert based on repo id) 3. **Webhook**: incremental create/delete for real-time updates 4. **On cache miss during query**: fall back to live MySQL query ## Out of Scope - Authentication on the API endpoint (internal service, only accessible via nginx on vps.git) - Caching collaborator permissions (queried live per request) - Handling repo rename/transfer (caught by 5h refresh)