You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
4.8 KiB
4.8 KiB
Plan
Status: active
Goal: implement the scope defined in ROADMAP.md — a small, login-gated,
container-based file browser that lets an admin mount arbitrary host folders,
browse them in a light/dark web UI, and download or stream video files with
zero server-side transcoding.
Scope
- Go backend, SQLite for users/sessions, server-rendered HTML templates + minimal vanilla JS, single Docker image, plain HTTP behind a reverse proxy.
- Zero unauthenticated access to any route except the login page: login is
gated first, then a mandatory password-change gate for any account with
must_change_password=true(including the seeded admin), then file browsing/download/streaming for bothadminanduserroles. - Multiple named roots are Docker volume mounts declared in a config file/env var (container path + display name), read at startup; adding a root requires a config edit + container restart (documented limitation, not solved in-app).
- Read-only browsing: list folders/files, breadcrumb navigation, strict containment inside each root (no traversal outside the mount, no symlink escape).
- Download and video streaming serve raw bytes with full HTTP
Rangesupport; no transcoding, thumbnailing, or format conversion anywhere. - Admin-only user management: create/list/reset-password/disable users; non-admin gets 403 on admin routes.
- Documentation:
README.mdis kept current with every behavior/interface/ workflow/config change in the same commit that makes the change (no follow-up doc tasks).
Out of scope (this cycle)
- Per-user/per-root permission restrictions.
- Any write operations from the UI (upload/rename/delete/move).
- Cross-folder search.
- App-managed TLS (assumed reverse proxy).
Acceptance Criteria
- No file listing, file content, download, stream, or admin route is ever reachable without a valid authenticated session — verified by an explicit test hitting each such route unauthenticated and expecting a redirect/401, never data.
- Login with the seeded admin (
boss@zecevic-ninja.com/Start1234!) forces a password change before any other page is reachable, and this same forced-change gate applies to any user created later with a temporary password. - Both
adminanduserroles can browse, download, and stream all configured roots; onlyadmincan reach user-management screens. - Downloaded file bytes are byte-identical to the source file; video
Rangerequests return206 Partial Contentwith correct byte ranges, enabling native browser seeking with no server-side transcoding. - Path handling cannot escape a configured root via
../traversal or symlink. docker build+docker run(with a sample volume mount and root config) produces a working, login-gated instance, andREADME.mdis sufficient for an operator to deploy it without reading source.
Implementation Phases
Phase 1 — Scaffolding & config (T-001)
- Go module layout, root-config loading (container path + display name from file/env), Dockerfile skeleton, docker-compose example, README skeleton.
Phase 2 — Data & auth foundation (T-002)
- SQLite schema/migrations for users + sessions, bcrypt hashing, seed admin
with
must_change_password=true, session-cookie middleware, login/logout, forced password-change gate blocking all other routes.
Phase 3 — Folder browsing UI (T-003)
- Root listing, directory navigation with breadcrumbs, strict path containment, light/dark theme, minimal vanilla JS/CSS.
Phase 4 — Download & video streaming (T-004)
- Raw-byte download endpoint, full HTTP Range support for video seek/resume, zero transcoding.
Phase 5 — Admin user management (T-005)
- Admin-only list/create/reset/disable-user screens, role-based route protection (403 for non-admin).
Phase 6 — Packaging & docs finalization (T-006)
- Finalize multi-stage Dockerfile and docker-compose example, complete
README.mdend to end (build/run, root config format, first-login/admin credential flow, forced password change, reverse-proxy TLS + Range passthrough requirement).
Tasks are sequential (T-001 → T-006); each phase's acceptance criteria and
required documentation updates are tracked per-task in .ai/TASKS.md.
Validation
Run before finishing each task, broader pass before commit:
go fmt ./...go vet ./...go test ./...
Task-specific manual/E2E checks (documented per task in .ai/TASKS.md):
- Unauthenticated access attempts against every protected route.
- Forced password-change flow for the seeded admin and for a newly created user.
- Path-traversal / symlink-escape attempts against the browsing routes.
- Checksum comparison of a downloaded file against its source.
Range-header request against a video file, confirming206 Partial Contentand correct byte range.docker build+docker runsmoke test with a sample mounted folder.