init
This commit is contained in:
commit
b15b95781c
108 changed files with 14802 additions and 0 deletions
495
IMPLEMENTATION_PLAN.md
Normal file
495
IMPLEMENTATION_PLAN.md
Normal file
|
|
@ -0,0 +1,495 @@
|
|||
# Update Server - Implementation Strategy
|
||||
|
||||
## 1. Recommended stack
|
||||
|
||||
### 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:
|
||||
|
||||
```text
|
||||
/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
|
||||
|
||||
## 14. Recommended implementation order for agents
|
||||
|
||||
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.
|
||||
Loading…
Add table
Add a link
Reference in a new issue