update_server/IMPLEMENTATION_PLAN.md
2026-06-10 20:51:17 +03:00

11 KiB

Update Server - Implementation Strategy

Backend

  • Go 1.24+
  • Router: chi or gin
  • HTML templates for admin UI, or server-rendered pages first
  • Database: SQLite
  • ORM/query layer: sqlc, bun, gorm, or plain database/sql
  • Migrations: golang-migrate or goose
  • Auth:
    • web admin via secure cookie session
    • client API via bearer API key

My recommendation

For this project, a pragmatic Go stack would be:

  • chi for routing;
  • database/sql + sqlc or bun;
  • SQLite with modernc.org/sqlite or mattn/go-sqlite3;
  • server-rendered HTML templates for admin pages;
  • goose for migrations.

Why this stack:

  • simple to deploy;
  • less JS and frontend complexity;
  • good fit for an internal admin panel;
  • easier to keep maintainable for a small self-hosted tool.

2. Quick glossary

GUI

  • graphical user interface;
  • here it simply means the admin web panel in a browser.

chi

  • a small and fast HTTP router for Go;
  • this is not CI;
  • it helps map routes like /api/v1/projects/{id} to handlers.

CI

  • continuous integration;
  • automated checks that run on commits, for example tests, linting, or building Docker images.

server-rendered HTML

  • the Go server itself generates HTML pages and returns them to the browser;
  • this keeps the admin panel simpler than building a separate frontend app.

3. Architecture proposal

Suggested project structure:

/cmd/server
/internal/app
/internal/http
/internal/auth
/internal/projects
/internal/releases
/internal/apikeys
/internal/users
/internal/tags
/internal/storage
/internal/db
/internal/config
/web/templates
/web/static
/migrations
/data

Main modules

projects

  • create/update/list/archive projects
  • manage project tags

releases

  • upload artifact
  • compute checksum
  • store metadata
  • provide release lookup and download

apikeys

  • generate secure random API keys
  • hash and persist
  • enforce permissions and project scope

tags

  • CRUD for tags
  • attach tags to projects
  • resolve tag-based access rules

users

  • admin authentication
  • password hashing
  • role checks

storage

  • local filesystem storage abstraction
  • future option to swap to S3-compatible storage

4. Suggested data model

Core tables:

  • users
  • projects
  • tags
  • project_tags
  • releases
  • api_keys
  • api_key_project_access
  • api_key_tag_access
  • sessions if server-side sessions are used
  • optionally audit_logs

Example relations

  • one project has many releases
  • one user uploads many releases
  • one project has many tags through project_tags
  • one api_key can reference many projects through api_key_project_access
  • one api_key can reference many tags through api_key_tag_access

Suggested key columns in api_keys:

  • scope_mode with values:
    • all_projects
    • project_allow_list
    • project_deny_list
    • tag_allow_list
    • tag_deny_list

5. Permission strategy

Recommended first implementation:

  • API key has boolean flags:
    • can_download
    • can_upload
    • can_delete
    • can_manage_projects
  • API key has access mode:
    • all_projects
    • project_allow_list
    • project_deny_list
    • tag_allow_list
    • tag_deny_list
  • linked projects stored in api_key_project_access
  • linked tags stored in api_key_tag_access

Recommended evaluation rules:

  • all_projects: allow every active project
  • project_allow_list: allow only linked projects
  • project_deny_list: allow every active project except linked projects
  • tag_allow_list: allow projects matching at least one linked tag
  • tag_deny_list: allow every active project except projects matching blocked tags

Recommended constraint for v1:

  • each key uses exactly one scope mode at a time.

This supports whitelist, blacklist, and future grouping without building a full RBAC engine upfront.

6. API design strategy

Split API into two logical areas:

Client API

Used by application clients:

  • authenticate by bearer API key
  • list accessible projects
  • query latest release
  • download release artifact

Admin API

Used by web UI and optionally automation:

  • manage projects
  • manage tags
  • manage releases
  • manage API keys
  • manage users

Keep both under /api/v1, but separate middleware and handlers clearly.

7. File upload strategy

Recommended upload flow:

  1. admin uploads file;
  2. backend stores temporary stream;
  3. checksum is calculated;
  4. file is moved into final artifact path;
  5. release metadata is inserted into DB;
  6. transaction/state is finalized.

Important safeguards:

  • limit file size;
  • sanitize filenames;
  • prevent path traversal;
  • avoid duplicate version collisions unless explicitly replacing;
  • validate project exists before storing;
  • store uploads outside any static web root;
  • never execute or unpack uploaded files.

8. Security checklist

  • hash passwords with bcrypt or argon2id
  • hash API keys before storing
  • show full API key only once
  • secure cookies with HttpOnly, Secure, SameSite
  • CSRF protection for admin forms
  • upload size limits
  • permission checks on every API endpoint
  • request logging without leaking secrets
  • rate limiting for login and API key endpoints
  • store artifacts outside the web root
  • serve downloads only after auth and permission checks
  • set server timeouts: read, write, idle, header
  • add security headers such as Content-Security-Policy, X-Frame-Options, X-Content-Type-Options
  • terminate TLS at Caddy or Nginx
  • optionally restrict admin UI by IP allow-list or VPN
  • avoid shelling out to external tools for file processing
  • keep dependencies updated and scan them periodically

9. Internet-facing deployment posture

If the server will be visible on the internet, this is the safe baseline:

  • app listens only behind a reverse proxy;
  • reverse proxy handles HTTPS certificates;
  • admin UI uses strong password and optionally IP allow-list;
  • SQLite file and artifacts live on a mounted persistent volume;
  • no public directory listing for artifacts;
  • uploads never become directly executable server-side content;
  • logs and backups are stored separately from app code.

10. Development strategy

Recommended approach:

  • develop locally on your Mac first;
  • keep everything in one project directory;
  • run the Go server natively for fast iteration;
  • add Docker packaging once the core flows work locally;
  • deploy to Proxmox only after the first end-to-end flow is stable.

Why local-first is better here:

  • faster feedback loop;
  • easier debugging;
  • easier file upload testing;
  • no need to fight remote networking while core logic is still changing.

Good compromise:

  • write code locally on Mac;
  • keep deployment target from day one in mind;
  • periodically verify that the Docker image still builds.

11. Deployment strategy

Single container is realistic.

Recommended runtime layout:

  • app binary in container
  • reverse proxy in front of container
  • mounted /data volume
  • SQLite DB in /data/db.sqlite
  • artifacts in /data/artifacts

Environment variables

  • APP_ADDR
  • APP_BASE_URL
  • DATA_DIR
  • SQLITE_PATH
  • ADMIN_EMAIL
  • ADMIN_PASSWORD
  • SESSION_SECRET

Recommended deployment target:

  • Proxmox VM or LXC with Docker or Podman;
  • app container plus reverse proxy;
  • mounted volume for /data;
  • regular backup of /data.

12. Delivery phases

Phase 1 - Skeleton

  • initialize Go module
  • wire config
  • HTTP server
  • health endpoint
  • migrations setup
  • SQLite connection
  • basic template rendering

Phase 2 - Auth and admin bootstrap

  • user table
  • create initial admin user
  • login/logout
  • session middleware

Phase 3 - Projects and releases

  • projects CRUD
  • project tags CRUD
  • release upload
  • release list/detail
  • local artifact storage

Phase 4 - API keys and access control

  • API key generation
  • hashed storage
  • project white-list and black-list
  • tag-based schema and access checks
  • permission middleware

Phase 5 - Client update API

  • latest release endpoint
  • release metadata endpoint
  • download endpoint
  • audit of last key usage

Phase 6 - Hardening

  • validation
  • CSRF
  • logging
  • soft deletes
  • basic audit logs
  • reverse proxy config
  • rate limiting
  • Docker image and compose setup

13. Agent execution plan

If multiple AI agents or contributors will implement this, split work by vertical ownership.

Agent 1 - Core platform

Owns:

  • Go module setup
  • config
  • server bootstrap
  • middleware skeleton
  • Docker setup

Agent 2 - Data layer

Owns:

  • migrations
  • schema
  • repositories/queries
  • SQLite integration
  • tags and access-rule tables

Agent 3 - Auth and users

Owns:

  • admin login
  • sessions
  • password handling
  • user management basics

Agent 4 - Projects and releases

Owns:

  • project CRUD
  • tag assignment to projects
  • release upload flow
  • artifact storage abstraction
  • checksum logic

Agent 5 - API keys and client API

Owns:

  • API key generation
  • permission model
  • whitelist/blacklist evaluation
  • tag-based access evaluation
  • client-facing release lookup and download endpoints

Agent 6 - Admin UI

Owns:

  • HTML templates
  • forms
  • tables/pages for projects, releases, keys, users, tags

Agent 7 - Security and deployment hardening

Owns:

  • secure headers
  • rate limiting
  • reverse proxy templates
  • deployment hardening review
  1. Agent 1 sets up application skeleton and app wiring.
  2. Agent 2 defines schema and migrations.
  3. Agent 3 implements admin auth.
  4. Agent 4 implements projects, tags, and release storage.
  5. Agent 5 implements API key model and client endpoints.
  6. Agent 6 builds the admin UI on top of completed flows.
  7. Agent 7 hardens internet-facing deployment paths.
  8. Final pass integrates validation, tests, and Docker packaging.

15. Testing strategy

Unit tests

  • version selection logic
  • permission checks
  • API key hashing/lookup
  • checksum generation
  • tag scope matching

Integration tests

  • login flow
  • create project
  • attach tags to project
  • upload release
  • create API key
  • fetch latest release via API key
  • reject unauthorized project access
  • reject blacklisted project or tag access

Manual sanity tests

  • upload file from admin UI
  • download via curl using bearer API key
  • restart container and verify persistence
  • verify admin login rate limits
  • verify artifacts are not directly exposed by URL guessing

16. My recommendations on product scope

To avoid overbuilding too early, I would start with:

  • SQLite
  • local filesystem storage
  • server-rendered admin UI
  • one file per release
  • one admin role first, but schema ready for more users
  • one scope mode per key
  • project whitelist and blacklist in v1
  • project tags in schema from day one

This version will already be useful and can stay very small operationally.

17. Nice first concrete milestone

The first milestone should be:

"Admin can log in, create a tagged project, upload a versioned file, create an API key with project or tag-based access, and a client can download the latest file using that key."

If that works end-to-end, the rest can be layered on safely.