Files
swanadiva a0c8483c0e docs: migrate all planning docs from React to GoFiber + HTMX
- New ARCHITECTURE_HTMX.md — comprehensive HTMX architecture doc
- ARCHITECTURE.md — updated to point to HTMX version
- UI_COMPONENTS.md — replaced React tree with HTMX partials
- SPRINT_PLAN.md — all sprint tasks updated for HTMX
- BUILD_SYSTEM.md — simplified (no Vite, no npm)
- TIMELINE.md — 3.5 week HTMX timeline
- PROGRESS.md — updated status + HTMX
- AGENTS.md — updated checkpoint with HTMX decision
2026-07-07 12:15:19 +07:00

253 lines
7.6 KiB
Markdown

# Hostkeeper V2 — Sprint Plan (HTMX)
> **Status**: Migrasi React → HTMX
> **Last Updated**: 2026-07-07
> **Framework**: GoFiber v2 + HTMX + Alpine.js + TailwindCSS v4
---
## Sprint 0 — Setup GoFiber + HTMX
**Goal**: GoFiber server running, layout HTML renders, TailwindCSS works.
### Tasks
| # | Task | Files | Verify |
|---|------|-------|--------|
| 0.1 | Go module init | `app/backend/go.mod` | `go mod init` clean |
| 0.2 | Install GoFiber + deps | `go.mod` | `go get github.com/gofiber/fiber/v2` |
| 0.3 | Minimal Fiber server | `app/backend/main.go` | Server starts on :1947 |
| 0.4 | Static files serving | `main.go` | `/static/` serves files |
| 0.5 | HTML template engine | `main.go` + `views/layout.html` | Template renders |
| 0.6 | Download HTMX + Alpine | `static/js/htmx.min.js`, `static/js/alpine.min.js` | JS files exist |
| 0.7 | Setup TailwindCSS v4 | `static/css/output.css` | Tailwind classes work |
| 0.8 | Custom CSS (Lumina) | `static/css/custom.css` | dot-grid, glassmorphism, keyframes |
| 0.9 | Layout template | `views/layout.html` | Sidebar + header + main |
| 0.10 | Nav template | `views/partials/nav.html` | Nav items with active state |
| 0.11 | Index + routing | `views/index.html` + `handler/dashboard.go` | Dashboard renders |
| 0.12 | Health endpoint | `handler/health.go` | `curl :1947/api/health` |
### Files to Create (Sprint 0)
```
app/backend/
├── main.go
├── go.mod
├── go.sum
├── internal/
│ ├── handler/
│ │ ├── dashboard.go
│ │ └── health.go
│ └── middleware/
│ └── viewdata.go
├── static/
│ ├── css/
│ │ ├── output.css
│ │ └── custom.css
│ └── js/
│ ├── htmx.min.js
│ └── alpine.min.js
└── views/
├── layout.html
├── index.html
└── partials/
└── nav.html
```
---
## Sprint 1 — Dashboard + Host List
**Goal**: Dashboard halaman dengan host list, search, filter, add host modal.
### Tasks
| # | Task | Files |
|---|------|-------|
| 1.1 | Model Host | `internal/model/host.go` |
| 1.2 | Dashboard handler | `internal/handler/dashboard.go` |
| 1.3 | Dashboard template | `views/partials/dashboard.html` |
| 1.4 | Host list partial | `views/partials/host_list.html` |
| 1.5 | Host card partial | `views/partials/host_card.html` |
| 1.6 | Search HTMX | `hx-get="/hosts?q=..." hx-trigger="keyup delay:200ms"` |
| 1.7 | Filter status | `hx-get="/hosts?filter=active"` + `<select>` |
| 1.8 | View toggle (grid/list) | Alpine `x-data` |
| 1.9 | Add host modal | `views/partials/host_modal.html` + Alpine |
| 1.10 | POST /hosts | Handler create host |
| 1.11 | Background transfers | `views/partials/dashboard.html` |
### Files to Create (Sprint 1)
```
internal/model/host.go
views/partials/dashboard.html
views/partials/host_list.html
views/partials/host_card.html
views/partials/host_modal.html
views/partials/toast.html
static/js/clipboard.js ← mulai buat
```
---
## Sprint 2 — Snippets + Keychain
**Goal**: Snippet library + credential keychain dengan CRUD.
### Tasks
| # | Task | Files |
|---|------|-------|
| 2.1 | Model Snippet | `internal/model/snippet.go` |
| 2.2 | Model Keychain | `internal/model/keychain.go` |
| 2.3 | Snippets handler | `internal/handler/snippets.go` |
| 2.4 | Keychain handler | `internal/handler/keychain.go` |
| 2.5 | Snippets template | `views/partials/snippets.html` |
| 2.6 | Snippet grid partial | `views/partials/snippet_grid.html` |
| 2.7 | Snippet modal | `views/partials/snippet_modal.html` |
| 2.8 | Keychain template | `views/partials/keychain.html` |
| 2.9 | Key grid partial | `views/partials/key_grid.html` |
| 2.10 | Key modal | `views/partials/key_modal.html` |
| 2.11 | Clipboard JS | `static/js/clipboard.js` |
| 2.12 | Passphrase reveal + strength | `static/js/utils.js` |
### Files to Create (Sprint 2)
```
internal/model/snippet.go
internal/model/keychain.go
internal/handler/snippets.go
internal/handler/keychain.go
views/partials/snippets.html
views/partials/snippet_grid.html
views/partials/snippet_modal.html
views/partials/keychain.html
views/partials/key_grid.html
views/partials/key_modal.html
static/js/clipboard.js
static/js/utils.js
```
---
## Sprint 3 — Settings + Brief Overlay
**Goal**: Settings page with profile form, toggles, connected devices.
### Tasks
| # | Task | Files |
|---|------|-------|
| 3.1 | Model Device + Config | `internal/model/device.go`, `internal/model/config.go` |
| 3.2 | Settings handler | `internal/handler/settings.go` |
| 3.3 | Brief handler | `internal/handler/brief.go` |
| 3.4 | Settings template | `views/partials/settings.html` |
| 3.5 | Brief template | `views/partials/brief.html` |
| 3.6 | Toggle switch JS | `static/js/toggles.js` |
| 3.7 | Toggle CSS | In custom.css |
| 3.8 | Danger zone | `localStorage.clear()` handler |
### Files to Create (Sprint 3)
```
internal/model/device.go
internal/model/config.go
internal/handler/settings.go
internal/handler/brief.go
views/partials/settings.html
views/partials/brief.html
static/js/toggles.js
```
---
## Sprint 4 — SFTP Dual-Pane
**Goal**: File browser dual-pane dengan navigasi folder, upload/download.
### Tasks
| # | Task | Files |
|---|------|-------|
| 4.1 | Model FileItem | `internal/model/file.go` |
| 4.2 | Model Transfer | `internal/model/transfer.go` |
| 4.3 | SFTP handler | `internal/handler/sftp.go` |
| 4.4 | SFTP template | `views/partials/sftp.html` |
| 4.5 | SFTP pane partial | `views/partials/sftp_pane.html` |
| 4.6 | Breadcrumb navigation | In sftp.html |
| 4.7 | Folder create + delete | Modal Alpine + POST |
| 4.8 | Toast notification | Alpine `x-data` |
### Files to Create (Sprint 4)
```
internal/model/file.go
internal/model/transfer.go
internal/handler/sftp.go
views/partials/sftp.html
views/partials/sftp_pane.html
```
---
## Sprint 5 — Terminal + xterm.js
**Goal**: SSH terminal via WebSocket + xterm.js dengan multi-tab.
### Tasks
| # | Task | Files |
|---|------|-------|
| 5.1 | Download xterm.js | `static/xterm/xterm.js`, `static/xterm/xterm.css` |
| 5.2 | Terminal handler | `internal/handler/terminal.go` |
| 5.3 | WebSocket handler | `internal/handler/terminal.go` (WS upgrade) |
| 5.4 | Terminal template | `views/partials/terminal.html` |
| 5.5 | Terminal JS | `static/js/terminal.js` (xterm init + WS) |
| 5.6 | Tab management | Alpine `x-data="terminalTabs()"` |
| 5.7 | SSH pipe (mock dulu) | Go backend → SSH via v1/pkg/ssh |
| 5.8 | Multi-tab per host | Alpine state + multiple xterm instances |
### Files to Create (Sprint 5)
```
internal/handler/terminal.go
views/partials/terminal.html
static/js/terminal.js
static/xterm/xterm.js
static/xterm/xterm.css
```
---
## Sprint 6 — Data Store Integration
**Goal**: Ganti mock data dengan real storage dari v1/pkg/. Integrasi SSH, SFTP, crypto.
### Tasks
| # | Task | Files |
|---|------|-------|
| 6.1 | replace directive go.mod | `app/backend/go.mod` |
| 6.2 | Integrate v1/pkg/storage | Semua handler |
| 6.3 | Integrate v1/pkg/config | `handler/settings.go` |
| 6.4 | Integrate v1/pkg/crypto | `handler/keychain.go` |
| 6.5 | Integrate v1/pkg/knownhosts | `handler/terminal.go` |
| 6.6 | Real SSH via v1/pkg/ssh | `handler/terminal.go` WS |
| 6.7 | Real SFTP via v1/pkg/ssh | `handler/sftp.go` |
| 6.8 | Remove all mock data | Semua handler |
---
## Total Files
| Sprint | Go Files | HTML Templates | JS Files | CSS Files |
|--------|----------|---------------|----------|-----------|
| Sprint 0 | 4 | 3 | 2 | 2 |
| Sprint 1 | 2 | 5 | 1 | 0 |
| Sprint 2 | 4 | 6 | 2 | 0 |
| Sprint 3 | 4 | 2 | 1 | 0 |
| Sprint 4 | 3 | 2 | 0 | 0 |
| Sprint 5 | 1 | 1 | 1 | 0 |
| Sprint 6 | (modify existing) | 0 | 0 | 0 |
| **Total** | **18** | **19** | **7** | **2** |