Fix remaining old terminology references

- backend/app/main.py: grove/ -> project/ in SPA route check
- frontend/vite.config.ts: /grove -> /project proxy
- helm/orchard/templates/NOTES.txt: Updated API examples
- migrations/001_initial.sql: Updated table/column names

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-12-08 10:41:26 -06:00
parent d382e5d6b7
commit a773998f45
4 changed files with 63 additions and 63 deletions

View File

@@ -42,7 +42,7 @@ if os.path.exists(static_dir):
@app.get("/{full_path:path}") @app.get("/{full_path:path}")
async def serve_spa_routes(full_path: str): async def serve_spa_routes(full_path: str):
# Don't catch API routes # Don't catch API routes
if full_path.startswith("api/") or full_path.startswith("health") or full_path.startswith("grove/"): if full_path.startswith("api/") or full_path.startswith("health") or full_path.startswith("project/"):
from fastapi import HTTPException from fastapi import HTTPException
raise HTTPException(status_code=404, detail="Not found") raise HTTPException(status_code=404, detail="Not found")

View File

@@ -7,7 +7,7 @@ export default defineConfig({
proxy: { proxy: {
'/api': 'http://localhost:8080', '/api': 'http://localhost:8080',
'/health': 'http://localhost:8080', '/health': 'http://localhost:8080',
'/grove': 'http://localhost:8080', '/project': 'http://localhost:8080',
} }
} }
}) })

View File

@@ -24,31 +24,31 @@ Orchard has been installed!
{{- end }} {{- end }}
2. API Endpoints: 2. API Endpoints:
- Health Check: GET /health - Health Check: GET /health
- List Groves: GET /api/v1/groves - List Projects: GET /api/v1/projects
- Create Grove: POST /api/v1/groves - Create Project: POST /api/v1/projects
- Upload: POST /api/v1/grove/{grove}/{tree}/cultivate - Upload: POST /api/v1/project/{project}/{package}/upload
- Download: GET /api/v1/grove/{grove}/{tree}/+/{ref} - Download: GET /api/v1/project/{project}/{package}/+/{ref}
3. Example Usage: 3. Example Usage:
# Create a grove # Create a project
curl -X POST http://localhost:8080/api/v1/groves \ curl -X POST http://localhost:8080/api/v1/projects \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d '{"name": "my-project", "description": "My project", "is_public": true}' -d '{"name": "my-project", "description": "My project", "is_public": true}'
# Create a tree # Create a package
curl -X POST http://localhost:8080/api/v1/grove/my-project/trees \ curl -X POST http://localhost:8080/api/v1/project/my-project/packages \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d '{"name": "releases", "description": "Release builds"}' -d '{"name": "releases", "description": "Release builds"}'
# Upload an artifact # Upload an artifact
curl -X POST http://localhost:8080/api/v1/grove/my-project/releases/cultivate \ curl -X POST http://localhost:8080/api/v1/project/my-project/releases/upload \
-F "file=@./my-artifact.tar.gz" \ -F "file=@./my-artifact.tar.gz" \
-F "tag=v1.0.0" -F "tag=v1.0.0"
# Download an artifact # Download an artifact
curl -O http://localhost:8080/api/v1/grove/my-project/releases/+/v1.0.0 curl -O http://localhost:8080/api/v1/project/my-project/releases/+/v1.0.0
{{- if .Values.postgresql.enabled }} {{- if .Values.postgresql.enabled }}

View File

@@ -1,8 +1,8 @@
-- Orchard Database Schema -- Orchard Database Schema
-- Content-Addressable Storage System -- Content-Addressable Storage System
-- Groves (Projects) -- Projects (top-level organizational containers)
CREATE TABLE IF NOT EXISTS groves ( CREATE TABLE IF NOT EXISTS projects (
id UUID PRIMARY KEY, id UUID PRIMARY KEY,
name VARCHAR(255) UNIQUE NOT NULL, name VARCHAR(255) UNIQUE NOT NULL,
description TEXT, description TEXT,
@@ -12,25 +12,25 @@ CREATE TABLE IF NOT EXISTS groves (
created_by VARCHAR(255) NOT NULL created_by VARCHAR(255) NOT NULL
); );
CREATE INDEX idx_groves_name ON groves(name); CREATE INDEX idx_projects_name ON projects(name);
CREATE INDEX idx_groves_created_by ON groves(created_by); CREATE INDEX idx_projects_created_by ON projects(created_by);
-- Trees (Packages) -- Packages (collections within projects)
CREATE TABLE IF NOT EXISTS trees ( CREATE TABLE IF NOT EXISTS packages (
id UUID PRIMARY KEY, id UUID PRIMARY KEY,
grove_id UUID NOT NULL REFERENCES groves(id) ON DELETE CASCADE, project_id UUID NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
name VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL,
description TEXT, description TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
UNIQUE(grove_id, name) UNIQUE(project_id, name)
); );
CREATE INDEX idx_trees_grove_id ON trees(grove_id); CREATE INDEX idx_packages_project_id ON packages(project_id);
CREATE INDEX idx_trees_name ON trees(name); CREATE INDEX idx_packages_name ON packages(name);
-- Fruits (Content-Addressable Artifacts) -- Artifacts (Content-Addressable)
CREATE TABLE IF NOT EXISTS fruits ( CREATE TABLE IF NOT EXISTS artifacts (
id VARCHAR(64) PRIMARY KEY, -- SHA256 hash id VARCHAR(64) PRIMARY KEY, -- SHA256 hash
size BIGINT NOT NULL, size BIGINT NOT NULL,
content_type VARCHAR(255), content_type VARCHAR(255),
@@ -41,75 +41,75 @@ CREATE TABLE IF NOT EXISTS fruits (
s3_key VARCHAR(1024) NOT NULL s3_key VARCHAR(1024) NOT NULL
); );
CREATE INDEX idx_fruits_created_at ON fruits(created_at); CREATE INDEX idx_artifacts_created_at ON artifacts(created_at);
CREATE INDEX idx_fruits_created_by ON fruits(created_by); CREATE INDEX idx_artifacts_created_by ON artifacts(created_by);
-- Grafts (Aliases/Tags) -- Tags (Aliases pointing to artifacts)
CREATE TABLE IF NOT EXISTS grafts ( CREATE TABLE IF NOT EXISTS tags (
id UUID PRIMARY KEY, id UUID PRIMARY KEY,
tree_id UUID NOT NULL REFERENCES trees(id) ON DELETE CASCADE, package_id UUID NOT NULL REFERENCES packages(id) ON DELETE CASCADE,
name VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL,
fruit_id VARCHAR(64) NOT NULL REFERENCES fruits(id), artifact_id VARCHAR(64) NOT NULL REFERENCES artifacts(id),
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
created_by VARCHAR(255) NOT NULL, created_by VARCHAR(255) NOT NULL,
UNIQUE(tree_id, name) UNIQUE(package_id, name)
); );
CREATE INDEX idx_grafts_tree_id ON grafts(tree_id); CREATE INDEX idx_tags_package_id ON tags(package_id);
CREATE INDEX idx_grafts_fruit_id ON grafts(fruit_id); CREATE INDEX idx_tags_artifact_id ON tags(artifact_id);
-- Graft History (for rollback capability) -- Tag History (for rollback capability)
CREATE TABLE IF NOT EXISTS graft_history ( CREATE TABLE IF NOT EXISTS tag_history (
id UUID PRIMARY KEY, id UUID PRIMARY KEY,
graft_id UUID NOT NULL REFERENCES grafts(id) ON DELETE CASCADE, tag_id UUID NOT NULL REFERENCES tags(id) ON DELETE CASCADE,
old_fruit_id VARCHAR(64) REFERENCES fruits(id), old_artifact_id VARCHAR(64) REFERENCES artifacts(id),
new_fruit_id VARCHAR(64) NOT NULL REFERENCES fruits(id), new_artifact_id VARCHAR(64) NOT NULL REFERENCES artifacts(id),
changed_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), changed_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
changed_by VARCHAR(255) NOT NULL changed_by VARCHAR(255) NOT NULL
); );
CREATE INDEX idx_graft_history_graft_id ON graft_history(graft_id); CREATE INDEX idx_tag_history_tag_id ON tag_history(tag_id);
-- Harvests (Upload events) -- Uploads (upload event records)
CREATE TABLE IF NOT EXISTS harvests ( CREATE TABLE IF NOT EXISTS uploads (
id UUID PRIMARY KEY, id UUID PRIMARY KEY,
fruit_id VARCHAR(64) NOT NULL REFERENCES fruits(id), artifact_id VARCHAR(64) NOT NULL REFERENCES artifacts(id),
tree_id UUID NOT NULL REFERENCES trees(id), package_id UUID NOT NULL REFERENCES packages(id),
original_name VARCHAR(1024), original_name VARCHAR(1024),
harvested_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), uploaded_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
harvested_by VARCHAR(255) NOT NULL, uploaded_by VARCHAR(255) NOT NULL,
source_ip VARCHAR(45) source_ip VARCHAR(45)
); );
CREATE INDEX idx_harvests_fruit_id ON harvests(fruit_id); CREATE INDEX idx_uploads_artifact_id ON uploads(artifact_id);
CREATE INDEX idx_harvests_tree_id ON harvests(tree_id); CREATE INDEX idx_uploads_package_id ON uploads(package_id);
CREATE INDEX idx_harvests_harvested_at ON harvests(harvested_at); CREATE INDEX idx_uploads_uploaded_at ON uploads(uploaded_at);
-- Consumers (Dependency tracking) -- Consumers (Dependency tracking)
CREATE TABLE IF NOT EXISTS consumers ( CREATE TABLE IF NOT EXISTS consumers (
id UUID PRIMARY KEY, id UUID PRIMARY KEY,
tree_id UUID NOT NULL REFERENCES trees(id) ON DELETE CASCADE, package_id UUID NOT NULL REFERENCES packages(id) ON DELETE CASCADE,
project_url VARCHAR(2048) NOT NULL, project_url VARCHAR(2048) NOT NULL,
last_access TIMESTAMP WITH TIME ZONE DEFAULT NOW(), last_access TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
UNIQUE(tree_id, project_url) UNIQUE(package_id, project_url)
); );
CREATE INDEX idx_consumers_tree_id ON consumers(tree_id); CREATE INDEX idx_consumers_package_id ON consumers(package_id);
CREATE INDEX idx_consumers_last_access ON consumers(last_access); CREATE INDEX idx_consumers_last_access ON consumers(last_access);
-- Access Permissions -- Access Permissions
CREATE TABLE IF NOT EXISTS access_permissions ( CREATE TABLE IF NOT EXISTS access_permissions (
id UUID PRIMARY KEY, id UUID PRIMARY KEY,
grove_id UUID NOT NULL REFERENCES groves(id) ON DELETE CASCADE, project_id UUID NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
user_id VARCHAR(255) NOT NULL, user_id VARCHAR(255) NOT NULL,
level VARCHAR(20) NOT NULL CHECK (level IN ('read', 'write', 'admin')), level VARCHAR(20) NOT NULL CHECK (level IN ('read', 'write', 'admin')),
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
expires_at TIMESTAMP WITH TIME ZONE, expires_at TIMESTAMP WITH TIME ZONE,
UNIQUE(grove_id, user_id) UNIQUE(project_id, user_id)
); );
CREATE INDEX idx_access_permissions_grove_id ON access_permissions(grove_id); CREATE INDEX idx_access_permissions_project_id ON access_permissions(project_id);
CREATE INDEX idx_access_permissions_user_id ON access_permissions(user_id); CREATE INDEX idx_access_permissions_user_id ON access_permissions(user_id);
-- API Keys -- API Keys
@@ -142,19 +142,19 @@ CREATE INDEX idx_audit_logs_resource ON audit_logs(resource);
CREATE INDEX idx_audit_logs_user_id ON audit_logs(user_id); CREATE INDEX idx_audit_logs_user_id ON audit_logs(user_id);
CREATE INDEX idx_audit_logs_timestamp ON audit_logs(timestamp); CREATE INDEX idx_audit_logs_timestamp ON audit_logs(timestamp);
-- Trigger to update graft history on changes -- Trigger to update tag history on changes
CREATE OR REPLACE FUNCTION track_graft_changes() CREATE OR REPLACE FUNCTION track_tag_changes()
RETURNS TRIGGER AS $$ RETURNS TRIGGER AS $$
BEGIN BEGIN
IF TG_OP = 'UPDATE' AND OLD.fruit_id != NEW.fruit_id THEN IF TG_OP = 'UPDATE' AND OLD.artifact_id != NEW.artifact_id THEN
INSERT INTO graft_history (id, graft_id, old_fruit_id, new_fruit_id, changed_at, changed_by) INSERT INTO tag_history (id, tag_id, old_artifact_id, new_artifact_id, changed_at, changed_by)
VALUES (gen_random_uuid(), NEW.id, OLD.fruit_id, NEW.fruit_id, NOW(), NEW.created_by); VALUES (gen_random_uuid(), NEW.id, OLD.artifact_id, NEW.artifact_id, NOW(), NEW.created_by);
END IF; END IF;
RETURN NEW; RETURN NEW;
END; END;
$$ LANGUAGE plpgsql; $$ LANGUAGE plpgsql;
CREATE TRIGGER graft_changes_trigger CREATE TRIGGER tag_changes_trigger
AFTER UPDATE ON grafts AFTER UPDATE ON tags
FOR EACH ROW FOR EACH ROW
EXECUTE FUNCTION track_graft_changes(); EXECUTE FUNCTION track_tag_changes();