Documentation
¶
Overview ¶
Package projectsvc is the Hanzo Cloud projects control plane: the ONE org-scoped store of buildable/deployable sites, shared by every surface that shows a user's projects.
Why it exists: hanzo.app (the builder) and console.hanzo.ai (the Projects module) must show the SAME projects for the same org. They do, because both call this one /v1/projects surface through the gateway, which mints the tenant (X-Org-Id) from the validated IAM JWT (HIP-0111). There is no second copy of project state anywhere — this SQLite-backed store is the source of truth; the builder keeps only per-project working state (chat, draft files) in Hanzo Base.
Surface (all org-scoped; see CONTRACT.md — the published shape console2 consumes):
POST /v1/projects create GET /v1/projects list (org) GET /v1/projects/:slug get PATCH /v1/projects/:slug update DELETE /v1/projects/:slug delete (+ purge S3 site) POST /v1/projects/:slug/deploy deploy (tar body | git json) GET /v1/projects/:slug/deployments deploy history GET /v1/projects/:slug/deployments/:id one deployment POST /v1/projects/:slug/deployments/:id/complete CI completion hook
Deploy pipeline: a deploy uploads the built static site to OUR S3 (CLOUD_PROJECTS_BUCKET on s3.hanzo.ai) under "<org>/<slug>/", marks the bucket public-read, and records a live URL. The hanzoai/static container (the static-app image) serves the same bucket behind the gateway for a pretty host; GitHub export is an optional second step that never blocks going live.
Index ¶
- func Mount(app *zip.App, deps cloud.Deps) error
- func Shutdown() error
- type Deployment
- type Project
- type Store
- func (s *Store) BindHost(ctx context.Context, host, org, slug string, now int64) error
- func (s *Store) Close() error
- func (s *Store) CreateProject(ctx context.Context, p Project) error
- func (s *Store) DeleteProject(ctx context.Context, org, slug string) (Project, bool, error)
- func (s *Store) GetDeployment(ctx context.Context, org, projectID, id string) (Deployment, error)
- func (s *Store) GetProject(ctx context.Context, org, slug string) (Project, error)
- func (s *Store) InsertDeployment(ctx context.Context, d Deployment) error
- func (s *Store) ListDeployments(ctx context.Context, org, projectID string) ([]Deployment, error)
- func (s *Store) ListProjects(ctx context.Context, org string) ([]Project, error)
- func (s *Store) NextVersion(ctx context.Context, projectID string) (int, error)
- func (s *Store) ResolveHost(ctx context.Context, host string) (Project, error)
- func (s *Store) UnbindHost(ctx context.Context, host, org, slug string) error
- func (s *Store) UpdateDeployment(ctx context.Context, d Deployment) error
- func (s *Store) UpdateProject(ctx context.Context, p Project) error
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Deployment ¶
type Deployment struct {
ID string
ProjectID string
Org string
Version int
Status string
Source string
Commit string
LiveURL string
Bucket string
Prefix string
Files int
Bytes int64
Message string
CreatedAt int64
UpdatedAt int64
}
Deployment is one deploy attempt for a project, versioned monotonically per project. A deploy moves through queued→building→uploading→live (or →error); the upload path (tar body) lands directly in "live", the git/CI path starts "queued" and is flipped by the CI completion call.
type Project ¶
type Project struct {
ID string
Org string
Slug string
Name string
Description string
RepoURL string
RepoBranch string
RepoProvider string
Framework string
Status string
LiveURL string
Bucket string
CurrentDeploy string
// CacheControl is the per-project override for the HTML/document Cache-Control
// header applied to deployed objects (and honored by the site server). Empty =
// the honest default (public, max-age=60, s-maxage=86400). Content-hashed
// assets are always immutable regardless of this override.
CacheControl string
// LastPurgeAt is the unix time of the last successful (or attempted) Cloudflare
// edge purge for this site. Surfaced on the API so a console can show cache freshness.
LastPurgeAt int64
CreatedAt int64
UpdatedAt int64
}
Project is the org-scoped, canonical record of a buildable/deployable site. It is the SAME record whether read from hanzo.app (the builder) or console.hanzo.ai (the Projects module): tenant isolation is the org column, enforced at the query layer, and the gateway-minted X-Org-Id selects the tenant. Repo fields are flat columns here; the HTTP surface nests them under "repo" (see projectsvc.go). It never stores a secret.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store is the projects metadata database. ONE SQLite file ({DataDir}/projects.db) holds every org's records; tenancy is the org column. MaxOpenConns(1) serializes writes against the file lock without busy retries.
func (*Store) BindHost ¶ added in v1.786.32
BindHost claims the global public host for (org, slug), first-come. It is idempotent for the SAME owner (a re-deploy just refreshes updated_at). If host is already bound to a DIFFERENT project it returns errHostTaken WITHOUT overwriting — a losing bind must never hijack another tenant's live subdomain.
func (*Store) CreateProject ¶
CreateProject inserts one project. A UNIQUE(org,slug) violation surfaces as errConflict.
func (*Store) DeleteProject ¶
DeleteProject removes a project and all its deployment rows. Reports whether a project row was deleted.
func (*Store) GetDeployment ¶
GetDeployment returns one deployment scoped to (org, project, id).
func (*Store) GetProject ¶
GetProject returns the project for (org,slug) or errNotFound.
func (*Store) InsertDeployment ¶
func (s *Store) InsertDeployment(ctx context.Context, d Deployment) error
InsertDeployment writes one deployment row.
func (*Store) ListDeployments ¶
ListDeployments returns deployments for a project, newest version first.
func (*Store) ListProjects ¶
ListProjects returns every project for org, most-recently-updated first.
func (*Store) NextVersion ¶
NextVersion returns the next monotonic deploy version for a project (1-based).
func (*Store) ResolveHost ¶ added in v1.786.32
ResolveHost returns the project a public host is bound to, joining the global site_hosts binding to the org-scoped project. This is the authoritative slug→project resolution the site server uses; the org and bucket come ONLY from here, never from the request. Missing binding OR missing project ⇒ errNotFound.
func (*Store) UnbindHost ¶ added in v1.786.32
UnbindHost releases a host binding, but only the row owned by (org, slug) — so deleting project A can never drop project B's host even if they somehow shared a row (they cannot, but the scoping makes the guarantee explicit).
func (*Store) UpdateDeployment ¶
func (s *Store) UpdateDeployment(ctx context.Context, d Deployment) error
UpdateDeployment overwrites the mutable fields of a deployment (status flow).